mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-30 02:14:43 +08:00
feat: replace text inputs with dropdown selects for OpenClaw agent model config
- Add useOpenClawModelOptions hook to aggregate models from all configured OpenClaw providers - Replace read-only primary model display with a searchable Select dropdown - Replace comma-separated fallback text input with add/remove Select rows - Filter out already-selected models from fallback options - Show "(not configured)" marker for values whose provider has been deleted - Unify terminology: rename "主模型/Primary Model" to "默认模型/Default Model"
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { useMemo } from "react";
|
||||
import { useProvidersQuery } from "@/lib/query/queries";
|
||||
import type { OpenClawProviderConfig } from "@/types";
|
||||
|
||||
export interface ModelOption {
|
||||
value: string; // "providerId/modelId"
|
||||
label: string; // "Provider Name / Model Name"
|
||||
}
|
||||
|
||||
export function useOpenClawModelOptions(): {
|
||||
options: ModelOption[];
|
||||
isLoading: boolean;
|
||||
} {
|
||||
const { data: providersData, isLoading } = useProvidersQuery("openclaw");
|
||||
|
||||
const options = useMemo<ModelOption[]>(() => {
|
||||
const allProviders = providersData?.providers;
|
||||
if (!allProviders) return [];
|
||||
|
||||
const dedupedOptions = new Map<string, string>();
|
||||
|
||||
for (const [providerKey, provider] of Object.entries(allProviders)) {
|
||||
let config: OpenClawProviderConfig;
|
||||
try {
|
||||
config =
|
||||
typeof provider.settingsConfig === "string"
|
||||
? (JSON.parse(provider.settingsConfig) as OpenClawProviderConfig)
|
||||
: (provider.settingsConfig as OpenClawProviderConfig);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
|
||||
const models = config.models;
|
||||
if (!Array.isArray(models)) continue;
|
||||
|
||||
const providerDisplayName =
|
||||
typeof provider.name === "string" && provider.name.trim()
|
||||
? provider.name
|
||||
: providerKey;
|
||||
|
||||
for (const model of models) {
|
||||
if (!model.id) continue;
|
||||
const value = `${providerKey}/${model.id}`;
|
||||
const modelDisplayName =
|
||||
typeof model.name === "string" && model.name.trim()
|
||||
? model.name
|
||||
: model.id;
|
||||
const label = `${providerDisplayName} / ${modelDisplayName}`;
|
||||
|
||||
if (!dedupedOptions.has(value)) {
|
||||
dedupedOptions.set(value, label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(dedupedOptions.entries())
|
||||
.map(([value, label]) => ({ value, label }))
|
||||
.sort((a, b) => a.label.localeCompare(b.label, "zh-CN"));
|
||||
}, [providersData?.providers]);
|
||||
|
||||
return { options, isLoading };
|
||||
}
|
||||
Reference in New Issue
Block a user