page-agent-sdk 2.4.1 → 2.5.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/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  [![npm](https://img.shields.io/npm/v/page-agent-sdk.svg)](https://www.npmjs.com/package/page-agent-sdk)
10
10
  [![license](https://img.shields.io/badge/license-ISC-blue.svg)](./LICENSE)
11
- [![tests](https://img.shields.io/badge/self%20tests-364%20asserts-brightgreen.svg)](#self-tests)
11
+ [![tests](https://img.shields.io/badge/self%20tests-434%20asserts-brightgreen.svg)](#self-tests)
12
12
 
13
13
  ---
14
14
 
@@ -24,9 +24,10 @@ At its core, it gives the AI a **standardized, safe JSON-operation channel**. AI
24
24
 
25
25
  | Constraint | Mechanism | Effect |
26
26
  |---|---|---|
27
- | **Scope control** | Property registry (`data`) — only declared paths are writable | AI touching undeclared fields → rejected |
27
+ | **Scope control** | Declared schema fields (`data`) — only declared top-level keys are writable; schema shape auto-whitelist (top-level keys limit visible + writable; undeclared fields hidden/denied; whole-set becomes merge to prevent accidental deletion) | AI touching undeclared fields → `PATH_DENIED` |
28
28
  | **Validity check** | zod schema — `write`/`set`/`edit` validated against schema | Invalid type/enum/structure → structured error, no write |
29
- | **Incremental op** | `write` with `patch` (or advanced `edit_data`) patches by `jsonPath` (set/remove/merge/append) | Avoid re-sending the whole large JSON; precise local edits |
29
+ | **Incremental op** | `write` with `patch`/`patches` (batch, atomic rollback) or advanced `edit_data` patches by `jsonPath` (set/remove/merge/append) | Avoid re-sending the whole large JSON; precise local edits; use `patches` to edit many at once |
30
+ | **Large-object retrieval** | `read` supports `fields` (projection) + `depth` (truncation) to shrink payload; `query_data` (JSONPath)/`search_data` (text)/`eval_script` (sandboxed JS) | Efficient retrieval + pinpoint location in large JSON |
30
31
  | **Rollbackable** | per-path snapshots (auto-stacked) + session checkpoint | Bad edit → one-click restore to the last good state |
31
32
  | **Optimistic lock** | `expectedHash` on `set`/`edit`/`delete` + conflict human-in-the-loop | Concurrent external edits detected → suspend, user picks keep/overwrite/restore |
32
33
 
@@ -132,15 +133,15 @@ ChatDialog, MessageContent, CodePreview, useChat
132
133
  | | `ui` | `boolean \| 'default'` · default `true` | `false` = headless (build UI with `agent.messages`) |
133
134
  | | `llm` | `LLMConfig \| BaseChatModel` · **required** | `LLMConfig={apiKey,baseUrl?,model?,temperature?,maxTokens?}`; OpenAI-compatible (default DeepSeek) |
134
135
  | | `id` | `string` | Stable id (multi-agent isolation + persistence resume; random+warn if omitted) |
135
- | | `systemPrompt` | `string` | Agent identity (no hardcoded business; inject via this). Optional — built-in default (page assistant + `reliableWriteRules`) used if omitted; passing your own fully overrides it |
136
- | **Page data** | `data` | `{path,description,schema}[]` | Register data slots readable/writable by tools + zod schema |
136
+ | | `systemPrompt` | `string` | Agent identity (no hardcoded business; inject via this). Optional — built-in default (JSON operation assistant + `reliableWriteRules`) used if omitted; passing your own fully overrides it |
137
+ | **Page data** | `data` | `{schema,bind,description?}` | Single main object: declare zod schema (validation + field descriptions auto-injected into prompt) + bind (reactive/plain object, tools read/write directly, no `window`) + description |
137
138
  | | `tools` / `skills` / `memory` | `Tool[]` / `SkillSpec[]` / `string` | Custom tools / skills / AGENTS.md-style directives |
138
139
  | **Capability toggles** | `capabilities` | `{planning?,dataOps?,fetch?,skills?,vfs?,summarization?,memory?,subagent?,verify?}` | Default all on (`verify` default off); `false` to turn off |
139
140
  | | `permissions` | `PermissionRule[]` | Scope whitelist (first-match-wins, default off) |
140
141
  | | `humanConfirm` | `boolean` · default `true` | Proactive inquiry (AI asks when uncertain/multi-plan) |
141
142
  | | `approval` | `{tools?,confirm?,timeoutMs?,humanConfirmTool?}` · default off | Passive confirm whitelist (pre-write allow/deny) |
142
143
  | | `checkpoint` | `boolean \| {maxCheckpoints?,auto?}` · default off | Session-level rollback (`auto` default `true`) |
143
- | | `verify` | `{check?,maxAttempts?,adversarial?}` | Needs `capabilities.verify:true`; `check` omitted → `createWriteBackCheck` |
144
+ | | `verify` | `{check?,maxAttempts?,adversarial?}` | Needs `capabilities.verify:true`; `check` omitted → `createWriteBackCheck` (read-back root auto-bound to `data.bind`, adapts to `sdk.setData` runtime swap) |
144
145
  | **Subagents** | `subagent` | `{allowedTools?,systemPrompt?,temperature?,llm?,maxDepth?·1,maxParallel?·4}` | Runtime ad-hoc delegation (`spawn_agent`/`spawn_agents`) |
145
146
  | | `subagents` | `SubagentConfig[]` | Pre-declared named subagents → each generates `use_<id>` tool |
146
147
  | **Context** | `contextPreset` | `'auto' \| 'conservative' \| 'aggressive'` · default `auto` | Compression preset |
@@ -180,7 +181,7 @@ createChatSdk({ subagents: [
180
181
 
181
182
  ### Built-in tools (Agent-callable)
182
183
 
183
- - **data slot ops** (default `toolMode:'simple'`): `read` (list/get/describe merged) / `write` (set/edit/delete merged + auto optimistic lock + auto snapshot) — recommended; `toolMode:'advanced'` also exposes low-level `describe_data` / `describe_data` / `get_data` / `get_data` / `set_data` / `edit_data` (jsonPath patch) / `delete_data` / `snapshot_data` / `list_data_snapshots` / `restore_data`
184
+ - **data ops** (default `toolMode:'simple'`): `read` (list/get/describe merged) / `write` (set/edit/delete merged + auto optimistic lock + auto snapshot) — recommended; `toolMode:'advanced'` also exposes low-level `describe_data` / `list_data_snapshots` / `get_data` / `set_data` / `edit_data` (jsonPath patch) / `delete_data` / `snapshot_data` / `restore_data`
184
185
  - **window query**: `query_data` (JSONPath) / `search_data` (fuzzy) / `eval_script` (sandboxed)
185
186
  - **fetch**: `fetch_document`
186
187
  - **vfs**: `vfs_read` / `vfs_write` / `vfs_edit` / `vfs_ls` / `vfs_glob` / `vfs_grep`
@@ -200,7 +201,7 @@ src/core/
200
201
  │ todos.ts skills.ts memory.ts summarization.ts retry.ts
201
202
  │ subagent.ts verify.ts approval.ts humanConfirm.ts checkpoint.ts
202
203
  │ permissions.ts usageHints.ts
203
- ├── tools/ # dataOps (registry + incremental edit + snapshot) / dataSlotQuery / fetchDoc
204
+ ├── tools/ # dataOps (schema validation + incremental edit + snapshot + whitelist) / dataSlotQuery / fetchDoc
204
205
  ├── backends/ # vfs (memory) / storage (IndexedDB + multi-backend + quota eviction)
205
206
  ├── mcp/client.ts # remote MCP tool integration
206
207
  ├── composables/ # useChat / useContextManager / useMarkdown
@@ -235,7 +236,7 @@ createChatSdk({ subagents: [
235
236
 
236
237
  ### Built-in tools (Agent-callable)
237
238
 
238
- - **data slot ops** (default `toolMode:'simple'`): `read` (list/get/describe merged) / `write` (set/edit/delete merged + auto optimistic lock + auto snapshot) — recommended; `toolMode:'advanced'` also exposes low-level `describe_data` / `describe_data` / `get_data` / `get_data` / `set_data` / `edit_data` (jsonPath patch) / `delete_data` / `snapshot_data` / `list_data_snapshots` / `restore_data`
239
+ - **data ops** (default `toolMode:'simple'`): `read` (list/get/describe merged) / `write` (set/edit/delete merged + auto optimistic lock + auto snapshot) — recommended; `toolMode:'advanced'` also exposes low-level `describe_data` / `list_data_snapshots` / `get_data` / `set_data` / `edit_data` (jsonPath patch) / `delete_data` / `snapshot_data` / `restore_data`
239
240
  - **window query**: `query_data` (JSONPath) / `search_data` (fuzzy) / `eval_script` (sandboxed)
240
241
  - **fetch**: `fetch_document`
241
242
  - **vfs**: `vfs_read` / `vfs_write` / `vfs_edit` / `vfs_ls` / `vfs_glob` / `vfs_grep`
@@ -255,7 +256,7 @@ src/core/
255
256
  │ todos.ts skills.ts memory.ts summarization.ts retry.ts
256
257
  │ subagent.ts verify.ts approval.ts humanConfirm.ts checkpoint.ts
257
258
  │ permissions.ts usageHints.ts
258
- ├── tools/ # dataOps (registry + incremental edit + snapshot) / dataSlotQuery / fetchDoc
259
+ ├── tools/ # dataOps (schema validation + incremental edit + snapshot + whitelist) / dataSlotQuery / fetchDoc
259
260
  ├── backends/ # vfs (memory) / storage (IndexedDB + multi-backend + quota eviction)
260
261
  ├── mcp/client.ts # remote MCP tool integration
261
262
  ├── composables/ # useChat / useContextManager / useMarkdown
@@ -299,12 +300,12 @@ flowchart TD
299
300
  CORE --> AGENT[createAgent<br/>ReAct loop + middleware stack]
300
301
  AGENT --> MW[Middleware stack<br/>usageHints→todos→skills→vfs→summarization<br/>→memory→permissions→checkpoint→approval<br/>→humanConfirm→verify→subagent→user]
301
302
  AGENT --> TOOLS[Tools<br/>dataOps / fetchDoc / vfs / MCP / user]
302
- TOOLS -->|zero-bridge| WIN[Host page window<br/>read/write registered props directly]
303
+ TOOLS -->|direct read/write| DATA[Main data bind<br/>reactive/plain object<br/>schema validation + whitelist]
303
304
  AGENT --> LLM[LLM<br/>OpenAI-compatible / any ChatModel]
304
305
  SDK --> UI[ChatDialog UI<br/>Vue bundled in / or headless]
305
306
  ```
306
307
 
307
- - **Framework-agnostic**: Vue bundled in the lib (not a peer); host can be React/vanilla. Also supports `ui:false` headless — and runs in **Node.js** as a backend Agent (custom tools / subagents / verify; disable `dataOps`+`fetch`, use `storage:'memory'`)
308
+ - **Framework-agnostic**: Vue bundled in the lib (not a peer); host can be React/vanilla. Also supports `ui:false` headless — and runs in **Node.js** as a backend Agent (custom tools / subagents / verify; disable `fetch`+`eval_script` (dataOps body works in Node with any `bind`), use `storage:'memory'`)
308
309
  - **Provider-agnostic**: `llm` accepts any LangChain `BaseChatModel`, or `LLMConfig` (builds `ChatOpenAI` internally, OpenAI-compatible, default DeepSeek)
309
310
  - **In-house harness**: no LangGraph/langchain full bundle; avoids browser bundling blockers
310
311
 
@@ -380,8 +381,8 @@ Framework-agnostic integration: `demo/plain.html` (importmap + esm.sh).
380
381
  ## Self-tests
381
382
 
382
383
  ```bash
383
- npm test # 364 assertions (tsx, source-level; no LLM dependency)
384
- npm run test:e2e # 120 integration assertions (node, built dist; covers APIs/options/modules/simple&complex scenes: default systemPrompt(capability overview) / dynamic register + inspect sync / inspect(tools/middleware/subagent/verify/mcp/todos/lastCompression/checkpoints reflect config) / custom tools/middleware/skills/memory injection / switchSession(on/off) / shareContext on/off sharing/independent / storage backends + object config / presets(3) / checkpoint / exports complete(39+ fns/components) / util fns usable(isQuotaError/estimateTokens/jpEval/searchJson) / source=builtin / mount boundary / hook multi-listener / llm config / error scenes)
384
+ npm test # 434 assertions (tsx, source-level; no LLM dependency)
385
+ npm run test:e2e # 125 integration assertions (node, built dist; covers APIs/options/modules/simple&complex scenes: default systemPrompt(capability overview) / dynamic register + inspect sync / inspect(tools/middleware/subagent/verify/mcp/todos/lastCompression/checkpoints reflect config) / custom tools/middleware/skills/memory injection / switchSession(on/off) / shareContext on/off sharing/independent / storage backends + object config / presets(3) / checkpoint / exports complete(39+ fns/components) / util fns usable(isQuotaError/estimateTokens/jpEval/searchJson) / source=builtin / mount boundary / hook multi-listener / llm config / error scenes)
385
386
  ```
386
387
 
387
388
  ## Local npm package test
package/README.zh-CN.md CHANGED
@@ -24,9 +24,10 @@
24
24
 
25
25
  | 约束 | 机制 | 作用 |
26
26
  |---|---|---|
27
- | **范围控制** | schema 校验(`data`)—— 只能改 schema 允许的值 | AI 传非法值 → 拒绝 |
27
+ | **范围控制** | schema 校验(`data`)—— 只能改 schema 允许的值;schema 形状自动白名单(顶层 key 限制可见 + 可写,未声明字段隐藏/拒改/整体 set 转 merge 防误删) | AI 传非法值 → 拒绝;非声明字段 → `PATH_DENIED` |
28
28
  | **合法性校验** | zod schema —— `write`/`set`/`edit` 按 schema 校验 | 类型/枚举/结构不合法 → 结构化错误,不写入 |
29
- | **增量操作** | `write` 的 `patch`(或 advanced `edit_data`)按 `jsonPath` 发 patch(set/remove/merge/append) | 避免重传整个大 JSON,精确改局部 |
29
+ | **增量操作** | `write` 的 `patch`/`patches`(批量,原子回滚)或 advanced `edit_data` 按 `jsonPath` 发 patch(set/remove/merge/append) | 避免重传整个大 JSON,精确改局部;一次改多处用 `patches` |
30
+ | **大对象检索** | `read` 支持 `fields`(字段裁剪)+ `depth`(深度截断)减体积;`query_data`(JSONPath)/`search_data`(文本)/`eval_script`(沙箱 JS) | 大 JSON 高效检索 + 局部定位 |
30
31
  | **可回滚** | per-path 快照(自动入栈)+ 会话 checkpoint | 改坏了一键回退到上次正常态 |
31
32
  | **乐观锁** | `set`/`edit`/`delete` 传 `expectedHash` + 冲突人工介入 | 检测并发外部修改 → 挂起,用户选保留/覆盖/回退 |
32
33
 
@@ -132,15 +133,15 @@ ChatDialog, MessageContent, CodePreview, useChat
132
133
  | | `ui` | `boolean \| 'default'` · 默认 `true` | `false` = headless(用 `agent.messages` 自建 UI) |
133
134
  | | `llm` | `LLMConfig \| BaseChatModel` · **必传** | `LLMConfig={apiKey,baseUrl?,model?,temperature?,maxTokens?}`;兼容 OpenAI 协议(默认 DeepSeek) |
134
135
  | | `id` | `string` | 稳定 id(多 agent 隔离 + 持久化恢复;不传随机+warn) |
135
- | | `systemPrompt` | `string` | Agent 身份(不硬编码业务,靠这注入)。可选——不传用内置默认(页面操作助手 + `reliableWriteRules`);传了则完全覆盖 |
136
- | **页面数据** | `data` | `{path,description,schema}[]` | 注册可被工具读写的 数据槽 + zod schema 校验 |
136
+ | | `systemPrompt` | `string` | Agent 身份(不硬编码业务,靠这注入)。可选——不传用内置默认(JSON 操作助手 + `reliableWriteRules`);传了则完全覆盖 |
137
+ | **页面数据** | `data` | `{schema,bind,description?}` | 单主对象:声明 zod schema(校验 + 字段描述自动注入提示词)+ bind(reactive/普通对象,工具直接读写,不挂 window)+ description |
137
138
  | | `tools` / `skills` / `memory` | `Tool[]` / `SkillSpec[]` / `string` | 自定义工具 / 技能 / AGENTS.md 风格持久指令 |
138
139
  | **能力开关** | `capabilities` | `{planning?,dataOps?,fetch?,skills?,vfs?,summarization?,memory?,subagent?,verify?}` | 默认全开(`verify` 默认关);`false` 关掉省 token |
139
140
  | | `permissions` | `PermissionRule[]` | scope 白名单(first-match-wins,默认不启用) |
140
141
  | | `humanConfirm` | `boolean` · 默认 `true` | 主动征询(AI 不确定/多方案主动问你,不猜测) |
141
142
  | | `approval` | `{tools?,confirm?,timeoutMs?,humanConfirmTool?}` · 默认关 | 被动确认白名单(写操作前弹允许/拒绝) |
142
143
  | | `checkpoint` | `boolean \| {maxCheckpoints?,auto?}` · 默认关 | 会话级回滚(`auto` 默认 `true` 每轮存档) |
143
- | | `verify` | `{check?,maxAttempts?,adversarial?}` | 需 `capabilities.verify:true`;`check` 省略用 `createWriteBackCheck` |
144
+ | | `verify` | `{check?,maxAttempts?,adversarial?}` | 需 `capabilities.verify:true`;`check` 省略用 `createWriteBackCheck`(读回根对象自动取 `data.bind`,适配 `sdk.setData` 运行时替换) |
144
145
  | **子 agent** | `subagent` | `{allowedTools?,systemPrompt?,temperature?,llm?,maxDepth?·1,maxParallel?·4}` | 运行时自由委派(`spawn_agent`/`spawn_agents`) |
145
146
  | | `subagents` | `SubagentConfig[]` | 预声明命名子 agent → 每个生成 `use_<id>` 委派工具 |
146
147
  | **上下文** | `contextPreset` | `'auto' \| 'conservative' \| 'aggressive'` · 默认 `auto` | 压缩预设档位 |
@@ -200,7 +201,7 @@ src/core/
200
201
  │ todos.ts skills.ts memory.ts summarization.ts retry.ts
201
202
  │ subagent.ts verify.ts approval.ts humanConfirm.ts checkpoint.ts
202
203
  │ permissions.ts usageHints.ts
203
- ├── tools/ # dataOps(注册表+增量编辑+快照)/ dataSlotQuery / fetchDoc
204
+ ├── tools/ # dataOps(单主对象+schema 白名单+增量编辑+快照)/ dataSlotQuery / fetchDoc
204
205
  ├── backends/ # vfs(内存) / storage(IndexedDB+多后端+配额淘汰)
205
206
  ├── mcp/client.ts # MCP 远程工具接入
206
207
  ├── composables/ # useChat / useContextManager / useMarkdown
@@ -244,12 +245,12 @@ flowchart TD
244
245
  CORE --> AGENT[createAgent<br/>ReAct 循环 + 中间件栈]
245
246
  AGENT --> MW[中间件栈<br/>usageHints→todos→skills→vfs→summarization<br/>→memory→permissions→checkpoint→approval<br/>→humanConfirm→verify→subagent→用户]
246
247
  AGENT --> TOOLS[工具集<br/>dataOps / fetchDoc / vfs / MCP / 用户]
247
- TOOLS -->|零桥接| WIN[宿主页面 window<br/>直接读写注册属性]
248
+ TOOLS -->|直接读写 bind| DATA[主数据 bind<br/>reactive/普通对象<br/>schema 校验 + 白名单]
248
249
  AGENT --> LLM[LLM<br/>OpenAI 协议 / 任意 ChatModel]
249
250
  SDK --> UI[ChatDialog UI<br/>Vue 打包进库 / 或 headless]
250
251
  ```
251
252
 
252
- - **框架无关**:Vue 打包进库(非 peer),宿主用 React/原生都行;也支持 `ui:false` headless 自建 UI —— 且可在 **Node.js 服务端**跑作后端 Agent(自定义工具/子 agent/自检;关 `dataOps`+`fetch`,用 `storage:'memory'`)
253
+ - **框架无关**:Vue 打包进库(非 peer),宿主用 React/原生都行;也支持 `ui:false` headless 自建 UI —— 且可在 **Node.js 服务端**跑作后端 Agent(自定义工具/子 agent/自检;关 `fetch`+`eval_script`,dataOps 主体传 `bind` 即可跑,用 `storage:'memory'`)
253
254
  - **provider 抽离**:`llm` 传任意 LangChain `BaseChatModel`,或 `LLMConfig`(内部构造 `ChatOpenAI`,兼容 OpenAI 协议,默认接 DeepSeek)
254
255
  - **自研 harness**:不引 LangGraph/langchain 整包,规避浏览器打包阻塞
255
256
 
@@ -325,8 +326,8 @@ createChatSdk({
325
326
  ## 自测
326
327
 
327
328
  ```bash
328
- npm test # 364 项断言(tsx 源码级,不依赖 LLM)
329
- npm run test:e2e # 120 项集成断言(node 跑构建产物 dist;覆盖各 API/配置项/功能模块/简单与复杂场景:默认 systemPrompt(含能力概述) / 动态注册与 inspect 同步 / inspect(tools/middleware/subagent/verify/mcp/todos/lastCompression/checkpoints 反映配置) / 自定义 tools/middleware/skills/memory 注入 / switchSession(开/未开) / shareContext 开/关共享独立 / storage 后端+对象配置 / presets 三预设 / checkpoint / 导出项完整(39+ 函数/组件) / 工具函数可用(isQuotaError/estimateTokens/jpEval/searchJson) / source=builtin / mount 边界 / hook 多监听器 / llm 配置 / 错误场景)
329
+ npm test # 434 项断言(tsx 源码级,不依赖 LLM)
330
+ npm run test:e2e # 125 项集成断言(node 跑构建产物 dist;覆盖各 API/配置项/功能模块/简单与复杂场景:默认 systemPrompt(含能力概述) / 动态注册与 inspect 同步 / inspect(tools/middleware/subagent/verify/mcp/todos/lastCompression/checkpoints 反映配置) / 自定义 tools/middleware/skills/memory 注入 / switchSession(开/未开) / shareContext 开/关共享独立 / storage 后端+对象配置 / presets 三预设 / checkpoint / 导出项完整(39+ 函数/组件) / 工具函数可用(isQuotaError/estimateTokens/jpEval/searchJson) / source=builtin / mount 边界 / hook 多监听器 / llm 配置 / 错误场景)
330
331
  ```
331
332
 
332
333
  ## 本地 npm 包测试