Files
zn-ai/docs/ClawX-Chat-Skill-Runtime-Migration-Checklist.md
DEV_DSW 4c61e93c3e Add unit tests for skill capabilities, skill planner, and UV setup
- Implement tests for random ID generation, ensuring preference for crypto.randomUUID.
- Create tests for runtime context capabilities, validating the injection of enabled skill capabilities.
- Add tests for skill capability parsing, including classification and command example extraction.
- Introduce tests for the skill planner, verifying tool call planning based on user requests and attachment requirements.
- Establish tests for UV setup, ensuring proper handling of Python installation scenarios and environment checks.
2026-04-24 17:02:59 +08:00

46 KiB
Raw Blame History

zn-ai 对齐 ClawX 的聊天 Skill 运行时迁移清单

1. 目标

zn-ai 的聊天运行时具备与 ClawX 同方向的能力:

  • 用户在聊天中提到某个已启用的 skill 时,模型能把它当成可规划、可调用、可回传结果的运行时能力,而不是只把它当成设置页里的开关。
  • 用户上传文件、引用网页、请求执行动作时,运行时能根据当前已启用 skills 自动规划合适的 skill/tool 链路。
  • 聊天链路能产生真实的 thinking / tool_use / tool_result / final answer
  • 用户能在 UI 中看到执行过程、失败原因和最终结果。

首个样板场景仍然是:

  • 用户发送:使用 minimax-xlsx 这个 skill帮我分析下
  • 如果会话里已有 .xlsx/.csv/.tsv 附件,运行时能识别并把文件交给表格类 skill

但这份文档的目标已经调整为:

  • 架构上按“所有已启用 skills 都能接入聊天运行时”来设计
  • xlsx/minimax-xlsx 只是第一条落地样板,不再作为唯一目标

2. 范围定义

2.1 最终目标范围

最终目标不是只支持 minimax-xlsx,而是支持:

  • 所有已启用 skills 在聊天时可见
  • 所有已启用 skills 可被模型规划
  • 所有已启用 skills 可被运行时调用
  • 所有已启用 skills 的结果可回传给模型并写入会话历史
  • 所有已启用 skills 的执行结果可被 renderer 展示

2.2 首批交付范围

首批交付不要求把每一个 skill 都逐个深度适配,但要求:

  • 运行时架构必须按“全量 skills 通用接入”设计
  • 第一批用 xlsx/minimax-xlsx 完成端到端验收
  • 第二批逐步覆盖其他 skill 类型,而不是继续新增特判分支

2.3 明确不再采用的方向

不采用下面这种方案:

  • 只为 minimax-xlsx 单独写一条聊天特判链路
  • 只为少数 skill 手工写 prompt 注入和执行代码
  • 让不同 skill 分别走不同的 ad-hoc 执行协议

3. 全量 skills 通用接入边界与阶段化策略

这一节单独回答一个关键问题:

  • 这次迁移是不是要把“所有 skills 都接进聊天运行时”考虑进去?

答案是:

  • 要考虑进去
  • 但不是要求第一批把每一个 skill 都做成同等质量的深度适配
  • 而是要求从第一天起,架构必须按“全量 skills 可接入”来设计

3.1 通用接入边界

本次迁移的“全量 skills 通用接入”边界如下:

  • 所有已启用 skills 都必须能进入聊天运行时的 capability 列表
  • 所有已启用 skills 都必须能被 planner 看见并参与候选规划
  • 所有已启用 skills 都必须能映射到统一 executor 协议
  • 所有 skills 的执行结果都必须能落入统一的 tool_result 结构
  • 所有 skills 的执行过程都必须能被 transcript 和 renderer 消费

本次迁移不承诺的边界如下:

  • 不承诺首批就为每一个 skill 做专门的高质量 UI 定制
  • 不承诺首批就为每一个 skill 做类型专属优化
  • 不承诺首批就覆盖所有外部依赖复杂、权限要求高的 skills

换句话说:

  • 首批必须做到“都能接”
  • 但不要求首批“都接得一样深、一样好看、一样聪明”

3.2 SKILL.md -> runtime capability 通用抽取规则

这是第一项必须补进文档的内容。

目标:

  • 不能把 SKILL.md 原文直接塞给模型
  • 需要抽成稳定、短小、可规划的 runtime capability

通用抽取规则建议如下:

  1. 基础身份字段

    • skillKey
    • displayName
    • description
  2. 能力字段

    • inputKinds
    • outputKinds
    • triggerHints
    • supportedFileTypes
  3. 约束字段

    • requiresFiles
    • requiresEnv
    • requiresRuntime
    • riskLevel
  4. 执行字段

    • defaultEntrypoint
    • callPattern
    • resultShape

抽取优先级建议:

  1. 先读显式元数据
  2. 再读 SKILL.md 的标题、description、usage、limitations
  3. 最后使用默认推断规则兜底

兜底策略:

  • 如果 skill 没有足够结构化信息,也必须能生成最小 capability
  • 不能因为 metadata 不完整就把 skill 排除出聊天运行时

3.3 Skill 分类分层策略

这是第二项必须补进文档的内容。

目标:

  • 不同 skill 的输入输出模式不同
  • 不能要求所有 skill 共用完全相同的 planner 提示和 executor 适配方式

首版推荐分层如下:

  1. 文档/文件类

    • 例:xlsxminimax-xlsxpdfdocx
    • 典型输入文件、路径、sheet、段落、页码
    • 典型输出:结构化数据、文件、摘要
  2. 浏览器/网页类

    • browser automation、web browse
    • 典型输入URL、页面元素、交互动作
    • 典型输出页面快照、DOM 结果、提取数据
  3. 搜索/检索类

    • web search、knowledge search
    • 典型输入query、filters、time range
    • 典型输出:候选结果、摘要、来源
  4. 命令/脚本类

    • shell、uv、脚本执行型 skill
    • 典型输入:命令参数、工作目录、文件引用
    • 典型输出stdout、stderr、产物文件、退出状态
  5. 外部 API / 服务类

    • 例:需要第三方 API key 的 skill
    • 典型输入:结构化参数、凭据引用、速率限制
    • 典型输出API 响应、结构化记录、失败状态

