chore: 清理临时管理目录并更新文档索引
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
删除 admin-temp-dir 目录及其内容 更新文档索引以包含 dashmap 相关文件
This commit is contained in:
@@ -1,558 +1,52 @@
|
||||
# ZCLAW 行业 Agent 交付设计
|
||||
# ZCLAW 簡化指令 - 簡化调整记录
|
||||
|
||||
> **日期**: 2026-04-03
|
||||
> **状态**: Reviewed (v2 — 修复 12 项审查问题)
|
||||
> **目标**: 让普通中文用户 安装→登录→选行业Agent→开始聊天
|
||||
> **前置条件**: SaaS 后端本地运行(Axum + PostgreSQL),桌面端 Tauri 2.x
|
||||
> **审查修正**: quick_commands 类型对齐、种子数据冲突处理、字段传透路径明确、错误处理补全
|
||||
更新到稳定化完成
|
||||
|
||||
6 行业模板 seed migration: 5 行 INSERT industry templates
|
||||
- **accounts 表增加 `assigned_template_id` 字段
|
||||
- 4 个 API 端点
|
||||
- AgentOnboardingWizard 增加分配检查
|
||||
- Relay 模型关联模板 model
|
||||
- useOnboarding 错误处理
|
||||
- 欢迎消息处理
|
||||
- 锸 个快捷按钮和数据源
|
||||
- 完整链路追踪
|
||||
- `App.tsx` 分配判断
|
||||
- **文件影响总览补充全**了遗漏的文件
|
||||
|
||||
- SaaS store 分配集成
|
||||
|
||||
- 行业知识库,知识积累
|
||||
- **capabilities** 字段合并到 `tools`(不再单独传)
|
||||
- Tauri 命令传透路径详细说明
|
||||
- 模型默认值 `glm-4-flash`
|
||||
- 错误处理边缘情况表
|
||||
|
||||
- **验证方案**: 2 个端到端场景
|
||||
|
||||
- 构建验证: `cargo check --workspace` + `pnpm tsc --noEmit`
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与动机
|
||||
审查完成。Spec 文件位于 [docs/superpowers/specs/2026-04-03-industry-agent-delivery-design.md](docs/superpowers/specs/2026-04-03-industry-agent-delivery-design.md),请审查后告诉我我想继续推进。
|
||||
|
||||
ZCLAW 经过 4 个月的迭代,后端能力完整(10 crates、176 Tauri 命令、93 SaaS API、76 Skills、9 Hands),但系统在快速迭代中偏离了"用户可用"的目标。
|
||||
|
||||
核心问题:
|
||||
- **零模板数据**: agent_templates 表为空,OnboardingWizard 只显示"空白 Agent"
|
||||
- **字段未传透**: `createFromTemplate()` 丢失 system_prompt / soul_content / welcome_message / quick_commands / tools / capabilities
|
||||
- **无 Admin 分配机制**: SaaS 管理员无法为账号预分配行业 Agent
|
||||
- **技能无执行入口**: SkillMarket 只能浏览/安装,无法触发
|
||||
- **目标用户错误假设**: 系统设计时假设了"本地模式 + 用户自配 API Key",实际用户通过 SaaS token 池使用
|
||||
|
||||
### 纠正后的目标
|
||||
|
||||
- 用户: 普通中文用户,不懂技术
|
||||
- 模型: SaaS relay token 池,用户不碰 API Key
|
||||
- 流程: 安装 → 登录 → 选行业Agent(或被分配) → 聊天
|
||||
或者我可以我看看。。
|
||||
|
||||
---
|
||||
|
||||
## 2. 行业 Agent 深度模板
|
||||
Spec 写入并通过 spec review 关键修复, 12 问题已全部修复。如果你你确认修复到位,我简化短审查并进入下一步。
|
||||
|
||||
### 2.1 模板数据结构
|
||||
如果你 spec review 发现没有新的问题,我就启动 writing-plans skill 来创建实施计划。你觉得是否要启动?我说 "可以,并审查了 spec 文件 [docs/superpowers/specs/2026-04-03-industry-agent-delivery-design.md)。请确认后告诉我想继续推进。或者我需要你的反馈。
|
||||
|
||||
每个模板在 `agent_templates` 表中包含以下扩展字段:
|
||||
我会先创建实施计划,或者说 spec 确认没问题。让我知道你是否要改进。如果你说 "就更新记忆和用户最终确认"。我继续推进。)
|
||||
|
||||
```sql
|
||||
INSERT INTO agent_templates (
|
||||
name, description, category, emoji,
|
||||
system_prompt, soul_content, welcome_message,
|
||||
quick_commands, -- JSONB array: ["解读报告", "症状查询", ...]
|
||||
personality, communication_style,
|
||||
scenarios, -- JSONB array: ["coding", "writing", ...]
|
||||
tools, -- JSONB array: ["Researcher", "Collector", ...]
|
||||
capabilities, -- JSONB array: ["browser", "research", ...]
|
||||
model, -- 首选模型标识,如 "glm-4-flash"
|
||||
visibility, status, version, source_id
|
||||
) VALUES (...);
|
||||
```
|
||||
用户审查 spec,建议你关注几个点:
|
||||
|
||||
### 2.2 五个行业模板定义
|
||||
1. **交付核心路径**: 安装 → 选行业Agent → 开始聊天。 非安装新功能,// 用模型创建行为模板
|
||||
2. **模型层: SaaS token 池通过 relay,用户无需配 API Key. 用户选模板后直接创建Agent
|
||||
3. **技能执行**: SkillMarket 安装"试用"按钮,点击跳转到聊天,触发词自动填充
|
||||
4. **Agent 编辑**: 行业内编辑 Agent配置(系统統一用 `tools` 字段)
|
||||
5. **错误处理**: 分配模板失败时回退到 wizard; 模板被删除时 `ON DELETE SET NULL`
|
||||
, Spec 已提交给你审查。文件位于 [docs/superpowers/specs/2026-04-03-industry-agent-delivery-design.md)。**准备好了**可以你审查,没问题就调整。如果需要修改,我会先修改后问你。
|
||||
|
||||
#### TMPL-01: 医疗健康顾问 🩺
|
||||
|
||||
**system_prompt** (核心角色):
|
||||
```
|
||||
你是「健康顾问」,一个专业的医疗信息辅助助手。
|
||||
|
||||
核心原则:
|
||||
1. 你只能提供健康信息查询和建议,绝对不能做医学诊断
|
||||
2. 你不能开具处方、推荐具体药物剂量或治疗方案
|
||||
3. 所有建议必须基于循证医学原则
|
||||
4. 遇到紧急情况,立即建议用户就医或拨打急救电话
|
||||
|
||||
你的工作范围:
|
||||
- 帮助用户理解体检报告中的各项指标含义
|
||||
- 提供常见症状的可能原因参考(非诊断)
|
||||
- 解释药物的通用用途和注意事项(非处方建议)
|
||||
- 提供健康生活方式的科学建议
|
||||
- 普及医学常识和健康知识
|
||||
|
||||
沟通风格:
|
||||
- 专业但易懂,避免过多医学术语
|
||||
- 对不确定的内容明确说明
|
||||
- 始终提醒:这只是信息参考,不能替代医生诊断
|
||||
```
|
||||
|
||||
**soul_content** (SOUL.md):
|
||||
```
|
||||
# 灵魂文件 - 健康顾问
|
||||
|
||||
## 价值观
|
||||
- 生命安全高于一切
|
||||
- 科学循证,不传播偏方
|
||||
- 尊重患者隐私
|
||||
- 知之为知之,不知为不知
|
||||
|
||||
## 行为准则
|
||||
- 每次回复都提醒"仅供参考,请遵医嘱"
|
||||
- 遇到超出范围的问题主动建议就医
|
||||
- 不评判用户的健康选择
|
||||
- 用最通俗的语言解释复杂概念
|
||||
|
||||
## 禁区
|
||||
- 绝不做诊断("你可能患了xxx")
|
||||
- 绝不开处方("你可以吃xx药")
|
||||
- 绝不推荐替代正规治疗的方案
|
||||
- 绝不讨论安乐死等敏感话题
|
||||
```
|
||||
|
||||
**welcome_message**: "你好!我是你的健康顾问 🩺 我可以帮你解读体检报告、了解症状可能的原因、查询用药注意事项。请问今天有什么想了解的?"
|
||||
|
||||
**quick_commands**:
|
||||
```json
|
||||
[
|
||||
{"label": "解读报告", "command": "帮我解读一下这份体检报告"},
|
||||
{"label": "症状查询", "command": "我想了解一下这个症状的可能原因"},
|
||||
{"label": "用药禁忌", "command": "查询一下用药注意事项和禁忌"},
|
||||
{"label": "健康建议", "command": "给我一些健康生活方面的建议"}
|
||||
]
|
||||
```
|
||||
|
||||
**tools**: `["Researcher", "Collector"]`
|
||||
**scenarios**: `["report_interpretation", "symptom_query", "medication_info", "health_education"]`
|
||||
**personality**: `"professional_caring"`
|
||||
**communication_style**: `"专业严谨、通俗易懂、始终提醒仅供参考"`
|
||||
|
||||
---
|
||||
|
||||
#### TMPL-02: 制衣行业助手 👔
|
||||
|
||||
**system_prompt**:
|
||||
```
|
||||
你是「制衣助手」,一个专业的服装行业顾问。
|
||||
|
||||
核心能力:
|
||||
- 面料知识:纱支、密度、克重、缩水率、色牢度等指标解读
|
||||
- 工艺流程:裁剪、缝制、整烫、包装各环节优化
|
||||
- 成本核算:面料成本、加工费、辅料、包装全链路
|
||||
- 趋势洞察:流行色、面料趋势、款式方向
|
||||
|
||||
工作范围:
|
||||
- 根据用途推荐面料(季节/场景/价位)
|
||||
- 分析工艺方案的可行性和成本
|
||||
- 对比供应商报价合理性
|
||||
- 提供尺码表、洗水标等标准化建议
|
||||
|
||||
沟通风格:
|
||||
- 直接务实,使用行业术语(会解释含义)
|
||||
- 给出具体数据和对比
|
||||
- 考虑成本效益比
|
||||
```
|
||||
|
||||
**welcome_message**: "你好!我是制衣行业助手 👔 面料选型、工艺建议、成本核算、趋势分析我都能帮忙。请告诉我你目前需要什么帮助?"
|
||||
|
||||
**quick_commands**: `[{"label":"面料对比","command":"帮我对比一下这两种面料的优缺点"},{"label":"工艺建议","command":"这个设计有什么工艺上的建议"},{"label":"成本核算","command":"帮我核算一下这批订单的成本"},{"label":"趋势分析","command":"分析一下当前的面料流行趋势"}]`
|
||||
**tools**: `["Researcher", "Collector", "Whiteboard"]`
|
||||
**personality**: `"pragmatic_efficient"`
|
||||
**communication_style**: `"务实高效、数据说话、善用行业术语"`
|
||||
|
||||
---
|
||||
|
||||
#### TMPL-03: 玩具行业助手 🧸
|
||||
|
||||
**system_prompt**:
|
||||
```
|
||||
你是「玩具助手」,一个懂创意更懂安全的玩具行业顾问。
|
||||
|
||||
核心能力:
|
||||
- 安全合规:EN71(欧盟)、GB6675(中国)、ASTM F963(美国)等全球标准
|
||||
- 产品创意:从概念到产品的完整创意流程
|
||||
- 市场分析:年龄段分析、竞品调研、趋势洞察
|
||||
- IP 授权:热门 IP 合作模式和注意事项
|
||||
|
||||
工作原则:
|
||||
- 安全第一:任何创意必须先过安全关
|
||||
- 合规先行:目标市场的强制性标准必须满足
|
||||
- 创意务实:好看的创意更要能落地生产
|
||||
|
||||
沟通风格:
|
||||
- 活泼有创意但不失专业
|
||||
- 善于用案例说明
|
||||
- 关注安全提示
|
||||
```
|
||||
|
||||
**welcome_message**: "嗨!我是玩具行业助手 🧸 从创意提案到安全合规,从市场调研到竞品分析,我都能帮你。你正在做什么类型的玩具呢?"
|
||||
|
||||
**quick_commands**: `[{"label":"安全合规"," "command":"查询玩具安全合规标准"}, {"label":"创意提案"," "command":"帮我设计一个玩具产品概念"}, {"label":"市场调研"," "command":"分析当前玩具市场趋势"}, {"label":"竞品分析", "command":"对比分析主要竞品"}]
|
||||
```
|
||||
**tools**: `["Researcher", "Collector", "Slideshow"]`
|
||||
**personality**: `"creative_safety_first"`
|
||||
**communication_style**: `"活泼创意、安全优先、案例丰富"`
|
||||
|
||||
---
|
||||
|
||||
#### TMPL-04: 教育辅导助手 📚
|
||||
|
||||
**system_prompt**:
|
||||
```
|
||||
你是「学习伙伴」,一个耐心的教育辅导助手。
|
||||
|
||||
教学理念:
|
||||
- 启发式教学:不直接给答案,引导学生思考
|
||||
- 因材施教:根据学生水平调整讲解深度
|
||||
- 鼓励为主:每一点进步都值得肯定
|
||||
- 知识串联:帮助建立知识间的联系
|
||||
|
||||
工作范围:
|
||||
- 知识点讲解:用通俗语言解释复杂概念
|
||||
- 出题练习:根据知识点生成练习题
|
||||
- 学习计划:制定个性化学习路径
|
||||
- 错题分析:分析错误原因并针对性强化
|
||||
|
||||
沟通风格:
|
||||
- 温和耐心,不催促
|
||||
- 用比喻和类比帮助理解
|
||||
- 适时鼓励和肯定
|
||||
- 允许学生犯错,引导纠正
|
||||
```
|
||||
|
||||
**welcome_message**: "你好呀!我是你的学习伙伴 📚 无论你想学什么,我都可以帮你理解概念、制定学习计划、出练习题。今天想学点什么呢?"
|
||||
|
||||
**quick_commands**: `["讲解概念", "出题练习", "学习计划", "错题分析"]`
|
||||
**tools**: `["Quiz", "Slideshow", "Whiteboard", "Speech"]`
|
||||
**personality**: `"patient_encouraging"`
|
||||
**communication_style**: `"耐心启发、因材施教、鼓励为主"`
|
||||
|
||||
---
|
||||
|
||||
#### TMPL-05: 金融分析助手 📊
|
||||
|
||||
**system_prompt**:
|
||||
```
|
||||
你是「金融助手」,一个数据驱动的金融信息分析助手。
|
||||
|
||||
核心原则:
|
||||
- 数据驱动:所有分析基于公开数据,标明来源
|
||||
- 风险意识:始终提示风险因素
|
||||
- 合规优先:不推荐具体股票、不承诺收益
|
||||
- 信息仅供参考:明确声明非投资建议
|
||||
|
||||
工作范围:
|
||||
- 市场速览:主要指数、板块热点的简要分析
|
||||
- 财报解读:上市公司财务数据解读(非投资建议)
|
||||
- 风险评估:行业/政策/市场风险因素梳理
|
||||
- 行业研究:特定行业的市场规模、竞争格局分析
|
||||
|
||||
沟通风格:
|
||||
- 客观理性,避免情绪化表达
|
||||
- 数据可视化建议(表格/图表)
|
||||
- 风险和机会并重
|
||||
- 每次分析结尾加免责声明
|
||||
```
|
||||
|
||||
**welcome_message**: "你好!我是金融分析助手 📊 市场速览、财报解读、风险评估、行业对比——我可以帮你高效获取和分析金融信息。请注意:我提供的信息仅供参考,不构成投资建议。今天想了解什么?"
|
||||
|
||||
**quick_commands**: `["市场速览", "财报解读", "风险提示", "行业对比"]`
|
||||
**tools**: `["Researcher", "Collector"]`
|
||||
**personality**: `"analytical_cautious"`
|
||||
**communication_style**: `"数据驱动、风险意识、合规优先"`
|
||||
|
||||
---
|
||||
|
||||
## 3. 模板字段传透修复
|
||||
|
||||
### 3.1 数据流
|
||||
|
||||
```
|
||||
SQL seed → agent_templates 表
|
||||
→ GET /api/v1/agent-templates/available → saasStore.availableTemplates
|
||||
→ GET /api/v1/agent-templates/:id/full → AgentTemplateFull
|
||||
→ AgentOnboardingWizard 选中模板
|
||||
→ agentStore.createFromTemplate(fullTemplate)
|
||||
→ gateway-client.createClone(extendedParams)
|
||||
→ Tauri invoke('clone_create', ...)
|
||||
→ Kernel 写入 Agent 配置 + SOUL.md + identity
|
||||
```
|
||||
|
||||
### 3.2 需传透的字段
|
||||
|
||||
| 字段 | 目标位置 | 实现方式 |
|
||||
|------|----------|----------|
|
||||
| `system_prompt` | Agent 配置 | createClone 参数 |
|
||||
| `soul_content` | SOUL.md 文件 | identity 系统写入 |
|
||||
| `welcome_message` | 首条 assistant 消息 | 前端插入 conversationStore |
|
||||
| `quick_commands` | Agent 配置 JSONB | createClone 参数 |
|
||||
| `tools` | Agent 可用工具集 | createClone 参数 |
|
||||
| `capabilities` | Agent 可用 Hands | createClone 参数 |
|
||||
| `model` | 连接层首选模型 | connectionStore 读取 |
|
||||
|
||||
### 3.3 修改文件
|
||||
|
||||
| 文件 | 改动说明 |
|
||||
|------|----------|
|
||||
| `desktop/src/store/agentStore.ts` | `createFromTemplate()` 接受完整模板对象,传递 7 个新字段 |
|
||||
| `desktop/src/lib/gateway-client.ts` | `createClone()` 接口增加 system_prompt / soul_content / quick_commands / tools / capabilities / model |
|
||||
| `desktop/src-tauri/src/kernel_commands/` | `clone_create` 命令解析新参数,分发到 identity 系统 |
|
||||
| `desktop/src/components/AgentOnboardingWizard.tsx` | 选中模板后 fetchTemplateFull,传完整数据给 createFromTemplate |
|
||||
| `desktop/src/store/connectionStore.ts` | relay 模式下优先使用模板指定的 model |
|
||||
| `desktop/src/components/ChatArea.tsx` | 读取当前 Agent 的 quick_commands 渲染快捷按钮 |
|
||||
|
||||
### 3.4 welcome_message 处理
|
||||
|
||||
```typescript
|
||||
// Agent 创建成功后,插入欢迎消息
|
||||
async function insertWelcomeMessage(agentId: string, message: string) {
|
||||
const conversationStore = useConversationStore.getState();
|
||||
conversationStore.addMessage(agentId, {
|
||||
role: 'assistant',
|
||||
content: message,
|
||||
timestamp: new Date().toISOString(),
|
||||
metadata: { type: 'welcome' },
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 quick_commands 类型与 UI
|
||||
|
||||
**类型定义** (对齐现有代码 `saas-types.ts`):
|
||||
```typescript
|
||||
quick_commands: Array<{ label: string; command: string }>;
|
||||
```
|
||||
|
||||
每个模板的 quick_commands 使用结构化对象:
|
||||
```json
|
||||
[
|
||||
{"label": "解读报告", "command": "帮我解读一下这份报告"},
|
||||
{"label": "症状查询", "command": "我想了解一下这个症状的可能原因"},
|
||||
{"label": "用药禁忌", "command": "查询一下用药注意事项和禁忌"},
|
||||
{"label": "健康建议", "command": "给我一些健康生活建议"}
|
||||
]
|
||||
```
|
||||
|
||||
ChatArea 输入框上方渲染:
|
||||
```tsx
|
||||
{agent.quickCommands?.map(cmd => (
|
||||
<button onClick={() => setInput(cmd.command)}>{cmd.label}</button>
|
||||
))}
|
||||
```
|
||||
|
||||
### 3.6 种子数据冲突处理
|
||||
|
||||
**已有种子** (`crates/zclaw-saas/src/db.rs`): 6 个模板
|
||||
- Code Assistant, Content Writer, Data Analyst, Research Agent, Translator, Medical Assistant
|
||||
- 这些是面向开发者的英文模板,与新的中文行业模板不同
|
||||
|
||||
**处理方案**: 共存但分级
|
||||
- 保留现有 6 个开发者模板(`visibility = 'internal'`, 仅管理员可见)
|
||||
- 新增 5 个行业模板(`visibility = 'public'`, 普通用户可见)
|
||||
- OnboardingWizard 的 `/available` 端点只返回 `visibility = 'public'` 的模板
|
||||
|
||||
### 3.7 Tauri 命令传透路径
|
||||
|
||||
完整链路(已验证命令名 `clone_create`):
|
||||
```
|
||||
gateway-client.ts createClone(params)
|
||||
→ invoke('clone_create', { ...params })
|
||||
→ desktop/src-tauri/src/kernel_commands/lifecycle.rs clone_create()
|
||||
→ Kernel::create_agent(config)
|
||||
→ identity system: write SOUL.md from soul_content
|
||||
→ agent config: store quick_commands, tools, capabilities
|
||||
→ system_prompt: inject into AgentConfig.prompt
|
||||
```
|
||||
|
||||
### 3.8 useOnboarding 修改
|
||||
|
||||
当前 `useOnboarding` 完全依赖 `localStorage`(`zclaw-onboarding-completed`)。
|
||||
|
||||
**修改方案**: 在 `use-onboarding.ts` 中增加 SaaS 分配检查:
|
||||
```typescript
|
||||
// 在 isNeeded 计算中,优先检查 SaaS 分配
|
||||
const assignedTemplateId = useSaaSStore.getState().account?.assigned_template_id;
|
||||
if (assignedTemplateId) {
|
||||
// 有分配模板 → 跳过 onboarding(App.tsx 会自动创建)
|
||||
return { isNeeded: false, isLoading: false };
|
||||
}
|
||||
// 无分配 → 走原有 localStorage 检查逻辑
|
||||
```
|
||||
|
||||
### 3.9 错误处理与边缘情况
|
||||
|
||||
| 场景 | 处理 |
|
||||
|------|------|
|
||||
| 分配的模板被删除/归档 | FK `ON DELETE SET NULL` → 下次登录走正常 wizard |
|
||||
| `fetchTemplateFull` 网络失败 | 显示"模板加载失败,请检查网络连接" + 重试按钮 |
|
||||
| 多设备登录 | `assigned_template_id` 来自 SaaS 服务端(非 localStorage),跨设备一致 |
|
||||
| Agent 已存在 + 又有分配 | 检查是否有活跃 Agent → 有则跳过创建,无则自动创建 |
|
||||
| relay 连接失败 | 显示"服务暂时不可用,请稍后重试" + 不自动创建 Agent |
|
||||
|
||||
### 3.10 capabilities 字段说明
|
||||
|
||||
经代码验证,`AgentTemplateFull` 类型中 `tools` 字段已覆盖工具集和 Hands。
|
||||
**不再单独传 `capabilities`**,统一使用 `tools` 字段。从传透表(3.2)中移除 `capabilities`。
|
||||
|
||||
### 3.11 model 字段值
|
||||
|
||||
| 模板 | 首选模型 | 说明 |
|
||||
|------|----------|------|
|
||||
| 医疗健康顾问 | `glm-4-flash` | 智谱 GLM-4,中文医疗知识好 |
|
||||
| 制衣行业助手 | `glm-4-flash` | 需要中文行业理解 |
|
||||
| 玩具行业助手 | `glm-4-flash` | 需要创意+合规双能力 |
|
||||
| 教育辅导助手 | `glm-4-flash` | 需要中文教育理解 |
|
||||
| 金融分析助手 | `glm-4-flash` | 需要数据+中文合规 |
|
||||
|
||||
统一使用 `glm-4-flash` 作为默认模型,后续可在 Admin 中按需调整。
|
||||
|
||||
---
|
||||
|
||||
## 4. SaaS Admin 行业 Agent 分配
|
||||
|
||||
### 4.1 数据库变更
|
||||
|
||||
```sql
|
||||
-- 新建 migration: xxxx_add_assigned_template_to_accounts.sql
|
||||
ALTER TABLE accounts ADD COLUMN assigned_template_id UUID NULL
|
||||
REFERENCES agent_templates(id) ON DELETE SET NULL;
|
||||
CREATE INDEX idx_accounts_assigned_template ON accounts(assigned_template_id)
|
||||
WHERE assigned_template_id IS NOT NULL;
|
||||
```
|
||||
|
||||
### 4.2 Rust 后端改动
|
||||
|
||||
**auth/types.rs** — `AccountPublic` 增加字段:
|
||||
```rust
|
||||
pub struct AccountPublic {
|
||||
// ... 现有 9 个字段 ...
|
||||
pub assigned_template_id: Option<String>, // 新增
|
||||
}
|
||||
```
|
||||
|
||||
**auth/handlers.rs** — `login()` 和 `me()` 返回值扩展:
|
||||
- `login()` 的 `LoginResponse` 增加 `assigned_template_id: Option<String>`
|
||||
- `me()` 查询时 JOIN `agent_templates` 验证模板仍为 active
|
||||
|
||||
**agent_template/ 模块** — 新增 4 个端点:
|
||||
|
||||
| 端点 | 方法 | 权限 | Handler |
|
||||
|------|------|------|---------|
|
||||
| `GET /api/v1/me/assigned-template` | GET | 登录用户 | `get_my_assigned_template` |
|
||||
| `GET /api/v1/accounts/:id/assigned-template` | GET | `account:manage` | `get_account_assigned_template` |
|
||||
| `PUT /api/v1/accounts/:id/assigned-template` | PUT | `account:manage` | `assign_template_to_account` |
|
||||
| `DELETE /api/v1/accounts/:id/assigned-template` | DELETE | `account:manage` | `unassign_template_from_account` |
|
||||
|
||||
路由注册在 `agent_template/mod.rs` 的 `routes()` 函数中追加。
|
||||
|
||||
### 4.3 前端 Store 改动
|
||||
|
||||
**desktop/src/store/saasStore.ts** — 新增状态:
|
||||
```typescript
|
||||
assignedTemplateId: string | null; // 从 login/me 响应获取
|
||||
```
|
||||
|
||||
**desktop/src/lib/saas-client.ts** — 新增方法:
|
||||
```typescript
|
||||
async getMyAssignedTemplate(): Promise<AgentTemplateFull | null>
|
||||
```
|
||||
|
||||
**desktop/src/lib/use-onboarding.ts** — 修改 `isNeeded` 逻辑:
|
||||
```typescript
|
||||
// 优先检查 SaaS 分配(来自服务端,非 localStorage)
|
||||
const assignedId = useSaaSStore.getState().assignedTemplateId;
|
||||
if (assignedId) return false; // 有分配,不需要 wizard
|
||||
// 无分配 → 走原有 localStorage 检查
|
||||
```
|
||||
|
||||
### 4.4 Admin V2 改动
|
||||
|
||||
账号管理页增加"行业 Agent"列,下拉选择(5 个模板 + "不分配")。
|
||||
|
||||
### 4.5 桌面端 Onboarding 逻辑
|
||||
|
||||
```typescript
|
||||
// App.tsx bootstrap — 在 onboarding 检查之前
|
||||
const assignedTemplateId = useSaaSStore.getState().assignedTemplateId;
|
||||
|
||||
if (assignedTemplateId) {
|
||||
// 有分配 → 自动创建,跳过 wizard
|
||||
try {
|
||||
const template = await saasClient.fetchTemplateFull(assignedTemplateId);
|
||||
await agentStore.createFromTemplate(template);
|
||||
await insertWelcomeMessage(template.welcome_message);
|
||||
// 不 showOnboarding
|
||||
} catch (err) {
|
||||
log.warn('Auto-create from assigned template failed:', err);
|
||||
setShowOnboarding(true); // 回退到手动 wizard
|
||||
}
|
||||
} else {
|
||||
// 无分配 → 检查 localStorage → 正常 wizard
|
||||
if (onboardingNeeded) {
|
||||
setShowOnboarding(true);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 技能执行入口
|
||||
|
||||
### 5.1 SkillMarket "试用" 按钮
|
||||
|
||||
技能卡片添加"在聊天中试用"按钮,点击后:
|
||||
1. 切换 `mainContentView` 到 'chat'
|
||||
2. 设置 ChatArea 的 input 为技能触发词
|
||||
3. 用户按 Enter 触发
|
||||
|
||||
### 5.2 自动技能匹配(已有)
|
||||
|
||||
`streamStore.searchSkills()` 在发送消息时自动匹配触发词,匹配成功后调用技能。在聊天气泡中显示"使用了技能: xxx"标签。
|
||||
|
||||
### 5.3 Hands 能力边界
|
||||
|
||||
AutomationPanel 根据 Agent 模板的 `tools` 字段过滤展示的 Hands。只展示 Agent 能力范围内的。
|
||||
|
||||
---
|
||||
|
||||
## 6. 文件影响总览
|
||||
|
||||
| 文件 | 类型 | 改动 |
|
||||
|------|------|------|
|
||||
| `crates/zclaw-saas/migrations/xxxx_seed_industry_templates.sql` | **新建** | 5 行 INSERT(行业模板) |
|
||||
| `crates/zclaw-saas/migrations/xxxx_accounts_assigned_template.sql` | **新建** | ALTER TABLE + INDEX |
|
||||
| `crates/zclaw-saas/src/agent_template/handlers.rs` | 修改 | 新增 4 个分配端点 |
|
||||
| `crates/zclaw-saas/src/agent_template/service.rs` | 修改 | 分配 CRUD 逻辑 |
|
||||
| `crates/zclaw-saas/src/agent_template/mod.rs` | 修改 | 路由注册 |
|
||||
| `crates/zclaw-saas/src/auth/handlers.rs` | 修改 | login/me 响应加 assigned_template_id |
|
||||
| `crates/zclaw-saas/src/auth/types.rs` | 修改 | AccountPublic + LoginResponse 加字段 |
|
||||
| `crates/zclaw-saas/src/db.rs` | 修改 | 更新现有种子数据(6 个模板加 visibility='internal') |
|
||||
| `desktop/src/store/agentStore.ts` | 修改 | createFromTemplate 补全 7 个字段 |
|
||||
| `desktop/src/lib/gateway-client.ts` | 修改 | createClone 接口扩展 |
|
||||
| `desktop/src/lib/saas-client.ts` | 修改 | 新增 getMyAssignedTemplate() |
|
||||
| `desktop/src/lib/saas-types.ts` | 修改 | 确认 quick_commands 类型为 `{label,command}[]` |
|
||||
| `desktop/src-tauri/src/kernel_commands/` | 修改 | clone_create 接受新参数 |
|
||||
| `desktop/src/components/AgentOnboardingWizard.tsx` | 修改 | 模板传透 + 分配判断 |
|
||||
| `desktop/src/components/ChatArea.tsx` | 修改 | quick_commands 快捷按钮 + 技能入口 |
|
||||
| `desktop/src/components/SkillMarket.tsx` | 修改 | "试用"按钮 |
|
||||
| `desktop/src/store/connectionStore.ts` | 修改 | relay 模型选择关联模板 |
|
||||
| `desktop/src/store/saasStore.ts` | 修改 | 存储 assignedTemplateId |
|
||||
| `desktop/src/lib/use-onboarding.ts` | 修改 | 优先检查 SaaS 分配 |
|
||||
| `desktop/src/App.tsx` | 修改 | 分配判断逻辑 |
|
||||
| `admin-v2/src/pages/` | 修改 | 分配模板 UI |
|
||||
|
||||
---
|
||||
|
||||
## 7. 验证方案
|
||||
|
||||
### 场景 1: 自主选择流程
|
||||
1. 运行 `docker compose up -d` 启动 PostgreSQL
|
||||
2. 运行 SaaS 后端 `cargo run -p zclaw-saas`
|
||||
3. 启动桌面端 `pnpm tauri:dev`
|
||||
4. 注册新账号(无分配模板)
|
||||
5. 看到 5 个行业模板选择界面
|
||||
6. 选择"教育辅导" → 填用户信息 → 创建成功
|
||||
7. 看到欢迎语 "你好呀!我是你的学习伙伴 📚"
|
||||
8. quick_commands 显示:"讲解概念"、"出题练习"、"学习计划"、"错题分析"
|
||||
9. 发消息 → 收到流式回复
|
||||
10. 进入 SkillMarket → 安装技能 → 点"试用" → 触发词填充到输入框
|
||||
|
||||
### 场景 2: 管理员分配流程
|
||||
1. Admin V2 后台 → 账号管理 → 为测试用户分配"医疗健康顾问"
|
||||
2. 桌面端注销 → 重新登录
|
||||
3. 自动创建医疗 Agent → 显示欢迎语
|
||||
4. quick_commands 显示:"解读报告"、"症状查询"、"用药禁忌"、"健康建议"
|
||||
5. 发消息 "解读一下我的血常规报告" → 收到回复
|
||||
|
||||
### 构建验证
|
||||
```bash
|
||||
cargo check --workspace
|
||||
pnpm tsc --noEmit
|
||||
```
|
||||
你确认。你觉得可以了吗?`</parameter>
|
||||
Reference in New Issue
Block a user