跳到主要内容
路径文档

运行时自省与动态 Cordis 插件

一句话版@deepseek-ai/dsh-tool-cordis 让模型先查询当前 Host/Client 能力,再定义一个不可变 Package,并通过稳定 pluginId 运行、更新、检查、停止或永久删除动态 Cordis 插件。

这套机制由四个包协作:

职责
@deepseek-ai/dsh-tool-cordis注册七个模型工具和 @pluginId 引用注入
@deepseek-ai/dsh-cordis-host-runner保存动态插件、Package、版本指针与 Host 运行状态
@deepseek-ai/dsh-cordis-client-runner在浏览器侧授权并运行 Client 半部
@deepseek-ai/dsh-client-ui-cordis在会话中渲染定义、启动和状态卡片

源码入口是 packages/extensions/tool-cordis/src/index.ts。实际注册表以 TypeScript 为准。

一、七个工具

工具作用是否改状态
cordis_inspect_list列出 Host 与 Client 已知的 Inspect Provider、方法和 schema
cordis_inspect_query调一个 Provider 声明的只读查询
cordis_inspect_self查看当前 Session 拥有的动态插件、Package、版本与诊断
cordis_define记录一个新的不可变 Package;只校验,不运行
cordis_run首次运行、重启、回滚或更新到指定 Package
cordis_stop停止当前运行,保留插件、Package、授权和版本指针
cordis_undefine永久删除插件及其所有 Package、授权和指针

旧的 cordis_inspect / cordis_mount / cordis_unmount 已由这套版本化生命周期取代。

二、先 Inspect,再写代码

cordis_inspect_list

先取得当前运行时真实存在的 Provider:

cordis_inspect_list

每项会给出:

  • platform: hostclient
  • Provider id 与用途
  • 可用的只读方法
  • 每个方法的输入/输出 schema

cordis_inspect_query

只能使用 list 返回的精确名字:

platform: host
provider: Service
method: listService
input: {}

Host 查询本地执行;Client 查询等待浏览器页面响应。Inspect 只能读取契约、服务、事件、Builtin、Slot、token 或当前树,不能代替业务 Service 调用,也不能修改运行时。

推荐顺序:

  1. cordis_inspect_list
  2. 用导航型查询找到精确 service/event/slot
  3. 再对精确目标查询完整契约
  4. 最后写 cordis_define

三、cordis_define:创建不可变 Package

新插件只提交 3–6 位小写英文语义前缀,Host 负责生成唯一 id:

plugin:
kind: new
idPrefix: echo
name: Echo tool
purpose: Register a small echo capability
code:
host: |
return {
name: 'echo-package',
inject: [],
apply(ctx) {
// 使用 inspect 得到的真实 Cordis API
}
}

更新已有插件时:

plugin:
kind: existing
pluginId: echo-1
name: Echo tool v2
purpose: Add the second behavior
code:
host: "return { name: 'echo-v2', inject: [], apply(ctx) {} }"

关键约束:

  • 至少提供 code.hostcode.client 之一
  • 内容是返回 Cordis Plugin 的普通 JavaScript function body
  • 不转换 TypeScript、JSX 或 import
  • Package 不可变;更新会追加 Package,不覆盖旧版本
  • define 只做参数/语法校验并保存源码,不申请授权、不执行 apply、不移动当前版本

成功返回稳定 pluginId 和精确 packageId。下一步必须显式 cordis_run

四、cordis_run:运行、更新与回滚

pluginId: echo-1
packageId: pkg-2
mode: update

mode 只有两种:

  • run: 首次启动、重启当前版本或回滚
  • update: 从当前版本切到另一个 Package

Client Package 首次运行可能返回 awaiting-approval;已授权的运行可能返回 starting 并在浏览器中异步继续。工具调用结束不代表 Client 半部已经完成。

版本指针语义:

  • 只有 Host/Client 全部成功后才更新 currentPackageId
  • 启动中目标记录为 nextPackageId
  • 技术失败保留旧 current 与目标 next,便于检查、修复和重试
  • 用户拒绝授权后,不重复发起相同授权请求

五、cordis_inspect_self:检查自己的版本和故障

cordis_inspect_self # 当前 Session 的插件摘要
cordis_inspect_self pluginId:"echo-1" # 版本指针、最近运行、Package 列表
cordis_inspect_self pluginId:"echo-1" packageId:"pkg-2"

最后一种会返回该不可变 Package 的 Host/Client 源码和运行诊断。packageId 不能脱离 pluginId 单独查询。

消息里写 @echo-1 时,agent/pre-step 会注入该插件当前引用;处理引用、修复异步失败或追加版本前,应先 inspect 精确 Package。

六、停止与永久删除

cordis_stop

停止当前运行并取消未完成的授权/启动请求,但保留:

  • 插件和全部 Package
  • Client 授权
  • currentPackageId / nextPackageId
  • 后续重启、更新和回滚能力

对已经停止的插件重复调用仍成功。

cordis_undefine

先停止活动运行,再永久删除插件、Package、授权和版本指针。之后旧 pluginIdpackageId@pluginId 引用全部失效;只在明确放弃全部版本时使用。

七、Host/Client 双半部流程

动态对象归当前 Session 所有,不再是旧实现中跨会话共享的一张临时挂载表。浏览器半部仍受页面连接、授权和异步生命周期约束。

八、验证

# 官方源码中确认七个注册名
rg -n "name: 'cordis_" packages/extensions/tool-cordis/src/index.ts

# 确认三个 runner/UI 包已进入 Web 组合
dsh web --dump-config | grep -E "cordis-(host|client)-runner|client-ui-cordis|tool-cordis"

下一步