feat(admin): 模型配置加「编辑」按钮 + 语音默认提示改 deepseek-v4-flash

- ModelManager: 每行加「编辑」→ 载入表单就地改(api_key 留空=沿用现有密钥),
  后端按 id 走更新而非新增;表单头/按钮随编辑态切换,带「取消」;省去删了重登记
- ModelsPage: 语音默认模型提示 deepseek-chat→deepseek-v4-flash(chat 2026/07/24 弃用)

注:语音模型实例已通过 admin API 从 deepseek-chat 热切到 deepseek-v4-flash(dispatcher
现读 v4-flash,无需重启)——验证了编辑/激活的 NATS 热更新链路。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-22 13:07:13 +08:00
parent a4669a0d82
commit 95f3781076
2 changed files with 31 additions and 5 deletions
+30 -4
View File
@@ -37,10 +37,18 @@ export function ModelManager({
const set = (k: keyof ModelInput, v: string) => setForm((f) => ({ ...f, [k]: v }));
const editing = !!form.id;
// onEdit 把某行载入表单就地编辑(api_key 留空=沿用现有密钥,后端按 id 更新而非新增)。
const onEdit = (m: Model) => {
setForm({ id: m.id, kind, provider: m.provider, base_url: m.base_url, api_key: "", model: m.model });
setMsg("");
};
const onSave = async () => {
try {
await saveModel({ ...form, kind });
setMsg("✓ 已保存");
setMsg(editing ? "✓ 已更新并热更新" : "✓ 已保存");
setForm(empty);
refresh();
} catch (e) {
@@ -107,6 +115,12 @@ export function ModelManager({
</button>
)}
<button
onClick={() => onEdit(m)}
className="rounded border px-2 py-0.5 text-xs text-gray-600 hover:bg-gray-50"
>
</button>
<button
onClick={() => {
// 删除不可撤销,且删掉在用模型会直接打断线上推理——所以要二次确认,
@@ -131,7 +145,9 @@ export function ModelManager({
</section>
<section className="max-w-xl">
<h2 className="mb-3 text-sm font-semibold text-gray-700">线 APIOpenAI </h2>
<h2 className="mb-3 text-sm font-semibold text-gray-700">
{editing ? `编辑「${form.model}」(改完保存即热更新)` : "登记(开发期:第三方在线 APIOpenAI 兼容)"}
</h2>
<div className="grid grid-cols-2 gap-3">
<label className="text-xs text-gray-500">
Provider
@@ -170,12 +186,14 @@ export function ModelManager({
className="mt-1 w-full rounded border px-2 py-1 text-sm font-mono"
value={form.api_key}
onChange={(e) => set("api_key", e.target.value)}
placeholder="sk-…"
placeholder={editing ? "留空=沿用现有密钥" : "sk-…"}
/>
</label>
</div>
<div className="mt-3 flex items-center gap-2">
<button onClick={onSave} className="rounded bg-violet-600 px-3 py-1 text-sm text-white"></button>
<button onClick={onSave} className="rounded bg-violet-600 px-3 py-1 text-sm text-white">
{editing ? "更新" : "保存"}
</button>
<button
onClick={onTest}
disabled={testing || !form.base_url}
@@ -183,6 +201,14 @@ export function ModelManager({
>
{testing ? "测试中…" : "测试连接"}
</button>
{editing && (
<button
onClick={() => { setForm(empty); setMsg(""); }}
className="rounded border px-3 py-1 text-sm text-gray-500 hover:bg-gray-50"
>
</button>
)}
{msg && <span className="text-xs text-gray-600">{msg}</span>}
</div>
</section>
+1 -1
View File
@@ -52,7 +52,7 @@ export function ModelsPage() {
kind="voice"
title="JARVIS 语音模型 (voice → 语音对话,选快模型抢首字时延)"
baseUrlHint="https://api.deepseek.com"
modelHint="deepseek-chat"
modelHint="deepseek-v4-flash"
/>
)}
{tab === "embedding" && (