分层原则:

  • planner 先按 skill type 缩小候选范围
  • executor 再按该 type 的 adapter 执行
  • UI 先展示通用结果,再逐步补 skill type 专属展示

3.4 Skill 前置检查策略

这是第三项必须补进文档的内容。

目标:

  • 不是 skill 已启用就一定可执行
  • 聊天运行时必须在规划前或执行前做前置检查

每个 skill 的前置检查至少包括:

  1. 依赖检查

    • 本地二进制是否存在
    • Python/Node/uv 运行时是否可用
    • 所需脚本是否存在
  2. 环境变量检查

    • 必需 env 是否已配置
    • API key 是否存在
    • 敏感变量是否允许在当前运行环境使用
  3. 权限检查

    • 是否需要文件访问
    • 是否需要网络访问
    • 是否需要 shell/命令执行权限
    • 是否需要浏览器自动化权限
  4. 输入检查

    • 文件是否存在
    • 文件类型是否受支持
    • 参数是否齐全

前置检查的输出必须标准化为:

  • ready
  • blocked_missing_dependency
  • blocked_missing_env
  • blocked_missing_permission
  • blocked_invalid_input

这一步的意义是:

  • 避免模型盲目调用 skill
  • 避免把“权限没给”误判成“skill 不会用”
  • 避免用户只看到一句模糊失败文案

3.5 通用 tool_result 标准化与 UI 渲染协议

这是第四项必须补进文档的内容。

目标:

  • 所有 skill 返回结果必须进入统一 tool_result
  • renderer 先消费统一协议,再渐进增强不同 skill 类型的展示

建议统一结果结构:

  • ok
  • summary
  • structuredData
  • artifacts
  • logs
  • error
  • retryable
  • skillType
  • renderHints

其中:

  • structuredData 用于模型继续推理
  • artifacts 用于文件、图片、表格结果回传
  • logs 用于调试和错误诊断
  • renderHints 用于 UI 做轻量差异化展示

UI 渲染协议建议分两层:

  1. 通用层

    • 所有 skills 都显示状态、摘要、错误、耗时、输入概览
  2. 类型增强层

    • 文档类显示文件、sheet、提取结果摘要
    • 搜索类显示来源列表和摘要
    • 浏览器类显示页面结果与操作轨迹
    • 命令类显示输出日志与产物

原则:

  • 没有类型增强时,通用层也必须完整可用
  • UI 不得依赖某个单 skill 的私有字段才能渲染

3.6 阶段化策略

“全量 skills 通用接入”建议按 4 个阶段推进:

Phase A通用协议冻结

目标:

  • 冻结 capability schema
  • 冻结 skill type taxonomy
  • 冻结 preflight check 输出
  • 冻结 tool_result 标准结构

产出:

  • skill registry 契约
  • planner 输入输出契约
  • renderer 消费契约

Phase B样板链路落地

目标:

  • xlsx/minimax-xlsx 跑通文件类样板
  • 验证“启用 -> 可见 -> 可规划 -> 可执行 -> 可回传 -> 可展示”

要求:

  • 代码实现必须走通用协议
  • 不允许新增只服务于 minimax-xlsx 的永久特判

Phase C扩展到多 skill 类型

目标:

  • 选至少 1 个搜索类 skill
  • 选至少 1 个浏览器或命令类 skill
  • 验证通用架构不是只对文件类有效

要求:

  • 不改聊天主链路,只增加 registry/parser/adapter 配置

Phase D规模化接入与收敛

目标:

  • 把更多已启用 skills 纳入 capability 列表
  • 补前置检查、错误模型、UI 增强
  • 补自动化回归

验收口径:

  • 新增 skill 时,原则上不需要再改 chat.send 主编排
  • 如果新增 skill 还需要改主编排,说明架构仍未真正通用

4. 当前主结论

当前 zn-ai 的主阻塞不是 minimax-xlsx 没启用,而是:

  • 聊天运行时没有把已启用 skills 注入成可用能力
  • 聊天主链路仍是“文本 provider 直连”,不是通用 tool/skill runtime
  • 附件虽然能进入聊天,但没有稳定进入“技能可消费输入链路”
  • renderer 能显示少量工具状态,但没有完整执行闭环
  • 现有设计更接近“个别功能特判”,还不是“所有 skills 通用接入聊天运行时”

5. 验收标准

迁移完成后,至少要通过这 6 个场景:

  1. 已启用 minimax-xlsx,用户发送 使用 minimax-xlsx 这个 skill帮我分析下,模型不会只返回空泛文本,而会进入 skill/tool 执行链路。
  2. 用户上传 .xlsx/.csv/.tsv 后发送同一句话,运行时能把附件作为分析输入,而不是只把文件路径当普通文本。
  3. 用户启用任意其他文档类或搜索类 skill 后,聊天运行时能把该 skill 暴露为能力,而不是只在 Skills 页显示“已启用”。
  4. 聊天中能看到工具执行状态、结果摘要、失败信息;失败时能明确是“文件缺失 / skill 不可见 / provider 不支持 / runtime 执行失败 / skill 依赖未满足”。
  5. 多轮对话里tool 结果能回灌到后续推理,不会出现“执行过了但模型下一轮不知道结果”。
  6. 新增一个符合规范的 skill 时,不需要再给聊天链路补新的特判代码,只需通过注册/抽取机制接入。

6. 通用接入原则

这一节是本次调整的核心。

5.1 所有 skills 都必须经过同一条能力链路

统一链路:

  1. Skill 发现
  2. Skill 元数据抽取
  3. Runtime capability 注入
  4. Planner 选择 skill/tool
  5. Executor 调用 skill/tool
  6. Tool result 标准化
  7. Transcript 写回
  8. Renderer 展示

任何 skill 都不应该绕过这条链路单独接入聊天。

5.2 xlsx/minimax-xlsx 只是样板,不是特例

首批先用它验收,是因为它最能暴露当前缺口:

  • 附件输入
  • 文件访问
  • tool loop
  • 结果回灌
  • UI 展示

但一旦链路建好,其他 skills 也必须复用同一套机制。

