@ai-zen/cli 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +20 -18
- package/README.zh.md +18 -16
- package/dist/conversation-runner.d.ts.map +1 -1
- package/dist/conversation-runner.js +11 -7
- package/dist/conversation-runner.js.map +1 -1
- package/dist/sub-agent-guard-plugin.d.ts +45 -0
- package/dist/sub-agent-guard-plugin.d.ts.map +1 -0
- package/dist/sub-agent-guard-plugin.js +47 -0
- package/dist/sub-agent-guard-plugin.js.map +1 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.0] - 2026-09-28
|
|
4
|
+
|
|
5
|
+
### 🚀 新功能
|
|
6
|
+
|
|
7
|
+
- **子 Agent 上下文护栏(`SubAgentGuardInstallerPlugin`)** — 补上「主 Agent 有护栏、子 Agent 无护栏」的缺口(新增 `src/sub-agent-guard-plugin.ts`):
|
|
8
|
+
- **背景**:SDK 的子 Agent 由 `AgentTool` / `AgentToolLazy` 在委派时 `new Agent({...})` 构建,新建实例不携带任何插件(`Agent._plugins` 每实例私有,不向子 Agent 传播),且子 Agent 走 `run()` 而非 `send()`(`onBeforeSend` / `onAfterSend` 不会触发)——因此主 Agent 上的 `ContextGuardPlugin` 与自动迁移插件对子 Agent 完全无效,子 Agent 的内循环没有约束
|
|
9
|
+
- **介入点**:core 4.2.0 的 `onSubAgentStart` 钩子在「子 Agent 已构建、尚未 `run()`」时由宿主 Agent 分发,载荷携带子 Agent 实例;`use()` 只是把插件推入 `_plugins`,而钩子分发每次都实时遍历该列表,故在钩子内安插对**本次 `run()` 立即生效**(无需 `init()`,`AgentTool` 也不调用子 Agent 的 `init()`)
|
|
10
|
+
- **约束口径**:把主 Agent 同款的 `ContextGuardPlugin` 装到子 Agent 上——同一 `maxTokens`(当前模型 `maxContextTokens`)、同样不传 ratio(沿用 SDK 默认 1.5),使「上下文 token 超过 `maxTokens` × 1.5 即中断」对子 Agent 同样成立;**不设轮次上限、不设工具调用次数上限**(仅此一项限制)
|
|
11
|
+
- **中断语义为「软中断」**:子 Agent 的 run 立即结束,异常经 `AgentTool` 的 `finally`(分发 `onSubAgentEnd`)上抛至父 Agent,而父 Agent 默认 `allowJsonParseError = true`,故被降级为一条工具结果文本(`执行工具 X 时出错: …`),父 Agent 继续下一轮——停掉烧钱的子 Agent,但不终止用户对话
|
|
12
|
+
- **递归覆盖**:安装器在委派时把自身一并装给子 Agent,故子 Agent 再委派(孙级)同样受约束(默认 SubAgent 定义为 `subagents: deny`,该路径默认不触发,仅在放开递归时生效)
|
|
13
|
+
- **覆盖范围**:仅 core 的 `AgentTool` / `AgentToolLazy` 两条委派路径(均分发 `onSubAgentStart`);SDK 的 `call_skill_sub_agent`(技能子 Agent)不分发该钩子,本次不覆盖
|
|
14
|
+
|
|
15
|
+
### ⚠️ 依赖升级
|
|
16
|
+
|
|
17
|
+
- **`@ai-zen/agents-core` 升至 `^4.2.0`、`@ai-zen/agents-sdk` 升至 `^0.10.0`** — `src/version.ts` 由实际安装版本读取,版本横幅随之显示 core `4.2.0` / sdk `0.10.0`;SDK 0.10.0 新增的 `load_mcp` `include_manifest` 开关为向后兼容的可选参数(默认 `true`,行为与升级前逐字一致),CLI 无需适配
|
|
18
|
+
|
|
19
|
+
### 🔧 修复
|
|
20
|
+
|
|
21
|
+
- **子 Agent 事件对齐 core 4.2.0 的改名与载荷结构** — core 4.2.0 将事件 `sub-agent` 更名为 `sub-agent-start`,载荷由 `{ agent: 子 Agent, ctx }` 改为 `SubAgentContext = { agent: 主 Agent, subAgent: 子 Agent, toolCallContext }`。`src/conversation-runner.ts` 同步适配:事件监听与注销改用 `sub-agent-start`(此前监听旧名将不再触发,子 Agent 流式渲染会静默失效);子 Agent 实例改取自 `subAgent` 字段,工具名改取自 `toolCallContext.tool_call.function.name`(此前读取已不存在的 `ctx` 字段会在 `sub-agent-end` 回调中抛错)
|
|
22
|
+
|
|
23
|
+
### ✅ 测试
|
|
24
|
+
|
|
25
|
+
- 新增 `src/sub-agent-guard-plugin.test.ts`(6 个用例):安装器的装载清单与「不拒绝委派」、安插后对本次 `run()` 立即生效(无需 `init()`)、用量恰好等于硬上限时放行、首轮无 usage 数据时放行、阈值随传入 `maxTokens` 变化、孙级传染
|
|
26
|
+
- `tsc --noEmit` 类型检查、全量单测与 `npm run build` 通过(74 passed / 9 files)
|
|
27
|
+
|
|
3
28
|
## [0.7.0] - 2026-09-20
|
|
4
29
|
|
|
5
30
|
### 🚀 新功能
|
package/README.md
CHANGED
|
@@ -84,6 +84,8 @@ When the API response's `usage.prompt_tokens` exceeds the model's `maxContextTok
|
|
|
84
84
|
|
|
85
85
|
You can also manually trigger a migration at any time by typing `/migrate` in the conversation — no need to wait for the token limit. Both automatic and manual migration delegate to the SDK's `TaskMigrationService`, so the handoff document is always produced consistently.
|
|
86
86
|
|
|
87
|
+
The same context guard also applies to **sub-agents**: at each delegation boundary (`onSubAgentStart`) the CLI installs the same `ContextGuardPlugin` (same `maxTokens`) onto the newly built sub-agent, so a delegated sub-agent is interrupted as soon as its context exceeds the hard limit. This is transparent — a normally-running sub-agent is unaffected.
|
|
88
|
+
|
|
87
89
|
The migration prompt template includes:
|
|
88
90
|
- **Conversation Breakpoint** — Last user/AI exchange verbatim
|
|
89
91
|
- **Completed Tasks** — Task titles and output paths
|
|
@@ -110,7 +112,7 @@ zen hook uninstall
|
|
|
110
112
|
|
|
111
113
|
## Configuration
|
|
112
114
|
|
|
113
|
-
Configuration is stored in `~/.ai-zen/
|
|
115
|
+
Configuration is stored in `~/.ai-zen/config.json` (or `$AI_ZEN_DIR/config.json` if set), shared with other AI-Zen clients. The `maxContextTokens` field on each model sets the migration threshold (typically ~25% of the model's actual context window, e.g. 250,000 for a 1M-token model).
|
|
114
116
|
|
|
115
117
|
```jsonc
|
|
116
118
|
{
|
|
@@ -133,15 +135,15 @@ Configuration is stored in `~/.ai-zen/cli/config.json` (or `$AI_ZEN_DIR/cli/conf
|
|
|
133
135
|
],
|
|
134
136
|
"imageModels": [
|
|
135
137
|
{
|
|
136
|
-
"id": "cogview-
|
|
137
|
-
"name": "CogView-
|
|
138
|
+
"id": "cogview-4",
|
|
139
|
+
"name": "CogView-4",
|
|
138
140
|
"endpointId": "bigmodelcn",
|
|
139
|
-
"modelName": "cogview-
|
|
141
|
+
"modelName": "cogview-4",
|
|
140
142
|
"defaultSize": "1024x1024"
|
|
141
143
|
}
|
|
142
144
|
],
|
|
143
145
|
"defaultModel": "deepseek-v4-flash",
|
|
144
|
-
"defaultImageModel": "cogview-
|
|
146
|
+
"defaultImageModel": "cogview-4",
|
|
145
147
|
"defaultAgent": "default",
|
|
146
148
|
"defaultMigrationModel": "deepseek-v4-flash"
|
|
147
149
|
}
|
|
@@ -155,8 +157,8 @@ Configuration is stored in `~/.ai-zen/cli/config.json` (or `$AI_ZEN_DIR/cli/conf
|
|
|
155
157
|
|
|
156
158
|
```
|
|
157
159
|
~/.ai-zen/ ← Shared root (AI_ZEN_DIR)
|
|
160
|
+
├── config.json ← Endpoints & models (shared with other AI-Zen clients)
|
|
158
161
|
├── cli/ ← CLI runtime data
|
|
159
|
-
│ ├── config.json ← CLI endpoints, models
|
|
160
162
|
│ ├── conversations/ ← CLI conversations
|
|
161
163
|
│ └── drafts/ ← CLI drafts
|
|
162
164
|
├── agents/ ← Agent definitions (shared)
|
|
@@ -192,9 +194,11 @@ Configuration is stored in `~/.ai-zen/cli/config.json` (or `$AI_ZEN_DIR/cli/conf
|
|
|
192
194
|
|
|
193
195
|
MCP server configurations are merged from multiple sources (high to low priority):
|
|
194
196
|
|
|
195
|
-
1. Project
|
|
196
|
-
2. Project
|
|
197
|
-
3.
|
|
197
|
+
1. Project shared `./.mcp.json` (collected from cwd up to git root)
|
|
198
|
+
2. Project personal `./.ai-zen/mcp.json` (same)
|
|
199
|
+
3. Project convention `./.agents/mcp.json`
|
|
200
|
+
4. User-level `~/.ai-zen/mcp.json`
|
|
201
|
+
5. User convention `~/.agents/mcp.json`
|
|
198
202
|
|
|
199
203
|
Same-named servers in higher priority override lower ones.
|
|
200
204
|
|
|
@@ -270,7 +274,7 @@ MCP servers are configured in `mcp.json` files:
|
|
|
270
274
|
{
|
|
271
275
|
"mcpServers": {
|
|
272
276
|
"my-server": {
|
|
273
|
-
"
|
|
277
|
+
"type": "stdio",
|
|
274
278
|
"command": "node",
|
|
275
279
|
"args": ["server.js"],
|
|
276
280
|
"env": {
|
|
@@ -283,9 +287,9 @@ MCP servers are configured in `mcp.json` files:
|
|
|
283
287
|
|
|
284
288
|
Connection lifecycle (connect, reconnect with exponential backoff, idle timeout) is fully managed by the SDK's `McpConnectionManager`.
|
|
285
289
|
|
|
286
|
-
### OAuth (HTTP transport only) —
|
|
290
|
+
### OAuth (HTTP transport only) — Not Yet Supported
|
|
287
291
|
|
|
288
|
-
OAuth 2.0
|
|
292
|
+
The OAuth 2.0 authorization flow (the `oauth` field in `mcp.json`) has its types defined and a `mcp-oauth/` storage directory reserved, but is not implemented yet. An HTTP MCP server configured with `oauth` currently fails to connect due to the missing token.
|
|
289
293
|
|
|
290
294
|
## Preset Endpoints
|
|
291
295
|
|
|
@@ -300,14 +304,12 @@ OAuth 2.0 授权流程(`mcp.json` 中的 `oauth` 字段)已定义类型和
|
|
|
300
304
|
| ID | Name | Endpoint |
|
|
301
305
|
|----|------|----------|
|
|
302
306
|
| `gpt-5.5` | GPT-5.5 | OpenAI |
|
|
303
|
-
| `glm-5.2` | GLM-5.2 | ZhipuAI |
|
|
304
307
|
| `glm-5.1` | GLM-5.1 | ZhipuAI |
|
|
305
|
-
| `glm-
|
|
306
|
-
| `glm-5-turbo` | GLM-5-Turbo | ZhipuAI |
|
|
307
|
-
| `glm-5v-turbo` | GLM-5V-Turbo | ZhipuAI |
|
|
308
|
+
| `glm-5v-turbo` | GLM-5V-Turbo (vision) | ZhipuAI |
|
|
308
309
|
| `glm-4.7-flash` | GLM-4.7-Flash | ZhipuAI |
|
|
309
310
|
| `deepseek-v4-pro` | DeepSeek-V4-Pro | DeepSeek |
|
|
310
311
|
| `deepseek-v4-flash` | DeepSeek-V4-Flash | DeepSeek (**default**) |
|
|
312
|
+
| `deepseek-v4-flash-vision-exp` | DeepSeek-V4-Flash-Vision-Exp (vision) | DeepSeek |
|
|
311
313
|
|
|
312
314
|
## Development
|
|
313
315
|
|
|
@@ -324,9 +326,9 @@ pnpm start
|
|
|
324
326
|
pnpm test
|
|
325
327
|
|
|
326
328
|
# E2E tests (requires API key in .env.local)
|
|
327
|
-
pnpm test
|
|
329
|
+
pnpm test:e2e
|
|
328
330
|
```
|
|
329
331
|
|
|
330
332
|
## License
|
|
331
333
|
|
|
332
|
-
|
|
334
|
+
MIT
|
package/README.zh.md
CHANGED
|
@@ -84,6 +84,8 @@ zen 你好,请介绍一下你自己。
|
|
|
84
84
|
|
|
85
85
|
你也可以在对话中随时输入 `/migrate` 手动触发迁移,而无需等待 token 超限。手动与自动迁移均委托给 SDK 的 `TaskMigrationService`,交接文档生成始终一致。
|
|
86
86
|
|
|
87
|
+
同样的上下文护栏也作用于**子 Agent**:每次委派边界(`onSubAgentStart`)CLI 都会把同一个 `ContextGuardPlugin`(同一 `maxTokens`)安插到新建的子 Agent 上,因此被委派的子 Agent 在上下文超出硬上限时同样会被中断。该过程是透明的,正常运行的子 Agent 不受影响。
|
|
88
|
+
|
|
87
89
|
迁移提示词模板包含:
|
|
88
90
|
- **对话断点** — 最后一段对话原文引用
|
|
89
91
|
- **已完成的任务** — 任务标题和产出路径
|
|
@@ -110,7 +112,7 @@ zen hook uninstall
|
|
|
110
112
|
|
|
111
113
|
## 配置管理
|
|
112
114
|
|
|
113
|
-
配置文件存储在 `~/.ai-zen/
|
|
115
|
+
配置文件存储在 `~/.ai-zen/config.json`(或 `$AI_ZEN_DIR/config.json`),与其他 AI-Zen 客户端共享。其中 `maxContextTokens` 是迁移触发阈值(通常设为模型实际上下文窗口的约 25%,例如 1M tokens 的模型设为 250,000)。
|
|
114
116
|
|
|
115
117
|
```jsonc
|
|
116
118
|
{
|
|
@@ -133,15 +135,15 @@ zen hook uninstall
|
|
|
133
135
|
],
|
|
134
136
|
"imageModels": [
|
|
135
137
|
{
|
|
136
|
-
"id": "cogview-
|
|
137
|
-
"name": "CogView-
|
|
138
|
+
"id": "cogview-4",
|
|
139
|
+
"name": "CogView-4",
|
|
138
140
|
"endpointId": "bigmodelcn",
|
|
139
|
-
"modelName": "cogview-
|
|
141
|
+
"modelName": "cogview-4",
|
|
140
142
|
"defaultSize": "1024x1024"
|
|
141
143
|
}
|
|
142
144
|
],
|
|
143
145
|
"defaultModel": "deepseek-v4-flash",
|
|
144
|
-
"defaultImageModel": "cogview-
|
|
146
|
+
"defaultImageModel": "cogview-4",
|
|
145
147
|
"defaultAgent": "default",
|
|
146
148
|
"defaultMigrationModel": "deepseek-v4-flash"
|
|
147
149
|
}
|
|
@@ -155,8 +157,8 @@ zen hook uninstall
|
|
|
155
157
|
|
|
156
158
|
```
|
|
157
159
|
~/.ai-zen/ ← 共享根(AI_ZEN_DIR)
|
|
160
|
+
├── config.json ← 端点与模型配置(与其他 AI-Zen 客户端共享)
|
|
158
161
|
├── cli/ ← CLI 运行时数据
|
|
159
|
-
│ ├── config.json ← CLI 的端点、模型配置
|
|
160
162
|
│ ├── conversations/ ← CLI 对话记录
|
|
161
163
|
│ └── drafts/ ← CLI 草稿
|
|
162
164
|
├── agents/ ← Agent 定义(共享)
|
|
@@ -192,9 +194,11 @@ zen hook uninstall
|
|
|
192
194
|
|
|
193
195
|
MCP 服务器配置从多个来源合并(优先级从高到低):
|
|
194
196
|
|
|
195
|
-
1.
|
|
196
|
-
2.
|
|
197
|
-
3.
|
|
197
|
+
1. 项目共享 `./.mcp.json`(从 cwd 向上到 git root 沿途收集)
|
|
198
|
+
2. 项目个人 `./.ai-zen/mcp.json`(同上)
|
|
199
|
+
3. 项目规范 `./.agents/mcp.json`
|
|
200
|
+
4. 用户级 `~/.ai-zen/mcp.json`
|
|
201
|
+
5. 用户规范 `~/.agents/mcp.json`
|
|
198
202
|
|
|
199
203
|
同名 server 高优先级覆盖低优先级。
|
|
200
204
|
|
|
@@ -270,7 +274,7 @@ MCP 服务器配置在 `mcp.json` 文件中:
|
|
|
270
274
|
{
|
|
271
275
|
"mcpServers": {
|
|
272
276
|
"my-server": {
|
|
273
|
-
"
|
|
277
|
+
"type": "stdio",
|
|
274
278
|
"command": "node",
|
|
275
279
|
"args": ["server.js"],
|
|
276
280
|
"env": {
|
|
@@ -300,14 +304,12 @@ OAuth 2.0 授权流程(`mcp.json` 中的 `oauth` 字段)已定义类型和
|
|
|
300
304
|
| ID | 名称 | 端点 |
|
|
301
305
|
|----|------|------|
|
|
302
306
|
| `gpt-5.5` | GPT-5.5 | OpenAI |
|
|
303
|
-
| `glm-5.2` | GLM-5.2 | 智谱AI |
|
|
304
307
|
| `glm-5.1` | GLM-5.1 | 智谱AI |
|
|
305
|
-
| `glm-
|
|
306
|
-
| `glm-5-turbo` | GLM-5-Turbo | 智谱AI |
|
|
307
|
-
| `glm-5v-turbo` | GLM-5V-Turbo | 智谱AI |
|
|
308
|
+
| `glm-5v-turbo` | GLM-5V-Turbo(视觉) | 智谱AI |
|
|
308
309
|
| `glm-4.7-flash` | GLM-4.7-Flash | 智谱AI |
|
|
309
310
|
| `deepseek-v4-pro` | DeepSeek-V4-Pro | DeepSeek |
|
|
310
311
|
| `deepseek-v4-flash` | DeepSeek-V4-Flash | DeepSeek(**默认模型**) |
|
|
312
|
+
| `deepseek-v4-flash-vision-exp` | DeepSeek-V4-Flash-Vision-Exp(视觉) | DeepSeek |
|
|
311
313
|
|
|
312
314
|
## 开发
|
|
313
315
|
|
|
@@ -324,9 +326,9 @@ pnpm start
|
|
|
324
326
|
pnpm test
|
|
325
327
|
|
|
326
328
|
# 端到端测试(需在 .env.local 中配置 API Key)
|
|
327
|
-
pnpm test
|
|
329
|
+
pnpm test:e2e
|
|
328
330
|
```
|
|
329
331
|
|
|
330
332
|
## 许可
|
|
331
333
|
|
|
332
|
-
|
|
334
|
+
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-runner.d.ts","sourceRoot":"","sources":["../src/conversation-runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"conversation-runner.d.ts","sourceRoot":"","sources":["../src/conversation-runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AA0D9C,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqJpF"}
|
|
@@ -8,6 +8,7 @@ import chalk from "chalk";
|
|
|
8
8
|
import { AgentNS } from "@ai-zen/agents-core";
|
|
9
9
|
import { AutoRefreshToolsPlugin, ContextGuardPlugin } from "@ai-zen/agents-sdk";
|
|
10
10
|
import { AutoMigrateConfirmPlugin } from "./auto-migrate-confirm-plugin.js";
|
|
11
|
+
import { SubAgentGuardInstallerPlugin } from "./sub-agent-guard-plugin.js";
|
|
11
12
|
import { DeltaRenderer } from "./delta-renderer.js";
|
|
12
13
|
import { createAgent } from "./agent-creator.js";
|
|
13
14
|
import { readConfig } from "./config.js";
|
|
@@ -95,6 +96,10 @@ export async function runConversation(options) {
|
|
|
95
96
|
// 触发后先做一次「二次确认」(AutoMigrateConfirmPlugin,CLI 层):非交互环境无确认通道,
|
|
96
97
|
// 保持既有静默自动迁移行为;用户拒绝则跳过本次迁移、不改变当前对话。
|
|
97
98
|
agent.use(new AutoMigrateConfirmPlugin({ service: migrationService, maxTokens }));
|
|
99
|
+
// subAgentGuard — 子 Agent 上下文护栏:委派前给子 Agent 安插主 Agent 同款的
|
|
100
|
+
// ContextGuardPlugin(同一 maxTokens)。子 Agent 由 SDK 新建实例、不继承宿主插件
|
|
101
|
+
// (且走 run() 而非 send()),故必须经 onSubAgentStart 显式安插。
|
|
102
|
+
agent.use(new SubAgentGuardInstallerPlugin({ maxTokens }));
|
|
98
103
|
}
|
|
99
104
|
// 初始化所有插件
|
|
100
105
|
await agent.init();
|
|
@@ -118,23 +123,22 @@ export async function runConversation(options) {
|
|
|
118
123
|
process.stdout.write(chalk.red(`\n❌ 错误: ${error?.message || error}\n`));
|
|
119
124
|
};
|
|
120
125
|
// ============ 子 Agent 渲染 ============
|
|
121
|
-
const onSubAgent = (
|
|
122
|
-
const
|
|
123
|
-
const toolName = event.ctx?.function_call?.name || "子任务";
|
|
126
|
+
const onSubAgent = ({ subAgent, toolCallContext }) => {
|
|
127
|
+
const toolName = toolCallContext?.tool_call?.function?.name || "子任务";
|
|
124
128
|
process.stdout.write(chalk.yellow.bold(`\n 🧩 ${toolName}:\n`));
|
|
125
129
|
subAgent.events.on("open", onRun);
|
|
126
130
|
subAgent.events.on("chunk", onChunk);
|
|
127
131
|
subAgent.events.on("error", onError);
|
|
128
132
|
};
|
|
129
|
-
const onSubAgentEnd = ({
|
|
130
|
-
const toolName =
|
|
133
|
+
const onSubAgentEnd = ({ toolCallContext }) => {
|
|
134
|
+
const toolName = toolCallContext?.tool_call?.function?.name || "子任务";
|
|
131
135
|
process.stdout.write(chalk.gray(`\n ✅ ${toolName} 完成\n`));
|
|
132
136
|
};
|
|
133
137
|
// ============ 注册事件 ============
|
|
134
138
|
ctx.agent.events.on("open", onRun);
|
|
135
139
|
ctx.agent.events.on("chunk", onChunk);
|
|
136
140
|
ctx.agent.events.on("error", onError);
|
|
137
|
-
ctx.agent.events.on("sub-agent", onSubAgent);
|
|
141
|
+
ctx.agent.events.on("sub-agent-start", onSubAgent);
|
|
138
142
|
ctx.agent.events.on("sub-agent-end", onSubAgentEnd);
|
|
139
143
|
// ============ 初始消息 ============
|
|
140
144
|
if (query) {
|
|
@@ -165,7 +169,7 @@ export async function runConversation(options) {
|
|
|
165
169
|
ctx.agent.events.off("open", onRun);
|
|
166
170
|
ctx.agent.events.off("chunk", onChunk);
|
|
167
171
|
ctx.agent.events.off("error", onError);
|
|
168
|
-
ctx.agent.events.off("sub-agent", onSubAgent);
|
|
172
|
+
ctx.agent.events.off("sub-agent-start", onSubAgent);
|
|
169
173
|
ctx.agent.events.off("sub-agent-end", onSubAgentEnd);
|
|
170
174
|
console.log(chalk.blue.bold("\n👋 再见!\n"));
|
|
171
175
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-runner.js","sourceRoot":"","sources":["../src/conversation-runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"conversation-runner.js","sourceRoot":"","sources":["../src/conversation-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 子 Agent 护栏安装器(CLI 层)— SubAgentGuardInstallerPlugin
|
|
3
|
+
*
|
|
4
|
+
* 背景:SDK 的子 Agent 由 `AgentTool` / `AgentToolLazy` 在委派时 `new Agent({...})` 构建,
|
|
5
|
+
* 新建实例不携带任何插件(`Agent._plugins` 每实例私有,不向子 Agent 传播),且子 Agent 走
|
|
6
|
+
* `run()` 而非 `send()`(`onBeforeSend` / `onAfterSend` 不会触发)。因此主 Agent 上的
|
|
7
|
+
* `ContextGuardPlugin` 对子 Agent 完全无效:子 Agent 的内循环没有上下文 token 护栏。
|
|
8
|
+
*
|
|
9
|
+
* 介入点:core 4.2.0 的 `onSubAgentStart` 钩子在「子 Agent 已构建、尚未 run()」时由宿主 Agent
|
|
10
|
+
* 分发,载荷携带子 Agent 实例。`use()` 只是把插件推入 `_plugins`,而钩子分发每次都实时遍历
|
|
11
|
+
* 该列表,故在钩子内安插对**本次 run 立即生效**(无需 init;AgentTool 也不会调用子 Agent 的
|
|
12
|
+
* init)。
|
|
13
|
+
*
|
|
14
|
+
* 约束口径(与主 Agent 一致,仅此一项):把主 Agent 同款的 `ContextGuardPlugin` 装到子 Agent 上
|
|
15
|
+
* —— 同一 `maxTokens`(当前模型 `maxContextTokens`)、同样不传 ratio(沿用 SDK 默认 1.5),
|
|
16
|
+
* 使「上下文 token 超过 maxTokens × 1.5 即中断」对子 Agent 同样成立。
|
|
17
|
+
* **不设**轮次上限,**不设**工具调用次数上限。
|
|
18
|
+
*
|
|
19
|
+
* 中断语义:抛错即结束子 Agent 的 run;异常经 `AgentTool` 的 finally(分发 onSubAgentEnd)
|
|
20
|
+
* 上抛至父 Agent,因父 Agent 默认 `allowJsonParseError = true` 而降级为一条工具结果文本
|
|
21
|
+
* (`执行工具 X 时出错: …`),父 Agent 继续下一轮——即「软中断」:停掉越界的子 Agent,但不
|
|
22
|
+
* 终止用户对话(如需硬停,父 Agent 须设 allowJsonParseError=false)。
|
|
23
|
+
*
|
|
24
|
+
* 覆盖范围:仅覆盖 core 的 `AgentTool` / `AgentToolLazy` 两条委派路径(均分发 onSubAgentStart)。
|
|
25
|
+
* SDK 的 `call_skill_sub_agent`(技能子 Agent)不分发该钩子,暂不覆盖。
|
|
26
|
+
*/
|
|
27
|
+
import type { AgentPlugin } from "@ai-zen/agents-sdk";
|
|
28
|
+
import type { SubAgentContext } from "@ai-zen/agents-core";
|
|
29
|
+
export interface SubAgentGuardOptions {
|
|
30
|
+
/** 子 Agent 的上下文 token 阈值;与主 Agent 同源(当前模型的 `maxContextTokens`) */
|
|
31
|
+
maxTokens: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 子 Agent 护栏安装器(装在**宿主 Agent** 上)。
|
|
35
|
+
*
|
|
36
|
+
* 每次委派边界把 `ContextGuardPlugin` 装到子 Agent 身上(阈值与主 Agent 相同),并递归安插
|
|
37
|
+
* 自身,使子 Agent 再委派(孙级)时同样受约束。始终返回 undefined,永不拒绝委派——是否中断
|
|
38
|
+
* 由 `ContextGuardPlugin` 按阈值决定。
|
|
39
|
+
*/
|
|
40
|
+
export declare class SubAgentGuardInstallerPlugin implements AgentPlugin {
|
|
41
|
+
private readonly maxTokens;
|
|
42
|
+
constructor(options: SubAgentGuardOptions);
|
|
43
|
+
onSubAgentStart({ subAgent }: SubAgentContext): void;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=sub-agent-guard-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sub-agent-guard-plugin.d.ts","sourceRoot":"","sources":["../src/sub-agent-guard-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACnC,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,qBAAa,4BAA6B,YAAW,WAAW;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,oBAAoB;IAIzC,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE,eAAe,GAAG,IAAI;CASrD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 子 Agent 护栏安装器(CLI 层)— SubAgentGuardInstallerPlugin
|
|
3
|
+
*
|
|
4
|
+
* 背景:SDK 的子 Agent 由 `AgentTool` / `AgentToolLazy` 在委派时 `new Agent({...})` 构建,
|
|
5
|
+
* 新建实例不携带任何插件(`Agent._plugins` 每实例私有,不向子 Agent 传播),且子 Agent 走
|
|
6
|
+
* `run()` 而非 `send()`(`onBeforeSend` / `onAfterSend` 不会触发)。因此主 Agent 上的
|
|
7
|
+
* `ContextGuardPlugin` 对子 Agent 完全无效:子 Agent 的内循环没有上下文 token 护栏。
|
|
8
|
+
*
|
|
9
|
+
* 介入点:core 4.2.0 的 `onSubAgentStart` 钩子在「子 Agent 已构建、尚未 run()」时由宿主 Agent
|
|
10
|
+
* 分发,载荷携带子 Agent 实例。`use()` 只是把插件推入 `_plugins`,而钩子分发每次都实时遍历
|
|
11
|
+
* 该列表,故在钩子内安插对**本次 run 立即生效**(无需 init;AgentTool 也不会调用子 Agent 的
|
|
12
|
+
* init)。
|
|
13
|
+
*
|
|
14
|
+
* 约束口径(与主 Agent 一致,仅此一项):把主 Agent 同款的 `ContextGuardPlugin` 装到子 Agent 上
|
|
15
|
+
* —— 同一 `maxTokens`(当前模型 `maxContextTokens`)、同样不传 ratio(沿用 SDK 默认 1.5),
|
|
16
|
+
* 使「上下文 token 超过 maxTokens × 1.5 即中断」对子 Agent 同样成立。
|
|
17
|
+
* **不设**轮次上限,**不设**工具调用次数上限。
|
|
18
|
+
*
|
|
19
|
+
* 中断语义:抛错即结束子 Agent 的 run;异常经 `AgentTool` 的 finally(分发 onSubAgentEnd)
|
|
20
|
+
* 上抛至父 Agent,因父 Agent 默认 `allowJsonParseError = true` 而降级为一条工具结果文本
|
|
21
|
+
* (`执行工具 X 时出错: …`),父 Agent 继续下一轮——即「软中断」:停掉越界的子 Agent,但不
|
|
22
|
+
* 终止用户对话(如需硬停,父 Agent 须设 allowJsonParseError=false)。
|
|
23
|
+
*
|
|
24
|
+
* 覆盖范围:仅覆盖 core 的 `AgentTool` / `AgentToolLazy` 两条委派路径(均分发 onSubAgentStart)。
|
|
25
|
+
* SDK 的 `call_skill_sub_agent`(技能子 Agent)不分发该钩子,暂不覆盖。
|
|
26
|
+
*/
|
|
27
|
+
import { ContextGuardPlugin } from "@ai-zen/agents-sdk";
|
|
28
|
+
/**
|
|
29
|
+
* 子 Agent 护栏安装器(装在**宿主 Agent** 上)。
|
|
30
|
+
*
|
|
31
|
+
* 每次委派边界把 `ContextGuardPlugin` 装到子 Agent 身上(阈值与主 Agent 相同),并递归安插
|
|
32
|
+
* 自身,使子 Agent 再委派(孙级)时同样受约束。始终返回 undefined,永不拒绝委派——是否中断
|
|
33
|
+
* 由 `ContextGuardPlugin` 按阈值决定。
|
|
34
|
+
*/
|
|
35
|
+
export class SubAgentGuardInstallerPlugin {
|
|
36
|
+
maxTokens;
|
|
37
|
+
constructor(options) {
|
|
38
|
+
this.maxTokens = options.maxTokens;
|
|
39
|
+
}
|
|
40
|
+
onSubAgentStart({ subAgent }) {
|
|
41
|
+
// 与主 Agent 完全同款:同一 maxTokens,不传 ratio(沿用 ContextGuardPlugin 默认 1.5)
|
|
42
|
+
subAgent.use(new ContextGuardPlugin({ maxTokens: this.maxTokens }));
|
|
43
|
+
// 传染到孙级:子 Agent 若再委派,其子 Agent 同样被安插
|
|
44
|
+
subAgent.use(new SubAgentGuardInstallerPlugin({ maxTokens: this.maxTokens }));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=sub-agent-guard-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sub-agent-guard-plugin.js","sourceRoot":"","sources":["../src/sub-agent-guard-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AASxD;;;;;;GAMG;AACH,MAAM,OAAO,4BAA4B;IACtB,SAAS,CAAS;IAEnC,YAAY,OAA6B;QACvC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACrC,CAAC;IAED,eAAe,CAAC,EAAE,QAAQ,EAAmB;QAC3C,oEAAoE;QACpE,QAAQ,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAEpE,oCAAoC;QACpC,QAAQ,CAAC,GAAG,CACV,IAAI,4BAA4B,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAChE,CAAC;IACJ,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-zen/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "AI-ZEN CLI - interactive conversation terminal with file tools and draft recovery",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"author": "LZQCN",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@ai-zen/agents-core": "^4.
|
|
24
|
-
"@ai-zen/agents-sdk": "^0.
|
|
23
|
+
"@ai-zen/agents-core": "^4.2.0",
|
|
24
|
+
"@ai-zen/agents-sdk": "^0.10.0",
|
|
25
25
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
26
26
|
"chalk": "^5.3.0",
|
|
27
27
|
"dayjs": "^1.11.21",
|