refactor(llm): merge preset selection into base URL field

Use a single editable Base URL combobox for LLM providers so preset endpoints and manual input share one field, with preset types shown as subtitles.
This commit is contained in:
jxxghp
2026-05-03 11:31:06 +08:00
parent a40e52079f
commit aa49c6ccbc
6 changed files with 29 additions and 34 deletions
+9 -2
View File
@@ -21,6 +21,12 @@ export interface LlmProviderUrlPreset {
value: string value: string
} }
export interface LlmProviderUrlPresetItem {
title: string
value: string
subtitle?: string
}
export interface LlmProvider { export interface LlmProvider {
id: string id: string
name: string name: string
@@ -102,10 +108,11 @@ export function useLlmProviderDirectory(options: UseLlmProviderDirectoryOptions)
() => models.value.find(item => item.id === normalizeValue(options.model.value)) || null, () => models.value.find(item => item.id === normalizeValue(options.model.value)) || null,
) )
const providerItems = computed(() => providers.value.map(item => ({ title: item.name, value: item.id }))) const providerItems = computed(() => providers.value.map(item => ({ title: item.name, value: item.id })))
const baseUrlPresetItems = computed(() => const baseUrlPresetItems = computed<LlmProviderUrlPresetItem[]>(() =>
(selectedProvider.value?.base_url_presets || []).map(item => ({ (selectedProvider.value?.base_url_presets || []).map(item => ({
title: item.label, title: item.value,
value: item.value, value: item.value,
subtitle: item.label,
})), })),
) )
const providerConnected = computed(() => Boolean(selectedProvider.value?.auth_status?.connected)) const providerConnected = computed(() => Boolean(selectedProvider.value?.auth_status?.connected))
-2
View File
@@ -1355,8 +1355,6 @@ export default {
llmApiKey: 'LLM API Key', llmApiKey: 'LLM API Key',
llmApiKeyHint: 'API key from the LLM service provider for authentication', llmApiKeyHint: 'API key from the LLM service provider for authentication',
llmApiKeyPlaceholder: 'Please enter API key', llmApiKeyPlaceholder: 'Please enter API key',
llmBaseUrlPreset: 'LLM URL Preset',
llmBaseUrlPresetHint: 'Start with a provider preset URL, then edit the actual request URL below if needed',
llmBaseUrl: 'LLM Base URL', llmBaseUrl: 'LLM Base URL',
llmBaseUrlHint: 'Base URL for LLM API, used for custom API endpoints', llmBaseUrlHint: 'Base URL for LLM API, used for custom API endpoints',
llmProviderAuth: 'Provider Authorization', llmProviderAuth: 'Provider Authorization',
-2
View File
@@ -1348,8 +1348,6 @@ export default {
llmApiKey: 'LLM API密钥', llmApiKey: 'LLM API密钥',
llmApiKeyHint: 'LLM服务提供商的API密钥,用于身份验证', llmApiKeyHint: 'LLM服务提供商的API密钥,用于身份验证',
llmApiKeyPlaceholder: '请输入API密钥', llmApiKeyPlaceholder: '请输入API密钥',
llmBaseUrlPreset: 'LLM地址预设',
llmBaseUrlPresetHint: '可先选择供应商预设地址,再按需修改下方实际调用地址',
llmBaseUrl: 'LLM基础URL', llmBaseUrl: 'LLM基础URL',
llmBaseUrlHint: 'LLM API的基础URL地址,用于自定义API端点', llmBaseUrlHint: 'LLM API的基础URL地址,用于自定义API端点',
llmProviderAuth: '提供商授权', llmProviderAuth: '提供商授权',
-2
View File
@@ -1350,8 +1350,6 @@ export default {
llmApiKey: 'LLM API密鑰', llmApiKey: 'LLM API密鑰',
llmApiKeyHint: 'LLM服務提供商的API密鑰,用於身份驗證', llmApiKeyHint: 'LLM服務提供商的API密鑰,用於身份驗證',
llmApiKeyPlaceholder: '請輸入API密鑰', llmApiKeyPlaceholder: '請輸入API密鑰',
llmBaseUrlPreset: 'LLM位址預設',
llmBaseUrlPresetHint: '可先選擇提供商預設位址,再按需修改下方實際調用位址',
llmBaseUrl: 'LLM基礎URL', llmBaseUrl: 'LLM基礎URL',
llmBaseUrlHint: 'LLM API的基礎URL地址,用於自定義API端點', llmBaseUrlHint: 'LLM API的基礎URL地址,用於自定義API端點',
llmProviderAuth: '提供商授權', llmProviderAuth: '提供商授權',
+10 -13
View File
@@ -1016,27 +1016,24 @@ watch(currentLlmSnapshotKey, (snapshotKey, previousSnapshotKey) => {
/> />
</VCol> </VCol>
<VCol v-if="SystemSettings.Basic.AI_AGENT_ENABLE && showBaseUrlField" cols="12" md="6"> <VCol v-if="SystemSettings.Basic.AI_AGENT_ENABLE && showBaseUrlField" cols="12" md="6">
<VSelect <VCombobox
v-if="llmBaseUrlPresetItems.length > 0"
:model-value="SystemSettings.Basic.LLM_BASE_URL" :model-value="SystemSettings.Basic.LLM_BASE_URL"
@update:model-value="(value: any) => { @update:model-value="(value: any) => {
SystemSettings.Basic.LLM_BASE_URL = value || ''; SystemSettings.Basic.LLM_BASE_URL = typeof value === 'object' && value !== null ? value.value : (value || '');
}" }"
:label="t('setting.system.llmBaseUrlPreset')"
:hint="t('setting.system.llmBaseUrlPresetHint')"
:items="llmBaseUrlPresetItems"
persistent-hint
prepend-inner-icon="mdi-format-list-bulleted-square"
class="mb-3"
/>
<VTextField
v-model="SystemSettings.Basic.LLM_BASE_URL"
:label="t('setting.system.llmBaseUrl')" :label="t('setting.system.llmBaseUrl')"
:hint="t('setting.system.llmBaseUrlHint')" :hint="t('setting.system.llmBaseUrlHint')"
:placeholder="selectedLlmProvider?.default_base_url || 'https://api.deepseek.com'" :placeholder="selectedLlmProvider?.default_base_url || 'https://api.deepseek.com'"
:items="llmBaseUrlPresetItems"
item-title="title"
item-value="value"
persistent-hint persistent-hint
prepend-inner-icon="mdi-link" prepend-inner-icon="mdi-link"
/> >
<template #item="{ props, item }">
<VListItem v-bind="props" :subtitle="item.raw.subtitle" />
</template>
</VCombobox>
</VCol> </VCol>
<VCol v-if="SystemSettings.Basic.AI_AGENT_ENABLE && showApiKeyField" cols="12" md="6"> <VCol v-if="SystemSettings.Basic.AI_AGENT_ENABLE && showApiKeyField" cols="12" md="6">
<VTextField <VTextField
+10 -13
View File
@@ -229,27 +229,24 @@ onMounted(async () => {
</VCol> </VCol>
<VCol v-if="showBaseUrlField" cols="12" md="6"> <VCol v-if="showBaseUrlField" cols="12" md="6">
<VSelect <VCombobox
v-if="baseUrlPresetItems.length > 0"
:model-value="wizardData.agent.baseUrl" :model-value="wizardData.agent.baseUrl"
@update:model-value="(value: any) => { @update:model-value="(value: any) => {
wizardData.agent.baseUrl = value || ''; wizardData.agent.baseUrl = typeof value === 'object' && value !== null ? value.value : (value || '');
}" }"
:label="t('setting.system.llmBaseUrlPreset')"
:hint="t('setting.system.llmBaseUrlPresetHint')"
:items="baseUrlPresetItems"
persistent-hint
prepend-inner-icon="mdi-format-list-bulleted-square"
class="mb-3"
/>
<VTextField
v-model="wizardData.agent.baseUrl"
:label="t('setting.system.llmBaseUrl')" :label="t('setting.system.llmBaseUrl')"
:hint="t('setting.system.llmBaseUrlHint')" :hint="t('setting.system.llmBaseUrlHint')"
:placeholder="selectedProvider?.default_base_url || 'https://api.deepseek.com'" :placeholder="selectedProvider?.default_base_url || 'https://api.deepseek.com'"
:items="baseUrlPresetItems"
item-title="title"
item-value="value"
persistent-hint persistent-hint
prepend-inner-icon="mdi-link-variant" prepend-inner-icon="mdi-link-variant"
/> >
<template #item="{ props, item }">
<VListItem v-bind="props" :subtitle="item.raw.subtitle" />
</template>
</VCombobox>
</VCol> </VCol>
<VCol v-if="showApiKeyField" cols="12" md="6"> <VCol v-if="showApiKeyField" cols="12" md="6">