@ai-zen/agents-sdk 0.12.0 → 1.0.0-alpha.1
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 +103 -36
- package/README.md +29 -21
- package/README.zh.md +29 -21
- package/dist/{plugin → agent-plugins}/AutoRefreshToolsPlugin.js +2 -2
- package/dist/{plugin → agent-plugins}/UnknownToolHintPlugin.d.ts +7 -5
- package/dist/{plugin → agent-plugins}/UnknownToolHintPlugin.js +9 -5
- package/dist/config/ConfigManager.d.ts +17 -0
- package/dist/config/ConfigManager.js +44 -1
- package/dist/config/constants.js +67 -37
- package/dist/index.d.ts +37 -29
- package/dist/index.js +28 -21
- package/dist/runtime/SdkAgent.d.ts +5 -5
- package/dist/runtime/SdkAgent.js +4 -4
- package/dist/runtime/TaskMigrationService.d.ts +1 -1
- package/dist/runtime/TaskMigrationService.js +2 -2
- package/dist/runtime/createAgent.d.ts +4 -4
- package/dist/runtime/createAgent.js +8 -8
- package/dist/runtime/createModel.d.ts +3 -3
- package/dist/runtime/createModel.js +3 -3
- package/dist/scope/Scope.d.ts +111 -0
- package/dist/scope/Scope.js +165 -0
- package/dist/scope/ScopePlugin.d.ts +51 -0
- package/dist/scope/ScopePlugin.js +1 -0
- package/dist/scope/plugins/allInOne.d.ts +18 -0
- package/dist/scope/plugins/allInOne.js +23 -0
- package/dist/{capabilities/implements → scope/plugins}/builtin/BatchEditTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/BatchEditTool.js +1 -1
- package/dist/scope/plugins/builtin/BuiltinToolsScopePlugin.d.ts +20 -0
- package/dist/scope/plugins/builtin/BuiltinToolsScopePlugin.js +30 -0
- package/dist/{capabilities/implements → scope/plugins}/builtin/CopyTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/CopyTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/CwdTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/CwdTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/DownloadFileTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/DownloadFileTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/EditTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/EditTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ExecAsyncTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ExecAsyncTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ExecTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ExecTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ExistTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ExistTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/FindTextTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/FindTextTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/GenerateImageTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/GenerateImageTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/GlobTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/GlobTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/InspectFileTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/InspectFileTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/LsTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/LsTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/MkdirTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/MkdirTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ReadFileTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ReadFileTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/RenameTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/RenameTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/RmTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/RmTool.js +1 -1
- package/dist/{runtime → scope/plugins/builtin}/SdkCallbackTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/SleepTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/SleepTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ViewImageTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/ViewImageTool.js +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/WriteFileTool.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/WriteFileTool.js +1 -1
- package/dist/{capabilities/discovery/builtin.d.ts → scope/plugins/builtin/discover.d.ts} +1 -1
- package/dist/{capabilities/discovery/builtin.js → scope/plugins/builtin/discover.js} +1 -1
- package/dist/{capabilities/implements → scope/plugins}/builtin/index.d.ts +2 -2
- package/dist/{capabilities/implements → scope/plugins}/builtin/index.js +1 -1
- package/dist/{runtime → scope/plugins/mcp}/McpConnectionManager.d.ts +1 -1
- package/dist/{runtime → scope/plugins/mcp}/McpConnectionManager.js +1 -1
- package/dist/scope/plugins/mcp/McpScopePlugin.d.ts +29 -0
- package/dist/scope/plugins/mcp/McpScopePlugin.js +60 -0
- package/dist/{capabilities/discovery/mcp.d.ts → scope/plugins/mcp/discover.d.ts} +1 -1
- package/dist/{capabilities/discovery/mcp.js → scope/plugins/mcp/discover.js} +1 -1
- package/dist/{capabilities/implements → scope/plugins/mcp}/mcpTools.d.ts +2 -2
- package/dist/{capabilities/implements → scope/plugins/mcp}/mcpTools.js +2 -2
- package/dist/scope/plugins/skills/SkillsScopePlugin.d.ts +28 -0
- package/dist/scope/plugins/skills/SkillsScopePlugin.js +48 -0
- package/dist/{capabilities/discovery/skills.js → scope/plugins/skills/discover.js} +1 -1
- package/dist/{capabilities/implements → scope/plugins/skills}/skillTools.d.ts +1 -1
- package/dist/{capabilities/implements → scope/plugins/skills}/skillTools.js +3 -3
- package/dist/scope/plugins/subagents/SubAgentsScopePlugin.d.ts +20 -0
- package/dist/scope/plugins/subagents/SubAgentsScopePlugin.js +34 -0
- package/dist/{capabilities/discovery/subagents.d.ts → scope/plugins/subagents/discover.d.ts} +1 -1
- package/dist/{capabilities/implements → scope/plugins/subagents}/subAgentTools.d.ts +3 -3
- package/dist/{capabilities/implements → scope/plugins/subagents}/subAgentTools.js +5 -5
- package/dist/scope/plugins/usertools/UserToolsScopePlugin.d.ts +24 -0
- package/dist/scope/plugins/usertools/UserToolsScopePlugin.js +28 -0
- package/dist/{capabilities/discovery/usertools.js → scope/plugins/usertools/discover.js} +1 -1
- package/dist/types/index.d.ts +23 -2
- package/package.json +3 -3
- package/dist/runtime/Provider.d.ts +0 -119
- package/dist/runtime/Provider.js +0 -218
- /package/dist/{plugin → agent-plugins}/AutoMigratePlugin.d.ts +0 -0
- /package/dist/{plugin → agent-plugins}/AutoMigratePlugin.js +0 -0
- /package/dist/{plugin → agent-plugins}/AutoRefreshToolsPlugin.d.ts +0 -0
- /package/dist/{plugin → agent-plugins}/ContextGuardPlugin.d.ts +0 -0
- /package/dist/{plugin → agent-plugins}/ContextGuardPlugin.js +0 -0
- /package/dist/{capabilities → scope}/PermissionEvaluator.d.ts +0 -0
- /package/dist/{capabilities → scope}/PermissionEvaluator.js +0 -0
- /package/dist/{capabilities → scope}/disclosure.d.ts +0 -0
- /package/dist/{capabilities → scope}/disclosure.js +0 -0
- /package/dist/{runtime → scope/plugins/builtin}/SdkCallbackTool.js +0 -0
- /package/dist/{capabilities/implements → scope/plugins}/builtin/outputGuard.d.ts +0 -0
- /package/dist/{capabilities/implements → scope/plugins}/builtin/outputGuard.js +0 -0
- /package/dist/{capabilities/implements → scope/plugins}/builtin/test-helpers.d.ts +0 -0
- /package/dist/{capabilities/implements → scope/plugins}/builtin/test-helpers.js +0 -0
- /package/dist/{capabilities/discovery/skills.d.ts → scope/plugins/skills/discover.d.ts} +0 -0
- /package/dist/{capabilities/discovery/subagents.js → scope/plugins/subagents/discover.js} +0 -0
- /package/dist/{capabilities/discovery/usertools.d.ts → scope/plugins/usertools/discover.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,94 +1,161 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.0-alpha.1] - 2026-10-03
|
|
4
|
+
|
|
5
|
+
### 💥 Breaking Changes
|
|
6
|
+
|
|
7
|
+
- **Factory model catalog refreshed (verified against vendor sources on 2026-10-03)** — every stale or retired model ID in `DEFAULT_APP_CONFIG.models` is replaced:
|
|
8
|
+
- **OpenAI**: `gpt-5.5` → `gpt-6-astra` / `gpt-6.1-sol` / `gpt-6-luna`
|
|
9
|
+
- **Zhipu**: `glm-5.1` / `glm-5v-turbo` → `glm-5.3` / `glm-5.3-flash` / `glm-5.3-flashx`
|
|
10
|
+
- **DeepSeek**: `deepseek-v4-pro` / `deepseek-v4-flash` / `deepseek-v4-flash-vision-exp` → `deepseek-flash`. The two V4-Flash variants were retired by the vendor, and V4-Pro requests are routed to V4.1-Flash.
|
|
11
|
+
- Defaults: `defaultModel` / `defaultMigrationModel` move from `deepseek-v4-flash` to `deepseek-flash`.
|
|
12
|
+
- **`Model.maxContextTokens` semantics clarified — it is the task-migration (handoff) trigger threshold, not the model context window** — `AutoMigratePlugin` does not estimate or learn: it only compares `usage.prompt_tokens` from the API response against this value. The previous comment read "上下文窗口 token 上限" ("context window token limit"), which is why values had been filled in with raw window sizes. Values are now ~25% of the real window (250K for ≥1M-window models), except `glm-4.7-flash` (200K window) which uses 100K.
|
|
13
|
+
|
|
14
|
+
### 🚀 New Features
|
|
15
|
+
|
|
16
|
+
- **Managed model catalog sync (`custom` opt-out)** — `ConfigManager.ensureDefaultConfig()` now reconciles the factory catalog on every `bootstrap()`. Entries in `models` / `imageModels` that do **not** carry `custom: true` are dropped and replaced by the latest `DEFAULT_APP_CONFIG` definitions; entries marked `custom: true` are treated as user-owned and kept verbatim (user wins on id collision, no duplicates). A dangling `defaultModel` / `defaultImageModel` / `defaultMigrationModel` falls back to the factory default, so no reference is ever left pointing at a removed model. `endpoints` are never managed. The sync is idempotent — it only writes when something actually changed. Implemented in `ConfigManager.syncManagedModels`.
|
|
17
|
+
- **`Model` / `ImageModel` gained an optional `custom?: boolean` field** — marks an entry as user-owned so the factory sync leaves it untouched.
|
|
18
|
+
|
|
19
|
+
### ✅ Tests
|
|
20
|
+
|
|
21
|
+
- Added coverage for the model catalog sync: stale non-custom entries replaced, `custom: true` entries preserved, user version winning on id collision without duplication, image models reconciled, dangling default IDs falling back, and idempotency across repeated calls.
|
|
22
|
+
- E2E model IDs updated to the current vendor names (`deepseek-flash`).
|
|
23
|
+
|
|
24
|
+
### 📄 Docs
|
|
25
|
+
|
|
26
|
+
- Current-version references in `docs/zh` and `docs/en` updated to `1.0.0-alpha.1`.
|
|
27
|
+
- `DEFAULT_APP_CONFIG` row in `sdk-design-v0.md` updated to the new model catalog.
|
|
28
|
+
|
|
29
|
+
## [1.0.0-alpha.0] - 2026-09-30
|
|
30
|
+
|
|
31
|
+
### 💥 Breaking Changes
|
|
32
|
+
|
|
33
|
+
- **`Provider` renamed to `Scope` (fully removed, no compatibility alias)** — `runtime/Provider.ts` is migrated to `scope/Scope.ts`. All `provider` fields / params / variables are renamed to `scope`: `SdkAgent.provider` → `SdkAgent.scope`, `createAgent(scope, …)`, `createModel(scope, …)`, `createSubAgentTool(def, scope)`. `FilterOutput` / `ExcludeOptions` / `FilterOptions` move from `runtime/Provider` to `scope/Scope` accordingly.
|
|
34
|
+
- **Capability sources "delegated" to `ScopePlugin` (new capability-plugin contract)** — `Scope` degrades to a pure orchestration container: it only holds `config` / `cwd` / `env` / `agentsDir` and orchestrates the three-stage pipeline (discover → filter → instantiate). The four capability sources previously hard-coded in `Provider.refresh/filter/instantiate` are split into **5 standard plugins**, each self-containing its discovery state and instantiation logic:
|
|
35
|
+
- `BuiltinToolsScopePlugin` (`id: "builtin"`) — 20 built-in tool classes
|
|
36
|
+
- `UserToolsScopePlugin` (`id: "user-tools"`) — `tools/*.js`
|
|
37
|
+
- `SkillsScopePlugin` (`id: "skills"`) — `SKILL.md` + `load_skill` / `call_skill_sub_agent`
|
|
38
|
+
- `McpScopePlugin` (`id: "mcp"`) — `mcp.json` + a private `McpConnectionManager` + `load_mcp` / `call_mcp_tool` / `read_mcp_resource`
|
|
39
|
+
- `SubAgentsScopePlugin` (`id: "subagents"`) — `sub-agents/*.json`
|
|
40
|
+
- **`Scope` no longer accepts capability-source paths, nor exposes an aggregated candidate set** — `new Provider({ config, cwd, agentsDir, skillsPaths, toolsPaths, subAgentsPaths, mcpPaths })` → `new Scope({ config, cwd, agentsDir })`. Paths are now held by the plugins (pass absolute paths, or pass relative ones that each plugin joins against `scope.cwd` during `discover()`). `Scope` no longer has `builtinTools` / `userTools` / `subagents` / `skills` / `mcps` / `mcpManager` fields.
|
|
41
|
+
- **`Provider.create()` removed** — replaced by explicit assembly: `new Scope({...}).use(...plugins)` → `await scope.init()`. (The static `create` shortcut is removed for now, to be revisited later.)
|
|
42
|
+
- **Plugins must be assembled explicitly** — `Scope` registers no default plugins itself; without assembly it has "empty capabilities". The convenience factory `allInOne({ skillsPaths, toolsPaths, subAgentsPaths, mcpPaths })` always returns the 5 standard plugins for one-shot assembly.
|
|
43
|
+
|
|
44
|
+
### 🚀 New Features
|
|
45
|
+
|
|
46
|
+
- **New `ScopePlugin` extension point** — contract `{ id; discover?; candidates; instantiate; dispose? }`, an extension point independent of core's `AgentPlugin` (Agent runtime hooks):
|
|
47
|
+
- `discover?(scope, { silent })` — stage 1 · discovery (may be async, re-scans internally)
|
|
48
|
+
- `candidates(scope, definition)` — stage 2 · contribute four-dimension candidate names (including availability checks, e.g. a synchronous `isAvailable`)
|
|
49
|
+
- `instantiate(scope, filtered)` — stage 3 · produce `Tool[]` from the allowed names after filtering
|
|
50
|
+
- `dispose?()` — release (e.g. disconnect MCP)
|
|
51
|
+
- **New `Scope` API**: `use(...plugins)` (chainable, variadic), `getPluginById(id)` (for external code / plugins to query plugin state), `plugins` (read-only view), `init()` / `refresh({ silent })` / `filter()` / `instantiate()` / `buildTools()` / `dispose()`. Calling `use()` after `init()` throws.
|
|
52
|
+
- **`dispose()` symmetric with `init()`** — calls each plugin's `dispose()` in reverse order; `McpScopePlugin.dispose()` → `mcpManager.disconnectAll()`, so MCP long-lived connections no longer rely solely on an idle timeout.
|
|
53
|
+
- **`allInOne()` convenience factory** — always returns the 5 standard plugins; order is priority (`builtin → user-tools → skills → mcp → subagents`; on dedupe, later registrations override earlier ones, so user tools can still override same-named built-in tools).
|
|
54
|
+
- **`McpScopePlugin.hasConfig()`** — lets `UnknownToolHintPlugin` determine "whether MCP config exists" (replacing a direct read of `provider.mcpPaths`).
|
|
55
|
+
|
|
56
|
+
### 🛠 Optimized
|
|
57
|
+
|
|
58
|
+
- **`UnknownToolHintPlugin` constructor now takes `{ scope }`** — it learns the MCP config via `scope.getPluginById(McpScopePlugin.ID)?.hasConfig()`; behavior semantics are unchanged (config present but `call_mcp_tool` denied → hint about permission; available → guide usage; no config → just hint that it doesn't exist).
|
|
59
|
+
- **`AutoRefreshToolsPlugin`** — now goes through `agent.scope.refresh()` / `agent.scope.buildTools()`.
|
|
60
|
+
- **Progressive-disclosure (lazy-loading) design unchanged** — the schema of `load_skill` / `call_skill_sub_agent` / `load_mcp` / `call_mcp_tool` / `read_mcp_resource`, enum disclosure (`createDisclosureParam`), the `include_manifest` switch, `touch` renewal, and `call_skill_sub_agent` reusing the parent tool set while excluding itself to prevent recursion — all **preserved verbatim**, merely moved from `Provider.instantiate()` to the `instantiate()` of `SkillsScopePlugin` / `McpScopePlugin`. Permission semantics are unchanged (denying `load_*` on the `tools` dimension cuts off the disclosure channel; denied skills/mcps never enter an enum).
|
|
61
|
+
|
|
62
|
+
### 📄 Docs
|
|
63
|
+
|
|
64
|
+
- Added [`docs/sdk-design-v1.md`](docs/sdk-design-v1.md) (the v1 design source of truth, covering the Scope / ScopePlugin architecture, the five plugins, and a migration guide); the old doc is renamed to [`docs/sdk-design-v0.md`](docs/sdk-design-v0.md).
|
|
65
|
+
|
|
66
|
+
### ✅ Tests
|
|
67
|
+
|
|
68
|
+
- All tests migrated to Scope + ScopePlugin: `capabilities.test.ts` rewritten to be organized by plugin dimension (built-in / SubAgent / Skill / MCP / user tools + lifecycle), with `createAgent` / `createModel` / `SdkAgent` / `UnknownToolHint` / `AutoRefreshTools` / `subAgentTools` / `integration` / `e2e-*` updated accordingly. SDK suite: **498 passed / 2 skipped** (including chat / view-image e2e against the real DeepSeek API).
|
|
69
|
+
|
|
3
70
|
## [0.12.0] - 2026-09-29
|
|
4
71
|
|
|
5
72
|
### 🚀 New Features
|
|
6
73
|
|
|
7
|
-
-
|
|
8
|
-
- **`exec`** — `stdout + stderr`
|
|
9
|
-
- **`findText`** —
|
|
10
|
-
- **`glob` / `ls`** —
|
|
11
|
-
- **`readFile`** —
|
|
12
|
-
-
|
|
13
|
-
- **`readFile`
|
|
14
|
-
-
|
|
15
|
-
- **`batchEdit`
|
|
16
|
-
- **`AgentDefinition`
|
|
17
|
-
-
|
|
74
|
+
- **Unified tool output protection (`maxToolOutput`)** — `AppConfig` gains `maxToolOutput?: number` (in characters, default 32768; the factory `DEFAULT_APP_CONFIG` already writes this value). New output-protection skeleton `guardOutput()` (`capabilities/implements/builtin/outputGuard.ts`): tools declare their policy via three callbacks — `isOverLimit(content)` (the tool reads config itself to decide, including a combined measure), `dump(dir, content)` (the dumped-file list; the default is "warn only, no dump"), `buildWarning(ctx)` (the return body, with preview and stats); the skeleton only does two things: "decide → return as-is when under the limit / dump when over". The dump directory is `<os.tmpdir()>/ai-zen/tool-output/<tool>-<timestamp>-<random>/`, isolated and non-overwriting per call, with no self-cleanup (relying on the OS's policy for temp directories). Wired into:
|
|
75
|
+
- **`exec`** — when `stdout + stderr` combined exceed the limit, they are dumped to separate files `stdout.log` / `stderr.log`, returning a warning + head/tail preview per stream (1000 chars each) + char/line counts; the original `exitCode` / `killed` / `terminated` fields are preserved;
|
|
76
|
+
- **`findText`** — dumps `result.json`, returns a warning + head preview (1000 chars); the existing `maxMatches` / `maxFileSize` / `maxLineLength` params are unchanged;
|
|
77
|
+
- **`glob` / `ls`** — dumps `result.json`, returns a warning + head preview, and hints how to narrow the scope (a more precise `pattern` / `exclude`, or switching to `glob`);
|
|
78
|
+
- **`readFile`** — does **not** dump on overflow, only returns a warning and suggests batched reads via `range`.
|
|
79
|
+
- Also exports `headPreview()` / `headTailPreview()` for tools to build previews as needed (the preview text is generated by each tool itself).
|
|
80
|
+
- **`readFile` gains a `range` param (optional)** — `range: [startLine, startCol, endLine, endCol]`, all 0-based, with `-1` meaning the last index; e.g. `[0, 0, 100, -1]` means "read from line 0 col 0 through line 100's last column". The 300KB read threshold is unchanged — the read threshold (whether a file can be read) and the output threshold (whether to dump) are independent.
|
|
81
|
+
- **New `inspectFile` tool (`InspectFileTool`)** — surveys a file's structural overview without reading content, complementing `readFile`'s `range` (look at the structure first, then decide the read range). Returns `path` / `bytes` / `lines` / `chars` / `maxCol` / `lineIndexOfMaxCol` (0-based) / `avgCol` / `lineEnding` (`LF` / `CRLF` / `mixed`); an optional `withColCountMap: true` returns a "line index → column count" object map. Streamed scan, **not limited by the 300KB read threshold**; columns are counted as characters, excluding the line-ending newline; on overflow the detail is not dumped, only the overview plus a hint that "the file scale exceeds the processable range". Built-in tool classes increased from 19 to 20.
|
|
82
|
+
- **`batchEdit` output slimmed down** — successful items no longer echo the old and new text; when all succeed it returns `{ result: "success", replacedCount }`; when there are unmatched items it returns `{ result: "partial", replacedCount, failed: [{ oldText, newText, reason }] }`, echoing only the problematic old and new text, so large blocks aren't echoed back to inflate the output.
|
|
83
|
+
- **`AgentDefinition` gains a `custom` field** — when `true`, SDK init does not touch the Agent's built-in content (e.g. the default prompt). The factory `DEFAULT_AGENT_DEFINITION` carries `custom: false`: `ensureDefaultAgent()` **syncs only the factory prompt** when `custom !== true` (user changes to `name` / `permissions` / `modelId` etc. are preserved), and when the prompt is identical it writes nothing and leaves `updatedAt` untouched (randomly generated message `id`s are ignored in the comparison to avoid timestamp drift).
|
|
84
|
+
- **Default Agent prompt adjusted** — the original rules are replaced by two: ① when a user decision is needed, ask only one question at a time; ② the current conversation is Node.js-driven, so you can write Node.js scripts to perform complex tasks and run them via the `exec` tool.
|
|
18
85
|
|
|
19
86
|
### ✅ Tests
|
|
20
87
|
|
|
21
|
-
-
|
|
88
|
+
- Added `outputGuard.test.ts` (skeleton: return as-is under the limit / dump + warning over the limit / warn-only without `dump` / directory isolation / `headPreview` and `headTailPreview`), `InspectFileTool.test.ts` (overview fields, the `colCountMap` map, CRLF and mixed, no trailing newline on the last line, empty files, files over 300KB, detail-overflow degradation, directories and non-existent paths), and overflow/range-read cases for each tool; `ConfigManager.bootstrap.test.ts` covers `custom: true` skipping, syncing only the prompt, and not writing when identical. SDK suite: **499 passed / 6 skipped**
|
|
22
89
|
|
|
23
90
|
## [0.11.0] - 2026-09-28
|
|
24
91
|
|
|
25
92
|
### 💥 Breaking Changes
|
|
26
93
|
|
|
27
|
-
- **`createCallSkillSubAgentTool`
|
|
94
|
+
- **`createCallSkillSubAgentTool` drops the third param `provider`** — the Skill sub-agent no longer re-resolves its tool set via `provider.buildTools(parent.definition, …)`; instead it **reuses the parent Agent's tool set directly** (`ctx.agent.tools`), excluding only `call_skill_sub_agent` itself: as a one-shot conversational clone, the Skill sub-agent reuses the caller's capabilities without a second permission pass, while also preventing chained skill self-recursion. Callers that passed a `Provider` must drop that argument
|
|
28
95
|
|
|
29
96
|
### 🚀 New Features
|
|
30
97
|
|
|
31
|
-
- **Skill
|
|
98
|
+
- **Skill sub-agent brought into the unified delegation boundary** — `call_skill_sub_agent` is now backed by `AgentToolLazy` (previously an in-place `CallbackTool`), so it shares the same `onSubAgentStart` / `onSubAgentEnd` plugin hooks and `sub-agent-start` / `sub-agent-end` events as regular SubAgent tools. Consumers that plug guards into `ctx.subAgent` (e.g. a context guard) and those that render sub-agent streaming output (e.g. the CLI) now cover this path
|
|
32
99
|
|
|
33
100
|
### 🛠 Optimized
|
|
34
101
|
|
|
35
|
-
- **Skill
|
|
36
|
-
-
|
|
37
|
-
-
|
|
102
|
+
- **Skill sub-agent construction consolidated into `buildAgent`** — the sub-agent's initial messages (`System(SKILL.md content)` + `User(task)`) are now decided by `buildAgent` (leveraging core 4.3.0's optional `messages`); the previously hand-written abort linkage and return-value handling are deleted, delegated to the tool base class for a unified implementation
|
|
103
|
+
- **Validation failures now throw** — a missing `skill_id`, or a Skill that doesn't declare `sub-agent: true`, now throws an error (previously it returned a hint text); the normal path is constrained by the `skill_id` enum, so it isn't triggered
|
|
104
|
+
- **Dependency `@ai-zen/agents-core` bumped to `^4.3.0`** — the dependency declaration stays `workspace:^`, expanded to `^4.3.0` by pnpm at publish time. core 4.3.0 makes `AgentToolLazy.messages` optional
|
|
38
105
|
|
|
39
106
|
### ✅ Tests
|
|
40
107
|
|
|
41
|
-
- `skillTools.test.ts`
|
|
108
|
+
- The `createCallSkillSubAgentTool` cases in `skillTools.test.ts` are rewritten around `AgentToolLazy`: tool contract unchanged, unknown Skill throws, non-sub-agent Skill throws, delegation boundary (`onSubAgentStart` and `sub-agent-start` dispatch, the child reusing the parent tool set while excluding itself, initial messages drawn from SKILL.md and `task`); SDK suite: **463 passed / 6 skipped**
|
|
42
109
|
|
|
43
110
|
## [0.10.0] - 2026-09-28
|
|
44
111
|
|
|
45
112
|
### 🚀 New Features
|
|
46
113
|
|
|
47
|
-
- **`load_mcp`
|
|
114
|
+
- **`load_mcp` gains an `include_manifest` switch (optional boolean, default `true`)** — the default behavior is unchanged verbatim (returns the full `{ tools, resources }` manifest, with tools carrying the full `inputSchema`); passing `false` explicitly only establishes the connection and returns a summary `{ server, connected, tools: count, resources: count }`, without any tool/resource definitions. It serves the "connection has gone stale after a process restart, but the manifest already exists in context" scenario: rebuild the connection only, without re-injecting tens of KB of tool definitions into the context, saving tokens. The full manifest stays inside `McpConnectionManager`, and `call_mcp_tool` / `read_mcp_resource` behavior is unchanged; the `server` param enum, the tool-name table, and `DYNAMIC_TOOL_NAMES` are all unchanged (the prefix-cache structure is unaffected). The failure-path and already-connected-path semantics are identical in both modes; `docs/sdk-design.md` §9 updated accordingly
|
|
48
115
|
|
|
49
116
|
### 🛠 Optimized
|
|
50
117
|
|
|
51
|
-
-
|
|
118
|
+
- **Dependency `@ai-zen/agents-core` bumped to `^4.2.0`** — the dependency declaration stays `workspace:^`, expanded to `^4.2.0` by pnpm at publish time. core 4.2.0 adds the sub-agent delegation blocking hooks `onSubAgentStart` / `onSubAgentEnd` and renames the existing `sub-agent` event to `sub-agent-start` (a core-side breaking change); the SDK doesn't listen to that event internally, so no source adaptation is needed. Consumers listening to that event must rename accordingly
|
|
52
119
|
|
|
53
120
|
### ✅ Tests
|
|
54
121
|
|
|
55
|
-
- `mcpTools.test.ts`
|
|
122
|
+
- `mcpTools.test.ts` gains 4 cases: silent + not connected, silent + connected, explicit `true`, silent + connection failure; SDK suite: **461 passed / 6 skipped**
|
|
56
123
|
|
|
57
124
|
## [0.9.4] - 2026-09-20
|
|
58
125
|
|
|
59
126
|
### 🔧 Fixed
|
|
60
127
|
|
|
61
|
-
- **MCP `sse` transport
|
|
128
|
+
- **MCP `sse` transport switched to a real SSE connection (`SSEClientTransport`)** — previously `http` and `sse` were handled together, both using `StreamableHTTPClientTransport` (Streamable HTTP: POST to send messages + an optional SSE stream), which made legacy HTTP+SSE servers declared as `type: "sse"` (GET to open the SSE stream, POST to the endpoint to send messages) actually run on a mismatched protocol stack. Now they are split by transport: `http` → `StreamableHTTPClientTransport`, `sse` → `SSEClientTransport` (both built-in official SDK implementations). `headers` are still passed through via `requestInit`, applied uniformly by the SDK to the SSE stream setup (GET) and message-sending (POST) requests; the error behavior when `url` is missing is unchanged. The `McpServerConfig.transport` comment and `docs/sdk-design.md` §10/§11 updated accordingly
|
|
62
129
|
|
|
63
130
|
### ✅ Tests
|
|
64
131
|
|
|
65
|
-
-
|
|
132
|
+
- Verified against a real MCP server (`packages/test-project/mcp-servers/sse-server.mjs`, legacy HTTP+SSE protocol): connection setup, tool discovery (`echo` / `add`), tool calls, and disconnect/reconnect; and confirmed the runtime transport instance is `SSEClientTransport`
|
|
66
133
|
|
|
67
134
|
## [0.9.3] - 2026-09-01
|
|
68
135
|
|
|
69
136
|
### 🔧 Fixed
|
|
70
137
|
|
|
71
|
-
- **`createAgent`
|
|
72
|
-
-
|
|
73
|
-
- `omit`
|
|
74
|
-
- `/new`
|
|
75
|
-
-
|
|
138
|
+
- **`createAgent` no longer pollutes the Agent definition template (`definition.messages` reference isolation)** — when creating an Agent, `definition.messages` is now snapshot (`[...(definition.messages ?? [])]`) instead of being referenced directly. Previously the definition array was passed straight to `AgentContext.messages` (a mutable runtime array), so during a conversation `append()` would write the full conversation history back into `definition.messages`, causing:
|
|
139
|
+
- the task-migration `prune` branch to expand the polluted "full history" instead of the template → old messages were neither physically deleted nor marked `omit`, yet the newly injected breakpoint message was visible;
|
|
140
|
+
- the `omit` branch's `preserveCount` to equal the full length because `definition.messages` and `agent.messages` pointed to the same array → history messages could not be marked `omit`;
|
|
141
|
+
- `/new` to copy from the polluted template, so a new conversation inherited the old history.
|
|
142
|
+
- Also fixes a crash when creating an Agent whose definition lacks a `messages` field (`undefined`) (with a `?? []` fallback).
|
|
76
143
|
|
|
77
144
|
### ✅ Tests
|
|
78
145
|
|
|
79
|
-
- `createAgent.test.ts`
|
|
146
|
+
- `createAgent.test.ts` gains: `append` does not pollute `definition.messages` (reference isolation); an Agent whose definition lacks a `messages` field is created normally
|
|
80
147
|
|
|
81
148
|
## [0.9.2] - 2026-08-31
|
|
82
149
|
|
|
83
150
|
### 🎯 Optimized
|
|
84
151
|
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
- **`ViewImageTool`
|
|
152
|
+
- **Default Agent prompt refactored (`DEFAULT_AGENT_DEFINITION`)** — streamlined and stylistically unified:
|
|
153
|
+
- the persona is set to "witty and humorous, rigorous and reliable"
|
|
154
|
+
- the original 8 principles are compressed into one core rule: whenever you hit any situation that is unclear, uncertain, contradictory, or that might affect the result, stop immediately and ask the user directly, rather than filling in the gaps yourself, guessing, or forcing ahead
|
|
155
|
+
- a new "terse" principle: state only the result and necessary explanation; the execution process (tool calls, reads/writes, searches, etc.) is already visible to the user, so don't restate it, to save tokens
|
|
156
|
+
- guards retained: proactively call tools, report faithfully, and act only within the scope you've been assigned
|
|
157
|
+
- injects "current operating system" info, dynamically using `process.platform` to adapt to different platforms
|
|
158
|
+
- **`ViewImageTool` gains a local-URL check** — a new `isLocalUrl()` rejects the `file://` protocol and http(s) URLs pointing to local loopback addresses (`localhost`/`127.0.0.1`/`[::1]`/`0.0.0.0`) (API providers cannot download them), erroring early in the call; `function.description` and the `path_or_url` param description now add "local URLs are not supported; use a file path for local images"
|
|
92
159
|
|
|
93
160
|
## [0.9.1] - 2026-08-28
|
|
94
161
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ AI-Zen SDK — shared business logic layer providing a unified Agent runtime for
|
|
|
4
4
|
|
|
5
5
|
## Source of Truth
|
|
6
6
|
|
|
7
|
-
**[`docs/sdk-design.md`](./docs/sdk-design.md)** is the single source of truth for this package's design. All implementations must stay consistent with the document.
|
|
7
|
+
**[`docs/sdk-design-v1.md`](./docs/sdk-design-v1.md)** is the single source of truth for this package's design. All implementations must stay consistent with the document. (Pre-refactor design is kept in [`docs/sdk-design-v0.md`](./docs/sdk-design-v0.md).)
|
|
8
8
|
|
|
9
9
|
## Architecture
|
|
10
10
|
|
|
@@ -18,23 +18,24 @@ Desktop ──┘ │
|
|
|
18
18
|
## Module Layering
|
|
19
19
|
|
|
20
20
|
```
|
|
21
|
-
types
|
|
22
|
-
config
|
|
23
|
-
crud
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
shared
|
|
21
|
+
types ← pure types, zero business dependencies (incl. ToolEnv)
|
|
22
|
+
config ← ConfigManager + constants: config.json read/write + directory setup + factory defaults
|
|
23
|
+
crud ← capability-entity CRUD (Agent definitions; conversations/drafts are persisted by each consumer)
|
|
24
|
+
runtime ← model factory + Agent assembly + task migration (createModel / createAgent / SdkAgent / TaskMigrationService)
|
|
25
|
+
scope ← Scope orchestration container + ScopePlugin contract + PermissionEvaluator / disclosure + plugins/ (5 self-contained capability sources: discovery + tools + plugin)
|
|
26
|
+
agent-plugins ← Agent plugins (autoMigrate, autoRefreshTools, contextGuard, unknownToolHint)
|
|
27
|
+
shared ← logging, errors
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
Dependency direction: `
|
|
30
|
+
Dependency direction: `agent-plugins → runtime → scope`; `runtime → scope / crud / shared / types`, `scope → types / shared`. Upper layers depend on lower layers.
|
|
31
31
|
|
|
32
32
|
## Core Concepts
|
|
33
33
|
|
|
34
34
|
| Entity | Description |
|
|
35
35
|
|--------|-------------|
|
|
36
|
-
| **
|
|
37
|
-
| **
|
|
36
|
+
| **Scope** | Orchestration container: global context (`config` / `cwd` / `agentsDir`) + the three-phase capability pipeline (discover → filter → instantiate) + plugin registry. Explicitly assembled via `scope.use(...)` |
|
|
37
|
+
| **ScopePlugin** | Capability plugin (the v1 extension point): self-owns one capability source's discovery state, candidate names, and instantiation (`discover` / `candidates` / `instantiate` / `dispose`). 5 standard plugins ship out of the box, assembled via `allInOne()` |
|
|
38
|
+
| **ToolEnv** | Tool environment `{ cwd, config }`; injected when the built-in-tools plugin (`BuiltinToolsScopePlugin`) instantiates tools, serving as the base for relative path resolution and config reads |
|
|
38
39
|
| **SdkCallbackTool** | Abstract base for built-in tools: `env` constructor injection + subclass `call()` + `resolve()` relative path resolution |
|
|
39
40
|
| **SdkAgent** | Extends the Core Agent, carries SDK metadata, supports `use()` plugin registration |
|
|
40
41
|
| **AgentPlugin** | Plugin interface (`onInit`, `onBeforeSend`, `onAfterSend`, `onInnerLoopStart`, `onInnerLoopEnd`, `onInnerLoopsStart`, `onInnerLoopsEnd`, `onToolCall`, `onUnknownTool`, `onSubAgentStart`, `onSubAgentEnd`) |
|
|
@@ -57,17 +58,24 @@ Agent.permissions
|
|
|
57
58
|
## Consumption
|
|
58
59
|
|
|
59
60
|
```typescript
|
|
60
|
-
const
|
|
61
|
+
const scope = new Scope({
|
|
61
62
|
config,
|
|
62
|
-
cwd: "/path/to/workspace", // one working directory per
|
|
63
|
-
|
|
64
|
-
})
|
|
65
|
-
|
|
63
|
+
cwd: "/path/to/workspace", // one working directory per Scope; parallel sessions don't interfere
|
|
64
|
+
agentsDir,
|
|
65
|
+
}).use(
|
|
66
|
+
...allInOne({ skillsPaths, toolsPaths, subAgentsPaths, mcpPaths }),
|
|
67
|
+
);
|
|
68
|
+
await scope.init();
|
|
69
|
+
|
|
70
|
+
const agent = await createAgent(scope, "my-agent");
|
|
66
71
|
const migrationService = new TaskMigrationService({ onMigrated }); // migrates via the agent's own model client
|
|
67
72
|
agent.use(new AutoMigratePlugin({ service: migrationService, maxTokens }));
|
|
68
73
|
agent.use(new AutoRefreshToolsPlugin());
|
|
74
|
+
agent.use(new UnknownToolHintPlugin({ scope }));
|
|
69
75
|
await agent.init();
|
|
70
76
|
await agent.send("Hello");
|
|
77
|
+
|
|
78
|
+
await scope.dispose(); // disconnect MCP, release plugin resources
|
|
71
79
|
```
|
|
72
80
|
|
|
73
81
|
## Development Status
|
|
@@ -77,14 +85,14 @@ await agent.send("Hello");
|
|
|
77
85
|
| `types` | ✅ Implemented — core entities, permission model, MCP types complete |
|
|
78
86
|
| `config` | ✅ Implemented — ConfigManager + factory defaults + one-shot bootstrap |
|
|
79
87
|
| `crud` | ✅ Implemented — capability-entity CRUD for Agents, etc. (conversations/drafts persisted by each consumer) |
|
|
80
|
-
| `
|
|
81
|
-
| `runtime` | ✅ Implemented —
|
|
82
|
-
| `
|
|
88
|
+
| `scope` | ✅ Implemented — Scope + ScopePlugin + 5 standard plugins (builtin / user-tools / skills / mcp / subagents) + allInOne |
|
|
89
|
+
| `runtime` | ✅ Implemented — createAgent, MCP connection management, task migration |
|
|
90
|
+
| `agent-plugins` | ✅ Implemented — AutoMigratePlugin / AutoRefreshToolsPlugin / ContextGuardPlugin / UnknownToolHintPlugin |
|
|
83
91
|
| `shared` | ✅ Implemented — SdkError + injectable Logger |
|
|
84
92
|
|
|
85
93
|
## Built-in Tools
|
|
86
94
|
|
|
87
|
-
All built-in tools are classes (extending `SdkCallbackTool`), instantiated by the
|
|
95
|
+
All built-in tools are classes (extending `SdkCallbackTool`), instantiated by the built-in-tools plugin (`BuiltinToolsScopePlugin`) with a `ToolEnv` — one set of instances per Scope, with `cwd` injected and relative paths resolved against `Scope.cwd`, never depending on the global `process.cwd()`.
|
|
88
96
|
|
|
89
97
|
| Tool | Description |
|
|
90
98
|
|------|-------------|
|
|
@@ -114,7 +122,7 @@ Conditionally injected based on the active model / config:
|
|
|
114
122
|
| `generateImage` | Only when `defaultImageModel` is configured | Generate an image from a text description |
|
|
115
123
|
| `viewImage` | Only for vision models (the agent's `modelId` resolves to a model with `vision: true`) | View / analyze an image: local images are auto-uploaded via the Files API, network URLs are referenced directly |
|
|
116
124
|
|
|
117
|
-
Tool output protection: `AppConfig.maxToolOutput` (in characters, default 32768) is the unified ceiling for tool output. Each tool handles overflow itself — `exec` dumps `stdout.log` / `stderr.log` separately (returning head/tail previews per stream), `findText` / `glob` / `ls` dump `result.json` (returning a head preview), and `readFile` only warns and suggests batched reads via `range`. Dumps go to `<tmpdir>/ai-zen/tool-output/<tool>-<timestamp>-<random>/`, one directory per call, with no self-cleanup. See [`docs/sdk-design.md` §
|
|
125
|
+
Tool output protection: `AppConfig.maxToolOutput` (in characters, default 32768) is the unified ceiling for tool output. Each tool handles overflow itself — `exec` dumps `stdout.log` / `stderr.log` separately (returning head/tail previews per stream), `findText` / `glob` / `ls` dump `result.json` (returning a head preview), and `readFile` only warns and suggests batched reads via `range`. Dumps go to `<tmpdir>/ai-zen/tool-output/<tool>-<timestamp>-<random>/`, one directory per call, with no self-cleanup. See [`docs/sdk-design-v1.md` §12](docs/sdk-design-v1.md).
|
|
118
126
|
|
|
119
127
|
## Built-in Plugins
|
|
120
128
|
|
package/README.zh.md
CHANGED
|
@@ -4,7 +4,7 @@ AI-Zen SDK — 共享业务逻辑层,为 CLI 和 Desktop 提供统一的 Agent
|
|
|
4
4
|
|
|
5
5
|
## 真相源
|
|
6
6
|
|
|
7
|
-
**[`docs/sdk-design.md`](./docs/sdk-design.md)**
|
|
7
|
+
**[`docs/sdk-design-v1.md`](./docs/sdk-design-v1.md)** 是本包的唯一设计真相源。所有实现必须与文档一致。(重构前的设计保留在 [`docs/sdk-design-v0.md`](./docs/sdk-design-v0.md)。)
|
|
8
8
|
## 架构
|
|
9
9
|
|
|
10
10
|
```
|
|
@@ -17,23 +17,24 @@ Desktop ──┘ │
|
|
|
17
17
|
## 模块分层
|
|
18
18
|
|
|
19
19
|
```
|
|
20
|
-
types
|
|
21
|
-
config
|
|
22
|
-
crud
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
shared
|
|
20
|
+
types ← 纯类型,零业务依赖(含 ToolEnv 工具环境)
|
|
21
|
+
config ← ConfigManager + constants:读写 config.json + 目录初始化 + 出厂默认
|
|
22
|
+
crud ← 能力实体 CRUD(Agent 定义等;会话/草稿已下放给各端自行持久化)
|
|
23
|
+
runtime ← 模型工厂 + Agent 组装 + 任务迁移(createModel / createAgent / SdkAgent / TaskMigrationService)
|
|
24
|
+
scope ← Scope 编排容器 + ScopePlugin 契约 + PermissionEvaluator / disclosure + plugins/(5 个自包含能力来源:发现 + 工具 + 插件)
|
|
25
|
+
agent-plugins ← Agent 插件(autoMigrate、autoRefreshTools、contextGuard、unknownToolHint)
|
|
26
|
+
shared ← 日志、错误
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
依赖方向:`
|
|
29
|
+
依赖方向:`agent-plugins → runtime → scope`;`runtime → scope / crud / shared / types`,`scope → types / shared`。上层依赖下层,反之不行。
|
|
30
30
|
|
|
31
31
|
## 核心概念
|
|
32
32
|
|
|
33
33
|
| 实体 | 说明 |
|
|
34
34
|
|------|------|
|
|
35
|
-
| **
|
|
36
|
-
| **
|
|
35
|
+
| **Scope** | 编排容器:全局上下文(`config` / `cwd` / `agentsDir`)+ 三阶段能力管线(发现 → 过滤 → 实例化)+ 插件注册表。经 `scope.use(...)` 显式装配 |
|
|
36
|
+
| **ScopePlugin** | 能力插件(v1 扩展点):自持一类能力的发现状态、候选名与实例化(`discover` / `candidates` / `instantiate` / `dispose`)。内置 5 个标准插件,经 `allInOne()` 一键装配 |
|
|
37
|
+
| **ToolEnv** | 工具环境 `{ cwd, config }`,内置工具插件(`BuiltinToolsScopePlugin`)实例化工具时注入,作为相对路径解析与配置读取的基准 |
|
|
37
38
|
| **SdkCallbackTool** | 内置工具抽象基类:`env` 构造注入 + 子类实现 `call()` + `resolve()` 相对路径解析 |
|
|
38
39
|
| **SdkAgent** | 继承 Core Agent,携带 SDK 元数据,支持 `use()` 插件注册 |
|
|
39
40
|
| **AgentPlugin** | 插件接口(`onInit`, `onBeforeSend`, `onAfterSend`, `onInnerLoopStart`, `onInnerLoopEnd`, `onInnerLoopsStart`, `onInnerLoopsEnd`, `onToolCall`, `onUnknownTool`, `onSubAgentStart`, `onSubAgentEnd`) |
|
|
@@ -56,17 +57,24 @@ Agent.permissions
|
|
|
56
57
|
## 消费模式
|
|
57
58
|
|
|
58
59
|
```typescript
|
|
59
|
-
const
|
|
60
|
+
const scope = new Scope({
|
|
60
61
|
config,
|
|
61
|
-
cwd: "/path/to/workspace", // 每个
|
|
62
|
-
|
|
63
|
-
})
|
|
64
|
-
|
|
62
|
+
cwd: "/path/to/workspace", // 每个 Scope 一个工作目录,多会话并行互不干扰
|
|
63
|
+
agentsDir,
|
|
64
|
+
}).use(
|
|
65
|
+
...allInOne({ skillsPaths, toolsPaths, subAgentsPaths, mcpPaths }),
|
|
66
|
+
);
|
|
67
|
+
await scope.init();
|
|
68
|
+
|
|
69
|
+
const agent = await createAgent(scope, "my-agent");
|
|
65
70
|
const migrationService = new TaskMigrationService({ onMigrated }); // 迁移复用传入 agent 自身的模型调用
|
|
66
71
|
agent.use(new AutoMigratePlugin({ service: migrationService, maxTokens }));
|
|
67
72
|
agent.use(new AutoRefreshToolsPlugin());
|
|
73
|
+
agent.use(new UnknownToolHintPlugin({ scope }));
|
|
68
74
|
await agent.init();
|
|
69
75
|
await agent.send("你好");
|
|
76
|
+
|
|
77
|
+
await scope.dispose(); // 断开 MCP、释放插件资源
|
|
70
78
|
```
|
|
71
79
|
|
|
72
80
|
## 开发状态
|
|
@@ -76,14 +84,14 @@ await agent.send("你好");
|
|
|
76
84
|
| `types` | ✅ 已实现 — 核心实体、权限模型、MCP 类型完整 |
|
|
77
85
|
| `config` | ✅ 已实现 — ConfigManager + 出厂默认配置 + 一键 bootstrap |
|
|
78
86
|
| `crud` | ✅ 已实现 — Agent 等能力实体 CRUD(会话/草稿由各端自行持久化) |
|
|
79
|
-
| `
|
|
80
|
-
| `runtime` | ✅ 已实现 —
|
|
81
|
-
| `
|
|
87
|
+
| `scope` | ✅ 已实现 — Scope + ScopePlugin + 5 个标准插件(builtin / user-tools / skills / mcp / subagents)+ allInOne |
|
|
88
|
+
| `runtime` | ✅ 已实现 — createAgent、MCP 连接管理、任务迁移 |
|
|
89
|
+
| `agent-plugins` | ✅ 已实现 — AutoMigratePlugin / AutoRefreshToolsPlugin / ContextGuardPlugin / UnknownToolHintPlugin |
|
|
82
90
|
| `shared` | ✅ 已实现 — SdkError + 可注入 Logger |
|
|
83
91
|
|
|
84
92
|
## 内置工具
|
|
85
93
|
|
|
86
|
-
内置工具全部类化(继承 `SdkCallbackTool
|
|
94
|
+
内置工具全部类化(继承 `SdkCallbackTool`),由内置工具插件(`BuiltinToolsScopePlugin`)用 `ToolEnv` 实例化——每个 Scope 一套实例,`cwd` 注入,相对路径以 `Scope.cwd` 为基准,不依赖全局 `process.cwd()`。
|
|
87
95
|
|
|
88
96
|
| 工具 | 说明 |
|
|
89
97
|
|------|------|
|
|
@@ -113,7 +121,7 @@ await agent.send("你好");
|
|
|
113
121
|
| `generateImage` | 配置了 `defaultImageModel` 才注册 | 根据文字描述生成图片 |
|
|
114
122
|
| `viewImage` | 仅视觉模型可用(Agent 的 `modelId` 解析为 `vision: true` 的模型) | 查看/分析图片:本地图片自动经 Files API 上传,网络 URL 直接引用 |
|
|
115
123
|
|
|
116
|
-
工具输出保护:`AppConfig.maxToolOutput`(字符数,缺省 32768)是工具输出的统一上限,超限时由各工具自行处置——`exec` 分文件落盘 `stdout.log` / `stderr.log`(返回各流头尾预览),`findText` / `glob` / `ls` 落盘 `result.json`(返回头部预览),`readFile` 仅警告并提示用 `range` 分批读取。落盘目录为 `<tmpdir>/ai-zen/tool-output/<工具名>-<时间戳>-<随机串>/`,每次调用独立、不自清理。详见 [`docs/sdk-design.md` §
|
|
124
|
+
工具输出保护:`AppConfig.maxToolOutput`(字符数,缺省 32768)是工具输出的统一上限,超限时由各工具自行处置——`exec` 分文件落盘 `stdout.log` / `stderr.log`(返回各流头尾预览),`findText` / `glob` / `ls` 落盘 `result.json`(返回头部预览),`readFile` 仅警告并提示用 `range` 分批读取。落盘目录为 `<tmpdir>/ai-zen/tool-output/<工具名>-<时间戳>-<随机串>/`,每次调用独立、不自清理。详见 [`docs/sdk-design-v1.md` §12](docs/sdk-design-v1.md)。
|
|
117
125
|
|
|
118
126
|
## 内置插件
|
|
119
127
|
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
export class AutoRefreshToolsPlugin {
|
|
10
10
|
async onBeforeSend(ctx) {
|
|
11
11
|
const agent = ctx.agent;
|
|
12
|
-
await agent.
|
|
13
|
-
agent.tools = agent.
|
|
12
|
+
await agent.scope.refresh({ silent: true });
|
|
13
|
+
agent.tools = agent.scope.buildTools(agent.definition, {
|
|
14
14
|
exclude: {
|
|
15
15
|
subagents: agent.definition.function?.name
|
|
16
16
|
? [agent.definition.function.name]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentPlugin, UnknownToolContext } from "@ai-zen/agents-core";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Scope } from "../scope/Scope.js";
|
|
3
3
|
/**
|
|
4
4
|
* 未知工具智能提示插件 — MCP 场景引导。
|
|
5
5
|
*
|
|
@@ -8,14 +8,16 @@ import type { Provider } from "../runtime/Provider.js";
|
|
|
8
8
|
* - 有 MCP 配置且 `call_mcp_tool` 可用 → 提示使用 `call_mcp_tool`
|
|
9
9
|
* - 否则 → 仅提示工具不存在
|
|
10
10
|
*
|
|
11
|
-
* 由调用方显式注册(`agent.use(new UnknownToolHintPlugin({
|
|
11
|
+
* 由调用方显式注册(`agent.use(new UnknownToolHintPlugin({ scope }))`)。
|
|
12
12
|
* 未注册时,Agent 回落到底层的简单文本默认提示(core 内建)。
|
|
13
|
+
*
|
|
14
|
+
* 是否"有 MCP 配置"经 `scope.getPluginById(McpScopePlugin.ID)` 查询 MCP 插件获得。
|
|
13
15
|
*/
|
|
14
16
|
export declare class UnknownToolHintPlugin implements AgentPlugin {
|
|
15
|
-
/** 全局
|
|
16
|
-
private readonly
|
|
17
|
+
/** 全局 Scope 实例 */
|
|
18
|
+
private readonly scope;
|
|
17
19
|
constructor(options: {
|
|
18
|
-
|
|
20
|
+
scope: Scope;
|
|
19
21
|
});
|
|
20
22
|
onUnknownTool(ctx: UnknownToolContext): string | undefined;
|
|
21
23
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { McpScopePlugin } from "../scope/plugins/mcp/McpScopePlugin.js";
|
|
1
2
|
/**
|
|
2
3
|
* 未知工具智能提示插件 — MCP 场景引导。
|
|
3
4
|
*
|
|
@@ -6,18 +7,21 @@
|
|
|
6
7
|
* - 有 MCP 配置且 `call_mcp_tool` 可用 → 提示使用 `call_mcp_tool`
|
|
7
8
|
* - 否则 → 仅提示工具不存在
|
|
8
9
|
*
|
|
9
|
-
* 由调用方显式注册(`agent.use(new UnknownToolHintPlugin({
|
|
10
|
+
* 由调用方显式注册(`agent.use(new UnknownToolHintPlugin({ scope }))`)。
|
|
10
11
|
* 未注册时,Agent 回落到底层的简单文本默认提示(core 内建)。
|
|
12
|
+
*
|
|
13
|
+
* 是否"有 MCP 配置"经 `scope.getPluginById(McpScopePlugin.ID)` 查询 MCP 插件获得。
|
|
11
14
|
*/
|
|
12
15
|
export class UnknownToolHintPlugin {
|
|
13
|
-
/** 全局
|
|
14
|
-
|
|
16
|
+
/** 全局 Scope 实例 */
|
|
17
|
+
scope;
|
|
15
18
|
constructor(options) {
|
|
16
|
-
this.
|
|
19
|
+
this.scope = options.scope;
|
|
17
20
|
}
|
|
18
21
|
onUnknownTool(ctx) {
|
|
19
22
|
const toolName = ctx.toolCall.function?.name ?? "未知";
|
|
20
|
-
const
|
|
23
|
+
const mcpPlugin = this.scope.getPluginById(McpScopePlugin.ID);
|
|
24
|
+
const hasMcpConfig = mcpPlugin?.hasConfig() ?? false;
|
|
21
25
|
const hasCallMcpTool = ctx.availableTools.some((t) => t.function.name === "call_mcp_tool");
|
|
22
26
|
if (hasMcpConfig && !hasCallMcpTool) {
|
|
23
27
|
return `工具 "${toolName}" 不存在。当前有 MCP 服务器配置,但 call_mcp_tool 权限已被禁用,如需使用 MCP 工具请调整权限。`;
|
|
@@ -18,6 +18,11 @@ export declare class ConfigManager {
|
|
|
18
18
|
ensureDirs(): Promise<void>;
|
|
19
19
|
/**
|
|
20
20
|
* 确保 config.json 存在。不存在时写入出厂默认配置 DSL。
|
|
21
|
+
*
|
|
22
|
+
* 已存在时执行「出厂模型清单同步」(见 syncManagedModels):
|
|
23
|
+
* models / imageModels 中凡是**没有** `custom: true` 的条目一律视为出厂托管,
|
|
24
|
+
* 会被移除并替换为 DEFAULT_APP_CONFIG 中的最新定义;标了 `custom: true` 的
|
|
25
|
+
* 条目视为用户自有,原样保留。同步结果与磁盘内容一致时不写盘。
|
|
21
26
|
*/
|
|
22
27
|
ensureDefaultConfig(): Promise<AppConfig>;
|
|
23
28
|
/**
|
|
@@ -70,4 +75,16 @@ export declare class ConfigManager {
|
|
|
70
75
|
/** 原子写 JSON 文件(先写 .tmp 再 rename,避免半成品)。 */
|
|
71
76
|
private writeJson;
|
|
72
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* 同步出厂托管的模型清单(与默认 Agent 的 custom 机制一致)。
|
|
80
|
+
*
|
|
81
|
+
* 规则:
|
|
82
|
+
* - 未标 `custom: true` 的条目 → 由 SDK 托管,从结果中移除,改用 defaults 中的最新定义;
|
|
83
|
+
* - 标了 `custom: true` 的条目 → 用户自有,原样保留;与出厂定义同 id 时用户版本优先;
|
|
84
|
+
* - 默认模型 ID(defaultModel / defaultImageModel / defaultMigrationModel)
|
|
85
|
+
* 在合并后若已不存在 → 回退到出厂默认,避免悬空引用。
|
|
86
|
+
*
|
|
87
|
+
* 端点(endpoints)不参与托管,始终保持用户配置。
|
|
88
|
+
*/
|
|
89
|
+
export declare function syncManagedModels(config: AppConfig): AppConfig;
|
|
73
90
|
export { DEFAULT_AGENT_ID, DEFAULT_AGENT_DEFINITION, DEFAULT_SUBAGENT_ID, DEFAULT_SUBAGENT_DEFINITION, DEFAULT_APP_CONFIG, DEFAULT_MCP_CONFIG, CONFIG_SUB_DIRS, } from "./constants.js";
|