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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "page-agent-sdk",
3
- "version": "2.4.1",
3
+ "version": "2.5.1",
4
4
  "type": "module",
5
5
  "description": "框架无关的页面内 Agent JS SDK —— 以对话框形态挂载到任意网页,通过自定义 tool 读写宿主预注册的数据槽(经 schema 校验 + jsonPath 增量 patch + 快照回退;GET 抓文档),具备 planning/skills/虚拟工作区/context 管理能力。Vue 打包进库,使用者无需安装 Vue。",
6
6
  "main": "./dist/page-agent-sdk.umd.cjs",
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  name: page-agent-sdk-integrate
3
- description: Integrate the page-agent-sdk npm package into a web app so an AI agent can read/write structured page data (data slots) via schema-validated tools. Use when the user wants to add/embed the SDK, declare dataSlots + zod schemas, configure the LLM, mount the chat dialog, subscribe to events (onEvent / sdk.hook), run headless (ui:false) with a custom UI, or troubleshoot common integration issues (DeepSeek 400 tool_call_id, MCP injecting 0 tools, etc).
3
+ description: Integrate the page-agent-sdk npm package into a web app so an AI agent can read/write a structured main data object via schema-validated tools. Use when the user wants to add/embed the SDK, declare `data` (single main object + zod schema + bind), configure the LLM, mount the chat dialog, subscribe to events (onEvent / sdk.hook), run headless (ui:false) with a custom UI, swap data at runtime (sdk.setData), or troubleshoot common integration issues (DeepSeek 400 tool_call_id, MCP injecting 0 tools, etc).
4
4
  ---
5
5
 
6
6
  # Integrate page-agent-sdk
7
7
 
8
- Help the user embed `page-agent-sdk` so an AI agent safely edits their page's structured JSON via tools.
8
+ Help the user embed `page-agent-sdk` so an AI agent safely edits a structured main JSON object via tools.
9
9
 
10
10
  ## Core concept
11
11
 
12
- The SDK is a **standardized JSON-operation agent**: the integrator declares writable `window` paths + zod schemas; the agent edits them via `read` / `write` (high-level entry, 2.2+; `write` merges set/edit/delete + auto optimistic lock + auto snapshot), validated by schema, scoped to the registry, with snapshot rollback. "Editing JSON" becomes structured + validatable + rollbackable, NOT free-form LLM text. Advanced mode (`toolMode:'advanced'`) also exposes low-level `get_data_slot`/`set_data_slot`/`edit_data_slot`/`delete_data_slot` for precise control.
12
+ The SDK is a **standardized JSON-operation agent**: the integrator declares ONE main data object (`data: { schema, bind, description? }`); the agent edits it via `read` / `write` (high-level entry; `write` merges set/edit/delete + auto optimistic lock + auto snapshot), validated by schema, scoped to schema-declared fields (ZodObject top-level keys auto-whitelist), with snapshot rollback. "Editing JSON" becomes structured + validatable + rollbackable, NOT free-form LLM text. `bind` is any reactive/plain object — tools read/write it directly, **no `window` dependency**. Advanced mode (`toolMode:'advanced'`) also exposes low-level `get_data`/`set_data`/`edit_data`/`delete_data` for precise control.
13
13
 
14
14
  ## Workflow
15
15
 
@@ -23,31 +23,35 @@ The SDK is a **standardized JSON-operation agent**: the integrator declares writ
23
23
 
24
24
  See `demo/plain.html` for a framework-agnostic importmap + esm.sh example.
25
25
 
26
- ### 2. Declare dataSlots + schemas (the key step)
26
+ ### 2. Declare `data` (the key step)
27
27
 
28
- Put the page data on `window` (e.g. `window.app = { title, theme }`), then declare each writable path with a zod schema. The agent can ONLY touch declared paths; `set`/`edit` are schema-validated (invalid → structured error, no write).
28
+ Create a plain/reactive object as the main data, then declare it with a zod schema. The agent can ONLY touch schema-declared top-level fields (ZodObject auto-whitelist); `set`/`edit` are schema-validated (invalid → structured error, no write). Field `.describe()` text is auto-injected into the system prompt so the LLM knows each field's purpose.
29
29
 
30
- > `systemPrompt` is optional — a built-in default is used if omitted (generic page-operation assistant + `systemPromptHelpers.reliableWriteRules`: read-before-write, list in dynamic scenarios, fields per `describe`, retry on validation error, prefer incremental `edit`). Passing your own fully overrides it; append `systemPromptHelpers.reliableWriteRules` yourself if you want the rules.
30
+ > `systemPrompt` is optional — a built-in default is used if omitted (generic JSON-operation assistant + `systemPromptHelpers.reliableWriteRules`: read-before-write, fields per `describe`, retry on validation error, prefer incremental `edit`). Passing your own fully overrides it; append `systemPromptHelpers.reliableWriteRules` yourself if you want the rules.
31
31
 
32
32
  ```ts
33
33
  import { createChatSdk, z } from 'page-agent-sdk'
34
34
  import 'page-agent-sdk/style.css'
35
35
 
36
- window.app = { title: 'Demo', theme: 'light', items: [] }
36
+ const app = { title: 'Demo', theme: 'light', items: [] } // plain object (or reactive for Vue auto-refresh)
37
37
 
38
38
  createChatSdk({
39
39
  container: '#root',
40
40
  llm: { apiKey, baseUrl: 'https://api.deepseek.com/v1', model: 'deepseek-chat' },
41
- systemPrompt: 'You are a page assistant; read/write window.app via tools.',
42
- dataSlots: [
43
- { path: 'app.title', description: '页面标题', schema: z.string() },
44
- { path: 'app.theme', description: '主题', schema: z.enum(['light','dark']) },
45
- { path: 'app.items', description: '列表项数组', schema: z.array(z.object({ name: z.string(), price: z.number() })) },
46
- ],
41
+ systemPrompt: 'You are a JSON operation assistant; read/write the main data via tools.',
42
+ data: {
43
+ schema: z.object({
44
+ title: z.string().describe('页面标题'),
45
+ theme: z.enum(['light', 'dark']).describe('主题'),
46
+ items: z.array(z.object({ name: z.string(), price: z.number() })).describe('列表项数组'),
47
+ }),
48
+ bind: app, // tools read/write `app` directly (no window)
49
+ description: '应用配置', // optional; auto-generated if omitted
50
+ },
47
51
  }).mount()
48
52
  ```
49
53
 
50
- For large JSON, prefer `write` with `patch` (jsonPath patch: set/remove/merge/append) over `write` with whole `value` — avoids re-sending the entire blob.
54
+ For large JSON, prefer `write` with `patch` (jsonPath patch: set/remove/merge/append) over `write` with whole `value` — avoids re-sending the entire blob. `read({ jsonPath, fields, depth })` supports field projection + depth truncation to slim large returns.
51
55
 
52
56
  ### 3. Configure the LLM
53
57
 
@@ -59,7 +63,7 @@ Two complementary ways to react to SDK changes from the host page:
59
63
 
