Files

14 KiB
Raw Permalink Blame History

DETA — Agent Plugins

DETA 领域能力在各类 Agent harness 上的分发仓:品牌 = 市场,产品 = 插件,一个仓承载多产品。

宿主 形态 安装
Codex 插件(.codex-plugin/plugin.json + skills/ + .mcp.json);本仓同时是 Codex 插件市场 deta codex plugin marketplace add https://git.deta.city/deta/deta-agent-plugins.git → codex plugin add studio@deta
dsh (deepseek-harness) 组合包 bundle(dsh.bundle.patch + cordis.patch.yml) dsh plugin --profile <name> add ./plugins/studio

发行标识(Codex 语法 = 插件@市场):studio@deta、writer@deta——两个插件互不冲突, 可同时安装(MCP 服务名 studio_mcp / writer_mcp,工作区各自独立)。新增产品按同一结构落位: plugins/<产品>/ 自带 .codex-plugin/plugin.json、.mcp.json、package.json、cordis.patch.yml、 bin/、skills/、README.md,市场 plugins 数组加一条即可。

能力本体(AML 建筑模型读写、编译校验、围护结构统计、空间邻接查询)以 MCP 服务提供, 运行时在本机解析(引擎包 / 源码构建),宿主侧只声明"用哪个启动器"; 同一份后端、同一个启动器、同一套技能被所有宿主复用,新增宿主只需再加一层声明式壳。

职责边界(仓库章程)

本仓是宿主适配与分发层,零逻辑、不承载契约。三条铁律:

问题 归属 内容
能力在哪 ant-copilot(唯一来源) 工具实现、MCP 协议层、启动形态(本机 stdio / 服务端 HTTP)、工具面裁剪、领域技能
怎么被发现和启动 本仓 宿主清单(.codex-plugin/plugin.json、cordis.patch.yml)、连接声明(.mcp.json)、启动器、宿主侧技能投影
怎么在云上跑 infra 部署 / 证书 / 路由 / 重启;云端只跑 ant-copilot 的构建产物

因此本仓不做这些事(由 scripts/check-plugin-contract.mjs 在 CI 强制):

  • 不在文档或技能里列工具清单 / 工具一览——工具面按部署形态裁剪,清单必然过期; 取清单的唯一途径是运行时调用 list_capabilities(技能必须给出这条指引)。
  • 不解释 ant-copilot 的内部常量与实现路径(DETA_TOOL_SURFACE、dist/… 等)。
  • 不把「开发检出路径」当作运行前提——启动器应随包解析运行时(当前仍保留开发检出回落, 校验脚本以 warning 提示,本机引擎包落地后升级为 error)。
  • 市场条目与实际插件目录必须一致(条目 name = 插件清单 name、path 真实存在), 由校验脚本的 E4 规则强制——改名或加产品时不会留下悬空条目。

衡量标准:新增一个工具需要改几处?目标是 1 处(ant-copilot 注册工具, 能力目录与文档自动派生),本仓零改动。

连接形态(唯一管道:本机 stdio)

宿主(Codex / dsh)
  └─ 拉起 plugins/<产品>/bin/deta-mcp.sh --profile <产品>    ← 各产品带自己的档位,脚本同一份
        ├─ 解析领域服务运行时:DETA_SERVER_ROOT → ~/.deta/runtime → 本机开发检出
        ├─ 解析工作目录:DETA_WORKSPACE → ANT_HEADLESS_WORKSPACE → ~/.deta/<产品>/workspace
        └─ 执行领域服务运行时入口(打包产物;回落未打包产物时打印警告)
             └─ MCP stdio:全量工具面;无 OAuth、无 401、无令牌续期
  • 本机形态不做 MCP 鉴权:进程在本机由宿主或用户拉起,天然可信。
  • 云侧能力(项目/楼栋列表、同步)是可选的输入:注入 DETA_TOKEN 即有,缺省时云类工具 返回 auth_required,其余工具照常——同一份工具实现,不是两套分支。
  • Studio 执行器中继(模拟/画布)需 ANT_WORKSPACE_BRIDGE_URL + 项目 ID 三要素齐备。
  • 各产品独立命名空间:MCP 服务名 studio_mcp / writer_mcp(工具前缀 mcp__<服务名>__<工具>),两个插件可同时安装互不冲突;产品间不共享工作区。
  • 服务端仍保留 HTTP 形态的服务(数据面/其他客户端用),但它不是本插件声明的连接形态; 插件的连接声明只有本机 stdio 一种。

内容

插件 服务名 技能 能力 依赖
studio@deta studio_mcp studio:aml-design AML 建筑模型读写、编译与校验、围护结构统计、空间邻接查询 node;领域服务运行时(本机引擎包或源码构建)
writer@deta writer_mcp writer:report-authoring 报告/文档产出:读模型、取数据(统计/分析/模拟缓存/气象/规范)、成文 同上

安装(Codex)

# 从 Git(分发用)
codex plugin marketplace add https://git.deta.city/deta/deta-agent-plugins.git

