From b5877769de4b92aa33b39c47c7af909fd3c76980 Mon Sep 17 00:00:00 2001 From: ringo Date: Thu, 10 Sep 2026 10:35:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20DETA=20Agent=20Plugins=20=E9=A6=96?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 一份产物、多宿主壳:同一目录既是 Codex 插件(.codex-plugin + .mcp.json + skills), 也是 dsh 组合包(dsh.bundle + cordis.patch.yml),能力本体以 MCP 服务提供、多宿主复用。 - Codex:插件市场 + deta 插件(默认市场与 API key 市场两份索引) - dsh:组合包 manifest + 配置层(本地 stdio / 远程 streamable-http 两种形态) - 技能:deta:aml-design(AML 唯一事实源、编译校验、围护结构统计、空间邻接) - 文档:双壳架构对照、本地迭代(cachebuster)、已验证缺陷与上游限制 --- .agents/plugins/api_marketplace.json | 20 +++ .agents/plugins/marketplace.json | 20 +++ .gitignore | 2 + README.md | 168 ++++++++++++++++++++++++ plugins/deta/.codex-plugin/plugin.json | 39 ++++++ plugins/deta/.mcp.json | 15 +++ plugins/deta/bin/deta-mcp.sh | 24 ++++ plugins/deta/cordis.patch.yml | 32 +++++ plugins/deta/package.json | 20 +++ plugins/deta/skills/aml-design/SKILL.md | 53 ++++++++ 10 files changed, 393 insertions(+) create mode 100644 .agents/plugins/api_marketplace.json create mode 100644 .agents/plugins/marketplace.json create mode 100644 .gitignore create mode 100644 README.md create mode 100644 plugins/deta/.codex-plugin/plugin.json create mode 100644 plugins/deta/.mcp.json create mode 100755 plugins/deta/bin/deta-mcp.sh create mode 100644 plugins/deta/cordis.patch.yml create mode 100644 plugins/deta/package.json create mode 100644 plugins/deta/skills/aml-design/SKILL.md diff --git a/.agents/plugins/api_marketplace.json b/.agents/plugins/api_marketplace.json new file mode 100644 index 0000000..df31151 --- /dev/null +++ b/.agents/plugins/api_marketplace.json @@ -0,0 +1,20 @@ +{ + "name": "deta", + "interface": { + "displayName": "DETA" + }, + "plugins": [ + { + "name": "deta", + "source": { + "source": "local", + "path": "./plugins/deta" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Education & Research" + } + ] +} diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json new file mode 100644 index 0000000..df31151 --- /dev/null +++ b/.agents/plugins/marketplace.json @@ -0,0 +1,20 @@ +{ + "name": "deta", + "interface": { + "displayName": "DETA" + }, + "plugins": [ + { + "name": "deta", + "source": { + "source": "local", + "path": "./plugins/deta" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Education & Research" + } + ] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..646ac51 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +node_modules/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..67bc099 --- /dev/null +++ b/README.md @@ -0,0 +1,168 @@ +# 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 add ./plugins/deta` | + +能力本体(AML 建筑模型读写、编译校验、围护结构统计、空间邻接查询)以 MCP 服务提供, +同一份后端与技能被所有宿主复用;新增宿主只需再加一层声明式壳。 + +> 命名约定:`ant` 为内部开发代号,不对外出现;对外产品名统一为 **DETA**。 +> 插件、市场、MCP 服务、技能一律使用 deta 命名。 + +## 安装(Codex) + +```bash +# 从 Git(分发用) +codex plugin marketplace add https://git.deta.city/deta/deta-agent-plugins.git + +# 或本地路径(开发用) +codex plugin marketplace add ~/Dev/ant/deta-agent-plugins + +codex plugin list +codex plugin add deta@deta +``` + +## 内容 + +| 插件 | 技能 | 能力 | 依赖 | +|------|------|------|------| +| `deta` | `deta:aml-design` | AML 建筑模型读写、编译与校验、围护结构统计、空间邻接查询 | node;领域服务已构建 | + +## 前置条件 + +`deta` 插件的 MCP 后端是领域服务的无头 MCP 服务: + +```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` | `/workspace` | AML 工作目录(`aml.xml` / `building.json` 落盘处,名称由底层服务决定) | + +编译与校验类工具需要编译服务在线(`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` 直接指向服务入口 | + +共享面(两端一致,零适配): +- **技能文件格式**:`/SKILL.md` + frontmatter 必填 `name`/`description`,kebab-case。 + Codex 与 dsh(`@deepseek-ai/dsh-skill-filesystem`)要求相同。 +- **共享技能根**:两端都扫描 `~/.agents/skills/` 与 `<项目>/.agents/skills/` + (dsh 侧为 rank 500 / 200 的发现根,且显式支持 `/skills`)。 + 把技能放这里即可双端生效,不需要安装插件。 +- **MCP 工具命名**:两端同为 `mcp____`,我们统一 `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 add ~/Dev/ant/deta-agent-plugins/plugins/deta + +# 公开发布形态(二选一) +npm publish # 用户:dsh plugin --profile add deta-plugin +dsh plugin --profile 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` + Bearer 头), +当前默认启用的是本地 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 声明(含 Codex 私有键) +├── package.json # dsh 组合包声明(dsh.bundle.patch) +├── cordis.patch.yml # dsh 配置层(挂载 MCP 服务) +├── bin/deta-mcp.sh # 本地 MCP 启动器(开发用) +└── skills/aml-design/SKILL.md # 领域技能(两宿主共享) +``` diff --git a/plugins/deta/.codex-plugin/plugin.json b/plugins/deta/.codex-plugin/plugin.json new file mode 100644 index 0000000..dce24f6 --- /dev/null +++ b/plugins/deta/.codex-plugin/plugin.json @@ -0,0 +1,39 @@ +{ + "name": "deta", + "version": "0.1.0+codex.20260910023121", + "description": "DETA \u5efa\u7b51\u6027\u80fd\u8bbe\u8ba1\u63d2\u4ef6\uff1a\u4ee5 AML \u4e3a\u552f\u4e00\u4e8b\u5b9e\u6e90\u7f16\u8f91\u5efa\u7b51\u6a21\u578b\uff0c\u7ecf GSA \u7f16\u8bd1\u4e3a\u5efa\u7b51\u6a21\u578b\u5e76\u505a\u89c4\u5219\u6821\u9a8c\u3002", + "author": { + "name": "DETA", + "url": "https://deta.city" + }, + "homepage": "https://deta.city", + "license": "Proprietary", + "keywords": [ + "architecture", + "aml", + "building-performance", + "energy", + "bim", + "design" + ], + "skills": "./skills/", + "interface": { + "displayName": "DETA \u5efa\u7b51\u6027\u80fd\u8bbe\u8ba1", + "shortDescription": "AML \u5efa\u7b51\u6a21\u578b\u8bfb\u5199\u3001\u7f16\u8bd1\u4e0e\u6821\u9a8c", + "longDescription": "\u5728\u7f16\u7801\u4ee3\u7406\u4e2d\u76f4\u63a5\u64cd\u4f5c\u5efa\u7b51\u6a21\u578b\uff1a\u8bfb\u53d6\u4e0e\u7f16\u8f91 AML \u8bbe\u8ba1\u6e90\u7801\uff0c\u7ecf\u7f16\u8bd1\u5668\u7f16\u8bd1\u4e3a\u5efa\u7b51\u6a21\u578b\uff0c\u6267\u884c\u8bed\u6cd5\u4e0e\u89c4\u5219\u6821\u9a8c\u3001\u56f4\u62a4\u7ed3\u6784\u7edf\u8ba1\u4e0e\u7a7a\u95f4\u90bb\u63a5\u67e5\u8be2\u3002AML \u662f\u5efa\u7b51\u8bed\u4e49\u7684\u552f\u4e00\u4e8b\u5b9e\u6e90\uff0c\u6240\u6709\u51e0\u4f55\u7f16\u8f91\u5747\u843d\u5230 AML \u6587\u672c\u3002", + "developerName": "DETA", + "category": "Education & Research", + "capabilities": [ + "Interactive", + "Read", + "Write" + ], + "brandColor": "#2F6F4E", + "websiteURL": "https://deta.city", + "defaultPrompt": [ + "\u8bfb\u53d6\u5f53\u524d AML \u8bbe\u8ba1\u6e90\u7801\u5e76\u8bf4\u660e\u5efa\u7b51\u6784\u6210\u3002", + "\u5728 AML \u4e2d\u4fee\u6539\u6307\u5b9a\u7a7a\u95f4\u7684\u5c42\u9ad8\uff0c\u7136\u540e\u91cd\u65b0\u7f16\u8bd1\u6821\u9a8c\u3002", + "\u7edf\u8ba1\u5f53\u524d\u6a21\u578b\u7684\u56f4\u62a4\u7ed3\u6784\u9762\u79ef\u4e0e\u5916\u7a97\u9762\u79ef\u3002" + ] + } +} diff --git a/plugins/deta/.mcp.json b/plugins/deta/.mcp.json new file mode 100644 index 0000000..f34debe --- /dev/null +++ b/plugins/deta/.mcp.json @@ -0,0 +1,15 @@ +{ + "mcpServers": { + "deta": { + "command": "./bin/deta-mcp.sh", + "args": [], + "cwd": ".", + "env_vars": [ + "DETA_SERVER_ROOT", + "ANT_HEADLESS_WORKSPACE" + ], + "default_tools_approval_mode": "approve", + "supports_parallel_tool_calls": false + } + } +} diff --git a/plugins/deta/bin/deta-mcp.sh b/plugins/deta/bin/deta-mcp.sh new file mode 100755 index 0000000..43ca0d0 --- /dev/null +++ b/plugins/deta/bin/deta-mcp.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# DETA 领域服务 MCP stdio 启动器 +# +# 依赖:node + 已构建的领域服务(默认 ~/Dev/ant/ant-copilot 的 dist/src/headless/mcp-server.js) +# 可用环境变量: +# DETA_SERVER_ROOT 领域服务仓库根目录(缺省 ~/Dev/ant/ant-copilot) +# ANT_HEADLESS_WORKSPACE AML 工作目录(缺省 /workspace,供底层服务读取) +set -euo pipefail + +ROOT="${DETA_SERVER_ROOT:-$HOME/Dev/ant/ant-copilot}" +ENTRY="$ROOT/dist/src/headless/mcp-server.js" + +if ! command -v node >/dev/null 2>&1; then + echo "[deta] 未找到 node,请先安装 Node.js" >&2 + exit 1 +fi + +if [ ! -f "$ENTRY" ]; then + echo "[deta] 未找到 $ENTRY" >&2 + echo "[deta] 请先构建领域服务(npm run build)或设置 DETA_SERVER_ROOT" >&2 + exit 1 +fi + +exec node "$ENTRY" "$@" diff --git a/plugins/deta/cordis.patch.yml b/plugins/deta/cordis.patch.yml new file mode 100644 index 0000000..3c76fd9 --- /dev/null +++ b/plugins/deta/cordis.patch.yml @@ -0,0 +1,32 @@ +# DETA 组合包(dsh bundle)配置层 +# +# 挂载方式:dsh plugin --profile add <本包> +# 本层只做一件事:把 DETA 领域能力作为 MCP 服务挂进 harness。 +# 工具以 mcp__deta__ 暴露(与 Codex 侧同名)。 +# +# ── 公开发布形态(远程端点,推荐)───────────────────────────── +# 服务端化完成后启用本节,并删除下面的本地 stdio 节。 +# +# - insert: +# - id: deta-mcp +# name: '@deepseek-ai/dsh-mcp-client' +# config: +# serverName: deta +# transport: streamable-http +# url: https://deta.city/workspace-api/mcp +# headers: +# Authorization: !!js '`Bearer ${process.env.DETA_TOKEN ?? ''}`' +# +# ── 本地形态(当前可用:本机已构建的领域服务,stdio)───────── +# 需要 DETA_SERVER_ROOT 指向已构建的领域服务仓库(缺省见启动器脚本)。 +- insert: + - id: deta-mcp + name: '@deepseek-ai/dsh-mcp-client' + config: + serverName: deta + transport: stdio + command: node + args: + - !!js '`${process.env.DETA_SERVER_ROOT ?? process.env.HOME + "/Dev/ant/ant-copilot"}/dist/src/headless/mcp-server.js`' + env: + ANT_HEADLESS_WORKSPACE: !!js process.env.ANT_HEADLESS_WORKSPACE ?? '' diff --git a/plugins/deta/package.json b/plugins/deta/package.json new file mode 100644 index 0000000..b58dcea --- /dev/null +++ b/plugins/deta/package.json @@ -0,0 +1,20 @@ +{ + "name": "deta-plugin", + "version": "0.1.0", + "description": "DETA 建筑性能设计:AML 建筑模型读写与编译校验(Codex 插件 / dsh 组合包 双壳)", + "type": "module", + "license": "Proprietary", + "files": [ + "cordis.patch.yml", + "skills", + ".codex-plugin", + ".mcp.json", + "bin", + "README.md" + ], + "dsh": { + "bundle": { + "patch": "./cordis.patch.yml" + } + } +} diff --git a/plugins/deta/skills/aml-design/SKILL.md b/plugins/deta/skills/aml-design/SKILL.md new file mode 100644 index 0000000..cf78a02 --- /dev/null +++ b/plugins/deta/skills/aml-design/SKILL.md @@ -0,0 +1,53 @@ +--- +name: aml-design +description: 以 AML 为唯一事实源读写建筑模型并编译校验。当用户要求创建/修改建筑方案、房间布局、层高、开洞、围护结构或做建筑性能相关的模型准备时使用。 +--- + +# DETA 建筑性能设计(AML) + +## 何时使用 + +用户提到建筑方案、房间/空间布局、层高、墙体开洞(门窗)、围护结构、体形系数、 +建筑模型校验,或需要为后续能耗/日照/CFD 模拟准备模型时使用本技能。 + +## 铁律 + +1. **AML 是建筑语义的唯一事实源**。任何几何或属性变更都必须落到 AML 文本, + 不得用中间 JSON 表达修改意图。 +2. **禁止凭记忆编写 AML 结构**。动手前必须先取真实语法: + - 已有模型:`read_source`(读当前 AML) + - 语法规则:`get_aml_schema`(从编译服务实时获取,唯一权威) +3. **属性知识不硬编码**:房间用途、构造材料、洞口参数等可选值从工具返回中获取, + 不要凭经验列举。 +4. **局部修改优于整体重写**:改单个空间属性时只改该空间,不重写整个模型。 +5. **控制单会话工具调用量**。编码代理在会话累积较多本插件工具调用后,会在请求里重复 + 声明 `deta` 命名空间,上游模型服务(Responses 兼容层)直接拒绝: + `Duplicate namespace name 'deta'; Namespace names must be unique`。 + 实测触发点随会话长度前移(并发调用会显著提前触发)。规程: + - 同一轮只调用一个本插件工具,不要并发; + - 单会话保持轻量,完成任务后另起会话继续; + - 一旦出现该错误,**停止重试并告知用户重开会话**(工作区文件不会丢失)。 + +## 标准工作流 + +1. `read_source` 读取当前设计源码(`aml.xml`)。模型为空时先用 `generate_aml` + 按需求生成骨架,再用 `get_aml_schema` 核对语法。 +2. 编辑:直接修改 AML 文本(工作区文件的 edit/write),或使用领域工具。 +3. `apply_design` 提交编译 → 编译为建筑模型,产物落盘 `building.json`。 +4. `validate_model` 做语法与规则校验,逐条读取错误码并修复,不得跳过。 +5. 需要几何指标时用 `envelope_stats`(围护结构/外窗面积)或 `query_spatial_graph` + (空间邻接与查询)。 + +## 错误处理 + +- 编译服务未在线时,编译/校验类工具会返回明确错误文本。此时**不要伪造结果**, + 直接报告「编译服务未接入」,只使用可离线工作的读写类工具。 +- 编译报错必须逐条修复后重新 `apply_design`,禁止在报错状态下声称完成。 + +## 工具一览 + +设计源码:`read_source`、`edit_source`、`get_design_params`、`read_reference`、`run_script` +生成与语法:`generate_aml`、`get_aml_schema` +编译与校验:`apply_design`、`validate_model`、`envelope_stats`、`query_spatial_graph`、 +`generate_candidates` +项目与计算:`list_projects`、`list_buildings`、`analyze_building`、`parameter_sweep`