feat(model): 工作模型与 JARVIS 语音模型分开配置 + 语音任务路由到快模型

模型配置加"用途"维度:工作主力(chat,要强)与 JARVIS 语音(voice,要快/低时延)各配各激活,
语音任务走语音模型池,未配置则透明回落工作模型——不影响现有功能。

- contract: ConfigKindVoice="voice" + Meta[model_profile]=voice(与 intent==report 同类路由)
- gateway: ServeConfig/broadcastActive 循环纳入 voice;submitVoiceTask 打 model_profile=voice 标记
- dispatcher: 第二个 llm.Pool(voicePool)吃 voice 配置热更新;board.useVoice 从 Meta 派生(含快照);
  Orchestrator.agentPool(b) 按黑板选池——语音且语音池就绪→语音池,否则工作池;
  agent 生成路径(graph/react/coordinator/compose)全改走 agentPool(b),报告/护栏/记忆固定工作池
- admin: 模型页三 Tab(工作主力/JARVIS语音/向量化),复用 ModelManager;api Kind 加 voice

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-22 11:39:17 +08:00
parent b6927247da
commit aec7ad949c
15 changed files with 102 additions and 50 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ export async function me(): Promise<AuthUser | null> {
}
// ---- 模型配置(id 为雪花字符串)----
export type Kind = "chat" | "embedding";
export type Kind = "chat" | "voice" | "embedding";
export interface Model {
id: string;
+36 -29
View File
@@ -1,9 +1,17 @@
import { useState } from "react";
import { ModelManager } from "../components/ModelManager";
import type { Kind } from "../api";
// 模型配置页:工作主力(chat) / JARVIS 语音(voice) / 向量化(embedding) 三 Tab 统一管理。
// 工作与语音分开:编排/报告用强模型(chat),JARVIS 语音对话用快模型(voice, 低时延)——各配各激活。
const TABS: { key: Kind; label: string }[] = [
{ key: "chat", label: "工作主力模型" },
{ key: "voice", label: "JARVIS 语音模型" },
{ key: "embedding", label: "向量化模型" },
];
// 模型配置页:Chat / Embedding 双 Tab 统一管理。
export function ModelsPage() {
const [tab, setTab] = useState<"chat" | "embedding">("chat");
const [tab, setTab] = useState<Kind>("chat");
return (
<div className="space-y-6">
@@ -11,46 +19,46 @@ export function ModelsPage() {
<div className="flex flex-wrap items-center justify-between gap-4 border-b border-gray-150 pb-4">
<div>
<h3 className="text-base font-semibold text-gray-800"></h3>
<p className="text-xs text-gray-400">LLMEmbedding</p>
<p className="text-xs text-gray-400">/· JARVIS · RAG</p>
</div>
<div className="flex rounded-lg border border-gray-200 bg-gray-50/50 p-1">
<button
onClick={() => setTab("chat")}
className={`rounded-md px-4 py-1.5 text-xs font-medium transition-all ${
tab === "chat"
? "bg-white text-violet-700 shadow-sm"
: "text-gray-500 hover:text-gray-700"
}`}
>
(Chat)
</button>
<button
onClick={() => setTab("embedding")}
className={`rounded-md px-4 py-1.5 text-xs font-medium transition-all ${
tab === "embedding"
? "bg-white text-violet-700 shadow-sm"
: "text-gray-500 hover:text-gray-700"
}`}
>
(Embedding)
</button>
{TABS.map((t) => (
<button
key={t.key}
onClick={() => setTab(t.key)}
className={`rounded-md px-4 py-1.5 text-xs font-medium transition-all ${
tab === t.key ? "bg-white text-violet-700 shadow-sm" : "text-gray-500 hover:text-gray-700"
}`}
>
{t.label}
</button>
))}
</div>
</div>
{/* 模型管理组件 */}
<div className="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
{tab === "chat" ? (
{tab === "chat" && (
<ModelManager
kind="chat"
title="对话模型配置 (chat → Dispatcher)"
title="工作主力模型 (chat → Dispatcher 编排/报告)"
baseUrlHint="https://api.deepseek.com"
modelHint="deepseek-v4-pro"
/>
)}
{tab === "voice" && (
<ModelManager
kind="voice"
title="JARVIS 语音模型 (voice → 语音对话,选快模型抢首字时延)"
baseUrlHint="https://api.deepseek.com"
modelHint="deepseek-chat"
/>
) : (
)}
{tab === "embedding" && (
<ModelManager
kind="embedding"
title="向量化模型配置 (embedding → mcp-go RAG)"
title="向量化模型 (embedding → mcp-go RAG)"
baseUrlHint="https://dashscope.aliyuncs.com/compatible-mode/v1"
modelHint="text-embedding-v3"
/>
@@ -59,4 +67,3 @@ export function ModelsPage() {
</div>
);
}