This commit is contained in:
王性驊 2026-06-28 16:52:29 +08:00
parent acd6eb93e9
commit 184e7763ac
2 changed files with 25 additions and 22 deletions

View File

@ -42,10 +42,17 @@ function parseConfigured(raw: Record<string, unknown> | undefined): Record<Provi
} }
function pickModel(models: string[], current: string | undefined, fallback: string): string { function pickModel(models: string[], current: string | undefined, fallback: string): string {
if (current && models.includes(current)) return current const trimmed = current?.trim()
if (trimmed) return trimmed
return models[0] ?? fallback return models[0] ?? fallback
} }
function mergeModelOptions(models: string[], current: string | undefined): string[] {
const trimmed = current?.trim()
if (!trimmed || models.includes(trimmed)) return models
return [trimmed, ...models]
}
export function AccountAiSettings({ accountId, compact }: AccountAiSettingsProps) { export function AccountAiSettings({ accountId, compact }: AccountAiSettingsProps) {
const [settings, setSettings] = useState<ThreadsAccountAiSettingsData | null>(null) const [settings, setSettings] = useState<ThreadsAccountAiSettingsData | null>(null)
const [keyInputs, setKeyInputs] = useState<ProviderApiKeys>({}) const [keyInputs, setKeyInputs] = useState<ProviderApiKeys>({})
@ -87,15 +94,12 @@ export function AccountAiSettings({ accountId, compact }: AccountAiSettingsProps
const mainProvider = normalizeSupportedProvider(prev.provider) const mainProvider = normalizeSupportedProvider(prev.provider)
const researchProv = normalizeSupportedProvider(prev.research_provider ?? mainProvider) const researchProv = normalizeSupportedProvider(prev.research_provider ?? mainProvider)
let next = prev let next = prev
if (providerId === mainProvider && !models.includes(prev.model)) { if (providerId === mainProvider && !prev.model?.trim()) {
next = { ...next, model: models[0] } next = { ...next, model: models[0] }
} }
if (providerId === researchProv) { if (providerId === researchProv && !prev.research_model?.trim()) {
const currentResearch = prev.research_model ?? ''
if (!currentResearch || !models.includes(currentResearch)) {
next = { ...next, research_model: models[0] } next = { ...next, research_model: models[0] }
} }
}
return next return next
}) })
} }
@ -175,6 +179,8 @@ export function AccountAiSettings({ accountId, compact }: AccountAiSettingsProps
const primaryModels = getModelsForProvider(provider) const primaryModels = getModelsForProvider(provider)
const researchModels = getModelsForProvider(researchProvider) const researchModels = getModelsForProvider(researchProvider)
const primaryModelOptions = mergeModelOptions(primaryModels, settings?.model)
const researchModelOptions = mergeModelOptions(researchModels, settings?.research_model)
const primaryModelsMeta = modelsMeta[provider] const primaryModelsMeta = modelsMeta[provider]
const researchModelsMeta = modelsMeta[researchProvider] const researchModelsMeta = modelsMeta[researchProvider]
const currentProviderConfigured = configured[provider] const currentProviderConfigured = configured[provider]
@ -288,18 +294,18 @@ export function AccountAiSettings({ accountId, compact }: AccountAiSettingsProps
} }
> >
<Select <Select
value={primaryModels.includes(settings.model) ? settings.model : ''} value={settings.model?.trim() ?? ''}
disabled={primaryModelsMeta?.loading || primaryModels.length === 0} disabled={primaryModelsMeta?.loading || primaryModelOptions.length === 0}
onChange={(e) => onChange={(e) =>
setSettings((prev) => (prev ? { ...prev, model: e.target.value } : prev)) setSettings((prev) => (prev ? { ...prev, model: e.target.value } : prev))
} }
> >
{primaryModels.length === 0 ? ( {primaryModelOptions.length === 0 ? (
<option value=""> <option value="">
{primaryModelsMeta?.loading ? '載入中…' : '尚無可用模型'} {primaryModelsMeta?.loading ? '載入中…' : '尚無可用模型'}
</option> </option>
) : ( ) : (
primaryModels.map((model) => ( primaryModelOptions.map((model) => (
<option key={model} value={model}> <option key={model} value={model}>
{model} {model}
</option> </option>
@ -349,24 +355,20 @@ export function AccountAiSettings({ accountId, compact }: AccountAiSettingsProps
} }
> >
<Select <Select
value={ value={settings.research_model?.trim() ?? ''}
settings.research_model && researchModels.includes(settings.research_model) disabled={researchModelsMeta?.loading || researchModelOptions.length === 0}
? settings.research_model
: ''
}
disabled={researchModelsMeta?.loading || researchModels.length === 0}
onChange={(e) => onChange={(e) =>
setSettings((prev) => setSettings((prev) =>
prev ? { ...prev, research_model: e.target.value } : prev, prev ? { ...prev, research_model: e.target.value } : prev,
) )
} }
> >
{researchModels.length === 0 ? ( {researchModelOptions.length === 0 ? (
<option value=""> <option value="">
{researchModelsMeta?.loading ? '載入中…' : '尚無可用模型'} {researchModelsMeta?.loading ? '載入中…' : '尚無可用模型'}
</option> </option>
) : ( ) : (
researchModels.map((model) => ( researchModelOptions.map((model) => (
<option key={model} value={model}> <option key={model} value={model}>
{model} {model}
</option> </option>

View File

@ -82,9 +82,10 @@ export function resolveProviderApiToken(
return value return value
} }
function normalizeModel(provider: ProviderId, model: string | undefined, fallback: string): string { function normalizeModel(_provider: ProviderId, model: string | undefined, fallback: string): string {
const models = modelsForProvider(provider) const trimmed = model?.trim()
if (model && models.includes(model)) return model if (trimmed) return trimmed
const models = modelsForProvider(_provider)
return models[0] ?? fallback return models[0] ?? fallback
} }