5.3 先做“通用协议”,再做“具体 skill 适配”

顺序必须是:

  1. 先冻结通用 skill capability schema
  2. 先冻结通用 planner/executor/tool_result 协议
  3. 再做 xlsx/minimax-xlsx 样板接入
  4. 再扩展到更多 skills

不能反过来先做某一个 skill 的特例实现,再倒推通用架构。

7. 通用能力模型

6.1 Skill capability schema

每个已启用 skill 在聊天运行时至少要暴露这些字段:

  • skillKey
  • displayName
  • description
  • inputKinds
  • outputKinds
  • triggerHints
  • requiresFiles
  • supportedFileTypes
  • requiresEnv
  • requiresRuntime
  • riskLevel

说明:

  • 这里不是把整个 SKILL.md 原样塞给模型
  • 而是把它抽成稳定的、可规划的最小能力描述

6.2 Tool execution schema

所有 skills 在执行层至少统一到这些结构:

  • toolName
  • toolCallId
  • input
  • status
  • result
  • error
  • artifacts
  • summary

6.3 Tool result schema

所有 skill/tool 返回结果都要能映射成统一结构:

  • ok
  • summary
  • structuredData
  • files
  • logs
  • error
  • retryable

6.4 Transcript schema

所有 skills 的执行都要进入统一会话记录:

  • thinking
  • tool_use
  • tool_result
  • assistant final

6.5 Skills 通用接入数据流图

下面这张文字版流程图,定义的是 registry -> planner -> executor -> tool_result -> transcript -> renderer 的标准主链路:

[已启用 skills / 内建 tools / SKILL.md metadata / adapter manifest]
                            |
                            v
                    [Registry]
  产出统一 capability list / tool registry entries / preflight metadata
                            |
                            v
[用户消息 / 附件 / 会话历史 / runtime context / capability list]
                            |
                            v
                    [Planner]
  选择 skill/tool产出 thinking + tool_use plan
  如果当前无需调用 tool则直接走 assistant final
                            |
                            v
                    [Executor]
  执行 preflight check
  把附件、参数、上下文转成 adapter 可消费输入
  调用具体 skill/tool adapter拿到 raw result / artifacts / logs / error
                            |
                            v
                  [tool_result Normalize]
  统一映射成 ok / summary / structuredData / files / logs / error / retryable / renderHints
                            |
              +-------------+-------------+
              |                           |
              v                           v
        [Transcript]                [模型续推]
  写回 thinking / tool_use /     把 tool_result 回灌给模型,
  tool_result / assistant final   决定继续下一次 tool_use 或输出 final
              |
              v
         [Renderer]
  渲染执行状态、结果卡片、错误原因、产物入口、最终回答

实现约束:

  • registry 只负责暴露能力,不负责替模型做最终决策
  • planner 只负责选什么能力、传什么输入,不直接承担具体执行
  • executor 只负责执行与标准化,不负责私自改写会话历史
  • tool_result 必须同时服务两条链路:一条给模型续推,一条给 transcript / renderer 展示
  • transcript 是多轮续接的唯一可信记录,不能只在 UI 本地保留工具结果
  • renderer 优先消费统一协议,再按 skill type 做渐进增强

落地时最容易漏掉的环节:

  • 只做了 registry -> planner -> executor,但没有把 tool_result 回灌模型
  • 只做了 tool_result -> renderer,但没有把 tool_use / tool_result 写回 transcript
  • 只让 minimax-xlsx 走这条链路,其他 enabled skills 仍然走特判分支
  • 让 provider 直接内嵌 planner / executor 逻辑,导致通用 runtime 无法复用

6.6 Skills 通用接入代码文件映射图

下面这张图把上一节的数据流,直接映射到当前 zn-ai 里已经存在或建议新增的关键文件:

[Registry capability 装配入口]
  runtime-context.ts
  说明:当前这里是 runtime capability 注入边界;
       后续可把真正的 registry 生成下沉到 skill-capability-registry.ts
       但对 chat.send 的上游入口仍然是这里。
                |
                v
[聊天主编排入口]
  handlers/chat.ts
  说明:接收用户消息、附件、会话历史,串联 planner / executor / transcript
                |
      +---------+---------+
      |                   |
      v                   v
[规划层]              [执行层]
  skill-planner.ts      tool-runtime.ts
  说明:                 说明:
  - 消费 message         - 执行 preflight check
    / attachments        - 调用 skill/tool adapter
    / history            - 生成标准化 tool_result
    / runtime context    - 产出 tool status / artifacts / logs
  - 产出 thinking
    / tool_use plan
    / no-tool decision
      |                   |
      +---------+---------+
                |
                v
[共享协议层]
  chat-model.ts
  说明:定义 thinking / tool_use / tool_result / assistant final
       的 transcript schema 与共享消息结构
                |
                v
[渲染层]
  ChatMessageList.tsx
  说明:消费 transcript、toolStatuses、attachments、tool_result
       渲染执行状态、结果摘要、错误信息和最终回答

按职责拆到文件后的推荐边界如下:

  • runtime-context.ts

    • 负责把当前 enabled skills、内建 tools、session 信息装配成模型可见的 runtime context
    • 不负责直接决定“这次该调用哪个 skill”
    • 不负责写死某个 skill 的执行分支
  • handlers/chat.ts

    • 负责主编排,是 chat.send 的唯一入口
    • 负责把用户消息、附件、历史、runtime context 串起来
    • 负责调用 skill-planner.tstool-runtime.ts
    • 负责把 thinking / tool_use / tool_result / final 写回 transcript
    • 不负责继续堆 if user says x then call y 的特判
  • skill-planner.ts

    • 负责根据 capability list、附件类型、用户意图、历史上下文决定是否调用 skill/tool
    • 输出统一的 planner decision而不是直接在这里执行 tool
    • 如果模型无需调 tool也要能明确返回 assistant-final-only 这类决策
  • tool-runtime.ts

    • 负责 preflight check、adapter dispatch、错误归一化、tool_result 标准化
    • 负责把 raw result 转成 transcript 和 renderer 都能消费的结构
    • 不负责挑选哪个 tool那是 planner 的职责
  • chat-model.ts

    • 负责冻结共享协议,避免 gateway 和 renderer 各自维护一套 message shape
    • 这里必须成为 thinking / tool_use / tool_result / tool status / attachments 的统一来源
    • 如果协议扩展,不应该只改 UI 或只改 gateway 单边
  • ChatMessageList.tsx

    • 负责把通用 transcript 协议渲染出来
    • 先支持通用 tool_result 卡片,再渐进增强不同 skill type 的专属展示
    • 不应该依赖某个 skill 的私有字段才能完成基础渲染

