@ai-zen/agents-sdk 0.9.3 → 0.10.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 +24 -0
- package/README.md +4 -6
- package/README.zh.md +4 -5
- package/dist/capabilities/implements/mcpTools.js +29 -9
- package/dist/runtime/McpConnectionManager.js +13 -3
- package/dist/types/index.d.ts +3 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.0] - 2026-09-28
|
|
4
|
+
|
|
5
|
+
### 🚀 New Features
|
|
6
|
+
|
|
7
|
+
- **`load_mcp` 新增 `include_manifest` 开关(可选布尔,默认 `true`)** — 默认行为逐字不变(返回 `{ tools, resources }` 完整清单,tools 含完整 `inputSchema`);显式传 `false` 时仅建立连接并返回摘要 `{ server, connected, tools: 数量, resources: 数量 }`,不返回任何工具/资源定义。用于「进程重启后连接已失效、但上文中已存在该清单」的场景:只重建连接,不重复向上下文灌入数十 KB 的工具定义,节省 token。完整清单仍留在 `McpConnectionManager` 内,`call_mcp_tool` / `read_mcp_resource` 行为不变;`server` 参数枚举、工具名表与 `DYNAMIC_TOOL_NAMES` 均未变动(前缀缓存结构不变)。失败路径与已连接路径的语义在两种模式下一致;`docs/sdk-design.md` §9 同步更新
|
|
8
|
+
|
|
9
|
+
### 🛠 Optimized
|
|
10
|
+
|
|
11
|
+
- **依赖 `@ai-zen/agents-core` 升至 `^4.2.0`** — 依赖声明保持 `workspace:^`,由 pnpm 在发布时展开为 `^4.2.0`。core 4.2.0 新增子 Agent 委派阻塞钩子 `onSubAgentStart` / `onSubAgentEnd`,并将原有事件 `sub-agent` 更名为 `sub-agent-start`(core 侧破坏性变更);SDK 内部不监听该事件,源码无需适配。监听该事件的消费方需同步更名
|
|
12
|
+
|
|
13
|
+
### ✅ Tests
|
|
14
|
+
|
|
15
|
+
- `mcpTools.test.ts` 新增 4 个用例:静默 + 未连接、静默 + 已连接、显式 `true`、静默 + 连接失败;SDK 全量 **461 passed / 6 skipped**
|
|
16
|
+
|
|
17
|
+
## [0.9.4] - 2026-09-20
|
|
18
|
+
|
|
19
|
+
### 🔧 Fixed
|
|
20
|
+
|
|
21
|
+
- **MCP `sse` transport 改为真正的 SSE 连接(`SSEClientTransport`)** — 此前 `http` 与 `sse` 合并处理,统一使用 `StreamableHTTPClientTransport`(Streamable HTTP:POST 发送消息 + 可选 SSE 流),使配置声明 `type: "sse"` 的旧版 HTTP+SSE 服务器(GET 建立 SSE 流、POST 到 endpoint 发送消息)实际运行在不匹配的协议栈上。现按 transport 拆分:`http` → `StreamableHTTPClientTransport`,`sse` → `SSEClientTransport`(均为官方 SDK 内置实现)。`headers` 仍经 `requestInit` 透传,由 SDK 统一应用于 SSE 建流(GET)与消息发送(POST)请求;缺少 `url` 时的报错行为保持不变。`McpServerConfig.transport` 注释与 `docs/sdk-design.md` §10/§11 同步更新
|
|
22
|
+
|
|
23
|
+
### ✅ Tests
|
|
24
|
+
|
|
25
|
+
- 针对真实 MCP 服务器(`packages/test-project/mcp-servers/sse-server.mjs`,旧版 HTTP+SSE 协议)验证通过:建立连接、工具发现(`echo` / `add`)、工具调用、断开重连;并确认运行时 transport 实例为 `SSEClientTransport`
|
|
26
|
+
|
|
3
27
|
## [0.9.3] - 2026-09-01
|
|
4
28
|
|
|
5
29
|
### 🔧 Fixed
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ Desktop ──┘ │
|
|
|
19
19
|
|
|
20
20
|
```
|
|
21
21
|
types ← pure types, zero business dependencies (incl. ToolEnv)
|
|
22
|
-
config ←
|
|
22
|
+
config ← ConfigManager + constants: config.json read/write + directory setup + factory defaults
|
|
23
23
|
crud ← capability-entity CRUD (Agent definitions, etc.; conversations/drafts are persisted by each consumer)
|
|
24
24
|
capabilities ← capability discovery & assembly (built-in + user + MCP + Skill + SubAgent)
|
|
25
25
|
runtime ← Provider + model factory + Agent assembly + MCP connection management + task migration + SdkCallbackTool base
|
|
@@ -37,7 +37,7 @@ Dependency direction: `plugin → runtime → capabilities → crud → config
|
|
|
37
37
|
| **ToolEnv** | Tool environment `{ cwd, config }`; injected when the Provider instantiates built-in tools, serving as the base for relative path resolution and config reads |
|
|
38
38
|
| **SdkCallbackTool** | Abstract base for built-in tools: `env` constructor injection + subclass `call()` + `resolve()` relative path resolution |
|
|
39
39
|
| **SdkAgent** | Extends the Core Agent, carries SDK metadata, supports `use()` plugin registration |
|
|
40
|
-
| **AgentPlugin** | Plugin interface (`onInit`, `onBeforeSend`, `onAfterSend`, `onInnerLoopStart`, `onInnerLoopEnd`) |
|
|
40
|
+
| **AgentPlugin** | Plugin interface (`onInit`, `onBeforeSend`, `onAfterSend`, `onInnerLoopStart`, `onInnerLoopEnd`, `onInnerLoopsStart`, `onInnerLoopsEnd`, `onToolCall`, `onUnknownTool`, `onSubAgentStart`, `onSubAgentEnd`) |
|
|
41
41
|
| **Endpoint** | API endpoint (baseUrl + apiKey) |
|
|
42
42
|
| **Model** | Model config, bound to an Endpoint |
|
|
43
43
|
| **SubAgent** | An Agent with a `function` field, callable by other Agents as a tool |
|
|
@@ -62,7 +62,7 @@ const provider = await Provider.create({
|
|
|
62
62
|
cwd: "/path/to/workspace", // one working directory per Provider; parallel sessions don't interfere
|
|
63
63
|
...paths,
|
|
64
64
|
});
|
|
65
|
-
const agent = createAgent(provider, "my-agent");
|
|
65
|
+
const agent = await createAgent(provider, "my-agent");
|
|
66
66
|
const migrationService = new TaskMigrationService({ onMigrated }); // migrates via the agent's own model client
|
|
67
67
|
agent.use(new AutoMigratePlugin({ service: migrationService, maxTokens }));
|
|
68
68
|
agent.use(new AutoRefreshToolsPlugin());
|
|
@@ -78,10 +78,9 @@ await agent.send("Hello");
|
|
|
78
78
|
| `config` | ✅ Implemented — ConfigManager + factory defaults + one-shot bootstrap |
|
|
79
79
|
| `crud` | ✅ Implemented — capability-entity CRUD for Agents, etc. (conversations/drafts persisted by each consumer) |
|
|
80
80
|
| `capabilities` | ✅ Implemented — discovery + permission filtering + safe pre-filtering + enumeration disclosure |
|
|
81
|
-
| `runtime` | ✅ Implemented — Provider,
|
|
81
|
+
| `runtime` | ✅ Implemented — Provider, createAgent, MCP connection management, task migration |
|
|
82
82
|
| `plugin` | ✅ Implemented — AutoMigratePlugin / AutoRefreshToolsPlugin / ContextGuardPlugin / UnknownToolHintPlugin |
|
|
83
83
|
| `shared` | ✅ Implemented — SdkError + injectable Logger |
|
|
84
|
-
| Tests | ✅ 452 passing, 51 files, all green (incl. real-API chat & viewImage e2e) |
|
|
85
84
|
|
|
86
85
|
## Built-in Tools
|
|
87
86
|
|
|
@@ -134,4 +133,3 @@ See the project-root [`PRINCIPLES.md`](../../PRINCIPLES.md):
|
|
|
134
133
|
5. Occam's razor
|
|
135
134
|
6. Refactor as you go; keep clean layering
|
|
136
135
|
7. Tests are the foundation
|
|
137
|
-
he foundation
|
package/README.zh.md
CHANGED
|
@@ -18,7 +18,7 @@ Desktop ──┘ │
|
|
|
18
18
|
|
|
19
19
|
```
|
|
20
20
|
types ← 纯类型,零业务依赖(含 ToolEnv 工具环境)
|
|
21
|
-
config ←
|
|
21
|
+
config ← ConfigManager + constants:读写 config.json + 目录初始化 + 出厂默认
|
|
22
22
|
crud ← 能力实体 CRUD(Agent 定义等;会话/草稿已下放给各端自行持久化)
|
|
23
23
|
capabilities ← 能力发现与装配(内置 + 用户 + MCP + Skill + SubAgent)
|
|
24
24
|
runtime ← Provider + 模型工厂 + Agent 组装 + MCP 连接管理 + 任务迁移 + SdkCallbackTool 工具基类
|
|
@@ -36,7 +36,7 @@ shared ← 日志、错误
|
|
|
36
36
|
| **ToolEnv** | 工具环境 `{ cwd, config }`,Provider 实例化内置工具时注入,作为相对路径解析与配置读取的基准 |
|
|
37
37
|
| **SdkCallbackTool** | 内置工具抽象基类:`env` 构造注入 + 子类实现 `call()` + `resolve()` 相对路径解析 |
|
|
38
38
|
| **SdkAgent** | 继承 Core Agent,携带 SDK 元数据,支持 `use()` 插件注册 |
|
|
39
|
-
| **AgentPlugin** | 插件接口(`onInit`, `onBeforeSend`, `onAfterSend`, `onInnerLoopStart`, `onInnerLoopEnd`) |
|
|
39
|
+
| **AgentPlugin** | 插件接口(`onInit`, `onBeforeSend`, `onAfterSend`, `onInnerLoopStart`, `onInnerLoopEnd`, `onInnerLoopsStart`, `onInnerLoopsEnd`, `onToolCall`, `onUnknownTool`, `onSubAgentStart`, `onSubAgentEnd`) |
|
|
40
40
|
| **Endpoint** | API 端点(baseUrl + apiKey) |
|
|
41
41
|
| **Model** | 模型配置,绑定 Endpoint |
|
|
42
42
|
| **SubAgent** | 有 `function` 字段的 Agent,可被其他 Agent 作为工具调用 |
|
|
@@ -61,7 +61,7 @@ const provider = await Provider.create({
|
|
|
61
61
|
cwd: "/path/to/workspace", // 每个 Provider 一个工作目录,多会话并行互不干扰
|
|
62
62
|
...paths,
|
|
63
63
|
});
|
|
64
|
-
const agent = createAgent(provider, "my-agent");
|
|
64
|
+
const agent = await createAgent(provider, "my-agent");
|
|
65
65
|
const migrationService = new TaskMigrationService({ onMigrated }); // 迁移复用传入 agent 自身的模型调用
|
|
66
66
|
agent.use(new AutoMigratePlugin({ service: migrationService, maxTokens }));
|
|
67
67
|
agent.use(new AutoRefreshToolsPlugin());
|
|
@@ -77,10 +77,9 @@ await agent.send("你好");
|
|
|
77
77
|
| `config` | ✅ 已实现 — ConfigManager + 出厂默认配置 + 一键 bootstrap |
|
|
78
78
|
| `crud` | ✅ 已实现 — Agent 等能力实体 CRUD(会话/草稿由各端自行持久化) |
|
|
79
79
|
| `capabilities` | ✅ 已实现 — 发现 + 权限过滤 + 安全预过滤 + 枚举披露 |
|
|
80
|
-
| `runtime` | ✅ 已实现 — Provider、
|
|
80
|
+
| `runtime` | ✅ 已实现 — Provider、createAgent、MCP 连接管理、任务迁移 |
|
|
81
81
|
| `plugin` | ✅ 已实现 — AutoMigratePlugin / AutoRefreshToolsPlugin / ContextGuardPlugin / UnknownToolHintPlugin |
|
|
82
82
|
| `shared` | ✅ 已实现 — SdkError + 可注入 Logger |
|
|
83
|
-
| 测试 | ✅ 452 通过,51 个文件,全绿(含真实 API 聊天与 viewImage e2e) |
|
|
84
83
|
|
|
85
84
|
## 内置工具
|
|
86
85
|
|
|
@@ -24,7 +24,7 @@ export function createLoadMcpTool(mcpManager, filteredMcps) {
|
|
|
24
24
|
return new CallbackTool({
|
|
25
25
|
function: {
|
|
26
26
|
name: "load_mcp",
|
|
27
|
-
description: "连接到指定 MCP
|
|
27
|
+
description: "连接到指定 MCP 服务器,获取其可用工具和资源列表。可用 include_manifest=false 仅建立连接、不返回清单(适用于上文中已有该清单的场景)。",
|
|
28
28
|
parameters: {
|
|
29
29
|
type: "object",
|
|
30
30
|
properties: {
|
|
@@ -33,6 +33,11 @@ export function createLoadMcpTool(mcpManager, filteredMcps) {
|
|
|
33
33
|
description: serverIdDescription,
|
|
34
34
|
...(param.enum ? { enum: param.enum } : {}),
|
|
35
35
|
},
|
|
36
|
+
include_manifest: {
|
|
37
|
+
type: "boolean",
|
|
38
|
+
description: "是否返回该服务器的完整能力清单(工具与资源)。可选,默认 true。若你的上文中已存在该清单(例如本会话早前加载过,而进程重启后连接已失效),可设为 false 仅建立连接、只返回摘要,以节省上下文 token",
|
|
39
|
+
default: true,
|
|
40
|
+
},
|
|
36
41
|
},
|
|
37
42
|
required: ["server"],
|
|
38
43
|
additionalProperties: false,
|
|
@@ -44,20 +49,35 @@ export function createLoadMcpTool(mcpManager, filteredMcps) {
|
|
|
44
49
|
if (!config) {
|
|
45
50
|
return `❌ MCP 服务器 "${serverName}" 不存在`;
|
|
46
51
|
}
|
|
52
|
+
// 披露开关:默认返回完整清单;显式传 false 时仅建立连接、只返回摘要
|
|
53
|
+
const includeManifest = input.include_manifest !== false;
|
|
54
|
+
// 获取清单:已连接 → 复用缓存(touch 续期);未连接 → 建连并发现
|
|
55
|
+
let manifest;
|
|
47
56
|
const existingManifest = mcpManager.getManifest(serverName);
|
|
48
57
|
if (existingManifest && mcpManager.getState(serverName) === "connected") {
|
|
49
58
|
mcpManager.touch(serverName);
|
|
50
|
-
|
|
51
|
-
return JSON.stringify({ tools: existingManifest.tools, resources: existingManifest.resources });
|
|
59
|
+
manifest = existingManifest;
|
|
52
60
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
else {
|
|
62
|
+
try {
|
|
63
|
+
manifest = await mcpManager.connect(serverName, config);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
return `无法连接到 "${serverName}": ${error?.message ?? error}`;
|
|
67
|
+
}
|
|
57
68
|
}
|
|
58
|
-
|
|
59
|
-
|
|
69
|
+
// 静默模式:只回吐摘要(清单仍留在管理器内,供 call_mcp_tool 使用)
|
|
70
|
+
if (!includeManifest) {
|
|
71
|
+
log.info(`[load_mcp] ${serverName}: 已连接(未披露清单:工具 ${manifest.tools.length} 个,资源 ${manifest.resources.length} 个)`);
|
|
72
|
+
return JSON.stringify({
|
|
73
|
+
server: serverName,
|
|
74
|
+
connected: true,
|
|
75
|
+
tools: manifest.tools.length,
|
|
76
|
+
resources: manifest.resources.length,
|
|
77
|
+
});
|
|
60
78
|
}
|
|
79
|
+
log.info(`[load_mcp] ${serverName}:\n${JSON.stringify(manifest, null, 2)}`);
|
|
80
|
+
return JSON.stringify({ tools: manifest.tools, resources: manifest.resources });
|
|
61
81
|
},
|
|
62
82
|
});
|
|
63
83
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
2
3
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
3
4
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
4
5
|
import { getLogger } from "../shared/logger.js";
|
|
@@ -197,15 +198,24 @@ export class McpConnectionManager {
|
|
|
197
198
|
env: config.env,
|
|
198
199
|
});
|
|
199
200
|
}
|
|
200
|
-
// http
|
|
201
|
-
if (config.transport === "http"
|
|
201
|
+
// http 使用 Streamable HTTP 传输(POST + 可选 SSE 流)
|
|
202
|
+
if (config.transport === "http") {
|
|
202
203
|
if (!config.url) {
|
|
203
|
-
throw new Error(`MCP
|
|
204
|
+
throw new Error(`MCP http server 缺少 url`);
|
|
204
205
|
}
|
|
205
206
|
return new StreamableHTTPClientTransport(new URL(config.url), {
|
|
206
207
|
requestInit: config.headers ? { headers: config.headers } : undefined,
|
|
207
208
|
});
|
|
208
209
|
}
|
|
210
|
+
// sse 使用旧版 HTTP+SSE 传输(GET 建立 SSE 流,POST 发送消息)
|
|
211
|
+
if (config.transport === "sse") {
|
|
212
|
+
if (!config.url) {
|
|
213
|
+
throw new Error(`MCP sse server 缺少 url`);
|
|
214
|
+
}
|
|
215
|
+
return new SSEClientTransport(new URL(config.url), {
|
|
216
|
+
requestInit: config.headers ? { headers: config.headers } : undefined,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
209
219
|
throw new Error(`不支持的 MCP transport 类型: ${config.transport}`);
|
|
210
220
|
}
|
|
211
221
|
// ---- 断开 ----
|
package/dist/types/index.d.ts
CHANGED
|
@@ -111,8 +111,9 @@ export interface McpServerConfig {
|
|
|
111
111
|
/**
|
|
112
112
|
* MCP 底层传输适配器(已废弃)。
|
|
113
113
|
*
|
|
114
|
-
* 现在由 @modelcontextprotocol/sdk 内置的 StdioClientTransport
|
|
115
|
-
* StreamableHTTPClientTransport
|
|
114
|
+
* 现在由 @modelcontextprotocol/sdk 内置的 StdioClientTransport、
|
|
115
|
+
* StreamableHTTPClientTransport(http)和 SSEClientTransport(sse)实现,
|
|
116
|
+
* 不再需要外部注入。
|
|
116
117
|
*
|
|
117
118
|
* McpConnectionManager 内部使用官方 SDK 的 Transport 接口,
|
|
118
119
|
* 上层无需关心 transport 实现细节。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-zen/agents-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "AI-Zen Agents SDK — shared business logic for CLI and Desktop",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"author": "LZQCN",
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@ai-zen/agents-core": "^4.
|
|
19
|
+
"@ai-zen/agents-core": "^4.2.0",
|
|
20
20
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
21
21
|
"dayjs": "^1.11.21",
|
|
22
22
|
"openai": "^7.5.0"
|