Why: 卡流机制与中栏过程/回复分离的用户五项裁定(2026-09-30)入库:显式路由、卡片权威+引用回填、默认关、CF0 先行、完备性剧本修订;Cursor 式过程折叠决策(D41)。 Evidence: 提案 docs/proposals/2026-09-30-cardflow-and-process-split.md;usage.md 增过程折叠/长回复折叠/长结果进卡片三节;plugin-development.md 增通道外溢验收项(06 §2.7)。 Impact: 文档;决策编号 D39–D43(D34–D38 为认证提案预留段)。 Refs: Dev 任务卡 feature/cardflow-r1。
139 lines
6.1 KiB
Markdown
139 lines
6.1 KiB
Markdown
# 插件开发指南
|
||
|
||
面向 Agent-System v0.1.0(plugin API `1.0`)。原则:**能数据化的都数据化,代码只留接口**——
|
||
插件 = manifest + 声明资产 + 可选代码;声明资产热加载,装卸不触碰核心二进制。
|
||
|
||
参考实现:Dev 仓 `plugins/example`(覆盖全部五类能力,可直接复制改造)。
|
||
|
||
## 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
|
||
|
||
```json
|
||
{
|
||
"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)
|
||
|
||
```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 形态(数组):
|
||
|
||
```json
|
||
[ { "id": "ask", "domain": "demo", "description": "…", "includes_any": ["示例"], "slots": [] } ]
|
||
```
|
||
|
||
slots 声明即 HITL 该问什么(能力目录理念);宿主识别闸门接入后自动成为命令/分流入口。
|
||
|
||
### 3.4 面板与卡片(UI schema 有限词汇)
|
||
|
||
panels/main.json:
|
||
|
||
```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)
|
||
|
||
```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. 验证清单(发布前自测)
|
||
|
||
```bash
|
||
# 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/)。
|