这张映射图对应的实施顺序建议是:

  1. 先冻结 chat-model.ts 的共享 schema
  2. 再补 skill-planner.tstool-runtime.ts
  3. 然后让 handlers/chat.ts 接管主编排
  4. 再把 runtime-context.ts 从“固定两三个 tool 描述”升级成“全量 enabled skills capability 注入”
  5. 最后让 ChatMessageList.tsx 完整消费新的 transcript / tool_result 协议

如果后面要继续往下拆实现任务,这 6 个文件基本就能直接映射成 6 条主工作流,不容易再把 registry、planner、executor、renderer 的职责混到一起。

8. 优先级清单

状态回填基线2026-04-24

  • 已完成:当前阶段目标已经落地,后续只做增强,不再影响本阶段是否达标
  • 部分完成:主链路已接入或已有样板,但仍有明显缺口,暂不能视为该项收口
  • 未开始:还停留在文档/设计层,或尚未形成有效实现

P0 阻塞项

这些必须先补,不补就很难达到目标效果。

P0-1 建立“全量 enabled skills -> runtime capabilities”注入机制

状态:部分完成

现状:

  • 已有 capability registry 和 runtime context 注入链路,首批样板能把已启用 skill 暴露给聊天运行时
  • 但“依赖/环境不满足”的统一降级提示还没有完全收口,新增 skill 也还没有做到真正零补丁接入

目标:

  • 聊天发送前,运行时拿到当前所有已启用 skills 的能力描述
  • 不是只暴露 browser.open_urlskills.install
  • 首批先验证 xlsx/minimax-xlsx,但实现必须支持所有 skills

当前涉及文件:

  • zn-ai/electron/gateway/runtime-context.ts
  • zn-ai/electron/gateway/handlers/chat.ts
  • zn-ai/electron/gateway/handlers/skills.ts

清单:

  • 在聊天发送前读取当前 enabled skills
  • 为 enabled skills 生成通用 runtime capability 描述
  • 首批先支持 xlsx/minimax-xlsx 样板注入
  • 确保后续 skill 接入不需要再改聊天主链路
  • 明确“已启用但依赖/环境不满足”时的降级提示

P0-2 建立通用 skill metadata 抽取机制

状态:已完成

现状:

  • capability schema、默认抽取规则、SKILL.md 降级抽取和 registry 入口都已落地
  • 更细的 skill type 扩展仍会继续增强,但不影响这一阶段的 metadata 抽取主目标

目标:

  • 从 skill 配置和 SKILL.md 提取统一 capability schema
  • 为所有 skills 提供同一套抽取入口

当前涉及文件:

  • zn-ai/electron/gateway/handlers/skills.ts
  • 新增建议文件:zn-ai/electron/gateway/skill-capability-registry.ts
  • 新增建议文件:zn-ai/electron/gateway/skill-capability-parser.ts

清单:

  • 定义 capability schema
  • 定义默认抽取规则
  • 为缺少结构化元数据的 skill 提供降级抽取策略
  • 支持后续按 skill 类型扩展抽取器

P0-3 从“文本 provider”升级到“可执行 tool 的聊天运行时”

状态:部分完成

现状:

  • tool-capable provider/runtime 契约和 planner-first 执行链路已接入,tool_result 也能回灌后续回答
  • 但 provider 原生 tool loop 还没有完整打通,tools/toolChoice 仍未成为统一主路径

目标:

  • 聊天主链路不能只调用 provider.chat(messages, model)
  • 必须支持模型发起工具调用,运行时执行后再把结果回给模型

当前涉及文件:

  • zn-ai/electron/providers/BaseProvider.ts
  • zn-ai/electron/providers/OpenAIProvider.ts
  • zn-ai/electron/gateway/handlers/chat.ts

清单:

  • 设计统一 tool-capable provider/runtime 接口
  • 支持模型输出 tool_use 或等价调用结构
  • 运行时执行 skill/tool 后生成 tool_result
  • tool_result 回灌给模型,继续完成最终回答
  • 保留现有文本流式输出作为降级路径

P0-4 建立通用 planner / registry而不是继续堆特判

状态:部分完成

现状:

  • tool registry、planner、tool runtime 已建立统一入口,skills.install、浏览器、xlsx/minimax-xlsx 已纳入同一条链路
  • 但新增 skill 仍需要补 adapter尚未做到“任意已启用 skill 都能直接执行”

目标:

  • skill 调用不能再靠“遇到某句提示词就手工分支”
  • 所有 skills 和内建 tools 都通过统一 registry 暴露给 planner

当前涉及文件:

  • zn-ai/electron/gateway/handlers/chat.ts
  • 新增建议文件:zn-ai/electron/gateway/tool-runtime.ts
  • 新增建议文件:zn-ai/electron/gateway/tool-registry.ts
  • 新增建议文件:zn-ai/electron/gateway/skill-planner.ts

清单:

  • 抽象通用 tool registry
  • skill/tool 共用一套注册与调度模型
  • skills.install、浏览器、xlsx/minimax-xlsx 纳入统一 planner
  • 后续 skill 不再新增聊天特判

P0-5 把附件真正接入“通用 skill 输入链路”

状态:部分完成

现状:

  • 文件类样板已能把附件作为结构化输入交给表格分析链路,.xls 也已补上本地 fallback
  • 但附件输入 schema 还没有沉淀成所有文件类 skill 共用的公共层

目标:

  • .xlsx/.csv/.tsv,不能只把 [media attached: ...] 拼到文本里
  • 附件要变成 planner/executor 可消费的标准输入
  • 设计要对所有“需要文件输入”的 skills 通用

