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 # 宿主侧技能(报告取数与纪律)