codex plugin list
codex plugin add studio@deta

领域服务运行时随插件包分发,启动器首次拉起时自动安装到 ~/.deta/runtime,插件升级后自动同步 (只比对哈希,命中就跳过)。需要显式重装、或补装候选预览图的栅格化依赖时:

~/.deta/bin/deta install-runtime   # 安装/更新运行时 + 预览图依赖,并立刻做一次真实 MCP 握手
~/.deta/bin/deta status            # 运行时来源(版本 / 提交 / 哈希)、凭据来源、工作区
~/.deta/bin/deta doctor            # 端到端自检:运行时 / 凭据 / 编译服务 / MCP 握手

装完即用:没有额外安装步骤,也不需要终端。需要云侧能力(项目列表 / 新建项目 / 项目同步 / 打开 Studio)时:让助手调 login 工具 → 浏览器打开授权地址(首次输一次账号密码或邮箱验证码)→ 点「登录并授权」;令牌自动写入 ~/.deta 并即时生效,过期先静默续期。

命令行形态(无 login 工具)的兜底及排查(助手用法见 plugins/studio/README.md):

~/.deta/bin/deta login     # 由启动器自动注册;账号密码或 --email-code <邮箱>
~/.deta/bin/deta doctor    # 自检:运行时 / 凭据 / GSA / MCP 握手

本地迭代

插件内容改动后 Codex 不会自动感知,按官方流程打 cachebuster 版本号再重装:

python3.11 ~/.codex/skills/.system/plugin-creator/scripts/update_plugin_cachebuster.py \
  ~/Dev/ant/deta-agent-plugins/plugins/studio
codex plugin add studio@deta

(版本号形如 0.1.0+codex.20260910020424;重装后需开新会话才能加载新技能。)

开发态要跑工作树(而不是插件包里那份打包运行时)时,显式指定运行时根:

DETA_SERVER_ROOT=<领域服务仓库所在路径> bash plugins/studio/bin/deta-mcp.sh --profile studio

领域服务改动后,要把新产物同步进插件包(否则同事与你自己装的都是旧运行时), 并顺手升插件版本(契约校验会拦下版本与运行时不一致的情况):

node scripts/sync-runtime.mjs
node scripts/check-plugin-contract.mjs
bash scripts/verify-runtime-provision.sh     # 运行时供给探针(全新 HOME 下 10 项断言)

校验清单:

python3.11 ~/.codex/skills/.system/plugin-creator/scripts/validate_plugin.py \
  ~/Dev/ant/deta-agent-plugins/plugins/studio
node scripts/check-plugin-contract.mjs          # 本仓章程校验(CI 同款)
codex plugin marketplace list
codex mcp list | grep -i studio                 # 应显示 stdio 形态(Command 列)与 studio_mcp

接入 WorkBuddy

WorkBuddy 的自定义 MCP 支持 command/args 形态(经其二进制的配置哈希实现取证确认), 因此可以拿到与 Codex 同款的本机 full 工具面:

~/.deta/bin/deta install-workbuddy        # 写 ~/.workbuddy/mcp.json(本机 stdio)+ 装技能 + 握手自证
  • 稳定入口是 ~/.deta/bin/deta-mcp-<档位>(随插件升级自动刷新;WorkBuddy 对 MCP 的信任按命令行 算哈希,入口路径稳定 ⇒ 插件升级后不再重弹信任确认);
  • 领域技能随安装装进 ~/.workbuddy/skills/(与 Codex 插件内的是同一份,单一事实源);
  • 装完退出并重启 WorkBuddy,首次会弹「是否信任 MCP 服务器」→ 点允许,开新对话即可用;
  • 无本机运行时的机器用 ~/.deta/bin/deta install-workbuddy --http 回落为远程引擎面(deta.city,OAuth 授权);
  • 验收:bash scripts/verify-workbuddy.sh(配置形态 / 稳定入口 / 技能 / 真实握手 / WB 日志);
  • 插件升级后重跑一次 deta install-workbuddy(幂等:刷新稳定入口指向与技能内容;不重跑则 WB 仍拉起旧副本)。

双壳架构(Codex + dsh 同一产物)

plugins/studio/ 这一个目录同时是 Codex 插件根与 dsh 组合包根,共享核心、各带一层薄壳:

组成 文件 Codex dsh
插件清单 .codex-plugin/plugin.json(name = 产品名) ✅ 使用 —
MCP 声明 .mcp.json(stdio → bin/deta-mcp.sh --profile <产品>,serverName = <产品>_mcp) ✅ 使用(可放 Codex 私有键) —
组合包声明 package.json(dsh.bundle.patch) 忽略 ✅ 使用
配置层 cordis.patch.yml(同一启动器,stdio,serverName = <产品>_mcp) 忽略 ✅ 使用
宿主侧技能 skills/aml-design/SKILL.md ✅ 共享 ✅ 共享
启动器 bin/deta-mcp.sh ✅ 每产品一份(同一实现,产品差异走 --profile) ✅