当前涉及文件:

  • zn-ai/src/stores/chat.ts
  • zn-ai/electron/api/routes/files.ts
  • zn-ai/electron/gateway/handlers/chat.ts

清单:

  • 为文件类 skill 建立统一附件输入 schema
  • 首批先验证表格类输入
  • tool/skill 执行时能拿到稳定文件路径或句柄信息
  • 附件缺失、路径失效时返回结构化错误

P0-6 把 tool 结果写回会话历史

状态:部分完成

现状:

  • tool_use / tool_result 已写回 transcript并能参与后续轮次的推理
  • 但大结果摘要、上下文膨胀控制和进一步的历史裁剪策略还没有完全收口

目标:

  • 执行过的 skill 结果必须成为会话上下文的一部分
  • 下一轮问“继续分析第 2 个 sheet”时模型能接上

当前涉及文件:

  • zn-ai/electron/gateway/handlers/chat.ts
  • zn-ai/src/stores/chat.ts
  • zn-ai/runtime-shared/shared/chat-model.ts

清单:

  • 在 transcript/session history 中保留 tool_use / tool_result
  • 重新定义发送下一轮时的 history flatten 规则
  • 避免把关键 tool 结果过滤掉
  • 对大结果做摘要,避免上下文膨胀

P1 重要项

这些不一定是第一批 blocker但会直接影响可用性和稳定性。

P1-1 建立“聊天 runtime 与 Skills 页”的同步机制

状态:部分完成

现状:

  • skills.update/install 后已能广播 runtime refreshSkills 页也已经接到这类变化
  • 但聊天 runtime/store 侧还没有完整消费这些变更,热更新边界仍不够清晰

当前涉及文件:

  • zn-ai/electron/gateway/handlers/skills.ts
  • zn-ai/electron/gateway/types.ts
  • zn-ai/src/lib/skills-api.ts

清单:

  • skills.update 后广播 runtime refresh
  • 聊天 runtime 监听 skills 变化并刷新能力缓存
  • 明确“需要重启 gateway”与“可热更新”的边界

P1-2 补齐聊天 UI 的执行可视化

状态:部分完成

现状:

  • 通用 tool-only 消息和结果卡片已经具备,browser.open_urlskills.install 有专项展示
  • 但表格分析专项卡片、失败重试和查看详情入口还没有补齐

当前涉及文件:

  • zn-ai/src/stores/chat.ts
  • zn-ai/src/components/chat/ChatMessageList.tsx
  • zn-ai/src/pages/Home/index.tsx

清单:

  • 区分普通 assistant 文本和 tool-only 消息
  • 增加通用 tool 结果展示结构
  • 首批先做好表格分析类结果卡片
  • 为失败结果增加重试或查看详情入口

P1-3 对齐 ClawX 的 workspace/context 注入机制

状态:未开始

现状:

  • 目前仍以现有 runtime context 注入为主
  • workspace/context 资源目录、统一说明文件和启动期上下文装配还没有正式开工

当前参考文件:

  • ClawX/electron/utils/openclaw-workspace.ts
  • ClawX/resources/context/AGENTS.clawx.md
  • ClawX/resources/context/TOOLS.clawx.md

清单:

  • zn-ai 增加运行时 context 资源目录
  • 定义 skill/tool 使用约束说明
  • 让 agent/workspace 在 gateway 启动后获得一致上下文

P1-4 明确 provider 能力矩阵

状态:未开始

现状:

  • provider 契约已经开始具备 tool-capable 方向的定义
  • 但支持矩阵、白名单和成体系的降级策略还没有形成可执行结果

清单:

  • 列出支持 tool loop 的 provider/model 白名单
  • 不支持时给出明确降级策略
  • 区分“模型不支持”与“skill 执行失败”

P2 增强项

这些会提高稳定性、可维护性和长期对齐度。

P2-1 Skill 类型分层

状态:部分完成

现状:

  • capability parser 已有轻量分类能力
  • 但 taxonomy 冻结、分类专属 adapter 和跨类型接入标准还没有全部完成

目标:

  • 不是所有 skill 都有相同输入输出模式
  • 需要按类型建立统一接入层

推荐分类:

  • 文档/文件类
  • 浏览器/网页类
  • 搜索/检索类
  • 命令/脚本类
  • 外部 API 类

清单:

  • 定义 skill type taxonomy
  • 为每类定义默认 input/output adapter
  • 首批至少覆盖文档类与浏览器类

P2-2 回归测试与 smoke

状态:部分完成

现状:

  • 已有 runtime context、planner、shortcut、chat-tooling 等聚焦单测
  • 但非 xlsx skill 回归、tool_use -> tool_result -> final 集成测试,以及开发态/打包态 smoke 还未补齐

清单:

  • 单测:已启用 skill 会出现在 runtime context
  • 单测:上传 .xlsx 后进入表格分析链路
  • 单测:新增一个非 xlsx skill 也能进入通用 registry
  • 集成测试:tool_use -> tool_result -> final
  • smoke开发态和打包态都验证一次

P2-3 错误模型和日志分层

状态:部分完成

现状:

  • shared schema 已具备基础的 tool error/result 结构
  • 但授权、provider、tool、skill、附件的统一错误模型和 UI 提示映射仍未收口

清单:

  • 区分授权错误、provider 错误、tool 错误、skill 错误、附件错误
  • transcript 中保留最小必要诊断字段
  • UI 侧映射成用户能理解的提示

9. 推荐推进顺序

当前进度判断:

  • 第一阶段:已基本完成
  • 第二阶段:部分完成
  • 第三阶段:未完成

第一阶段

  • P0-1 全量 enabled skills 注入 runtime
  • P0-2 通用 skill metadata 抽取
  • P0-3 tool-capable 聊天运行时
  • P0-4 通用 planner / registry
  • P0-5 附件进入通用 skill 输入链路

完成标志:

  • 架构上已经不再依赖单个 skill 特判
  • xlsx/minimax-xlsx 成为第一条跑通的样板链路

第二阶段

  • P0-6 tool 结果回灌历史
  • P1-1 runtime 与 Skills 页同步
  • P1-2 聊天 UI 执行可视化