60
64
  ```ts
61
65
  const sdk = createChatSdk({
62
- onEvent(e) { if (e.type === 'data_slot_change') renderUI() }, // constructor-time, single
66
+ onEvent(e) { if (e.type === 'data_change') renderUI() }, // constructor-time, single
63
67
  // ...
64
68
  }).mount()
65
69
 
@@ -68,7 +72,7 @@ const off = sdk.hook((e) => { if (e.type === 'tool_call') analytics.track(e.name
68
72
  // off() to unsubscribe
69
73
  ```
70
74
 
71
- Event types: `data_slot_change` / `message_update` / `tool_call` / `tool_result` / `text` / `round_start` / `done` / `error` (+ stream events in stream mode). `approval_request` is NOT forwarded (UI handles it).
75
+ Event types: `data_change` / `message_update` / `tool_call` / `tool_result` / `text` / `round_start` / `done` / `error` (+ stream events in stream mode). `approval_request` is NOT forwarded (UI handles it).
72
76
 
73
77
  ### 5. Headless mode (custom UI, framework-agnostic)
74
78
 
@@ -76,25 +80,29 @@ Event types: `data_slot_change` / `message_update` / `tool_call` / `tool_result`
76
80
 
77
81
  ### 6. Capabilities & presets
78
82
 
79
- - `capabilities: { dataSlotOps:false, fetch:false, planning:false, skills:false, vfs:false, summarization:false, memory:false, subagent:false }` — turn off unused built-ins to save tokens/size. `verify` is the reverse (off by default; `capabilities.verify:true` enables write-back self-check).
83
+ - `capabilities: { dataOps:false, fetch:false, planning:false, skills:false, vfs:false, summarization:false, memory:false, subagent:false }` — turn off unused built-ins to save tokens/size. `verify` is the reverse (off by default; `capabilities.verify:true` enables write-back self-check).
80
84
  - `presets.pageBuilder` / `researcher` / `minimal` — spread into `createChatSdk` for common scenarios.
81
85
 
86
+ ### 7. Swap data at runtime (lazy-loaded / dynamic schema)
87
+
88
+ `sdk.setData({ schema, bind, description? })` replaces the whole main data config at runtime — tools pick up the new bind/schema immediately (no rebuild). `sdk.getData()` reads the current config. Useful for lazy-loaded components or when the page schema changes dynamically.
89
+
82
90
  ## Common use cases (match the user's scenario, then read [references/use-cases.md](references/use-cases.md) for full code)
83
91
 
84
92
  | Scenario | Key setup |
85
93
  |---|---|
86
- | **Low-code page builder** | `dataSlots` = component tree; `write` patch jsonPath; `onEvent` → canvas refresh; `checkpoint` + `approval` |
87
- | **Form designer** | `dataSlots` = field definitions with enum/required schemas; schema validation prevents malformed forms |
88
- | **CMS batch ops** | `eval_script` for bulk loops; `search_data_slot` to filter; `write` patch for targeted edits |
94
+ | **Low-code page builder** | `data` = component tree; `write` patch jsonPath; `onEvent('data_change')` → canvas refresh; `checkpoint` + `approval` |
95
+ | **Form designer** | `data` = field definitions with enum/required schemas; schema validation prevents malformed forms |
96
+ | **CMS batch ops** | `eval_script` for bulk loops; `search_data` to filter; `write` patch for targeted edits |
89
97
  | **Ops config console** | `approval:{tools:['write']}` human-confirm; `capabilities.verify:true` write-back read; `checkpoint` |
90
- | **AI-native assistant** | `capabilities:{dataSlotOps:false,fetch:false}` + custom `tools` (your product API) |
91
- | **Research agent** | `capabilities:{dataSlotOps:false}`; `subagent:{allowedTools:['fetch_document']}`; `contextPreset:'conservative'` |
92
- | **Headless / server-side** | `ui:false` + `storage:'memory'` + `capabilities:{dataSlotOps:false,fetch:false}`; drive via `sdk.send` |
98
+ | **AI-native assistant** | `capabilities:{dataOps:false,fetch:false}` + custom `tools` (your product API) |
99
+ | **Research agent** | `capabilities:{dataOps:false}`; `subagent:{allowedTools:['fetch_document']}`; `contextPreset:'conservative'` |
100
+ | **Headless / server-side** | `ui:false` + `storage:'memory'` + `capabilities:{fetch:false}` (dataOps body works in Node with any `bind`); drive via `sdk.send` |
93
101
  | **Multi-agent on one page** | same `id` + `shareContext:true` → multiple dialogs share one `AgentCore` |
94
102
  | **MCP integration** | `mcp:[{transport,url}]` remote tool servers; `@modelcontextprotocol/sdk` optional peerDep |
95
- | **Lazy-loaded components (dynamic schemas)** | `sdk.addDataSlot(spec)` on component mount / `removeDataSlot` on unmount; tools pick up new registrations immediately, no rebuild. See [references/advanced.md §0](references/advanced.md) |
103
+ | **Dynamic / lazy-loaded schema** | `sdk.setData({ schema, bind })` on component mount to swap the main data; tools pick up immediately, no rebuild. See [references/advanced.md §0](references/advanced.md) |
96
104
 
97
- When the user describes a scenario, map it to the row above and load `references/use-cases.md` for the matching numbered case (1→10) with copy-paste code. For dynamic/lazy-loaded component schemas, custom tools/skills/subagents/MCP, load [references/advanced.md](references/advanced.md).
105
+ When the user describes a scenario, map it to the row above and load `references/use-cases.md` for the matching numbered case (1→10) with copy-paste code. For dynamic schema / custom tools/skills/subagents/MCP, load [references/advanced.md](references/advanced.md).
98
106
 
99
107
  ## References (read as needed)
100
108
 
@@ -102,13 +110,13 @@ Detailed docs live in this skill's `references/` folder — load the one matchin
102
110
 
103
111
  - **[references/quickstart.md](references/quickstart.md)** — progressive setup from 5-line CDN to full-featured (Stages 0→6). Read when the user wants a step-by-step "from simple to complete" walkthrough.
104
112
  - **[references/options.md](references/options.md)** — every `createChatSdk` option: type, default, purpose & when to use. Read when the user asks "what does option X do" or needs to tune behavior.
