diff --git a/docs/superpowers/specs/2026-03-21-llm-config-table-design.md b/docs/superpowers/specs/2026-03-21-llm-config-table-design.md new file mode 100644 index 0000000..dfe51c6 --- /dev/null +++ b/docs/superpowers/specs/2026-03-21-llm-config-table-design.md @@ -0,0 +1,157 @@ +# LLM 模型配置表格设计 + +## 1. 概述 + +重新设计 Settings 页面的 LLM 模型配置 UI,将原有的卡片列表改为表格行内编辑形式,简化交互、减少页面长度,同时支持多模型配置。 + +## 2. 需求 + +- **chat**: 必填,多个(子智能体可选不同模型) +- **vlm**: 选填,多个 +- **embedding**: 必填,1 个(知识库专用) +- **rerank**: 必填,1 个(知识库专用) + +## 3. UI 设计 + +### 3.1 整体布局 + +每种 LLM 类型(chat/vlm/embedding/rerank)独立成区,区头部显示类型名称和必填/选填标识,右上角有 [+] 添加按钮。 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ // LLM CONFIGURATION │ +├─────────────────────────────────────────────────────────────┤ +│ ┌─ CHAT ─────────────────────────────────────────────── [+] │ +│ │ 名称 │ Provider │ 模型 │ 状态 │ 操作 │ +│ ├─────────────────────────────────────────────────────────┤ │ +│ │ Agent-Chat │ OpenAI │ gpt-4o │ ● 可用 │ ▶ ✕ │ +│ └─────────────────────────────────────────────────────────┘ │ +│ ... (vlm, embedding, rerank 同理) │ +└─────────────────────────────────────────────────────────────┘ +``` + +### 3.2 表格列(精简版) + +| 列 | 说明 | +|----|------| +| 名称 | 模型名称,支持输入编辑 | +| Provider | 下拉选择:OpenAI / Claude / Ollama / DeepSeek / Custom | +| 模型 | 模型名称,支持输入编辑 | +| 状态 | ● 可用(绿色)/ ○ 不可用(灰色)/ ⚠ 必填未填(红色) | +| 操作 | 展开详情按钮 ▶ / 删除按钮 ✕ | + +### 3.3 行内展开详情面板 + +点击任意行,行下方展开详情表单: + +``` +│ ▼ Agent-Chat │ OpenAI │ gpt-4o │ ● 可用 │ ▶ ✕ │ +│ ┌─────────────────────────────────────────────────────────┐ │ +│ │ │ │ +│ │ Provider: [OpenAI ▼] Model: [gpt-4o ] │ │ +│ │ Base URL: [https://api.openai.com/v1 ] │ │ +│ │ API Key: [sk-•••••••••••••••• ] 👁 │ │ +│ │ │ │ +│ │ [▶ 测试连接] [保存] [取消] │ │ +│ └─────────────────────────────────────────────────────────┘ │ +``` + +### 3.4 状态说明 + +| 状态 | 颜色 | 含义 | +|------|------|------| +| ● 可用 | 绿色 | 测试通过 | +| ○ 不可用 | 灰色 | 未测试或测试失败 | +| ⚠ 必填未填 | 红色 | chat/embedding/rerank 未配置 | + +### 3.5 警告提示 + +当 chat/embedding/rerank 任一类型为空时,表格顶部显示红色警告条: + +``` +┌─────────────────────────────────────────────────────────────┐ +│ ⚠ chat / embedding / rerank 为知识库必填,请确保已配置 │ +└─────────────────────────────────────────────────────────────┘ +``` + +## 4. 交互规则 + +| 动作 | 行为 | +|------|------| +| 添加模型 | 点击 [+] 在对应类型底部添加新行,状态默认为 ○ 不可用 | +| 展开编辑 | 点击任意行,行内展开详情面板,同时收起其他已展开的行 | +| 测试连接 | 点击"测试连接",调用后端 API,测试通过则状态变 ● 可用,失败显示错误 Toast | +| 保存 | 只有测试通过的模型才能保存,保存后更新 originalLlmConfig | +| 删除 | 点击 ✕ 删除该模型(embedding/rerank 至少保留 1 个) | +| 取消编辑 | 点击"取消"或再次点击展开按钮,收起详情面板,表单数据恢复原值 | +| Provider 变化 | 自动填充对应 Provider 的默认 Base URL | + +## 5. 数据模型 + +```typescript +interface LLMModelConfig { + name: string // 模型名称 + provider: 'openai' | 'claude' | 'ollama' | 'deepseek' | 'custom' + model: string // 模型名称 + base_url: string // API Base URL + api_key: string // API Key + enabled: boolean // 是否启用 +} + +interface LLMConfig { + chat: LLMModelConfig[] // 必填,多个 + vlm: LLMModelConfig[] // 选填,多个 + embedding: LLMModelConfig[] // 必填,1个 + rerank: LLMModelConfig[] // 必填,1个 +} +``` + +## 6. 后端 API + +### 6.1 保存策略 + +`saveModel(type, index)` 发送完整 `LLMConfig` 对象到后端,后端整体替换该类型的模型列表。 + +- chat/vlm: 列表直接替换 +- embedding/rerank: 列表直接替换(限制最多 1 个) + +### 6.2 测试连接 API + +```typescript +POST /api/settings/llm/test +{ + "type": "chat" | "vlm" | "embedding" | "rerank", + "provider": "openai" | "claude" | "ollama" | "deepseek" | "custom", + "model": "gpt-4o", + "base_url": "https://api.openai.com/v1", + "api_key": "sk-..." +} +``` + +返回: +```typescript +{ "success": true, "message": "连接成功" } +{ "success": false, "error": "错误信息" } +``` + +## 7. 组件结构 + +``` +SettingsView.vue +├── LLMConfigSection (chat/vlm/embedding/rerank 四区) +│ ├── LLMTypeCard (每个类型一个卡片) +│ │ ├── LLMTable (表格头部 + 列表) +│ │ │ ├── LLMTableRow (每行模型) +│ │ │ └── LLMExpandPanel (展开的详情面板) +│ │ └── LLMEmptyState (空状态 + 添加按钮) +│ └── LLMWarning (必填警告条) +``` + +## 8. 实现要点 + +1. **单行展开**: 点击行时收起其他已展开行,保持 UI 简洁 +2. **测试通过才可保存**: 保存按钮仅在 `model.enabled === true` 时可用 +3. **API Key 脱敏**: 列表中不显示 API Key,详情面板中默认隐藏(显示为 ••••) +4. **Provider 默认 URL**: `onProviderChange` 自动填充默认值 +5. **深拷贝比较**: `isModelDirty` 使用 `JSON.stringify` 深拷贝比较 +6. **originalLlmConfig 同步**: 每次保存成功后更新原始配置副本