feat(gateway,admin-web): 面板可编辑 provider 推理形状 / 角色级路由 / multimodal 真语义(裁决 03.4.2/03.4.1)
- 后端:AdminLlmProvider 暴露 reasoning{kind}(恒下发,""=未声明=auto)、personaModels、personaProviders;
顶层新增 reasoningKinds / personaProviderOptions 两个**取值域**(唯一来源= runtimeconfig 导出枚举,
校验错误文案也由枚举拼接 ⇒ 不可能漂移)
- 读写共用同一映射(admin_llm_provider.go),避免「读侧少一个键 ⇒ 面板一保存就抹掉」
- 写侧语义:缺失=保留、给出=整块/整表替换;非法值一律 runtimeconfig.Group.Validate() ⇒ 400 bad_request
(实测非法 kind 返回 400 且 models.json 完全不动,而非 500 静默失败)
- 前端:新增 LlmProviderRouting(推理形状下拉 + multimodal 开关 + 按角色路由编辑器);
目录能力位改三态(true/false/未标注),「未标注」不再谎称「不支持」;目录/角色清单不可用时
**不阻塞编辑**且与「字段为空」是不同状态;绝无 mock/sample 回退
- 复核:build/vet 绿 + gateway/config 包测试绿 + tsc 0 错 + vite build 成功;2 条变异反证(删 reasoning
补丁 → 2 例红;删 Group.Validate → 该 400 用例红)已还原
- 注意(主会话已知):npm run build 把新 SPA 写进 frontend/web/dist,而运行中的二进制优先从磁盘读该目录
⇒ :10942 目前是「新面板 + 旧后端」,等阶段 5 全绿后按红线「先 build 到位、再一次 restart」切换
This commit is contained in:
1 parent
8890c30bb5
commit
1ac02bd77e
12 files changed
+998
-85
No files matched your search
@@ -123,6 +123,13 @@ export interface AdminUserRecord {
|
||||
createdAt?: string;
|
||||
}
|
||||
|
||||
/** 一个 provider 组的推理开关形状声明(models.json 的 `reasoning` 块的线上投影)。
|
||||
* kind 为空串 = **未声明形状**(等同 auto:按模型名/baseURL 推断,形状有歧义时
|
||||
* 不下发任何开关),与「后端没报告这个字段」是两种状态。 */
|
||||
export interface AdminLlmReasoning {
|
||||
kind: string;
|
||||
}
|
||||
|
||||
/** LLM provider/model configuration (GET/PUT /api/v1/admin/llm, design/04 §3.1).
|
||||
* API key is never returned by the backend; provider is the wire protocol. */
|
||||
export interface AdminLlmProvider {
|
||||
@@ -131,15 +138,28 @@ export interface AdminLlmProvider {
|
||||
provider: string;
|
||||
baseUrl: string;
|
||||
model: string;
|
||||
/** 主模型**自己能否收图**(裁决 14.4.1)。它不表示本部署有视觉能力:图片识别 /
|
||||
* OCR 工具用的模型由 .env 的 LLM_VISION_MODEL / LLM_OCR_MODEL 单独配置。 */
|
||||
multimodal: boolean;
|
||||
enabled: boolean;
|
||||
fallback?: string;
|
||||
/** The group's token budget. Absent/0 = unset (the runtime falls back to
|
||||
* LLM_FALLBACK_MAX_TOKENS on the last step, then the adapter default). */
|
||||
maxTokens?: number;
|
||||
/** 该组的推理开关形状。后端始终下发(kind 可能为空串),旧构建则整个字段缺失。 */
|
||||
reasoning?: AdminLlmReasoning;
|
||||
/** persona → 模型名的路由表(裁决 03.4.1);缺失 = 该组没有 per-persona 绑定。 */
|
||||
personaModels?: Record<string, string>;
|
||||
/** persona → wire 协议的覆盖表;取值只能是 personaProviderOptions。 */
|
||||
personaProviders?: Record<string, string>;
|
||||
}
|
||||
export interface AdminLlmConfig {
|
||||
providers: AdminLlmProvider[];
|
||||
/** `reasoning.kind` 的合法取值(不含空串),由后端配置层直接下发 —— 面板的
|
||||
* 下拉框据此渲染候选,绝不自己硬编码一套枚举。旧构建缺省该字段。 */
|
||||
reasoningKinds?: string[];
|
||||
/** `personaProviders` 值的合法取值(协议名)。旧构建缺省该字段。 */
|
||||
personaProviderOptions?: string[];
|
||||
}
|
||||
|
||||
/** 目录里的一个模型能力位(GET /api/v1/admin/llm/catalog)。attachment 为 true
|
||||
|
||||
@@ -35,10 +35,20 @@ export interface LlmProviderRequest {
|
||||
baseUrl: string;
|
||||
apiKey?: string;
|
||||
model: string;
|
||||
/** 主模型能否收图(≠ 视觉/OCR 工具用的模型,那两个走 .env)。 */
|
||||
multimodal?: boolean;
|
||||
fallback?: string;
|
||||
/** Absent = keep the stored budget (or leave unset for a new group). */
|
||||
maxTokens?: number;
|
||||
/** 推理开关形状:**缺省 = 保留已存形状**;给出(哪怕 `{}`)= 用其中的 kind
|
||||
* 覆盖,kind 缺省/空串 = 回到「未声明」(等同 auto)。取值见
|
||||
* AdminLlmConfig.reasoningKinds —— 非法 kind 后端回 400。 */
|
||||
reasoning?: { kind?: string };
|
||||
/** persona → 模型名路由表:缺省 = 保留已存表;给出(哪怕 `{}`)= **整表替换**
|
||||
* (否则面板无法删除一条已存路由)。 */
|
||||
personaModels?: Record<string, string>;
|
||||
/** persona → 协议覆盖表,规则同上;取值非法(非 openai/anthropic)回 400。 */
|
||||
personaProviders?: Record<string, string>;
|
||||
}
|
||||
|
||||
/** POST /api/v1/admin/llm/test body. */
|
||||
|
||||
Reference in new issue
Block a user