page-agent-sdk 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -3
- package/README.zh-CN.md +39 -3
- package/dist/page-agent-sdk.iife.js +92 -92
- package/dist/page-agent-sdk.js +999 -891
- package/dist/page-agent-sdk.umd.cjs +40 -40
- package/package.json +1 -1
- package/skills/page-agent-sdk-integrate/references/api.md +8 -0
- package/skills/page-agent-sdk-integrate/references/options.md +9 -0
- package/skills/page-agent-sdk-integrate/references/use-cases.md +32 -0
- package/types/index.d.ts +36 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "page-agent-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
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",
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
| `hook(handler)` | `(h: SdkEventHandler) => () => void` | Runtime event subscription (multi-listener, returns unsubscribe). Complements `onEvent`. |
|
|
15
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
16
|
| `getData()` | `() => DataConfig \| undefined` | Read current main data config (reflects runtime `setData`). `undefined` if `dataOps` disabled. |
|
|
17
|
+
| `exportData()` | `() => any` | Deep copy of main data `bind` (backup/migration). `null` if dataOps off / no data. |
|
|
18
|
+
| `importData(json, opts?)` | `(json, opts?: { validate?: boolean; emit?: boolean }) => { ok: boolean; error?: string }` | Replace `bind` entirely (in-place, preserves reactive ref). Schema-validated by default; `opts.validate:false` skips; `opts.emit:false` suppresses `data_change`. |
|
|
19
|
+
| `setSkills(skills)` | `(skills: SkillSpec[]) => void` | Runtime swap the entire skill list (same-name skill overwrites). Takes effect next round: the skill index section of the system prompt re-renders with the new skills; clears the skill full-text cache & in-round loaded set, so the next `load_skill` re-fetches the latest full text (incl. vfs doc). Requires skills enabled (default on). |
|
|
20
|
+
| `invalidateSkillCache(name?)` | `(name?: string) => void` | Invalidate the skill full-text cache (proactive invalidation when a dynamic skill's content changes). Omit `name` to clear all; pass `name` to clear one. The next `load_skill` re-runs `getContent`/`readSkillDoc`. Requires skills enabled (default on). |
|
|
21
|
+
| `usage` | `TokenUsage` | Cumulative token usage `{prompt_tokens, completion_tokens, total_tokens}` (accumulated per LLM call). |
|
|
17
22
|
| `restoreLastCheckpoint()` | `() => boolean` | Restore last good checkpoint (needs `checkpoint` enabled). |
|
|
18
23
|
| `listCheckpoints()` | `() => CheckpointMeta[]` | List available checkpoints. |
|
|
19
24
|
|
|
@@ -121,6 +126,8 @@ Example: `write({ value: 9.9, patch: { op: 'set', jsonPath: 'items.0.price' } })
|
|
|
121
126
|
| `tool_result` | `name, result, status` | Tool returns (`status`: `done`/`error`) |
|
|
122
127
|
| `subagent` | `taskId, label, kind, name, args?, result?, status?` | Subagent tool progress (forwarded to UI, NOT into main LLM context) |
|
|
123
128
|
| `done` | `content` | Agent round completes |
|
|
129
|
+
| `usage` | `round, usage, cumulative` | After each LLM call (if provider returns usage); `usage`/`cumulative` are `{prompt_tokens, completion_tokens, total_tokens}` |
|
|
130
|
+
| `session_restored` | `sessionId, rounds` | After storage restores a session snapshot (mount auto-resume / `switchSession` to existing session) |
|
|
124
131
|
| `data_change` | `operation, value?` | Main data was written via `write` (infers `set`/`edit`/`delete` from args) or low-level `set`/`edit`/`delete`/`restore_data` |
|
|
125
132
|
| `message_update` | `count` | The `messages` array changed |
|
|
126
133
|
| `error` | `message` | An error occurred (abort excluded) |
|
|
@@ -152,6 +159,7 @@ createChatSdk({
|
|
|
152
159
|
- **`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.
|
|
153
160
|
- **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.
|
|
154
161
|
- **Runtime swap**: `sdk.setData({ schema, bind, description? })` replaces the whole config; tools pick up immediately (no rebuild). Snapshots & lock hash reset.
|
|
162
|
+
- **Runtime skill swap**: `sdk.setSkills(skills)` replaces the entire skill list (same-name overwrites); the skill index section of the system prompt re-renders next round, and the skill full-text cache is cleared so the next `load_skill` re-fetches the latest content (incl. vfs doc). Use `sdk.invalidateSkillCache(name?)` to proactively invalidate the cache when a dynamic skill's content changes (without swapping the whole list).
|
|
155
163
|
|
|
156
164
|
## Exported building blocks (for custom UIs)
|
|
157
165
|
|
|
@@ -120,9 +120,18 @@ Full reference for `createChatSdk(options)`. Grouped by purpose. Required: `llm`
|
|
|
120
120
|
| Option | Type | Default | Purpose / when |
|
|
121
121
|
|---|---|---|---|
|
|
122
122
|
| `onEvent` | `(e: SdkEvent) => void` | — | Constructor-time event subscription (single). Replaces polling for host-page reactivity. See [api.md](api.md) for event types. |
|
|
123
|
+
| `onAudit` | `(entry) => void` | — | Structured audit callback for data writes (independent of `debug`). Fires on every `set`/`edit`/`delete`/`restore` with `{op, jsonPath, opDetail, timestamp, success, error?}`. For compliance audit / operation tracing. |
|
|
123
124
|
|
|
124
125
|
Runtime subscription via `sdk.hook(handler) => () => void` (multi-listener, cancellable) — see [api.md](api.md).
|
|
125
126
|
|
|
127
|
+
## Convenience APIs (export / import / usage)
|
|
128
|
+
|
|
129
|
+
| API | Purpose | Notes |
|
|
130
|
+
|---|---|---|
|
|
131
|
+
| `sdk.exportData()` | Deep copy of main data `bind` (backup/migration) | Returns `null` if dataOps off / no data; mutating return does not affect original bind |
|
|
132
|
+
| `sdk.importData(json, opts?)` | Replace `bind` entirely (in-place, preserves reactive ref) | Schema-validated by default → `{ok:false,error}` if invalid; `opts.validate:false` skips; `opts.emit:false` suppresses `data_change` |
|
|
133
|
+
| `sdk.usage` | Cumulative token usage `{prompt_tokens, completion_tokens, total_tokens}` | Accumulated per LLM call; per-round detail via `onEvent('usage')` |
|
|
134
|
+
|
|
126
135
|
## vfs (in-memory workspace)
|
|
127
136
|
|
|
128
137
|
`vfs: { initialFiles?, maxBytes? }` — `maxBytes` default 4MB; LRU-evicts oldest files on overflow. Tool results > 6000 chars auto-offload to vfs (only preview + `vfs_read`/`vfs_grep` reference kept). Disabling `capabilities.vfs` degrades to truncation.
|
|
@@ -233,3 +233,35 @@ sdk.getData() // read current config (reflects runtime swap)
|
|
|
233
233
|
|
|
234
234
|
**完整可运行示例**:`examples/dynamic-demo/`(`npm run dev` → `/examples/dynamic-demo/`)。
|
|
235
235
|
**何时用**:可视化编辑器/低代码平台中,组件按需加载且结构各异(图表/表单/卡片 schema 各不同),无法在初始化时确定唯一 schema。详见 `advanced.md` §0。
|
|
236
|
+
|
|
237
|
+
## 11. Dynamic skills (swap / invalidate at runtime)
|
|
238
|
+
|
|
239
|
+
When the skill set changes at runtime (different business stages load different skill docs; lazy-loaded skill modules; a skill's content gets updated), swap the whole skill list or invalidate the cache on demand — the system-prompt skill index re-renders next round and `load_skill` re-fetches the latest full text (incl. vfs doc).
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const sdk = createChatSdk({
|
|
243
|
+
container: '#chat', llm: { ... },
|
|
244
|
+
skills: [
|
|
245
|
+
{ name: 'stage1', description: '阶段一:建表', getContent: () => STAGE1_DOC },
|
|
246
|
+
],
|
|
247
|
+
}).mount()
|
|
248
|
+
|
|
249
|
+
// later: business stage changes → swap the whole skill list (same-name overwrites)
|
|
250
|
+
function onStageChange(stage: 'stage2' | 'stage3') {
|
|
251
|
+
sdk.setSkills([
|
|
252
|
+
{ name: stage, description: `阶段:${stage}`, getContent: () => STAGE_DOCS[stage] },
|
|
253
|
+
])
|
|
254
|
+
// system-prompt skill index re-renders next round; load_skill re-fetches full text (cache cleared)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// or: a skill's content changed but the list stays → proactively invalidate that skill's cache
|
|
258
|
+
function onSkillContentUpdate(name: string) {
|
|
259
|
+
sdk.invalidateSkillCache(name) // next load_skill re-runs getContent / readSkillDoc
|
|
260
|
+
// sdk.invalidateSkillCache() // omit name to clear all
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
sdk.inspect().skills // reflects runtime swap (reads controller.get())
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**何时用**:多阶段业务流程(各阶段 skill 文档不同)、运行时按权限/角色加载不同 skill、skill 文档热更新(vfs doc 内容变化需主动失效缓存)。skills 关闭(`capabilities.skills:false`)时 `setSkills`/`invalidateSkillCache` 输出 warn 并 no-op,不抛错。
|
|
267
|
+
|
package/types/index.d.ts
CHANGED
|
@@ -58,8 +58,17 @@ export type SdkEvent =
|
|
|
58
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
|
+
| { type: 'session_restored'; sessionId: string; rounds: number }
|
|
62
|
+
| { type: 'usage'; round: number; usage: TokenUsage; cumulative: TokenUsage }
|
|
61
63
|
| { type: 'error'; message: string };
|
|
62
64
|
|
|
65
|
+
/** token 用量(OpenAI 协议字段名) */
|
|
66
|
+
export interface TokenUsage {
|
|
67
|
+
prompt_tokens?: number;
|
|
68
|
+
completion_tokens?: number;
|
|
69
|
+
total_tokens?: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
export type SdkEventHandler = (event: SdkEvent) => void;
|
|
64
73
|
|
|
65
74
|
/** 调试日志(与 harness/createAgent 的 DebugLog 一致) */
|
|
@@ -194,6 +203,15 @@ export interface DataOpsController {
|
|
|
194
203
|
update(bind: any): void;
|
|
195
204
|
}
|
|
196
205
|
|
|
206
|
+
export interface SkillsController {
|
|
207
|
+
/** 运行时替换整个 skill 列表(同名 skill 覆盖更新;清缓存) */
|
|
208
|
+
set(skills: SkillSpec[]): void;
|
|
209
|
+
/** 读取当前 skill 列表(反映运行时 setSkills 替换) */
|
|
210
|
+
get(): SkillSpec[];
|
|
211
|
+
/** 清指定 skill 的全文缓存(不传清全部);下次 load_skill 重新取最新 */
|
|
212
|
+
invalidateCache(name?: string): void;
|
|
213
|
+
}
|
|
214
|
+
|
|
197
215
|
export interface PermissionRule {
|
|
198
216
|
operations: ('read' | 'write')[];
|
|
199
217
|
scopes: string[];
|
|
@@ -354,6 +372,8 @@ export interface ChatSdkOptions {
|
|
|
354
372
|
maxSnapshots?: number;
|
|
355
373
|
/** 自动乐观锁(默认 true):写入时若 LLM 未传 expectedHash,自动用其最后 get 读到的 hash 比对;设 false 回退「不传 = 不校验」 */
|
|
356
374
|
autoLock?: boolean;
|
|
375
|
+
/** 数据操作审计回调:每次 set/edit/delete/restore 经此回调外发结构化事件(独立于 debug,无需 debug:true);集成方做合规审计/操作追溯 */
|
|
376
|
+
onAudit?: (entry: { op: string; jsonPath?: string; opDetail?: string; timestamp: number; success: boolean; error?: string }) => void;
|
|
357
377
|
/** 工具呈现模式:simple(默认,主推 read/write 但保留 query/search/eval/snapshot)| advanced(全暴露)| minimal(只 read/write) */
|
|
358
378
|
toolMode?: 'simple' | 'advanced' | 'minimal';
|
|
359
379
|
/** 读写拦截器:read/write 透传给数据工具(脱敏/转换/审计/拒绝 LLM 读写);input/output 在 agent IO 入口/出口预处理 */
|
|
@@ -434,6 +454,22 @@ export interface ChatSdk {
|
|
|
434
454
|
setData(config: DataConfig): void;
|
|
435
455
|
/** 读取当前主数据配置;dataOps 关闭时返回 undefined */
|
|
436
456
|
getData(): DataConfig | undefined;
|
|
457
|
+
/**
|
|
458
|
+
* 运行时替换整个 skill 列表(同名 skill 覆盖更新)。立即生效:system prompt 的 skill 索引段下轮重渲染反映新 skill;
|
|
459
|
+
* 清空 skill 全文缓存与本轮已加载记录,下次 load_skill 重新取最新全文(含 vfs doc)。需开启 skills(默认开)
|
|
460
|
+
*/
|
|
461
|
+
setSkills(skills: SkillSpec[]): void;
|
|
462
|
+
/**
|
|
463
|
+
* 清 skill 全文缓存(动态 skill 内容变化时主动失效)。不传 name 清全部;传 name 清指定。
|
|
464
|
+
* 下次 load_skill 重新 getContent/readSkillDoc 取最新。需开启 skills(默认开)
|
|
465
|
+
*/
|
|
466
|
+
invalidateSkillCache(name?: string): void;
|
|
467
|
+
/** 导出主数据 bind 的深拷贝(备份/迁移用);dataOps 关闭或无 data 返回 null */
|
|
468
|
+
exportData(): any;
|
|
469
|
+
/** 导入数据整体替换主数据 bind(就地还原,保留 reactive 引用);默认经 schema 校验,不合法返回 {ok:false,error};opts.validate:false 跳过校验,opts.emit:false 不发 data_change */
|
|
470
|
+
importData(json: any, opts?: { validate?: boolean; emit?: boolean }): { ok: boolean; error?: string };
|
|
471
|
+
/** 累计 token 用量(每轮 LLM 调用累加;prompt/completion/total_tokens)。无调用时为 0 */
|
|
472
|
+
usage: TokenUsage;
|
|
437
473
|
/** 乐观锁冲突挂起状态(响应式 ref;无冲突为 null,有冲突时 UI 据此渲染冲突对话框)。headless 集成方可 watch 自建 UI */
|
|
438
474
|
pendingConflict: Ref<PendingConflict | null>;
|
|
439
475
|
/** 冲突解决:用户点「保留外部」(keep_external)/「强制覆盖」(overwrite)/「回退」(restore) → 收口挂起的 conflict,被挂起的工具调用继续 */
|