Files
deta-agent-plugins/README.md
T

200 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DETA — Agent Plugins
DETA 领域能力在各类 Agent harness 上的分发仓:**一份产物,多个宿主壳**。
| 宿主 | 形态 | 安装 |
|------|------|------|
| Codex | 插件(`.codex-plugin/plugin.json` + `skills/` + `.mcp.json`);本仓同时是 Codex 插件市场 | `codex plugin marketplace add https://git.deta.city/deta/deta-agent-plugins.git` → `codex plugin add deta@deta` |
| dsh (deepseek-harness) | 组合包 bundle(`dsh.bundle.patch` + `cordis.patch.yml`) | `dsh plugin --profile <name> add ./plugins/deta` |
能力本体(AML 建筑模型读写、编译校验、围护结构统计、空间邻接查询)以 MCP 服务提供,
同一份后端与技能被所有宿主复用;新增宿主只需再加一层声明式壳。
## 安装(Codex)
```bash
# 从 Git(分发用)
codex plugin marketplace add https://git.deta.city/deta/deta-agent-plugins.git
codex plugin list
codex plugin add deta@deta
# 登录(一次性):打开浏览器完成 deta.city 账号登录
codex mcp login deta_mcp
```
`codex mcp login deta_mcp` 走 OAuth 2.1(授权码 + PKCE S256 + 动态客户端注册):终端给出
`https://deta.city/oauth/authorize?...`,在浏览器里用 deta.city 账号登录并授权即可,
随后 Codex 自行保管令牌并按 refresh token 自动续期。退出登录用 `codex mcp logout deta_mcp`。
不支持 OAuth 的宿主(dsh / 脚本 / CI)改用登录助手换取 `DETA_TOKEN`:
```bash
node ~/Dev/ant/deta-agent-plugins/plugins/deta/bin/deta-login.mjs
source ~/.deta/env # 让 DETA_TOKEN 进入当前 shell 环境
```
未登录时 MCP 端点返回 **401**,并带 OAuth 发现提示头
(`WWW-Authenticate: Bearer resource_metadata="https://deta.city/.well-known/oauth-protected-resource/mcp-api/mcp"`)——
标准 MCP 客户端据此自动进入浏览器授权流程,含义是「当前环境没有可用的 deta.city 登录态」。
## 内容
| 插件 | 技能 | 能力 | 依赖 |
|------|------|------|------|
| `deta` | `deta:aml-design` | AML 建筑模型读写、编译与校验、围护结构统计、空间邻接查询 | node;领域服务已构建 |
## 前置条件
| 项 | 值 |
|----|-----|
| MCP 端点 | `https://deta.city/mcp-api/mcp`(MCP Streamable HTTP) |
| 凭据来源 | **deta.city 账号**;`bin/deta-login.mjs` 登录取令牌,经环境变量 `DETA_TOKEN` 传给 harness |
| 凭据文件 | `~/.deta/credentials.json`(令牌 + 账号 + 端点)、`~/.deta/env`(`export DETA_TOKEN=...`),均 0600 |
端点除探活接口(服务端 `GET /health`,经 Nginx 前缀对外为 `/mcp-api/health`)外全部需要鉴权:
- 未带凭据 / 凭据失效 → `401`(提示重新登录,不回显凭据);
- 服务端认证服务不可用 → `500`,同样不放行;
- 各账号在服务端有独立工作区(`<工作区根>/<账号 ID>`),互不可见。
### 本地 stdio 形态(开发用,默认关闭)
本机开发时也可以直连领域服务的无头 MCP 服务(`bin/deta-mcp.sh`,stdio),
它**不校验 deta.city 账号、不隔离工作区**,仅供本机迭代领域能力:
```bash
cd ~/Dev/ant/ant-copilot && npm run build
node dist/src/headless/mcp-server.js # 冒烟:应等待 stdin/stdout
```
该形态的环境变量:
| 变量 | 缺省 | 说明 |
|------|------|------|
| `DETA_SERVER_ROOT` | `~/Dev/ant/ant-copilot` | 领域服务仓库根目录(内部路径) |
| `ANT_HEADLESS_WORKSPACE` | `<cwd>/workspace` | AML 工作目录(`aml.xml` / `building.json` 落盘处,名称由底层服务决定) |
编译与校验类工具需要编译服务在线(服务端为 `DETA_GSA_URL`,缺省 `localhost:8000`);
未在线时返回明确错误,读写类工具可离线工作。
## 本地迭代
插件内容改动后 Codex 不会自动感知,按官方流程打 cachebuster 版本号再重装:
```bash
python3.11 ~/.codex/skills/.system/plugin-creator/scripts/update_plugin_cachebuster.py \
~/Dev/ant/deta-agent-plugins/plugins/deta
codex plugin add deta@deta
```
(版本号形如 `0.1.0+codex.20260910020424`;重装后需开新会话才能加载新技能。)
校验清单:
```bash
python3.11 ~/.codex/skills/.system/plugin-creator/scripts/validate_plugin.py \
~/Dev/ant/deta-agent-plugins/plugins/deta
codex plugin marketplace list
codex mcp list | grep deta
```
## 双壳架构(Codex + dsh 同一产物)
`plugins/deta/` 这一个目录同时是 Codex 插件根与 dsh 组合包根,共享核心、各带一层薄壳:
| 组成 | 文件 | Codex | dsh |
|------|------|-------|-----|
| 插件清单 | `.codex-plugin/plugin.json` | ✅ 使用 | — |
| MCP 声明 | `.mcp.json` | ✅ 使用(可放 Codex 私有键) | — |
| 组合包声明 | `package.json`(`dsh.bundle.patch`) | 忽略 | ✅ 使用 |
| 配置层 | `cordis.patch.yml` | 忽略 | ✅ 使用 |
| 领域技能 | `skills/aml-design/SKILL.md` | ✅ 共享 | ✅ 共享 |
| 本地启动器 | `bin/deta-mcp.sh` | ✅ | 由配置层的 `args` 直接指向服务入口 |
共享面(两端一致,零适配):
- **技能文件格式**:`<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`,
因此技能里写裸工具名(`read_source`、`apply_design`)在两端都能解析。
各自不同的部分(不共享):
- MCP 的声明位置不同(Codex 读 `.mcp.json`,dsh 读 `cordis.patch.yml` 的 mcp-client 行)。
- Codex 私有键(`default_tools_approval_mode`、`supports_parallel_tool_calls`)只写在
`.mcp.json`,不影响 dsh;dsh 无审批模式概念。
- 分发渠道不同:Codex 走 git 市场,dsh 走 npm / git / tarball,且 dsh 没有官方市场。
### dsh 侧安装与验证
```bash
# 安装进某个 profile(pnpm 转发)
dsh plugin --profile <name> add ~/Dev/ant/deta-agent-plugins/plugins/deta
# 公开发布形态(二选一)
npm publish # 用户:dsh plugin --profile <name> add deta-plugin
dsh plugin --profile <name> add github:<你>/<仓库> # 需作者提供 prepare + 用户 allowBuilds
# 只验证配置层是否合并正确(不启动、不需凭据)
cd ~/Dev/ant/deepseek-harness
node apps/cli/lib/bin.js --profile headless --dump-config \
--patch ~/Dev/ant/deta-agent-plugins/plugins/deta/cordis.patch.yml
# 输出中应出现 `# == .../plugins/deta/cordis.patch.yml` 与 deta-mcp 行
```
`cordis.patch.yml` 当前默认启用**远程端点**(`streamable-http` +
`Authorization: Bearer ${DETA_TOKEN}`,指向 `https://deta.city/mcp-api/mcp`);
本地 stdio 段保留为注释、标注「本机开发用,默认关闭」,需要时手工切换。
## 已知缺陷(实测,2026-09-10)
**上游:编码代理 × 模型服务 命名空间重复**
会话累积较多本插件工具调用后,代理会在请求里重复声明 MCP 命名空间,模型服务的
Responses 兼容层拒绝请求:
```
Duplicate namespace name 'deta'; Namespace names must be unique.
```
复现记录(同一插件、不同会话长度):
| 代理版本 | 会话规模 | 触发位置 |
|---------|---------|---------|
| 0.144.4 | 一步并发 2 次调用 | input[10]、input[18] |
| 0.144.4 | 串行 7–8 次调用 | input[37]、input[47] |
| 0.154.0 | 短会话 5 工具 | 未触发 |
| 0.154.0 | 长会话(≈15+ 工具) | input[260] |
已排除/无效的手段:`wire_api = "chat"`(该版本已移除,仅支持 responses)、
`features.non_prefixed_mcp_tool_names`(仅去掉命名空间前缀,重复依旧)、
`supports_parallel_tool_calls = false`(削弱并发触发面,长会话仍复现)。
**应对**:完成一个任务后另起会话;撞到该错误不要重试,重开会话即可(工作区文件保留)。
## 已修缺陷(实测)
| 现象 | 根因 | 修复 |
|------|------|------|
| 写类工具返回 `user cancelled MCP tool call` | MCP 工具默认需审批,非交互模式下无法弹窗 | `.mcp.json` 加 `default_tools_approval_mode: "approve"`(实测 `auto`/`writes` 都会被取消,只有 `approve` 放行) |
| 并发调用触发命名空间重复 | 代理并发序列化 | `.mcp.json` 加 `supports_parallel_tool_calls: false` |
## 目录结构
```
.agents/plugins/marketplace.json # Codex 默认市场(ChatGPT 登录用户)
.agents/plugins/api_marketplace.json # Codex API key 登录用户市场
plugins/deta/ # 同一目录 = Codex 插件根 = dsh 组合包根
├── .codex-plugin/plugin.json # Codex 插件清单
├── .mcp.json # Codex MCP 声明(远程 streamable-http)
├── package.json # dsh 组合包声明(dsh.bundle.patch)
├── cordis.patch.yml # dsh 配置层(挂载 MCP 服务)
├── bin/deta-login.mjs # 登录助手(~/.deta/credentials.json + ~/.deta/env)
├── bin/deta-mcp.sh # 本地 stdio 启动器(开发用,默认关闭)
├── README.md # 插件说明(安装/凭据/401 语义)
└── skills/aml-design/SKILL.md # 领域技能(两宿主共享)
```