完成标志:

  • 用户能稳定看到执行过程,且多轮能接续

第三阶段

  • P1-3 workspace/context 对齐
  • P1-4 provider 能力矩阵
  • P2 全部增强项

完成标志:

  • 新增 skill 时,聊天运行时不再需要新增 ad-hoc 接入代码

10. 推荐 sub-agent 编制

9.1 推荐数量

  • 推荐:7 个 sub-agent
  • 最小可行:5 个 sub-agent
  • 稳妥完整:8 个 sub-agent

解释:

  • 因为这次目标已经从“单个 skill 样板”升级为“全量 skills 通用接入架构”
  • 需要单独有人负责 skill metadata/registry不适合继续塞进原有分工里

默认建议采用:

  • 7 个 worker sub-agent + 1 个主协调 agent

说明:

  • 主协调 agent 不计入上面的 sub-agent 数量
  • 主协调 agent 负责冻结接口、安排波次、收敛冲突、做最终集成

9.2 7 个 sub-agent 分工

SA-1 Skill Capability Registry

职责:

  • 把所有 enabled skills 注入聊天 runtime context
  • 定义通用 capability schema
  • 负责 skill metadata 抽取与 registry

主要文件归属:

  • zn-ai/electron/gateway/runtime-context.ts
  • zn-ai/electron/gateway/handlers/skills.ts
  • zn-ai/electron/gateway/types.ts
  • 新增 zn-ai/electron/gateway/skill-capability-registry.ts
  • 新增 zn-ai/electron/gateway/skill-capability-parser.ts

验收:

  • 任何已启用 skill 都能进入 runtime capability 列表

SA-2 Provider 与 Tool Runtime

职责:

  • 把文本 provider 升级为可执行 tool 的聊天运行时
  • 定义 tool call / tool result / resume 推理接口

主要文件归属:

  • zn-ai/electron/providers/BaseProvider.ts
  • zn-ai/electron/providers/OpenAIProvider.ts
  • 新增 zn-ai/electron/gateway/tool-runtime.ts

验收:

  • 模型能发起真实 tool 调用,不再只有文本流

SA-3 Planner / Tool Registry

职责:

  • 设计通用 planner
  • 统一 skill/tool 注册与调度
  • 去掉继续堆特判的趋势

主要文件归属:

  • 新增 zn-ai/electron/gateway/tool-registry.ts
  • 新增 zn-ai/electron/gateway/skill-planner.ts
  • 必要时补 zn-ai/electron/gateway/types.ts

验收:

  • skills.install、浏览器、xlsx/minimax-xlsx 都通过统一 registry 接入

SA-4 Chat Orchestration / Transcript

职责:

  • 负责 chat.send 主编排
  • tool_use / tool_result / final 写回会话历史
  • 处理 history flatten 和多轮续接

主要文件归属:

  • zn-ai/electron/gateway/handlers/chat.ts
  • zn-ai/electron/gateway/session-store.ts
  • zn-ai/runtime-shared/shared/chat-model.ts

验收:

  • 多轮对话能接上前一轮 tool 结果

SA-5 Attachment / File Skill Input

职责:

  • .xlsx/.csv/.tsv 等文件变成通用 skill 输入
  • 先打通文件类 skill 输入适配层

主要文件归属:

  • zn-ai/src/stores/chat.ts
  • zn-ai/electron/api/routes/files.ts

验收:

  • 文件类 skill 拿到稳定输入,不再只依赖文本路径猜测

SA-6 Renderer Tool UI

职责:

  • 聊天 UI 展示 tool 卡片、状态、结果摘要、失败详情
  • 对齐 pendingFinal、tool-only 消息和分析过程可视化

主要文件归属:

  • zn-ai/src/components/chat/ChatMessageList.tsx
  • zn-ai/src/pages/Home/index.tsx
  • 新增聊天执行可视化组件时归此 agent

验收:

  • 用户能在聊天页看清楚“何时开始分析、分析了什么、结果是什么”

SA-7 Testing / Smoke / Rollout

职责:

  • 为前 6 个 agent 的改动补回归测试
  • 增加最小集成测试和开发态 smoke
  • 记录“新增 skill 是否零特判接入”的验收结果

主要文件归属:

  • zn-ai/tests/chat-runtime-context.test.ts
  • zn-ai/tests/gateway-rpc-dispatch.test.ts
  • 新增与 skill registry、planner、tool_result 相关测试
  • 需要时补充 docs/ 中的验收记录

验收:

  • 至少有 1 条覆盖“已启用 skill + planner + tool_result + final”的集成链路
  • 至少有 1 条覆盖“新增非 xlsx skill 无需新增聊天特判”的回归验证

9.3 6 个核心文件实施任务拆解表

这张表只聚焦最容易互相卡住的 6 个核心文件。

  • 辅助文件仍然跟随主责 sub-agent 所在分支推进
  • 任何辅助文件的改动,都不应绕开对应核心文件的 owner
  • chat-model.ts 虽然归 SA-4 主责,但必须以“共享契约先冻结”方式提前进入 Wave 1
核心文件 主要实施任务 主责 sub-agent 主要协作方 前置冻结 / 依赖 推荐合并顺序
zn-ai/runtime-shared/shared/chat-model.ts 冻结 thinking / tool_use / tool_result / assistant final / tool status / attachments 的共享 schema统一 gateway、store、UI 的消息结构 SA-4 SA-1 SA-2 SA-6 先评审 schema再允许其他链路接入这是后续 handlers/chat.tsChatMessageList.tsx 的共同前置 0
zn-ai/electron/gateway/runtime-context.ts 把当前 enabled skills、内建 tools、session 信息装配成 runtime capability 注入入口;从“固定工具说明”升级成“全量能力注入” SA-1 SA-3 SA-4 依赖 capability schema 冻结;与 skill-capability-registry.tsskill-capability-parser.ts 一起推进 1
zn-ai/electron/gateway/tool-runtime.ts 定义 preflight check、adapter dispatch、raw result -> tool_result 标准化、resume 推理接口 SA-2 SA-3 SA-4 依赖 chat-model.tstool_result 结构;需要先冻结 provider / runtime contract 2
zn-ai/electron/gateway/skill-planner.ts 根据 capability list、附件、历史、用户意图产出统一 planner decision去掉继续堆特判的趋势 SA-3 SA-1 SA-2 SA-4 依赖 runtime capability shape 与 tool runtime contracttool-registry.ts 同分支推进 3
zn-ai/electron/gateway/handlers/chat.ts 接管 chat.send 主编排,串联 runtime context、planner、executor、transcript 写回与多轮续接 SA-4 SA-2 SA-3 SA-5 必须等 runtime-context.tstool-runtime.tsskill-planner.ts 的契约稳定后再合并;其他 agent 不直接改这个文件 4
zn-ai/src/components/chat/ChatMessageList.tsx 消费统一 transcript / tool_result / toolStatuses,渲染 tool 卡片、错误、摘要、最终回答 SA-6 SA-4 SA-7 必须等 chat-model.tshandlers/chat.ts 稳定后接入;优先做通用渲染,再做类型增强 5