105
- - **[references/api.md](references/api.md)** — instance methods (`mount`/`send`/`stream`/`inspect`/`switchSession`/`hook`/checkpoints), `defineTool`/`defineSkill`/`presets`, built-in data slot tools, and the full `SdkEvent` type table. Read when the user asks about APIs, tools, or events.
106
- - **[references/use-cases.md](references/use-cases.md)** — 10 end-to-end scenarios (low-code builder / form designer / CMS batch / ops console / AI-native / research / server-side / multi-agent / MCP / lazy-loaded dynamic components). Read when the user wants a concrete pattern for their use case.
107
- - **[references/advanced.md](references/advanced.md)** — detailed examples for the extensibility surfaces: **dynamic dataSlots (`sdk.addDataSlot`/`removeDataSlot` for lazy-loaded components)**, custom `defineTool` (with error handling + coexisting with dataSlotOps), `defineSkill` (inline content + remote doc), subagents (ad-hoc `spawn_agent`/`spawn_agents` + pre-declared `subagents` → `use_<id>`), MCP (http/sse/websocket + auth + dev gotcha). Read when the user asks "how to add custom tools / skills / subagents / MCP" or "lazy-load components with different schemas".
113
+ - **[references/api.md](references/api.md)** — instance methods (`mount`/`send`/`stream`/`inspect`/`switchSession`/`hook`/`setData`/`getData`/checkpoints), `defineTool`/`defineSkill`/`presets`, built-in data tools, and the full `SdkEvent` type table. Read when the user asks about APIs, tools, or events.
114
+ - **[references/use-cases.md](references/use-cases.md)** — 10 end-to-end scenarios (low-code builder / form designer / CMS batch / ops console / AI-native / research / server-side / multi-agent / MCP / dynamic schema via setData). Read when the user wants a concrete pattern for their use case.
115
+ - **[references/advanced.md](references/advanced.md)** — detailed examples for the extensibility surfaces: **dynamic schema (`sdk.setData` to swap main data at runtime)**, custom `defineTool` (with error handling + coexisting with dataOps), `defineSkill` (inline content + remote doc), subagents (ad-hoc `spawn_agent`/`spawn_agents` + pre-declared `subagents` → `use_<id>`), MCP (http/sse/websocket + auth + dev gotcha). Read when the user asks "how to add custom tools / skills / subagents / MCP" or "swap data/schema at runtime".
108
116
 
109
117
  Project-level docs (in the repo, not bundled in this skill):
110
118
  - `doc/usage-guide.md` (zh) / `doc/usage-guide.en.md` — full options reference
111
- - `examples/<demo>/` — runnable demos (page-demo, nested-demo, subagent-demo, mcp-demo, planner-demo, toolsets-demo, human-confirm-demo)
119
+ - `examples/<demo>/` — runnable demos (page-demo, nested-demo, complex-demo, dynamic-demo, subagent-demo, mcp-demo, planner-demo, toolsets-demo, human-confirm-demo)
112
120
  - `demo/plain.html` — framework-agnostic CDN integration
113
121
  - `CLAUDE.md` — internal dev guide (architecture, conventions)
114
122
 
@@ -118,4 +126,5 @@ Project-level docs (in the repo, not bundled in this skill):
118
126
  - **ChatOpenAI params**: use `apiKey` (not `openAIApiKey`), `model` (not `modelName`); `baseUrl` goes via `configuration.baseURL`.
119
127
  - **MCP injects 0 tools on first cold visit**: `vite.config.ts` `optimizeDeps.include` pre-declares the SDK sub-paths; if you fork the config, keep those entries or the first MCP page load injects nothing (reload fixes it).
