Files
Agent-System-Documents/docs/guides/plugin-development.md
T
weichenandCursor a0da588f90 Document the base extension roadmap and plugin contract v2
Why: The base must stay unmodified by downstream products, so the roadmap, compatibility window, and plugin contract need a written proposal before further forks.
Evidence: Three proposals under docs/proposals and a short pointer in the plugin development guide.
Impact: Downstream work follows extension-point requests and a published base version. Tag commands in the compat proposal are not executed.
Refs: .task/feature-base-extension-roadmap.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 10:34:30 +00:00

6.3 KiB
Raw Blame History

插件开发指南

面向 Agent-System v0.1.0(plugin API 1.0)。原则:能数据化的都数据化,代码只留接口—— 插件 = manifest + 声明资产 + 可选代码;声明资产热加载,装卸不触碰核心二进制。

参考实现:Dev 仓 plugins/example(覆盖全部五类能力,可直接复制改造)。

契约 v2(声明 / 进程内编译 / sidecar / 前端 ESM,下游仓不得改基座)见提案 docs/proposals/2026-10-01-plugin-contract-v2.md。make plugin-new NAME=<id> 生成声明式骨架。

1. 目录结构

my-plugin/
  plugin.json          # 必需:manifest
  tools/*.json         # 声明式 HTTP 工具(v1 代码工具走远期 sidecar 档)
  workflows/*.json     # 工作流定义(步骤:prompt/tool/hitl/artifact)
  intents/*.json       # 意图 specs(agent-intent overlay 形态;slots 即 HITL 询问项)
  prompts/*.md         # 提示词/画像模板
  panels/*.json        # 右栏面板(UI schema)
  cards/*.json         # 对话卡片模板(UI schema)
  settings.json        # 插件自身设置声明(自动出现在设置中心)

2. Manifest

{
  "id": "my-plugin",                  // 唯一;即目录名
  "name": "我的插件",
  "version": "0.1.0",
  "apiVersion": "1.0",                // 宿主兼容窗口检查(不匹配整批拒绝)
  "requires": { "network": ["api.example.com"] },   // 权限清单(装载时可见)
  "provides": {                        // 声明各目录下的资产名(不含扩展名)
    "tools": ["http_fetch"], "intents": ["ask"],
    "panels": ["main"], "cards": ["note"], "prompts": ["writer"], "settings": ["apikey"]
  }
}

fail-closed:任一资产缺失/非法 JSON/manifest 不合法 → 该插件整批拒绝,错误在启动日志与 POST /api/plugins/reload 响应中显式呈现;既有注册不受影响。

3. 五类能力

3.1 声明式 HTTP 工具(tools/*.json)

{
  "name": "http_fetch",
  "description": "获取 URL 内容",
  "parameters": { "type": "object", "properties": { "url": { "type": "string" } }, "required": ["url"] },
  "http": {
    "method": "GET",
    "url": "{{param.url}}",
    "headers": { "Accept": "application/json" },
    "authRef": "models.chat.apiKey",      // 或 env:MY_TOKEN;引用设置密钥/环境变量
    "resultPath": "data.items",            // jq 点路径裁剪(支持数组索引);空取整个响应
    "timeoutMs": 10000
  }
}
  • 模板变量 {{param.x}} 从模型调用参数注入;无脚本语义(防注入)。
  • 注册后受画像三清单约束(默认画像对 http. 前缀族要求执行前 HITL 确认)。
  • 调用审计自动记录(入参摘要/状态/时长)。

3.2 工作流(workflows/*.json)

步骤四类:prompt(发指令模板)/ tool(调工具)/ hitl(产卡片)/ artifact(产出工件)。 intentId 绑定意图后,命中即可启动(意图→工作流的联动消费在编排侧持续增强,v1 为目录数据)。

3.3 意图(intents/*.json)

agent-intent overlay 形态(数组):

[ { "id": "ask", "domain": "demo", "description": "…", "includes_any": ["示例"], "slots": [] } ]

slots 声明即 HITL 该问什么(能力目录理念);宿主识别闸门接入后自动成为命令/分流入口。

3.4 面板与卡片(UI schema 有限词汇)

panels/main.json:

{ "id": "main", "title": "我的面板",
  "body": [
    { "type": "markdown", "markdown": "## 说明\n…" },
    { "type": "kv", "title": "状态", "kv": [["版本", "0.1.0"]] },
    { "type": "list", "items": ["要点一", "要点二"] },
    { "type": "doc-ref", "docId": "art_xxx" },
    { "type": "actions", "actions": [{ "id": "refresh", "label": "刷新" }] },
    { "type": "chart-lite", "chart": { "kind": "bar", "labels": ["A","B"], "series": [3, 5] } },
    { "type": "section", "title": "分组", "children": [ … ] }
  ] }

cards/note.json:{ "kind": "note", "data": [ …UINode ] }。

新卡片类型验收项(通道外溢约束,源自目标系统 06 §2.7):任何新卡片类型都必须能回答「这张卡在飞书/微信群里长什么样」——按钮回调走命令总线(与 Web 同源审计),无交互卡的通道降级为模板消息 + H5 确认页;深读类内容不做通道投影,深链回 Web 弹层。

词汇边界:section / list / kv / form / markdown / doc-ref / actions / chart-lite。 表达不了的高级交互 → 向 Core 提案新词汇(契约扩展流程),不要期望注入 React 组件——前端不开放此口子,这是插件不破坏前端的机制保证。

3.5 提示词模板(prompts/*.md)

内容即模板正文;用户可复制为自有画像后微调。

3.6 插件设置(settings.json)

[ { "key": "apikey", "group": "plugin:my-plugin", "label": "服务密钥", "type": "secret", "effect": "hot" } ]

自动出现在设置中心 plugin:my-plugin 分区;type: secret 掩码显示不回显。

4. 装载、热重载与卸载

  • 启动装载:agent-system serve --plugins <dir>。
  • 热重载:设置 → 插件 → ⟳(或 POST /api/plugins/reload)——重扫目录:新增装载、同 ID 重载(先注销旧注册再装新)、消失卸载。
  • 卸载语义:注册项注销;在途任务对已卸载工具的引用按「定义缺失」稳定报错,不静默;内置能力零影响(测试断言覆盖)。

5. 验证清单(发布前自测)

# 1) manifest 与资产合法性(重载结果应无错误)
curl -s -X POST localhost:8787/api/plugins/reload
# 2) 注册结果
curl -s localhost:8787/api/tools | jq '.[] | select(.pluginId=="my-plugin")'
curl -s localhost:8787/api/plugins | jq '.[] | select(.manifest.id=="my-plugin")'
# 3) 装卸回退(移走目录→reload→内置功能应完全正常)
mv plugins/my-plugin /tmp/ && curl -X POST localhost:8787/api/plugins/reload

6. 领域插件立项提示(CDMO 等)

按既定决策(设计 r2/r3):领域插件基于本契约全新设计——工作流即数据、意图 slots 驱动 HITL、 文档产出走 artifacts、面板走 UI schema;不迁移老系统代码/接口/数据格式,老系统仅作领域业务知识参考。 立项时先写该插件的设计方案(建议放本仓 docs/proposals/)。