page-agent-sdk 2.1.0 → 2.4.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 +57 -40
- package/README.zh-CN.md +55 -38
- package/dist/page-agent-sdk.css +1 -1
- package/dist/page-agent-sdk.iife.js +120 -120
- package/dist/page-agent-sdk.js +841 -838
- package/dist/page-agent-sdk.umd.cjs +35 -35
- package/package.json +1 -1
- package/skills/page-agent-sdk-integrate/SKILL.md +5 -5
- package/skills/page-agent-sdk-integrate/references/advanced.md +5 -5
- package/skills/page-agent-sdk-integrate/references/api.md +52 -24
- package/skills/page-agent-sdk-integrate/references/quickstart.md +2 -2
- package/skills/page-agent-sdk-integrate/references/use-cases.md +7 -7
- package/types/index.d.ts +69 -55
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "page-agent-sdk",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.4.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",
|
|
@@ -9,7 +9,7 @@ Help the user embed `page-agent-sdk` so an AI agent safely edits their page's st
|
|
|
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 `
|
|
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.
|
|
13
13
|
|
|
14
14
|
## Workflow
|
|
15
15
|
|
|
@@ -47,7 +47,7 @@ createChatSdk({
|
|
|
47
47
|
}).mount()
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
For large JSON, prefer `
|
|
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.
|
|
51
51
|
|
|
52
52
|
### 3. Configure the LLM
|
|
53
53
|
|
|
@@ -83,10 +83,10 @@ Event types: `data_slot_change` / `message_update` / `tool_call` / `tool_result`
|
|
|
83
83
|
|
|
84
84
|
| Scenario | Key setup |
|
|
85
85
|
|---|---|
|
|
86
|
-
| **Low-code page builder** | `dataSlots` = component tree; `
|
|
86
|
+
| **Low-code page builder** | `dataSlots` = component tree; `write` patch jsonPath; `onEvent` → canvas refresh; `checkpoint` + `approval` |
|
|
87
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; `
|
|
89
|
-
| **Ops config console** | `approval:{tools:[
|
|
88
|
+
| **CMS batch ops** | `eval_script` for bulk loops; `search_data_slot` to filter; `write` patch for targeted edits |
|
|
89
|
+
| **Ops config console** | `approval:{tools:['write']}` human-confirm; `capabilities.verify:true` write-back read; `checkpoint` |
|
|
90
90
|
| **AI-native assistant** | `capabilities:{dataSlotOps:false,fetch:false}` + custom `tools` (your product API) |
|
|
91
91
|
| **Research agent** | `capabilities:{dataSlotOps:false}`; `subagent:{allowedTools:['fetch_document']}`; `contextPreset:'conservative'` |
|
|
92
92
|
| **Headless / server-side** | `ui:false` + `storage:'memory'` + `capabilities:{dataSlotOps:false,fetch:false}`; drive via `sdk.send` |
|
|
@@ -19,7 +19,7 @@ const sdk = createChatSdk({
|
|
|
19
19
|
// 组件懒加载时动态注册其 schema(结构各异)
|
|
20
20
|
function onComponentMount(comp: { id: string; type: string; schema: z.ZodType }) {
|
|
21
21
|
sdk.addDataSlot({ path: `app.components.${comp.id}`, description: `${comp.type} 组件`, schema: comp.schema })
|
|
22
|
-
// 立即生效:AI 现在能
|
|
22
|
+
// 立即生效:AI 现在能 write 这个 path,按其 schema 校验
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// 组件卸载时移除(快照栈一并清理)
|
|
@@ -177,7 +177,7 @@ createChatSdk({
|
|
|
177
177
|
container: '#chat', llm: { ... },
|
|
178
178
|
systemPrompt: '多源对比时用 spawn_agents 并行委派。',
|
|
179
179
|
subagent: {
|
|
180
|
-
allowedTools: ['fetch_document', '
|
|
180
|
+
allowedTools: ['fetch_document', 'read'], // read-only subset (no spawn → no recursion)
|
|
181
181
|
maxDepth: 1, // physical recursion cut (default 1)
|
|
182
182
|
maxParallel: 3, // max parallel subagents in spawn_agents
|
|
183
183
|
temperature: 0.2, // subagent temperature (default inherits main)
|
|
@@ -199,13 +199,13 @@ createChatSdk({
|
|
|
199
199
|
{
|
|
200
200
|
id: 'researcher',
|
|
201
201
|
description: '调研专家:搜集资料、对比方案(只读)',
|
|
202
|
-
tools: ['fetch_document', '
|
|
202
|
+
tools: ['fetch_document', 'read'], // read-only
|
|
203
203
|
temperature: 0.2,
|
|
204
204
|
},
|
|
205
205
|
{
|
|
206
206
|
id: 'reviewer',
|
|
207
207
|
description: '审查专家:检查代码/配置的安全与性能问题',
|
|
208
|
-
tools: ['
|
|
208
|
+
tools: ['read', 'search_data_slot'],
|
|
209
209
|
systemPrompt: '你是审查专家,只报告问题不改数据。',
|
|
210
210
|
temperature: 0.1,
|
|
211
211
|
},
|
|
@@ -276,7 +276,7 @@ createChatSdk({
|
|
|
276
276
|
subagents: [{ id: 'researcher', description: '...', tools: ['fetch_document'] }], // pre-declared
|
|
277
277
|
mcp: [{ transport: 'http', url: '...' }], // external tools
|
|
278
278
|
capabilities: { verify: true }, // self-check
|
|
279
|
-
approval: { tools: ['
|
|
279
|
+
approval: { tools: ['write'] }, // human confirm writes
|
|
280
280
|
checkpoint: true, // rollback
|
|
281
281
|
}).mount()
|
|
282
282
|
```
|
|
@@ -73,36 +73,39 @@ createChatSdk({
|
|
|
73
73
|
}).mount()
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
`reliableWriteRules` — standardized "reliable write rules": read before write (`
|
|
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.
|
|
77
77
|
|
|
78
78
|
## Built-in data slot tools (auto-injected when `capabilities.dataSlotOps`)
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
|
83
|
-
|
|
84
|
-
|
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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`.
|
|
81
|
+
|
|
82
|
+
| Tool | Purpose | Mode |
|
|
83
|
+
|---|---|---|
|
|
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 |
|
|
93
|
+
| `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 |
|
|
97
|
+
|
|
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).
|
|
99
|
+
|
|
100
|
+
### write / jsonPath edit operations
|
|
101
|
+
|
|
102
|
+
`write({ path, value, patch: { op, jsonPath } })` (or `write({ path, del: true })` to delete):
|
|
103
|
+
- `set` — set a sub-path (or whole value when no `patch`)
|
|
101
104
|
- `remove` — remove a sub-path / array element
|
|
102
105
|
- `merge` — shallow-merge an object
|
|
103
106
|
- `append` — append to an array
|
|
104
107
|
|
|
105
|
-
Example: `
|
|
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.
|
|
106
109
|
|
|
107
110
|
## Built-in fetch tools (`capabilities.fetch`)
|
|
108
111
|
|
|
@@ -119,12 +122,37 @@ Example: `edit_data_slot({ path: 'app.items', jsonPath: '0.price', op: 'set', va
|
|
|
119
122
|
| `tool_result` | `name, result, status` | Tool returns (`status`: `done`/`error`) |
|
|
120
123
|
| `subagent` | `taskId, label, kind, name, args?, result?, status?` | Subagent tool progress (forwarded to UI, NOT into main LLM context) |
|
|
121
124
|
| `done` | `content` | Agent round completes |
|
|
122
|
-
| `data_slot_change` | `path, operation, value?` | A data slot was written (`
|
|
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` |
|
|
123
126
|
| `message_update` | `count` | The `messages` array changed |
|
|
124
127
|
| `error` | `message` | An error occurred (abort excluded) |
|
|
125
128
|
|
|
126
129
|
`approval_request` is **NOT** forwarded via `onEvent`/`hook` (UI handles it; headless integrators use a custom approval middleware listener).
|
|
127
130
|
|
|
131
|
+
## `dataSlots` unified config (3.0+, declarative — schema + bind + auto field-hints)
|
|
132
|
+
|
|
133
|
+
`dataSlots` is the single entry for data-slot config — combining schema declaration + optional object direct-bind + auto field-hint injection:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { reactive } from 'vue' // or any reactivity impl
|
|
137
|
+
const PageSchema = z.object({ title: z.string().describe('页面标题'), count: z.number() })
|
|
138
|
+
const page = reactive({ title: '首页', count: 0 }) // reactive recommended for UI auto-refresh
|
|
139
|
+
|
|
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
|
+
],
|
|
148
|
+
})
|
|
149
|
+
// LLM write page → page reactively updates; integrator changes page → LLM read sees it
|
|
150
|
+
```
|
|
151
|
+
|
|
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.
|
|
155
|
+
|
|
128
156
|
## Exported building blocks (for custom UIs)
|
|
129
157
|
|
|
130
158
|
- `ChatDialog`, `MessageContent`, `CodePreview` — Vue components
|
|
@@ -28,7 +28,7 @@ Drop into any HTML page. The built-in dialog mounts itself. (`systemPrompt` is o
|
|
|
28
28
|
</script>
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Talk to it: "change theme to dark" → AI calls `
|
|
31
|
+
Talk to it: "change theme to dark" → AI calls `write({ path:'app.theme', value:'dark' })` → `window.app.theme === 'dark'`.
|
|
32
32
|
|
|
33
33
|
## Stage 2 — npm + module project
|
|
34
34
|
|
|
@@ -95,7 +95,7 @@ createChatSdk({
|
|
|
95
95
|
// ...llm, dataSlots...
|
|
96
96
|
capabilities: { verify: true }, // write-back self-check before agent returns
|
|
97
97
|
verify: { maxAttempts: 2 }, // auto-correct on failure (default check = write-back read + schema)
|
|
98
|
-
approval: { tools: ['
|
|
98
|
+
approval: { tools: ['write'] }, // human-confirm before writes
|
|
99
99
|
checkpoint: true, // session-level rollback on bad edits
|
|
100
100
|
maxParallelTools: 1, // serial tool calls (safe for stateful middleware)
|
|
101
101
|
contextPreset: 'conservative', // save cost on long sessions
|
|
@@ -17,7 +17,7 @@ window.page = {
|
|
|
17
17
|
createChatSdk({
|
|
18
18
|
container: '#chat',
|
|
19
19
|
llm: { apiKey, baseUrl: 'https://api.deepseek.com/v1', model: 'deepseek-chat', temperature: 0.3 },
|
|
20
|
-
systemPrompt: '你是页面搭建助手。用
|
|
20
|
+
systemPrompt: '你是页面搭建助手。用 write 的 patch 按 jsonPath 增量改 components,不要重传整树。',
|
|
21
21
|
dataSlots: [
|
|
22
22
|
{ path: 'page.components', description: '组件树',
|
|
23
23
|
schema: z.array(z.object({
|
|
@@ -27,11 +27,11 @@ createChatSdk({
|
|
|
27
27
|
],
|
|
28
28
|
onEvent(e) { if (e.type === 'data_slot_change') renderCanvas() }, // canvas reactive refresh
|
|
29
29
|
checkpoint: true, // bad edit → one-click rollback
|
|
30
|
-
approval: { tools: ['
|
|
30
|
+
approval: { tools: ['write'] }, // confirm writes
|
|
31
31
|
}).mount()
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
User: "顶部 Banner 改深色、主标题加粗、加一张新品卡" → AI calls `
|
|
34
|
+
User: "顶部 Banner 改深色、主标题加粗、加一张新品卡" → AI calls `write` with `patch` per component.
|
|
35
35
|
|
|
36
36
|
## 2. Form designer
|
|
37
37
|
|
|
@@ -66,7 +66,7 @@ User: "手机号加格式校验、地址改三级联动" → AI patches `form.fi
|
|
|
66
66
|
|
|
67
67
|
## 3. CMS batch operation
|
|
68
68
|
|
|
69
|
-
Bulk-edit a product list; use `eval_script` or `search_data_slot` + `
|
|
69
|
+
Bulk-edit a product list; use `eval_script` or `search_data_slot` + `write` with `patch` for batch ops.
|
|
70
70
|
|
|
71
71
|
```ts
|
|
72
72
|
window.products = [
|
|
@@ -88,7 +88,7 @@ createChatSdk({
|
|
|
88
88
|
}).mount()
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
User: "标题加『限时』前缀、低于 100 元的标红" → AI uses `eval_script` for the prefix loop + `search_data_slot` to find `<100` then `
|
|
91
|
+
User: "标题加『限时』前缀、低于 100 元的标红" → AI uses `eval_script` for the prefix loop + `search_data_slot` to find `<100` then `write` with `patch` to set `highlight`.
|
|
92
92
|
|
|
93
93
|
## 4. Ops config console
|
|
94
94
|
|
|
@@ -109,7 +109,7 @@ createChatSdk({
|
|
|
109
109
|
{ path: 'config.featureB', description: 'B开关',
|
|
110
110
|
schema: z.object({ enabled: z.boolean() }) },
|
|
111
111
|
],
|
|
112
|
-
approval: { tools: ['
|
|
112
|
+
approval: { tools: ['write'] }, // human-in-the-loop
|
|
113
113
|
checkpoint: true,
|
|
114
114
|
capabilities: { verify: true }, // write-back read + schema check
|
|
115
115
|
}).mount()
|
|
@@ -208,7 +208,7 @@ const sdk = createChatSdk({
|
|
|
208
208
|
container: '#chat', llm: { ... },
|
|
209
209
|
// only the static container is pre-declared; per-component paths are dynamic
|
|
210
210
|
dataSlots: [{ path: 'app.components', description: '动态组件容器', schema: z.record(z.any()) }],
|
|
211
|
-
systemPrompt: '用
|
|
211
|
+
systemPrompt: '用 read() 查看当前可操作的组件 path,再按各自 schema 操作',
|
|
212
212
|
}).mount()
|
|
213
213
|
|
|
214
214
|
// 组件挂载(懒加载)→ 动态注册其 schema,立即对 AI 生效
|
package/types/index.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export type StreamHandler = (event: StreamEvent) => void;
|
|
|
45
45
|
/**
|
|
46
46
|
* SDK 事件(供 createChatSdk({ onEvent }) 订阅常用时机)。
|
|
47
47
|
* 复用 StreamEvent(round_start/reasoning/text/tool_call/tool_result/subagent/done;approval_request 不外发)
|
|
48
|
-
* + 额外时机:
|
|
48
|
+
* + 额外时机:data_change / message_update / error。
|
|
49
49
|
*/
|
|
50
50
|
export type SdkEvent =
|
|
51
51
|
| { type: 'round_start'; round: number }
|
|
@@ -55,7 +55,7 @@ export type SdkEvent =
|
|
|
55
55
|
| { type: 'tool_result'; name: string; result: string; status: 'done' | 'error' }
|
|
56
56
|
| { type: 'subagent'; taskId: string; label: string; kind: 'tool_call' | 'tool_result'; name: string; args?: any; result?: string; status?: 'done' | 'error' }
|
|
57
57
|
| { type: 'done'; content: string }
|
|
58
|
-
| { type: '
|
|
58
|
+
| { type: 'data_change'; operation: 'set' | 'edit' | 'delete' | 'restore'; value?: unknown }
|
|
59
59
|
| { type: 'message_update'; count: number }
|
|
60
60
|
| { type: 'conflict'; conflict: PendingConflict }
|
|
61
61
|
| { type: 'error'; message: string };
|
|
@@ -80,7 +80,7 @@ export interface ChatDialogProps {
|
|
|
80
80
|
|
|
81
81
|
export interface ToolInfo { name: string; description: string; schema?: unknown; source?: string }
|
|
82
82
|
export interface SkillInfo { name: string; description: string }
|
|
83
|
-
export interface
|
|
83
|
+
export interface DataInfo { description?: string; schema?: unknown }
|
|
84
84
|
export interface SubagentInfo {
|
|
85
85
|
enabled: boolean;
|
|
86
86
|
maxDepth: number;
|
|
@@ -108,7 +108,7 @@ export interface AgentInfo {
|
|
|
108
108
|
systemPrompt: string;
|
|
109
109
|
tools: ToolInfo[];
|
|
110
110
|
skills: SkillInfo[];
|
|
111
|
-
|
|
111
|
+
data?: DataInfo;
|
|
112
112
|
memory: string;
|
|
113
113
|
middleware: string[];
|
|
114
114
|
todos: { content: string; status: string }[];
|
|
@@ -149,45 +149,49 @@ export type ChatModelLike = {
|
|
|
149
149
|
bindTools: (tools: any[]) => any;
|
|
150
150
|
};
|
|
151
151
|
|
|
152
|
-
export interface
|
|
153
|
-
/**
|
|
154
|
-
path: string;
|
|
155
|
-
description: string;
|
|
156
|
-
/** 值的 zod schema(写入时校验) */
|
|
152
|
+
export interface DataConfig {
|
|
153
|
+
/** 值的 zod schema(写入时校验);字段的 .describe() 自动提取注入 systemPrompt「可操作数据」段 */
|
|
157
154
|
schema: any;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
155
|
+
/** 数据源:reactive/普通对象,工具直接读写 bind(reactive 写后响应式刷新;不挂 window) */
|
|
156
|
+
bind: any;
|
|
157
|
+
/** 数据说明,供 Agent 理解用途;不传则自动生成 */
|
|
158
|
+
description?: string;
|
|
159
|
+
}
|
|
160
|
+
/** createDataOps 选项(审计回调 / 快照上限 / 乐观锁) */
|
|
161
|
+
export interface DataOpsOptions {
|
|
162
|
+
onAudit?: (entry: { op: string; value?: any; detail?: string; timestamp: number }) => void;
|
|
163
163
|
maxSnapshots?: number;
|
|
164
|
-
/**
|
|
165
|
-
* 字段白名单读模式(默认 true):仅允许读「注册 path 自身 / 其后代」,禁止读未注册的祖先,
|
|
166
|
-
* 防止 LLM 经 get_data_slot('page') 把整个大 JSON 拉进上下文。
|
|
167
|
-
* 集成方注册「可操作子路径」(如 page.theme.color / page.components)而非顶层时,默认即「LLM 只见声明字段」。
|
|
168
|
-
* 设 false 回退原行为(允许读注册 path 的祖先,即整体读)。
|
|
169
|
-
*/
|
|
170
|
-
whitelist?: boolean;
|
|
171
164
|
/** 乐观锁冲突人工介入回调(详见 ConflictInfo/ConflictResolution);不传则冲突时返回 VERSION_CONFLICT 错误 */
|
|
172
165
|
onConflict?: (conflict: ConflictInfo) => Promise<ConflictResolution>;
|
|
173
166
|
/**
|
|
174
|
-
* 自动乐观锁(默认 true):写入时若 LLM 未显式传 expectedHash,自动用「LLM 最后一次
|
|
167
|
+
* 自动乐观锁(默认 true):写入时若 LLM 未显式传 expectedHash,自动用「LLM 最后一次 read/get 读到的 hash」作基准比对。
|
|
175
168
|
* LLM 无需手动传 expectedHash 即可享受乐观锁保护;冲突走 onConflict(无 onConflict 则返回 VERSION_CONFLICT)。
|
|
176
169
|
* LLM 未读过直接写(无基准记录)时跳过锁(等同不校验)。设 false 回退「不传 expectedHash = 不校验」的旧行为。
|
|
177
170
|
*/
|
|
178
171
|
autoLock?: boolean;
|
|
172
|
+
/** 读写拦截器:read/write 透传给数据工具(脱敏/转换/审计/拒绝 LLM 读写) */
|
|
173
|
+
interceptors?: DataInterceptors;
|
|
179
174
|
}
|
|
180
175
|
|
|
181
|
-
/**
|
|
182
|
-
export interface
|
|
183
|
-
/**
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
176
|
+
/** 数据读写拦截器(集成方可脱敏/转换/审计/拒绝 LLM 的读写) */
|
|
177
|
+
export interface DataInterceptors {
|
|
178
|
+
/** LLM 读时拦截:原始值 → 改写后返回给 LLM(如脱敏/派生);抛错则返回 READ_INTERCEPT 错误 */
|
|
179
|
+
read?: (value: any) => any;
|
|
180
|
+
/** LLM 写时拦截:欲写值 + 当前值 → 改写后的值,或 { error } 拒绝;抛错则拒绝 */
|
|
181
|
+
write?: (payload: any, current: any) => any | { error: string };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** 工具呈现模式:simple=主推 read/write 但保留高级能力(默认)| advanced=全暴露| minimal=只 read/write */
|
|
185
|
+
export type ToolMode = 'simple' | 'advanced' | 'minimal';
|
|
186
|
+
|
|
187
|
+
/** 数据操作控制器(运行时替换配置;createDataOps 返回的工具数组上以不可枚举属性 `controller` 挂载) */
|
|
188
|
+
export interface DataOpsController {
|
|
189
|
+
/** 读取当前配置 */
|
|
190
|
+
get(): DataConfig;
|
|
191
|
+
/** 替换主数据配置(如页面切换、schema 变更);清空快照栈与乐观锁缓存 */
|
|
192
|
+
set(config: DataConfig): void;
|
|
193
|
+
/** 仅替换 bind 引用;清空快照栈与乐观锁缓存 */
|
|
194
|
+
update(bind: any): void;
|
|
191
195
|
}
|
|
192
196
|
|
|
193
197
|
export interface PermissionRule {
|
|
@@ -225,7 +229,7 @@ export interface VerifyMiddlewareOptions {
|
|
|
225
229
|
}
|
|
226
230
|
/** createWriteBackCheck 选项 */
|
|
227
231
|
export interface WriteBackCheckOptions {
|
|
228
|
-
/**
|
|
232
|
+
/** name → zod schema(由 createChatSdk 从 data 构造注入,键 '' 代表主数据);省略则只校验「读回非空」 */
|
|
229
233
|
schemas?: Record<string, any>;
|
|
230
234
|
/** 读 window 的根对象(默认 globalThis.window) */
|
|
231
235
|
window?: unknown;
|
|
@@ -333,15 +337,26 @@ export interface ChatSdkOptions {
|
|
|
333
337
|
tools?: any[];
|
|
334
338
|
skills?: SkillSpec[];
|
|
335
339
|
memory?: string;
|
|
336
|
-
|
|
340
|
+
data?: DataConfig;
|
|
337
341
|
permissions?: PermissionRule[];
|
|
338
342
|
/** 自定义中间件(注入到内置中间件之后;可拦截/观察模型调用、工具、prompt) */
|
|
339
343
|
middleware?: any[];
|
|
340
344
|
vfs?: { initialFiles?: Record<string, string>; maxBytes?: number };
|
|
341
|
-
/**
|
|
345
|
+
/** 每个数据对象最多保留快照数(默认 20) */
|
|
342
346
|
maxSnapshots?: number;
|
|
343
347
|
/** 自动乐观锁(默认 true):写入时若 LLM 未传 expectedHash,自动用其最后 get 读到的 hash 比对;设 false 回退「不传 = 不校验」 */
|
|
344
348
|
autoLock?: boolean;
|
|
349
|
+
/** 工具呈现模式:simple(默认,主推 read/write 但保留 query/search/eval/snapshot)| advanced(全暴露)| minimal(只 read/write) */
|
|
350
|
+
toolMode?: 'simple' | 'advanced' | 'minimal';
|
|
351
|
+
/** 读写拦截器:read/write 透传给数据工具(脱敏/转换/审计/拒绝 LLM 读写);input/output 在 agent IO 入口/出口预处理 */
|
|
352
|
+
interceptors?: {
|
|
353
|
+
read?: (value: any) => any;
|
|
354
|
+
write?: (payload: any, current: any) => any | { error: string };
|
|
355
|
+
/** agent 接收输入时拦截:send/stream 的 user message 预处理(可改写/审计) */
|
|
356
|
+
input?: (input: any) => any;
|
|
357
|
+
/** agent 产出输出时拦截:返回前 postprocess(可改写最终回复) */
|
|
358
|
+
output?: (json: any) => any;
|
|
359
|
+
};
|
|
345
360
|
/** 内存中保留的对话轮数上限(默认 50);超限把最旧轮次压缩为摘要 system 消息(防 OOM);0 关闭 */
|
|
346
361
|
maxMemoryRounds?: number;
|
|
347
362
|
debug?: boolean;
|
|
@@ -355,7 +370,7 @@ export interface ChatSdkOptions {
|
|
|
355
370
|
/** 模型最大输出(token);顶层声明对 llm 实例场景也生效,缺省按 model 名查表 */
|
|
356
371
|
maxOutputTokens?: number;
|
|
357
372
|
/** 子 agent 委派(默认开启;{ enabled: false } 关闭) */
|
|
358
|
-
capabilities?: {
|
|
373
|
+
capabilities?: { dataOps?: boolean; fetch?: boolean; planning?: boolean; skills?: boolean; vfs?: boolean; summarization?: boolean; memory?: boolean; subagent?: boolean; verify?: boolean };
|
|
359
374
|
subagent?: { enabled?: boolean; allowedTools?: string[]; systemPrompt?: string; temperature?: number; maxTokens?: number; skills?: SkillSpec[]; llm?: LLMConfig | ChatModelLike; maxDepth?: number; maxParallel?: number };
|
|
360
375
|
/** 预声明子 agent 列表:每个用同主配置方式声明,自动生成 use_<id> 委派工具(与 spawn_agent 共存) */
|
|
361
376
|
subagents?: SubagentConfig[];
|
|
@@ -399,30 +414,27 @@ export interface ChatSdk {
|
|
|
399
414
|
send(message: string): Promise<string>;
|
|
400
415
|
switchSession(sessionId?: string): Promise<string>;
|
|
401
416
|
stream: (messages: AgentMessage[], onEvent: StreamHandler, signal?: AbortSignal) => Promise<string>;
|
|
402
|
-
/** 检视 agent 详细信息(tools/skills/
|
|
417
|
+
/** 检视 agent 详细信息(tools/skills/data/middleware/todos) */
|
|
403
418
|
inspect(): AgentInfo;
|
|
404
|
-
/** 回退到最近一次正常 checkpoint(整体还原对话历史 +
|
|
419
|
+
/** 回退到最近一次正常 checkpoint(整体还原对话历史 + 主数据 + vfs + todos);需开启 checkpoint,无可用返回 false */
|
|
405
420
|
restoreLastCheckpoint(): boolean;
|
|
406
421
|
/** 列出可用 checkpoint(回退点);需开启 checkpoint,未开启返回空数组 */
|
|
407
422
|
listCheckpoints(): CheckpointMeta[];
|
|
408
423
|
/** 运行时订阅 SDK 事件(可多个监听器,返回取消函数);与构造时 onEvent 互补 */
|
|
409
424
|
hook(handler: SdkEventHandler): () => void;
|
|
410
|
-
/**
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
|
|
414
|
-
/** 列出当前所有已注册 数据槽(反映动态增删后的最新状态) */
|
|
415
|
-
listDataSlots(): DataSlotSpec[];
|
|
425
|
+
/** 运行时替换主数据配置(如页面切换、schema 变更);立即对数据工具生效,无需重建 agent。需开启 dataOps */
|
|
426
|
+
setData(config: DataConfig): void;
|
|
427
|
+
/** 读取当前主数据配置;dataOps 关闭时返回 undefined */
|
|
428
|
+
getData(): DataConfig | undefined;
|
|
416
429
|
/** 乐观锁冲突挂起状态(响应式 ref;无冲突为 null,有冲突时 UI 据此渲染冲突对话框)。headless 集成方可 watch 自建 UI */
|
|
417
430
|
pendingConflict: Ref<PendingConflict | null>;
|
|
418
431
|
/** 冲突解决:用户点「保留外部」(keep_external)/「强制覆盖」(overwrite)/「回退」(restore) → 收口挂起的 conflict,被挂起的工具调用继续 */
|
|
419
432
|
resolveConflict(action: ConflictResolution['action']): void;
|
|
420
433
|
}
|
|
421
434
|
|
|
422
|
-
/** 乐观锁冲突挂起(
|
|
435
|
+
/** 乐观锁冲突挂起(dataOps 写入时 expectedHash 不匹配,挂起等用户决定) */
|
|
423
436
|
export interface PendingConflict {
|
|
424
437
|
id: number;
|
|
425
|
-
path: string;
|
|
426
438
|
op: 'set' | 'edit' | 'delete';
|
|
427
439
|
agentValue?: unknown;
|
|
428
440
|
currentValue: unknown;
|
|
@@ -438,9 +450,8 @@ export type ConflictResolution =
|
|
|
438
450
|
| { action: 'overwrite' }
|
|
439
451
|
| { action: 'restore' };
|
|
440
452
|
|
|
441
|
-
/** 乐观锁冲突信息(
|
|
453
|
+
/** 乐观锁冲突信息(dataOps onConflict 回调参数) */
|
|
442
454
|
export interface ConflictInfo {
|
|
443
|
-
path: string;
|
|
444
455
|
op: 'set' | 'edit' | 'delete';
|
|
445
456
|
agentValue?: unknown;
|
|
446
457
|
currentValue: unknown;
|
|
@@ -456,12 +467,13 @@ export declare function defineTool(opts: {
|
|
|
456
467
|
schema: any;
|
|
457
468
|
handler: (args: any) => unknown | Promise<unknown>;
|
|
458
469
|
}): any;
|
|
459
|
-
export declare function
|
|
460
|
-
export declare function
|
|
461
|
-
export declare function
|
|
470
|
+
export declare function createDataOps(config: DataConfig, opts?: DataOpsOptions): any[];
|
|
471
|
+
export declare function filterByToolMode(tools: any[], mode?: 'simple' | 'advanced' | 'minimal'): any[];
|
|
472
|
+
export declare function selectBuiltinTools(caps: { dataOps?: boolean; fetch?: boolean } | undefined, dataOps: any[], fetchDocs: any[]): any[];
|
|
473
|
+
export declare function createUsageHintsMiddleware(caps: { planning?: boolean; dataOps?: boolean; subagent?: boolean } | undefined, hasDataOps: boolean, toolMode?: 'simple' | 'advanced' | 'minimal'): any;
|
|
462
474
|
export declare const fetchDocTools: any[];
|
|
463
475
|
export declare const fetchTools: any[];
|
|
464
|
-
export declare function
|
|
476
|
+
export declare function defineDataToolset(config: DataConfig, opts?: DataOpsOptions): any[];
|
|
465
477
|
export declare function defineSkill(spec: SkillSpec): SkillSpec;
|
|
466
478
|
export declare function createAgent(options: any): any;
|
|
467
479
|
/** 检测模型把工具调用写成文本(伪 XML/标签)而非标准 tool_calls 的异常格式;主循环据此回灌 feedback 自纠 */
|
|
@@ -475,6 +487,8 @@ export declare const systemPromptHelpers: {
|
|
|
475
487
|
/** 可靠写入规则:改前先读、动态先 list、字段以 describe 为准、写错看校验错误重试、优先增量 patch */
|
|
476
488
|
readonly reliableWriteRules: string;
|
|
477
489
|
};
|
|
490
|
+
/** 从 zod schema 提取字段说明(io 契约注入 systemPrompt 用);非 object schema 用 description 兜底 */
|
|
491
|
+
export declare function extractSchemaHint(schema: any): string;
|
|
478
492
|
export declare function createSessionStore(config?: StorageConfig): SessionStore;
|
|
479
493
|
export declare function createMemoryBackend(): StorageBackend;
|
|
480
494
|
export declare function createWebStorageBackend(storage: Storage): StorageBackend;
|
|
@@ -560,10 +574,10 @@ export declare function createSubagentsMiddleware(opts: any): any;
|
|
|
560
574
|
export interface SubagentOptions { [k: string]: any }
|
|
561
575
|
export interface SubagentLlmConfig { [k: string]: any }
|
|
562
576
|
|
|
563
|
-
// checkpoint /
|
|
577
|
+
// checkpoint / dataOps / permissions
|
|
564
578
|
export interface CheckpointDeps { [k: string]: any }
|
|
565
|
-
export interface
|
|
566
|
-
export interface
|
|
579
|
+
export interface DataAuditEntry { [k: string]: any }
|
|
580
|
+
export interface DataSnapshotEntry { [k: string]: any }
|
|
567
581
|
export type PermissionOp = string;
|
|
568
582
|
|
|
569
583
|
// vfs
|