120
128
  - **`.env` `VITE_AI_SYSTEM_PROMPT` must be single-line** (dotenv doesn't support multi-line values).
121
- - **Server-side (Node.js)**: works with `ui:false` + `storage:'memory'` + `capabilities:{dataSlotOps:false,fetch:false}`; `mount()`/`unmount()` guard `window`/`document` access. Provide `globalThis.window` if you enable dataSlotOps in Node.
129
+ - **Server-side (Node.js)**: works with `ui:false` + `storage:'memory'` + `capabilities:{fetch:false}`; dataOps body (`read`/`write`/`get`/`edit`/`delete`/`query`/`search`) works in Node with any `bind` object — only `eval_script` needs Web Worker (disable via `capabilities:{dataOps:false}` if unused). `mount()`/`unmount()` guard `window`/`document` access.
130
+ - **`bind` not persisted**: `storage` persists messages/vfs/todos/memory but NOT the main data `bind` (it may contain non-serializable content). To restore `bind` across refresh/sessions, store it yourself and re-inject via `sdk.setData({ bind: restoredBind })`.
@@ -1,77 +1,73 @@
1
- # Advanced examples — custom tools, skills, subagents, MCP, dynamic dataSlots
1
+ # Advanced examples — custom tools, skills, subagents, MCP, dynamic schema
2
2
 
3
3
  Detailed, copy-paste examples for the extensibility surfaces. Read the section matching the user's need.
4
4
 
5
- ## 0. Dynamic dataSlots (lazy-loaded components) — `sdk.addDataSlot` / `removeDataSlot`
5
+ ## 0. Dynamic schema (lazy-loaded / runtime swap) — `sdk.setData` / `getData`
6
6
 
7
- When components are lazy-loaded with **different schemas each**, don't declare all `dataSlots` upfront. Register them at runtime as components mount/unmount. The agent's data slot tools pick up new registrations immediately (no agent rebuild).
7
+ When the page schema changes dynamically (lazy-loaded components with different structures), swap the whole main data config at runtime tools pick up the new bind/schema immediately, no agent rebuild.
8
8
 
9
9
  ```ts
10
10
  const sdk = createChatSdk({
11
11
  container: '#chat', llm: { ... },
12
- systemPrompt: '你是页面助手,按组件类型操作数据槽.app.components.<id>。',
13
- dataSlots: [
14
- // statically-declared ones (always present)
15
- { path: 'app.config', description: '全局配置', schema: z.record(z.any()) },
16
- ],
12
+ systemPrompt: '你是 JSON 操作助手,按当前 schema 操作主数据。',
13
+ data: { schema: initialSchema, bind: initialObj, description: '初始数据' },
17
14
  }).mount()
18
15
 
19
- // 组件懒加载时动态注册其 schema(结构各异)
20
- function onComponentMount(comp: { id: string; type: string; schema: z.ZodType }) {
21
- sdk.addDataSlot({ path: `app.components.${comp.id}`, description: `${comp.type} 组件`, schema: comp.schema })
22
- // 立即生效:AI 现在能 write 这个 path,按其 schema 校验
23
- }
24
-
25
- // 组件卸载时移除(快照栈一并清理)
26
- function onComponentUnmount(id: string) {
27
- sdk.removeDataSlot(`app.components.${id}`)
16
+ // later: swap to a different schema + bind (lazy-loaded / dynamic)
17
+ function onSchemaChange(newConfig: { schema: z.ZodType; bind: any; description?: string }) {
18
+ sdk.setData({
19
+ schema: newConfig.schema, // new zod schema (validation + field hints auto-injected)
20
+ bind: newConfig.bind, // new reactive/plain object
21
+ description: newConfig.description,
22
+ })
23
+ // 立即生效:AI 现在能 write newConfig.bind,按其 schema 校验
28
24
  }
29
25
 
30
- // 查看当前所有注册项(反映动态增删)
31
- const current: DataSlotSpec[] = sdk.listDataSlots()
26
+ // 查看当前配置(反映运行时 swap)
27
+ const current: DataConfig | undefined = sdk.getData()
32
28
  ```
33
29
 
34
30
  Notes:
35
- - `addDataSlot` 覆盖同名 path 时保留旧快照栈;按新 schema 校验。
36
- - 动态注册的属性**不自动纳入 checkpoint 快照**(checkpoint slotPaths 在构造时固定);如需回滚动态组件,自行管理或重建。
37
- - `inspect().dataSlots` `verify`(默认 `createWriteBackCheck`)均反映动态注册的最新 schemas(verify 每次 check 实时取 `listDataSlots()`)
38
- - `capabilities.dataSlotOps:false` `addDataSlot`/`removeDataSlot` no-op(并 warn)
31
+ - `setData` replaces the whole config; old snapshots cleared & optimistic-lock hash reset.
32
+ - `inspect().data` `verify`(默认 `createWriteBackCheck`)均反映 `setData` 后的最新 schema/bind(verify 每次 check 实时取 `getData()`)。
33
+ - `capabilities.dataOps:false` `setData`/`getData` 仍可调用(仅替换配置,工具不暴露);工具调用为 no-op
34
+ - `summarization` 压缩时自动注入当前 `getData()` description 进摘要 system 消息,LLM 不会基于过时记忆操作旧 schema
39
35
 
40
- **完整可运行示例**:`examples/dynamic-demo/`(dev 启动后访问 `/examples/dynamic-demo/`)—— 演示加载/卸载结构各异的组件(banner/card/stat/chart),挂载即 `addDataSlot` 注册其 schema,AI 立即可按各自 schema 操作,卸载即 `removeDataSlot`;右侧实时显示 `sdk.listDataSlots()` 反映动态增删。
36
+ **完整可运行示例**:`examples/dynamic-demo/`(dev 启动后访问 `/examples/dynamic-demo/`)—— 演示运行时 `setData` 切换不同 schema 的组件数据,AI 立即可按新 schema 操作。
41
37
 
42
38
  ### 动态场景下「压缩后不丢信息」的保障(内置,无需额外配置)
43
39
 
44
- 动态组件随时增删,长会话压缩后 LLM 可能基于过时记忆操作已卸载的组件、或不知道新组件已注册。SDK 内置两道保障:
40
+ schema 随时 swap,长会话压缩后 LLM 可能基于过时记忆操作旧 schema。SDK 内置两道保障:
45
41
 
46
- - **A. 压缩时注入注册表快照**:`summarization` 中间件压缩 older 轮次时,自动把当前 `listDataSlots()` 的 `path + description` 作为一段附进摘要 system 消息(不进压缩)。LLM 即便忘了历史 `describe`,每轮仍看得到「当前有哪些可操作 path」,不会再去操作已卸载的组件。`dataSlotOps` 关闭时返回空,无影响。
47
- - **C. preserveLastToolResults**:`contextOptions.preserveLastToolResults`(默认 `['describe_data_slot','list_data_slots']`)指定这些工具的步骤 `result` 在跨轮摘要时额外保留摘要片段进 summaryMsg。即便 older 轮被摘要,关键字段说明仍在摘要里,LLM 不必反复 `describe`。设为 `[]` 关闭。
42
+ - **A. 压缩时注入数据描述**:`summarization` 中间件压缩 older 轮次时,自动把当前 `getData()` 的 `description` 作为一段附进摘要 system 消息(不进压缩)。LLM 即便忘了历史 `describe`,每轮仍看得到「当前主数据是什么」,不会操作过时 schema。`dataOps` 关闭时返回空,无影响。
43
+ - **C. preserveLastToolResults**:`contextOptions.preserveLastToolResults`(默认 `['describe_data','read']`)指定这些工具的步骤 `result` 在跨轮摘要时额外保留摘要片段进 summaryMsg。即便 older 轮被摘要,关键字段说明仍在摘要里,LLM 不必反复 `describe`。设为 `[]` 关闭。
48
44
 
49
45
  ```ts
50
46
  // 默认即开启 A + C;如需关闭或自定义:
51
47
  createChatSdk({
52
48
  contextOptions: {
53
49
  preserveLastToolResults: [], // 关闭 C(不保留工具结果摘要)
54
- // getRegisteredSlots 由 SDK 内部注入(来自 sdk.listDataSlots),无需手动传
50
+ // getRegisteredData 由 SDK 内部注入(来自 sdk.getData),无需手动传
55
51
  },
56
52
  // ...
57
53
  })
58
54
  ```
59
55
 
60
- - **B. 写操作返回附当前可操作 path 列表**:`set`/`edit`/`delete` 成功返回末尾自动附 `(当前可操作 path: a, b, c)`,LLM 写完即知全貌,多组件批量场景减少 `list` 调用。超过 8 项或过长时只报数量,避免提示过长。
56
+ - **B. 写操作返回附当前可操作字段列表**:`set`/`edit`/`delete` 成功返回末尾自动附 `(当前可操作字段: a, b, c)`,LLM 写完即知全貌,减少 `describe` 调用。超过 8 项或过长时只报数量,避免提示过长。
61
57
  - **D. `systemPromptHelpers.reliableWriteRules`**:导出的标准化「可靠写入规则」片段,建议拼进 `systemPrompt`:
62
58
 
63
59
  ```ts
64
60
  import { systemPromptHelpers } from 'page-agent-sdk'
65
61
  createChatSdk({
66
- systemPrompt: `你是页面助手。\n${systemPromptHelpers.reliableWriteRules}`,
62
+ systemPrompt: `你是 JSON 操作助手。\n${systemPromptHelpers.reliableWriteRules}`,
67
63
  // ...
68
64
  })
69
65
  ```
70
- 内容:改前先 `get` 读真实值、动态场景先 `list`、字段以 `describe` 为准、写错看校验错误重试、优先 `edit` 增量 patch。避免集成方忘了写这些元规则导致 LLM 凭记忆瞎改。
66
+ 内容:改前先 `read` 读真实值、字段以 `describe` 为准、写错看校验错误重试、优先 `edit` 增量 patch。避免集成方忘了写这些元规则导致 LLM 凭记忆瞎改。
71
67
 
72
68
  ## 1. Custom tools (`defineTool`)
73
69
 
74
- Custom tools extend the agent beyond built-in `dataSlotOps`/`fetch`. Use them to expose your product's API to the AI.
70
+ Custom tools extend the agent beyond built-in `dataOps`/`fetch`. Use them to expose your product's API to the AI.
75
71
 
76
72
  ### Minimal
77
73
 
@@ -99,31 +95,31 @@ const updatePrice = defineTool({
99
95
  schema: z.object({ sku: z.string(), price: z.number().positive() }),
100
96
  handler: async ({ sku, price }) => {
101
97
  const ok = await api.setPrice(sku, price)
102
- if (!ok) return toolError({ path: sku, code: 'NOT_FOUND', message: `SKU ${sku} 不存在` })
98
+ if (!ok) return toolError({ code: 'NOT_FOUND', message: `SKU ${sku} 不存在` })
103
99
  return `已更新 ${sku} 价格为 ${price}`
104
100
  },
105
101
  })
106
102
  ```
107
103
 
108
- ### Coexisting with dataSlotOps
104
+ ### Coexisting with dataOps
109
105
 
110
- Mix custom tools with built-in data slot tools:
106
+ Mix custom tools with built-in data tools:
111
107
 
112
108
  ```ts
113
109
  createChatSdk({
114
110
  container: '#chat', llm: { ... },
115
- dataSlots: [{ path: 'app.config', description: '配置', schema: z.record(z.any()) }],
116
- tools: [lookupOrder, updatePrice], // custom + built-in dataSlotOps together
111
+ data: { schema: z.object({ config: z.record(z.any()) }), bind: { config: {} } },
112
+ tools: [lookupOrder, updatePrice], // custom + built-in dataOps together
117
113
  }).mount()
118
114
  ```
119
115
 
120
- ### Pure custom-tool agent (no dataSlotOps)
116
+ ### Pure custom-tool agent (no dataOps)
121
117
 
122
118
  ```ts
123
119
  createChatSdk({
124
120
  container: '#chat', llm: { ... },
125
121
  tools: [lookupOrder, updatePrice],
126
- capabilities: { dataSlotOps: false, fetch: false }, // drop built-ins
122
+ capabilities: { dataOps: false, fetch: false }, // drop built-ins
127
123
  }).mount()
128
124
  ```
129
125
 
@@ -205,7 +201,7 @@ createChatSdk({
205
201
  {
206
202
  id: 'reviewer',
207
203
  description: '审查专家:检查代码/配置的安全与性能问题',
208
- tools: ['read', 'search_data_slot'],
204
+ tools: ['read', 'search_data'],
209
205
  systemPrompt: '你是审查专家,只报告问题不改数据。',
210
206
  temperature: 0.1,
211
207
  },
@@ -270,7 +266,7 @@ createChatSdk({
270
266
  container: '#chat',
271
267
  llm: { apiKey, baseUrl, model },
272
268
  systemPrompt: '...',
273
- dataSlots: [{ path: 'app.data', description: '...', schema: z.record(z.any()) }],
269
+ data: { schema: z.object({ data: z.record(z.any()) }), bind: { data: {} } },
274
270
  tools: [lookupOrder, updatePrice], // custom tools
275
271
  skills: [apiDesignSkill, brandSkill], // progressive skills
276
272
  subagents: [{ id: 'researcher', description: '...', tools: ['fetch_document'] }], // pre-declared
@@ -1,4 +1,4 @@
1
- # API reference — instance methods, tool/skill definition, data slot tools, events
1
+ # API reference — instance methods, tool/skill definition, data tools, events
2
2
 
3
3
  ## ChatSdk instance (`createChatSdk(...)` return)
4
4
 
@@ -9,12 +9,11 @@
9
9
  | `messages` | `AgentMessage[]` (reactive) | The conversation. Headless reads this to render. UI shares the same array (single source). |
10
10
  | `send(message)` | `(msg: string) => Promise<string>` | Send a user message (invoke mode, no stream events). Returns final content. |
11
11
  | `stream` | `(messages, onEvent, signal?) => Promise<string>` | Low-level stream. UI uses this internally; headless can call directly for streaming. |
12
- | `inspect()` | `() => AgentInfo` | Inspect agent: tools/skills/dataSlots/middleware/todos/mcp.servers (each tool's `source`: `builtin`/`mcp:<name>`/`user`). DebugDrawer uses this. |
12
+ | `inspect()` | `() => AgentInfo` | Inspect agent: tools/skills/data/middleware/todos/mcp.servers (each tool's `source`: `builtin`/`mcp:<name>`/`user`). DebugDrawer uses this. |
13
13
  | `switchSession(id?)` | `(id?: string) => Promise<string>` | Switch session context (load or create by id). Requires `storage` enabled. |
14
14
  | `hook(handler)` | `(h: SdkEventHandler) => () => void` | Runtime event subscription (multi-listener, returns unsubscribe). Complements `onEvent`. |
15
- | `addDataSlot(spec)` | `(spec: DataSlotSpec) => void` | Runtime register/override a data slot (lazy-loaded components). Takes effect immediately, no rebuild. Needs `dataSlotOps` enabled. |
16
- | `removeDataSlot(path)` | `(path: string) => boolean` | Remove a registered data slot (component unmount); returns whether it existed. Clears its snapshot stack. |
17
- | `listDataSlots()` | `() => DataSlotSpec[]` | List currently-registered data slots (reflects dynamic add/remove). |
15
+ | `setData(config)` | `(config: DataConfig) => void` | Runtime swap the main data config (`{ schema, bind, description? }`). Tools pick up new bind/schema immediately, no rebuild. Clears snapshots & resets optimistic-lock hash. |
16
+ | `getData()` | `() => DataConfig \| undefined` | Read current main data config (reflects runtime `setData`). `undefined` if `dataOps` disabled. |
18
17
  | `restoreLastCheckpoint()` | `() => boolean` | Restore last good checkpoint (needs `checkpoint` enabled). |
19
18
  | `listCheckpoints()` | `() => CheckpointMeta[]` | List available checkpoints. |
20
19
 
@@ -33,7 +32,7 @@ const addTool = defineTool({
33
32
  createChatSdk({ tools: [addTool], /* llm, ... */ }).mount()
34
33
  ```
35
34
 
36
- `handler` receives validated args; return a string (or structured result stringified). Errors via `toolError({ path, code, message })`.
35
+ `handler` receives validated args; return a string (or structured result stringified). Errors via `toolError({ code, message })`.
37
36
 
38
37
  ## defineSkill (progressive disclosure)
39
38
 
@@ -68,44 +67,42 @@ Spread into options for common scenarios.
68
67
  import { createChatSdk, systemPromptHelpers } from 'page-agent-sdk'
69
68
 
70
69
  createChatSdk({
71
- systemPrompt: `你是页面助手。\n${systemPromptHelpers.reliableWriteRules}`,
70
+ systemPrompt: `你是 JSON 操作助手。\n${systemPromptHelpers.reliableWriteRules}`,
72
71
  llm, container,
73
72
  }).mount()
74
73
  ```
75
74
 
76
- `reliableWriteRules` — standardized "reliable write rules": read before write (`read`), list in dynamic scenarios (`read()` no path), fields per `read({path})` (returns format hint), retry on schema-validation errors, prefer `write` with `patch` incremental edits. Recommended for any scenario involving data-slot writes.
75
+ `reliableWriteRules` — standardized "reliable write rules": read before write (`read`), fields per `read({jsonPath})` (returns format hint), retry on schema-validation errors, prefer `write` with `patch` incremental edits. Recommended for any scenario involving data writes.
77
76
 
78
- ## Built-in data slot tools (auto-injected when `capabilities.dataSlotOps`)
77
+ ## Built-in data tools (auto-injected when `capabilities.dataOps`)
79
78
 
80
- Default `toolMode:'simple'` exposes high-level `read`/`write` + advanced query/snapshot tools (low-level `get`/`set`/`edit`/`delete`/`list`/`describe` are hidden, merged into `read`/`write`). `toolMode:'advanced'` exposes all; `toolMode:'minimal'` only `read`/`write`.
79
+ Default `toolMode:'simple'` exposes high-level `read`/`write` + advanced query/snapshot tools (low-level `get`/`set`/`edit`/`delete`/`describe` are hidden, merged into `read`/`write`). `toolMode:'advanced'` exposes all; `toolMode:'minimal'` only `read`/`write`.
81
80
 
82
81
  | Tool | Purpose | Mode |
83
82
  |---|---|---|
84
- | **`read`** / **`write`** (2.2+, recommended) | High-level entry: `read({path?})` lists/reads; `write({path, value?, patch?, del?})` merges set/edit/delete + auto optimistic lock + auto snapshot | simple/minimal |
85
- | `list_data_slots` | List declared paths + descriptions | advanced |
86
- | `describe_data_slot` | Show a path's schema | advanced |
87
- | `get_data_slot` | Read a path (or ancestor/descendant sub-paths of registered props) | advanced |
88
- | `get_slot_paths` | Batch-read multiple paths | simple/advanced |
89
- | `set_data_slot` | Write a whole path (schema-validated, scoped to registry) | advanced |
90
- | `edit_data_slot` | Patch by `jsonPath` (set/remove/merge/append) — avoids re-sending large JSON | advanced |
91
- | `delete_data_slot` | Delete a path | advanced |
92
- | `snapshot_data_slot` | Manual snapshot | simple/advanced |
83
+ | **`read`** / **`write`** (2.2+, recommended) | High-level entry: `read({jsonPath?, fields?, depth?})` lists/reads (supports field projection + depth truncation); `write({value?, patch?, patches?, del?})` merges set/edit/delete + auto optimistic lock + auto snapshot | simple/minimal |
84
+ | `describe_data` | Show main data description + schema field descriptions | advanced |
85
+ | `get_data` | Read main data (supports `jsonPath` precise sub-path read) | advanced |
86
+ | `set_data` | Write whole main data (schema-validated, scoped to declared fields) | advanced |
87
+ | `edit_data` | Patch by `jsonPath` (set/remove/merge/append) — avoids re-sending large JSON | advanced |
88
+ | `delete_data` | Delete a sub-path (jsonPath) | advanced |
89
+ | `snapshot_data` | Manual snapshot | simple/advanced |
93
90
  | `list_data_snapshots` | List snapshots | simple/advanced |
94
- | `restore_data_snapshot` | Restore (no id = most recent) | simple/advanced |
95
- | `query_data_slot` / `search_data_slot` | JSONPath query / full-text search | simple/advanced |
96
- | `eval_script` | Sandboxed script on data (for batch ops) | simple/advanced |
91
+ | `restore_data` | Restore (no id = most recent) | simple/advanced |
92
+ | `query_data` / `search_data` | JSONPath query / full-text search | simple/advanced |
93
+ | `eval_script` | Sandboxed script on data (query/transform; transform supports `{patches:[...]}` incremental mode) | simple/advanced |
97
94
 
98
- **Key rule**: `write`/`set`/`edit`/`delete` only affect **declared** `dataSlots` paths. Invalid schema → structured error, no write. `write`/`edit` writes in-place (preserves Vue reactive refs). `write` auto-tracks hash from `read` for optimistic lock (no manual `expectedHash` needed).
95
+ **Key rule**: `write`/`set`/`edit`/`delete` only affect **schema-declared** top-level fields (ZodObject auto-whitelist; undeclared fields hidden/denied). Invalid schema → structured error, no write. `write`/`edit` writes in-place (preserves Vue reactive refs). `write` auto-tracks hash from `read` for optimistic lock (no manual `expectedHash` needed). Whole-set / `set_data` / `eval` transform become **merge** semantics in whitelist mode (only updates declared fields, undeclared fields preserved — prevents accidental deletion).
99
96
 
100
97
  ### write / jsonPath edit operations
101
98
 
102
- `write({ path, value, patch: { op, jsonPath } })` (or `write({ path, del: true })` to delete):
99
+ `write({ value, patch: { op, jsonPath } })` (or `write({ patch: { jsonPath }, del: true })` to delete; or `write({ patches: [...] })` for batch atomic):
103
100
  - `set` — set a sub-path (or whole value when no `patch`)
104
101
  - `remove` — remove a sub-path / array element
105
102
  - `merge` — shallow-merge an object
106
103
  - `append` — append to an array
107
104
 
108
- Example: `write({ path: 'app.items', value: 9.9, patch: { op: 'set', jsonPath: '0.price' } })` — precise local edit, no full re-send. `value` is a JSON object (recommended) or JSON string.
105
+ Example: `write({ value: 9.9, patch: { op: 'set', jsonPath: 'items.0.price' } })` — precise local edit, no full re-send. `value` is a JSON object (recommended) or JSON string. `patches: [{op:'set', jsonPath:'a', value:1}, {op:'append', jsonPath:'items', value:newItem}]` — batch atomic (any failure → whole batch rolled back).
109
106
 
110
107
  ## Built-in fetch tools (`capabilities.fetch`)
111
108
 
@@ -122,36 +119,37 @@ Example: `write({ path: 'app.items', value: 9.9, patch: { op: 'set', jsonPath: '
122
119
  | `tool_result` | `name, result, status` | Tool returns (`status`: `done`/`error`) |
123
120
  | `subagent` | `taskId, label, kind, name, args?, result?, status?` | Subagent tool progress (forwarded to UI, NOT into main LLM context) |
124
121
  | `done` | `content` | Agent round completes |
125
- | `data_slot_change` | `path, operation, value?` | A data slot was written via `write` (high-level, infers `set`/`edit`/`delete` from args) or low-level `set`/`edit`/`delete`/`restore_data_snapshot` |
122
+ | `data_change` | `operation, value?` | Main data was written via `write` (infers `set`/`edit`/`delete` from args) or low-level `set`/`edit`/`delete`/`restore_data` |
126
123
  | `message_update` | `count` | The `messages` array changed |
127
124
  | `error` | `message` | An error occurred (abort excluded) |
128
125
 
129
126
  `approval_request` is **NOT** forwarded via `onEvent`/`hook` (UI handles it; headless integrators use a custom approval middleware listener).
130
127
 
131
- ## `dataSlots` unified config (3.0+, declarative — schema + bind + auto field-hints)
128
+ ## `data` config (single main object — schema + bind + auto field-hints)
132
129
 
133
- `dataSlots` is the single entry for data-slot config — combining schema declaration + optional object direct-bind + auto field-hint injection:
130
+ `data` is the single entry for main-data config — combining schema declaration + object direct-bind + auto field-hint injection:
134
131
 
135
132
  ```ts
136
- import { reactive } from 'vue' // or any reactivity impl
137
- const PageSchema = z.object({ title: z.string().describe('页面标题'), count: z.number() })
133
+ import { reactive } from 'vue' // or any reactivity impl; plain object also works
134
+ const PageSchema = z.object({
135
+ title: z.string().describe('页面标题'),
136
+ count: z.number().describe('计数器'),
137
+ })
138
138
  const page = reactive({ title: '首页', count: 0 }) // reactive recommended for UI auto-refresh
139
139
 
140
140
  createChatSdk({
141
- dataSlots: [
142
- {
143
- path: 'page', // path on window (dot-nested supported)
144
- schema: PageSchema, // write validation + field .describe() auto-injected into systemPrompt「可操作属性」section
145
- bind: page, // optional: reactive/plain object auto-mounted to window[path] + registered as dataSlot
146
- },
147
- ],
141
+ data: {
142
+ schema: PageSchema, // write validation + field .describe() auto-injected into systemPrompt「可操作数据」section + ZodObject top-level keys auto-whitelist
143
+ bind: page, // reactive/plain object; tools read/write directly (no window)
144
+ description: '页面配置', // optional; auto-generated if omitted
145
+ },
148
146
  })
149
147
  // LLM write page → page reactively updates; integrator changes page → LLM read sees it
150
148
  ```
151
149
 
152
- - **`bind` is an optional `dataSlots` field** (any object): reactive → auto-refresh on write (recommended for UI); plain object → write works but no auto-refresh (suitable for headless / backend; integrator uses `onEvent`/`hook` `data_slot_change` to be notified). Omit `bind` when the integrator mounts `window[path]` themselves (object already exists / dynamic registration via `addDataSlot`/`removeDataSlot` / field-whitelist read).
153
- - Tools `set`/`write` mutate in-place (`restoreInPlace`), compatible with reactive proxies; plain objects also write fine.
154
- - **Notifying the outside world of changes**: subscribe `data_slot_change` via `onEvent` (constructor) or `sdk.hook` (runtime, multi-listener, cancellable) — fires after `write`/`set`/`edit`/`delete`/`restore`, with `path`/`operation`/`value`. For Vue + reactive bind, template/watch auto-react (no manual notify needed); `onEvent` can coexist for audit/analytics.
150
+ - **`bind` is required** (any object): reactive → auto-refresh on write (recommended for UI); plain object → write works but no auto-refresh (suitable for headless / backend; integrator uses `onEvent`/`hook` `data_change` to be notified). Tools mutate in-place (`restoreInPlace`), compatible with reactive proxies; plain objects also write fine.
151
+ - **Notifying the outside world of changes**: subscribe `data_change` via `onEvent` (constructor) or `sdk.hook` (runtime, multi-listener, cancellable) — fires after `write`/`set`/`edit`/`delete`/`restore`, with `operation`/`value`. For Vue + reactive bind, template/watch auto-react (no manual notify needed); `onEvent` can coexist for audit/analytics.
152
+ - **Runtime swap**: `sdk.setData({ schema, bind, description? })` replaces the whole config; tools pick up immediately (no rebuild). Snapshots & lock hash reset.
155
153
 
156
154
  ## Exported building blocks (for custom UIs)
157
155
 
@@ -7,7 +7,7 @@ Full reference for `createChatSdk(options)`. Grouped by purpose. Required: `llm`
7
7
  | Option | Type | Default | Purpose / when |
8
8
  |---|---|---|---|
9
9
  | `llm` | `LLMConfig \| BaseChatModel` | — (required) | The model. `LLMConfig = { apiKey, baseUrl, model, temperature?, maxTokens? }` (OpenAI-compatible; DeepSeek default). Or pass any LangChain `BaseChatModel` (e.g. `ChatAnthropic`, install its peerDep). |
10
- | `systemPrompt` | `string` | built-in default (generic page assistant + reliable write rules) | Agent identity/instructions. Inject here, not hardcoded. Keep single-line in `.env` (`VITE_AI_SYSTEM_PROMPT`). If omitted, a built-in default is used (page-operation assistant + `systemPromptHelpers.reliableWriteRules`); passing your own fully overrides it (append `systemPromptHelpers.reliableWriteRules` yourself if needed). |
10
+ | `systemPrompt` | `string` | built-in default (JSON-operation assistant + reliable write rules) | Agent identity/instructions. Inject here, not hardcoded. Keep single-line in `.env` (`VITE_AI_SYSTEM_PROMPT`). If omitted, a built-in default is used (JSON-operation assistant + `systemPromptHelpers.reliableWriteRules`); passing your own fully overrides it (append `systemPromptHelpers.reliableWriteRules` yourself if needed). |
11
11
  | `id` | `string` | random + warn | Stable agent id for multi-agent isolation & persistence. **Must pass a stable value** if you use `storage` or run multiple agents on one page. |
12
12
  | `title` / `placeholder` | `string` | — | Dialog title / input placeholder (cosmetic). |
13
13
 
@@ -17,17 +17,20 @@ Full reference for `createChatSdk(options)`. Grouped by purpose. Required: `llm`
17
17
  |---|---|---|---|
18
18
  | `container` | `string \| HTMLElement` | — | Where the built-in dialog mounts. Required when `ui !== false`. |
19
19
  | `ui` | `boolean \| 'default'` | `true` | `false` = headless (no built-in dialog; you build UI from `sdk.messages` + `sdk.send`). `'default'` = built-in `ChatDialog`. |
20
- | `streaming` | `boolean` | `true` | Stream tokens live. `false` = wait for full reply. Headless `sdk.send` always uses invoke (no stream events, but window/message/error still fire). |
20
+ | `streaming` | `boolean` | `true` | Stream tokens live. `false` = wait for full reply. Headless `sdk.send` always uses invoke (no stream events, but data/message/error still fire). |
21
21
 
22
- ## data slot operation (the core)
22
+ ## Data operation (the core)
23
23
 
24
24
  | Option | Type | Default | Purpose / when |
25
25
  |---|---|---|---|
26
- | `dataSlots` | `DataSlotSpec[]` | `[]` | Declare writable `window` paths + zod schemas. The agent can ONLY touch declared paths; `set`/`edit` are schema-validated. **This is the key integration step.** |
27
- | `maxSnapshots` | `number` | 20 | Per-path snapshot stack depth for `restore_data_snapshot`. |
28
- | `permissions` | `PermissionRule[]` | off | Scope whitelist (first-match-wins) for fine-grained per-path/tool rules. Default off (all declared paths writable). |
26
+ | `data` | `DataConfig` | | Declare the single main data object: `{ schema, bind, description? }`. `schema` = zod (write validation + field `.describe()` auto-injected into prompt + ZodObject top-level keys auto-whitelist); `bind` = reactive/plain object (tools read/write directly, no `window`); `description` = optional data purpose. **This is the key integration step.** |
27
+ | `maxSnapshots` | `number` | 20 | Snapshot stack depth for `restore_data` (per-path snapshots auto-stored before set/edit/delete). |
28
+ | `permissions` | `PermissionRule[]` | off | Scope whitelist (first-match-wins) for fine-grained per-jsonPath/tool rules. Default off (all schema-declared fields writable). |
29
+ | `toolMode` | `'simple' \| 'advanced' \| 'minimal'` | `simple` | `simple` = high-level `read`/`write` + query/search/eval/snapshot (hides low-level get/set/edit/delete); `advanced` = all tools; `minimal` = only `read`/`write`. |
30
+ | `interceptors` | `{ read?, write?, input?, output? }` | — | `read(value)` desensitize/derive (changes only what LLM sees); `write(payload, current)` transform/audit/reject (return `{error}`); `input`/`output` for message-level interception. |
31
+ | `autoLock` | `boolean` | `true` | Auto optimistic lock: `write` compares LLM's last `read` hash with current; mismatch → `VERSION_CONFLICT` (or human resolution via `onConflict`). |
29
32
 
30
- `DataSlotSpec = { path: string; description: string; schema?: z.ZodType }`. `description` is shown to the AI write it clearly so the agent knows what each path means.
33
+ `DataConfig = { schema: z.ZodType; bind: any; description?: string }`. `bind` is any object — reactive (Vue auto-refresh) or plain (use `onEvent('data_change')` to re-render). Field `.describe()` text on `schema` is auto-extracted and injected into the system prompt so the LLM knows each field's purpose.
31
34
 
32
35
  ## Tools, skills, memory
33
36
 
@@ -44,8 +47,8 @@ Full reference for `createChatSdk(options)`. Grouped by purpose. Required: `llm`
44
47
 
45
48
  | Flag | Off when... |
46
49
  |---|---|
47
- | `dataSlotOps` | Pure research agent, no page edits (also drops data slot tools from subagents). |
48
- | `fetch` | No web fetching needed. ⚠️ turning off `dataSlotOps` also strips subagent data slot tools. |
50
+ | `dataOps` | Pure research agent, no data edits (also drops data tools from subagents). |
51
+ | `fetch` | No web fetching needed. ⚠️ turning off `dataOps` also strips subagent data tools. |
49
52
  | `planning` | Don't want `write_todos` planning. |
50
53
  | `skills` | Don't want progressive skill loading. |
51
54
  | `vfs` | No in-memory workspace; ⚠️ large tool results then truncate instead of offloading. |
@@ -70,7 +73,7 @@ Full reference for `createChatSdk(options)`. Grouped by purpose. Required: `llm`
70
73
  | Option | Type | Default | Purpose / when |
71
74
  |---|---|---|---|
72
75
  | `contextPreset` | `'auto'\|'conservative'\|'aggressive'` | `auto` | `conservative` = save cost; `aggressive` = save context. `contextOptions` fine-tunes further. |
73
- | `contextOptions` | `object` | — | Detailed compression params (overrides preset). `false` disables compression. Key fields: `windowRounds`, `summaryThresholdRounds`, `contextWindow`, `summaryThresholdRatio`, `windowRatio`, `enableRecall`, `recallTopK`, `enableLLMSummary`, `preserveLastToolResults` (default `['describe_data_slot','list_data_slots']` — keep these tools' result summaries in the compressed summary so field descriptions survive compression; set `[]` to disable). `getRegisteredSlots` is injected internally by the SDK (from `sdk.listDataSlots`) to embed a live registry snapshot in the summary — no need to set it manually. |
76
+ | `contextOptions` | `object` | — | Detailed compression params (overrides preset). `false` disables compression. Key fields: `windowRounds`, `summaryThresholdRounds`, `contextWindow`, `summaryThresholdRatio`, `windowRatio`, `enableRecall`, `recallTopK`, `enableLLMSummary`, `preserveLastToolResults` (default `['describe_data','read']` — keep these tools' result summaries in the compressed summary so field descriptions survive compression; set `[]` to disable). `getRegisteredData` is injected internally by the SDK (from `sdk.getData`) to embed a live data description in the summary — no need to set it manually. |
74
77
  | `summaryLlm` | `BaseChatModel \| LLMConfig` | main `llm` | Use a cheaper/faster model for summarization. |
75
78
  | `summaryTemperature` | `number` | 0.3 | Summary model temperature. |
76
79
  | `summaryMaxTokens` | `number` | 1024 | Summary output cap. |
@@ -86,7 +89,7 @@ Full reference for `createChatSdk(options)`. Grouped by purpose. Required: `llm`
86
89
  ## Verify (self-check before return)
87
90
 
88
91
  `capabilities.verify: true` enables. `verify: { check?, maxAttempts?, adversarial? }`:
89
- - `check` omitted → default `createWriteBackCheck()` (scans all writes, reads back + schema-validates; skips legitimately-rejected writes).
92
+ - `check` omitted → default `createWriteBackCheck()` (scans all writes, reads back from `data.bind` + schema-validates; skips legitimately-rejected writes). Read-back root auto-bound to `data.bind` (adapts to `sdk.setData` runtime swap).
90
93
  - custom `check: async ({ messages, state }) => ({ ok, feedback? })` — return **actionable** feedback.
91
94
  - `adversarial: true` → after check passes, spawn a read-only "refuter" subagent (costs extra rounds; for semantically complex cases).
92
95
  - `maxAttempts` (default 2) caps self-correction loops.
@@ -97,15 +100,15 @@ Full reference for `createChatSdk(options)`. Grouped by purpose. Required: `llm`
97
100
 
98
101
  ## Checkpoint (session rollback)
99
102
 
100
- `checkpoint: true \| { maxCheckpoints?, auto? }` — per-round snapshot of (messages + data slots + vfs + todos). `restoreLastCheckpoint()` / LLM tool `restore_last_checkpoint` / UI button. Distinct from dataSlotOps per-path snapshots (checkpoint = whole-session rollback).
103
+ `checkpoint: true \| { maxCheckpoints?, auto? }` — per-round snapshot of (messages + main data bind + vfs + todos). Read-back/restore auto-bound to `data.bind` via `getData` (adapts to `sdk.setData` runtime swap; in-place restore preserves reactive refs). `restoreLastCheckpoint()` / LLM tool `restore_last_checkpoint` / UI button. Distinct from dataOps per-path snapshots (checkpoint = whole-session rollback).
101
104
 
102
105
  ## Persistence (storage)
103
106
 
104
107
  | Option | Type | Default | Purpose / when |
105
108
  |---|---|---|---|
106
- | `storage` | `'indexed'\|'session'\|'local'\|'memory'\| StorageConfig \| false` | `false` (off) | Off by default; assign to enable. Persists messages/vfs/todos/memory (NOT window snapshots). Auto-degrades to memory if backend unavailable (private mode / quota). |
109
+ | `storage` | `'indexed'\|'session'\|'local'\|'memory'\| StorageConfig \| false` | `false` (off) | Off by default; assign to enable. Persists messages/vfs/todos/memory (NOT `bind` — it may contain non-serializable content; store & re-inject via `sdk.setData`). Auto-degrades to memory if backend unavailable (private mode / quota). |
107
110
  | `session` | `SessionOptions` | — | Session control (resume by id, etc.). |
108
- | `shareContext` | `boolean` | `false` | `true` → multiple `createChatSdk` with same `id` share one `AgentCore` (same agent, multiple dialog views on a page). |
111
+ | `shareContext` | `boolean` | `false` | `true` → multiple `createChatSdk` with same `id` share one `AgentCore` (same agent, multiple dialog views on a page; shares `data.bind` too). |
109
112
 
110
113
  ## MCP (external tools)
111
114