推荐按下面的节奏合并:

  1. 先合并 chat-model.ts 的 schema 冻结 PR。
  2. 再并行推进 runtime-context.tstool-runtime.tsskill-planner.ts,但以契约评审通过为合并门槛。
  3. 然后由 SA-4 合并 handlers/chat.ts,把前三者正式编排进主链路。
  4. 最后由 SA-6 合并 ChatMessageList.tsx,避免 UI 反向驱动协议。

这 6 个文件对应的辅助文件跟随关系建议如下:

  • runtime-context.ts 对应辅助文件:skill-capability-registry.tsskill-capability-parser.ts、必要时 handlers/skills.ts
  • tool-runtime.ts 对应辅助文件:BaseProvider.tsOpenAIProvider.ts
  • skill-planner.ts 对应辅助文件:tool-registry.ts、必要时 gateway/types.ts
  • handlers/chat.ts 对应辅助文件:session-store.ts、必要时 src/stores/chat.ts
  • ChatMessageList.tsx 对应辅助文件:src/pages/Home/index.tsx、新增 tool result 展示组件

如果要把冲突降到最低,可以把这张表当成 branch / PR 边界:

  • SA-1 不直接改 handlers/chat.ts,而是通过 capability schema 和 registry 模块接入
  • SA-2 不在 provider 内重做 planner而是只冻结 runtime contract
  • SA-3 不直接改 UI只输出 planner decision 与 registry 结构
  • SA-4 只在前三项契约稳定后改 handlers/chat.ts
  • SA-6 只消费共享协议,不反向决定 gateway 数据结构

11. 波次安排

Wave 1

当前状态:已完成

现状:

  • 核心契约、registry、planner 和 tool runtime 已经冻结并落地

  • 第一条样板链路已经跑通,不再停留在纯设计阶段

  • SA-1 Skill Capability Registry

  • SA-2 Provider 与 Tool Runtime

  • SA-3 Planner / Tool Registry

目标:

  • 先冻结最核心接口skill capability schema、tool runtime contract、planner contract

Wave 2

当前状态:部分完成

现状:

  • transcript 回写和样板附件链路已经进入主聊天编排

  • 但 runtime 与 Skills 页的同步,以及表格专项 UI 可视化还没有全部完成

  • SA-5 Attachment / File Skill Input

  • SA-4 Chat Orchestration / Transcript

目标:

  • 在已冻结契约上,把样板链路接入主聊天编排

Wave 3

当前状态:部分完成

现状:

  • 通用 tool UI 和一部分回归验证已经启动

  • 但 provider 能力矩阵、完整 smoke 和 rollout 收口还没有完成

  • SA-6 Renderer Tool UI

  • SA-7 Testing / Smoke / Rollout

目标:

  • 把用户体验和回归验证补齐

12. 协作约束

为避免冲突,建议遵守这 5 条:

  1. 每个 sub-agent 只改自己负责的文件,不跨写别人的主文件。
  2. zn-ai/electron/gateway/handlers/chat.ts 只归 SA-4,其他人不要直接改。
  3. zn-ai/src/stores/chat.ts 只归 SA-5UI agent 不要同时改这个文件。
  4. zn-ai/electron/gateway/types.tsSA-1 牵头冻结,其他 agent 只在评审后接入。
  5. 主协调 agent 统一做接口冻结、合并、回归验证,不让多个 agent 反复改同一入口。

13. 功能交叉与冲突清单

这一节把真正会互相卡住的交叉点单独列出来。

12.1 冲突 Achat.send 是所有能力的汇合点

交叉功能:

  • skill 可见性
  • planner 结果接入
  • tool runtime 执行
  • 附件输入
  • transcript 写回
  • final answer 回传

核心文件:

  • zn-ai/electron/gateway/handlers/chat.ts

处理规则:

  • 只允许 SA-4 直接修改
  • SA-1SA-2SA-3SA-5 通过契约和辅助模块接入

12.2 冲突 Bsrc/stores/chat.ts 同时承担“附件状态”和“聊天执行状态”

交叉功能:

  • 附件 staging
  • tool 状态消费
  • pendingFinal 状态
  • UI 展示状态

核心文件:

  • zn-ai/src/stores/chat.ts

处理规则:

  • SA-5 主责 store shape
  • SA-6 尽量通过 selector 和 helper 消费,不重写 store 结构

12.3 冲突 C事件协议同时影响 runtime、store、UI

交叉功能:

  • tool:status
  • chat:final
  • 未来的 tool_use / tool_result / thinking
  • runtime refresh

核心文件:

  • zn-ai/electron/gateway/types.ts
  • zn-ai/runtime-shared/shared/chat-model.ts

处理规则:

  • 先冻结 gateway event contract
  • 再冻结 transcript/chat-model contract
  • UI 最后接入,不反向驱动协议改名

12.4 冲突 Dprovider 能力和 planner/runtime 边界容易混淆

交叉功能:

  • provider 是否支持 tool loop
  • runtime 如何继续二次调用模型
  • planner 与 executor 谁负责决策

核心文件:

  • zn-ai/electron/providers/BaseProvider.ts
  • zn-ai/electron/providers/OpenAIProvider.ts
  • zn-ai/electron/gateway/tool-runtime.ts
  • zn-ai/electron/gateway/skill-planner.ts

