refactor: unify skills+cli runtime and streamline ag-ui flow
This commit is contained in:
@@ -204,8 +204,8 @@ interface ForwardedProps {
|
||||
|
||||
| runtime_mode | 说明 | Pipeline | 差异 |
|
||||
|--------------|------|----------|------|
|
||||
| `chat` | 标准对话模式 | `router` -> `worker` | `enabled_tools` 和 `context` 来自 `system_agents.yaml` |
|
||||
| `automation` | 自动化任务模式 | `router` -> `worker` | `enabled_tools` 和 `context` 来自 `AutomationJob.config`(通过 `runtime_config` 注入)|
|
||||
| `chat` | 标准对话模式 | `router` -> `worker` | `enabled_skills` 和 `context` 来自 `system_agents.yaml` |
|
||||
| `automation` | 自动化任务模式 | `router` -> `worker` | `enabled_skills` 和 `context` 来自 `AutomationJob.config`(通过 `runtime_config` 注入)|
|
||||
|
||||
> `runtime_mode` 仅影响 `RuntimeConfig`(工具列表与上下文配置),不改变执行阶段。两模式均使用固定两阶段 pipeline。
|
||||
|
||||
@@ -454,7 +454,7 @@ interface HistoryMessageAssistant {
|
||||
seq: number;
|
||||
role: "assistant";
|
||||
content: string;
|
||||
ui_schema: UiSchemaRenderer | null; // 由 agent_output.ui_hints 编译
|
||||
ui_schema: UiSchemaRenderer | null; // 当前 assistant 文本消息默认不携带 UI,通常为 null
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -242,11 +242,8 @@ SSE 协议中的工具名字段保持后端原样,不做服务端翻译:
|
||||
"stage": "worker",
|
||||
"status": "success" | "partial_success" | "failed",
|
||||
"answer": "...",
|
||||
"key_points": [],
|
||||
"result_type": "execution_report" | "clarification" | "error_report" | "unknown",
|
||||
"suggested_actions": [],
|
||||
"error": null,
|
||||
"ui_schema": {}
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
@@ -427,5 +424,5 @@ WHERE (visibility_mask & 2) != 0
|
||||
| agent 输出 visibility_mask | `UI_HISTORY \| CONTEXT_ASSEMBLY`(memory stage 仅 `UI_HISTORY`) | `UI_HISTORY` |
|
||||
| 进入 /history | ✅ | ✅(仅 agent 输出) |
|
||||
| 进入 context assembly | ✅(自动) | ❌(通过 run_input 注入) |
|
||||
| enabled_tools 来源 | `system_agents.yaml` worker 配置 | `AutomationJob.config.enabled_tools` |
|
||||
| enabled_skills 来源 | `system_agents.yaml` worker 配置 | `AutomationJob.config.enabled_skills` |
|
||||
| context 配置来源 | `system_agents.yaml` router context_messages | `AutomationJob.config.context` |
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
# Agent Tool Protocol
|
||||
|
||||
本文件定义当前项目中 AgentScope tool、项目 CLI、tool post-processor、SSE/history/persistence 之间的协议边界。
|
||||
|
||||
## 1. Scope
|
||||
|
||||
本协议覆盖:
|
||||
|
||||
- AgentScope tool wrapper
|
||||
- 项目内受限 CLI tool
|
||||
- runtime tool post-processor
|
||||
- `ToolResponse`
|
||||
- `ToolAgentOutput`
|
||||
- tool message `content`
|
||||
- tool 结果的 SSE/history/persistence 表达
|
||||
|
||||
本协议不覆盖:
|
||||
|
||||
- 前端视觉实现细节
|
||||
- worker answer 文案格式
|
||||
- 非 tool 的普通 assistant 文本输出
|
||||
|
||||
## 2. Core Principles
|
||||
|
||||
1. 项目 CLI 是受限工具执行边界,不是通用 shell。
|
||||
2. agent 只暴露一个 AgentScope tool:`project_cli`。
|
||||
3. skills 只负责向 agent 披露如何使用 `project_cli`,不承担执行 transport。
|
||||
4. Router 是 CLI 的唯一命令分发核心,只允许白名单 `command + subcommand`。
|
||||
5. 每个 CLI 子命令绑定 Python handler。
|
||||
6. handler 只能调用允许的内部能力,不开放任意系统命令执行。
|
||||
7. `ToolAgentOutput.result` 是 canonical machine-oriented tool result。
|
||||
8. `ToolResponse` 不承载完整 `ToolAgentOutput`,只承载给 agent 使用的文本投影。
|
||||
9. tool UI 只来自 `ToolAgentOutput.ui_hints`,不再经过 worker `ui_hints -> ui_schema` 链路。
|
||||
|
||||
## 3. Execution Flow
|
||||
|
||||
一次 tool 调用按如下顺序执行:
|
||||
|
||||
1. AgentScope tool `project_cli` 接收到模型生成的 tool call。
|
||||
2. wrapper 将 `command + subcommand + args` 映射为项目 CLI 输入。
|
||||
3. runtime 将受控认证凭证通过环境变量注入 CLI 子进程。
|
||||
4. CLI router 将 `(command, subcommand)` 分发给对应 Python handler。
|
||||
5. handler 执行业务逻辑并返回结构化 `result`。
|
||||
6. wrapper 将 `result` 投影为文本,写入 `ToolResponse.content`。
|
||||
7. runtime tool post-processor 基于 `result` 和 runtime 上下文生成完整 `ToolAgentOutput`。
|
||||
8. `ToolAgentOutput` 进入:
|
||||
- `TOOL_CALL_RESULT`
|
||||
- `metadata.tool_agent_output`
|
||||
- history replay
|
||||
- context rebuild
|
||||
|
||||
## 4. Input Channels
|
||||
|
||||
Agent -> `project_cli` 的结构化入参:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "calendar",
|
||||
"subcommand": "read",
|
||||
"args": {
|
||||
"start_at": "2026-04-21T00:00:00+08:00",
|
||||
"end_at": "2026-04-22T00:00:00+08:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
CLI 运行时输入通道采用“两者结合”:
|
||||
|
||||
- `argv` 为主:
|
||||
- command
|
||||
- subcommand
|
||||
- mode / formatting flags
|
||||
- `stdin` 为辅:
|
||||
- 较大的 JSON payload
|
||||
- 复杂对象参数
|
||||
- 多步批量操作负载
|
||||
- environment variables:
|
||||
- controlled credential
|
||||
- runtime-only internal context
|
||||
|
||||
约束:
|
||||
|
||||
- 模型不可见的认证信息不得进入 tool args。
|
||||
- CLI 不接受来自自然语言/模型参数的任意 token 字符串。
|
||||
- backend runtime 只能通过受控环境变量注入认证凭证。
|
||||
|
||||
## 5. CLI Output Contract
|
||||
|
||||
CLI handler 的原始成功输出必须是统一结构化结果。
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"command": "calendar",
|
||||
"subcommand": "read",
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"id": "evt_123",
|
||||
"title": "Project sync",
|
||||
"startAt": "2026-04-21T10:00:00+08:00"
|
||||
}
|
||||
],
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
失败时,CLI handler 必须返回结构化错误结果。
|
||||
|
||||
## 6. ToolResponse Contract
|
||||
|
||||
`ToolResponse` 只用于给 agent 提供 tool 结果文本投影。
|
||||
|
||||
规则:
|
||||
|
||||
- `ToolResponse.content` 只包含 `result` 的完整 JSON 文本投影。
|
||||
- 不再把完整 `ToolAgentOutput` 序列化后塞进 `ToolResponse.content`。
|
||||
- 文本投影必须与 `result` 保持等价信息量,不做摘要裁剪。
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{"status":"success","items":[{"id":"evt_123","title":"Project sync","startAt":"2026-04-21T10:00:00+08:00"}],"count":1}
|
||||
```
|
||||
|
||||
## 7. Tool Post-Processor Contract
|
||||
|
||||
runtime 必须在 tool 调用完成后运行 tool post-processor。
|
||||
|
||||
post-processor 负责生成完整 `ToolAgentOutput`,至少包括:
|
||||
|
||||
- `tool_name`(固定为 `project_cli`)
|
||||
- `tool_call_id`
|
||||
- `tool_call_args`
|
||||
- `status`
|
||||
- `result`
|
||||
- `error`
|
||||
- `ui_hints`
|
||||
|
||||
规则:
|
||||
|
||||
- `result` 是真源。
|
||||
- `result` 应保留 `command`、`subcommand` 和 `data`。
|
||||
- `ui_hints` 由 post-processor 生成,不由 worker 生成。
|
||||
- tool 失败时 `error` 必须为结构化对象。
|
||||
- `status` 必须是 `success | failure | partial`。
|
||||
|
||||
## 8. ToolAgentOutput Contract
|
||||
|
||||
`ToolAgentOutput` 用于系统内部和前端消费,不直接作为模型上下文主输入。
|
||||
|
||||
消费位置:
|
||||
|
||||
- `TOOL_CALL_RESULT`
|
||||
- 数据库存储 `metadata.tool_agent_output`
|
||||
- `/history` tool UI replay
|
||||
- cold-path context rebuild
|
||||
|
||||
规则:
|
||||
|
||||
- `tool_name` 固定为 `project_cli`。
|
||||
- `result` 必须是 JSON-native、machine-oriented 结构。
|
||||
- 必须包含后续链式调用所需的 ID/outcome/status/count 等事实。
|
||||
- `ui_hints` 是 tool UI 的唯一真源。
|
||||
|
||||
## 9. History Replay Contract
|
||||
|
||||
`/history` 必须支持 tool UI 回放。
|
||||
|
||||
规则:
|
||||
|
||||
- history 对外返回 tool message。
|
||||
- tool message 的 UI 恢复从 `metadata.tool_agent_output.ui_hints` 读取,编译为 `ui_schema` 后返回。
|
||||
- tool message `content` 仍是 `result` 的 JSON 文本投影。
|
||||
|
||||
## 10. SSE Contract
|
||||
|
||||
规则:
|
||||
|
||||
- `TEXT_MESSAGE_END` 不再包含 worker `ui_hints` 或 `ui_schema`。
|
||||
- `TOOL_CALL_RESULT` 携带 `ui_schema`(由后端 codec 从 `ui_hints` 编译而来)。
|
||||
- tool UI 前端消费基于 `ui_schema`(由 `ui_hints` 编译)。
|
||||
|
||||
## 11. Controlled Credential Contract
|
||||
|
||||
tool runtime 的认证边界使用 controlled credential。
|
||||
|
||||
规则:
|
||||
|
||||
- chat 与 automation 都不得把 `owner_id` 当作凭证。
|
||||
- controlled credential 由当前 bearer token 签发方在同一信任边界内签发。
|
||||
- TTL 目标为 5-10 分钟。
|
||||
- 该凭证只覆盖 tool runtime 所需权限窗口。
|
||||
- 凭证仅通过 backend-controlled env 注入 CLI。
|
||||
- 日志、错误响应、history、SSE 中不得暴露原始凭证。
|
||||
|
||||
## 12. Security Constraints
|
||||
|
||||
- 不开放 shell 执行能力。
|
||||
- 不允许通过 tool args 传任意 token。
|
||||
- 不允许通过 `owner_id` 伪造用户 Bearer token。
|
||||
- 不允许把 DB session 直接注入 CLI 边界。
|
||||
|
||||
## 13. Compatibility Strategy
|
||||
|
||||
- 策略:`backward-compatible`。
|
||||
- `ui_schema` 作为 wire format 保留,由后端 codec 从 `ui_hints` 编译而来。
|
||||
- 前端 renderer 继续消费 `ui_schema`。
|
||||
- `ui_hints` 作为内部字段,不直接传输给前端。
|
||||
Reference in New Issue
Block a user