共享面(两端一致,零适配):

  • 技能文件格式:<name>/SKILL.md + frontmatter 必填 name/description,kebab-case。 Codex 与 dsh(@deepseek-ai/dsh-skill-filesystem)要求相同。
  • 共享技能根:两端都扫描 ~/.agents/skills/ 与 <项目>/.agents/skills/ (dsh 侧为 rank 500 / 200 的发现根,且显式支持 <agentsHome>/skills)。
  • MCP 工具命名:两端同为 mcp__<serverName>__<tool>,我们统一 serverName = deta。

各自不同的部分(不共享):

  • MCP 的声明位置不同(Codex 读 .mcp.json,dsh 读 cordis.patch.yml 的 mcp-client 行), 但都指向同一个启动器。
  • Codex 私有键(default_tools_approval_mode、omit_tools_from)只写在 .mcp.json。
  • 分发渠道不同:Codex 走 git 市场,dsh 走 npm / git / tarball。

dsh 侧安装与验证

export DETA_PLUGIN_ROOT=~/Dev/ant/deta-agent-plugins/plugins/studio
dsh plugin --profile <name> add "$DETA_PLUGIN_ROOT"

# 只验证配置层是否合并正确(不启动、不需凭据)
cd ~/Dev/ant/deepseek-harness
node apps/cli/lib/bin.js --profile headless --dump-config \
  --patch "$DETA_PLUGIN_ROOT/cordis.patch.yml"
# 输出中应出现 `# == .../plugins/studio/cordis.patch.yml` 与 deta-mcp(transport: stdio)

已知缺陷(实测)

上游:编码代理 × 模型服务 命名空间重复 —— 会话累积较多本插件工具调用后,代理会在请求里 重复声明 MCP 命名空间,模型服务的 Responses 兼容层拒绝并报 Duplicate namespace name 'deta'; Namespace names must be unique.。 应对:完成一个任务后另起会话;撞到该错误不要重试(工作区文件保留)。 复现记录与已排除手段见 plugins/studio/README.md。

已修缺陷(实测)

现象 根因 修复
写类工具返回 user cancelled MCP tool call MCP 工具默认需审批,非交互模式无法弹窗 .mcp.json 声明 default_tools_approval_mode: "approve"
本机 stdio 形态起不来:ERR_UNSUPPORTED_DIR_IMPORT 启动器指向未打包的产物(依赖包目录 import 在 Node ESM 下非法) 领域服务提供打包入口;启动器优先取打包产物,回落未打包产物时打印警告
一个插件两种形态并存(远程 URL + 本机 stdio) 历史遗留,语义冲突 统一为本机 stdio 单一管道
启动器把开发检出当唯一运行前提 默认值写死开发检出路径 运行时按 DETA_SERVER_ROOT → ~/.deta/runtime → 开发检出 解析,回落时打印提示

目录结构

.agents/plugins/marketplace.json        # Codex 默认市场(ChatGPT 登录用户)
.agents/plugins/api_marketplace.json    # Codex API key 登录用户市场
.gitea/workflows/ci.yml                 # CI:跑 scripts/check-plugin-contract.mjs
scripts/check-plugin-contract.mjs       # 仓库章程校验(工具清单 / 内部实现 / 开发检出依赖)
plugins/studio/                          # 产品插件:同一目录 = Codex 插件根 = dsh 组合包根
├── .codex-plugin/plugin.json           # Codex 插件清单(name: studio)
├── .mcp.json                           # Codex MCP 声明(studio_mcp → ./bin/deta-mcp.sh --profile studio)
├── package.json                        # dsh 组合包声明(dsh.bundle.patch)
├── cordis.patch.yml                    # dsh 配置层(同一启动器,serverName: studio_mcp)
├── bin/deta-login.mjs                  # 登录助手(~/.deta/credentials.json + ~/.deta/env)
├── bin/deta-mcp.sh                     # 本机 stdio 启动器(多产品共用;--profile 区分档位)
├── README.md                           # 插件说明(连接形态 / 凭据 / 排障)
└── skills/aml-design/SKILL.md          # 宿主侧技能(不含工具清单)
plugins/writer/                          # 产品插件:报告/文档产出
├── .codex-plugin/plugin.json           # Codex 插件清单(name: writer)
├── .mcp.json                           # Codex MCP 声明(writer_mcp → ./bin/deta-mcp.sh --profile writer)
├── package.json                        # dsh 组合包声明(dsh.bundle.patch)
├── cordis.patch.yml                    # dsh 配置层(同一启动器,serverName: writer_mcp)
├── bin/deta-login.mjs                  # 登录助手(云侧能力用)
├── bin/deta-mcp.sh                     # 本机 stdio 启动器(同一实现;缺省档位 writer)
├── README.md                           # 插件说明(连接形态 / 能力边界 / 排障)
└── skills/report-authoring/SKILL.md    # 宿主侧技能(报告取数与纪律)