处理规则:

  • SA-2 先冻结 provider/runtime 边界
  • SA-3 再实现 planner不在 provider 内重复做编排

12.5 冲突 Eskill metadata 抽取与 renderer 展示不要耦合

交叉功能:

  • SKILL.md 抽取
  • capability schema
  • UI 上如何显示 skill 名称、说明、输入输出

处理规则:

  • SA-1 负责 runtime capability schema
  • SA-6 只能消费 schema不反过来决定抽取字段

14. 最小落地建议

如果本轮只做最小可行闭环,优先只做这 6 件事:

  1. 聊天发送前读取 enabled skills并把它们注入 runtime context。
  2. 建立通用 skill capability registry而不是只处理 minimax-xlsx
  3. 为聊天 runtime 增加最小 tool loop不再只走纯文本 provider。
  4. 让文件类附件进入统一 skill 输入链路。
  5. tool_result 写回 session history保证多轮可续接。
  6. 在聊天 UI 里把执行过程展示成 tool 卡片,而不是只显示最终一句话。

15. 非目标

这一版清单默认不把下面内容作为首批阻塞项:

  • skill 市场页样式优化
  • 为每一个 skill 都单独做精细化 UI 定制
  • 完整复刻 ClawX 的所有 execution graph 细节
  • 与 skill 运行时无关的 channel/plugin 改造

注意:

  • “所有 skills 一次性通用化接入聊天运行时”不再是非目标
  • 但“所有 skills 一次性都达到同等体验质量”仍然不是首批目标

16. 建议先开工的代码入口

  • zn-ai/electron/gateway/handlers/chat.ts
  • zn-ai/electron/gateway/runtime-context.ts
  • zn-ai/electron/gateway/handlers/skills.ts
  • zn-ai/electron/providers/BaseProvider.ts
  • zn-ai/electron/providers/OpenAIProvider.ts
  • zn-ai/src/stores/chat.ts
  • zn-ai/src/components/chat/ChatMessageList.tsx
  • zn-ai/electron/api/routes/files.ts
  • 新增 zn-ai/electron/gateway/skill-capability-registry.ts
  • 新增 zn-ai/electron/gateway/skill-capability-parser.ts
  • 新增 zn-ai/electron/gateway/tool-registry.ts
  • 新增 zn-ai/electron/gateway/skill-planner.ts

17. Progress Update (2026-04-24)

This checkpoint extends the "first batch of real generic skill execution adapters" beyond xlsx/minimax-xlsx and lands the first reusable document-family, search-family, browser-family, and command-family runtimes.

Completed in this round:

  • zn-ai/electron/gateway/chat-tooling.ts
    • Added a real document adapter for enabled docx, pptx, and pdf skills.
    • Added Node-side analyzers for .docx, .pptx, and .pdf.
    • Added real search adapters for brave-web-search and tavily-search.
    • Added a browser-category adapter so browser-capable skills can reuse the managed browser.open_url runtime.
    • Added a command-category adapter that keeps find-skills on the safe ClawHub path and also executes generic command-style skills from safe manifest command templates or a single local scripts/ entrypoint.
    • Reads skill credentials from saved skill config (apiKey / env) instead of relying only on process env.
    • Normalizes Brave and Tavily responses into shared search-results payloads and URL artifacts.
    • Reused the same tool_runtime -> tool_result -> transcript path as spreadsheet analysis.
    • Kept unsupported generic skills on capability-aware blocked results instead of silently falling through.
  • zn-ai/src/components/chat/ChatMessageList.tsx
    • Added a dedicated search-result card for query, provider, answer, ranked results, and install commands.
    • Reused the same card for command-style discovery results such as find-skills.
  • zn-ai/electron/gateway/skill-capability-parser.ts
    • Tightened file-extension inference so URL-like fragments such as .search or .results no longer become fake input extensions.
    • Tightened auth detection to prefer explicit auth/env signals and avoid substring false positives.
    • Promoted office-style document skills into the shared document-analysis render shape.
  • zn-ai/tests/chat-tooling.test.ts
    • Added execution regressions for .docx, .pptx, and .pdf.
    • Added execution regressions for brave-web-search and tavily-search.
    • Added execution regressions for browser-capable skills, find-skills, and generic command-style skills that run from manifest command templates or local script entrypoints.
    • Kept .xls fallback coverage and generic blocked-state coverage.
  • zn-ai/tests/chat-message-list.test.tsx
    • Added UI regressions for dedicated search cards and command-style install-command rendering.
  • zn-ai/tests/skill-capability-parser.test.ts
    • Added parser regressions for document capability classification, URL-like extension filtering, and auth detection.

Current first-batch runtime coverage:

  • Spreadsheet execution: .xls, .xlsx, .xlsm, .csv, .tsv
  • Document execution: .docx, .pptx, .pdf
  • Search execution: brave-web-search, tavily-search
  • Browser execution: browser-capable skills that map to explicit URL open flows
  • Command execution: find-skills through ClawHub search, plus generic command-style skills that expose a safe single-command template or one local scripts/ entrypoint
  • Generic non-document skills without a real adapter: still blocked with explicit reasons such as missing_required_env, user_authorization_required, or skill_runtime_not_implemented

What is still not done:

  • Browser/search/command category executors now exist, but multi-step shell flows, install/login/setup commands, and other unsafe command patterns are still intentionally blocked. Generic command execution is limited to safe single-command templates and local script entrypoints.
  • Cross-type adapter manifesting and large-scale skill onboarding are still follow-up work after this checkpoint.

Verification for this checkpoint:

  • pnpm typecheck
  • pnpm exec vitest run tests/skill-capability-parser.test.ts tests/chat-tooling.test.ts
  • pnpm exec vitest run tests/chat-provider-tool-loop.test.ts tests/chat-store-runtime-refresh.test.ts tests/chat-runtime-context.test.ts tests/runtime-context-capabilities.test.ts tests/skill-planner.test.ts tests/chat-tooling.test.ts tests/skill-capability-parser.test.ts tests/chat-message-list.test.tsx