feat(compute): 通道编辑表单 mosdel字段加「从 API 获取模型」按钮
- 支持从供应商 API 拉取模型列表,选择后自动填入 models(需先填 Base URL+Key)
This commit is contained in:
@@ -193,8 +193,22 @@ function ChannelFormDialog({ open, row, onClose, onDone }: {
|
||||
}) {
|
||||
const [f, setF] = React.useState<Row>(blank);
|
||||
const [busy, setBusy] = React.useState(false);
|
||||
const [fetching, setFetching] = React.useState(false);
|
||||
const [err, setErr] = React.useState<string | null>(null);
|
||||
|
||||
const fetchModels = async () => {
|
||||
if (!f.base_url || !f.key) { setErr("请先填 Base URL 与 Key 再获取模型"); return; }
|
||||
setFetching(true); setErr(null);
|
||||
const out = await computeAction<any>("POST", "channel/fetch-models", { base_url: f.base_url, key: f.key });
|
||||
setFetching(false);
|
||||
const list = out.data?.models;
|
||||
if (out.ok && Array.isArray(list) && list.length) {
|
||||
set("models", list.join(", "));
|
||||
} else {
|
||||
setErr(out.data?.message || out.message || "获取模型失败");
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (open) { setF(row && row.id ? { ...blank, ...row, model_mapping: row.model_mapping ?? "" } : blank); setErr(null); }
|
||||
}, [open, row]);
|
||||
@@ -232,7 +246,15 @@ function ChannelFormDialog({ open, row, onClose, onDone }: {
|
||||
</Field>
|
||||
<Field label="Key" full><Input value={f.key} onChange={(e) => set("key", e.target.value)} placeholder="API Key / 可多Key" type="password" /></Field>
|
||||
<Field label="Base URL" full><Input value={f.base_url || ""} onChange={(e) => set("base_url", e.target.value)} placeholder="https://api.xxx.com" /></Field>
|
||||
<Field label="模型(逗号分隔)" full><Input value={f.models} onChange={(e) => set("models", e.target.value)} placeholder="gpt-4o,claude-sonnet-4-6" /></Field>
|
||||
<Field label="模型(逗号分隔)" full>
|
||||
<div className="flex items-start gap-2">
|
||||
<Input value={f.models} onChange={(e) => set("models", e.target.value)} placeholder="gpt-4o,claude-sonnet-4-6" />
|
||||
<Button type="button" variant="outline" size="sm" className="whitespace-nowrap"
|
||||
onClick={fetchModels} disabled={fetching || busy}>
|
||||
{fetching && <Loader2 className="animate-spin" />} 从 API 获取
|
||||
</Button>
|
||||
</div>
|
||||
</Field>
|
||||
<Field label="分组"><Input value={f.group} onChange={(e) => set("group", e.target.value)} placeholder="default" /></Field>
|
||||
<Field label="模型映射(socat 映射)"><Input value={f.model_mapping || ""} onChange={(e) => set("model_mapping", e.target.value)} placeholder="model-a=>model-b, ..." /></Field>
|
||||
<Field label="权重"><Input type="number" value={f.weight} onChange={(e) => set("weight", e.target.value)} /></Field>
|
||||
|
||||
Reference in New Issue
Block a user