page-agent-sdk 2.18.1 → 2.20.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "page-agent-sdk",
3
- "version": "2.18.1",
3
+ "version": "2.20.0",
4
4
  "type": "module",
5
5
  "description": "AI agent SDK for web pages — embed a chat assistant that edits page data via schema-validated tools. A lighter, framework-agnostic alternative to CopilotKit/LangChain for in-page JSON-editing agents. Vue-bundled; works with DeepSeek, OpenAI, MCP.",
6
6
  "main": "./dist/page-agent-sdk.umd.cjs",
@@ -52,7 +52,9 @@
52
52
  "test:types": "tsc --noEmit -p tsconfig.test.json",
53
53
  "test:size": "node tests/size-check.mjs",
54
54
  "test:browser": "playwright test",
55
- "test:browser:ui": "playwright test --ui"
55
+ "test:browser:ui": "playwright test --ui",
56
+ "test:draft-real": "tsx tests/runtime/draft-real-llm.ts",
57
+ "test:trace-real": "tsx tests/runtime/trace-real-llm.ts"
56
58
  },
57
59
  "keywords": [
58
60
  "ai",
package/types/index.d.ts CHANGED
@@ -75,7 +75,8 @@ export type SdkEvent =
75
75
  | { type: 'conflict'; conflict: PendingConflict }
76
76
  | { type: 'session_restored'; sessionId: string; rounds: number }
77
77
  | { type: 'usage'; round: number; usage: TokenUsage; cumulative: TokenUsage }
78
- | { type: 'error'; message: string; severity?: 'recoverable' | 'fatal' | 'observable'; code?: string; context?: unknown };
78
+ | { type: 'error'; message: string; severity?: 'recoverable' | 'fatal' | 'observable'; code?: string; context?: unknown }
79
+ | { type: 'trace'; spans: TraceSpan[]; metrics: TraceMetrics };
79
80
 
80
81
  /** token 用量(OpenAI 协议字段名) */
81
82
  export interface TokenUsage {
@@ -83,6 +84,26 @@ export interface TokenUsage {
83
84
  completion_tokens?: number;
84
85
  total_tokens?: number;
85
86
  }
87
+ /** 批处理单任务结果(sdk.batch 返回;ok=true 含 reply,ok=false 含 error) */
88
+ export interface BatchResult {
89
+ /** 任务在入参数组中的下标 */
90
+ index: number;
91
+ /** 任务文本 */
92
+ task: string;
93
+ /** 成功时的 agent 回复 */
94
+ reply?: string;
95
+ /** 失败时的错误信息 */
96
+ error?: string;
97
+ /** 是否成功 */
98
+ ok: boolean;
99
+ }
100
+ /** 批处理进度回调 payload(sdk.batch 的 onProgress 每任务完成调一次) */
101
+ export interface BatchProgress {
102
+ done: number;
103
+ total: number;
104
+ task: string;
105
+ ok: boolean;
106
+ }
86
107
 
87
108
  export type SdkEventHandler = (event: SdkEvent) => void;
88
109
 
@@ -158,6 +179,8 @@ export interface AgentInfo {
158
179
  };
159
180
  /** 会话级 checkpoint 装载状态(未开启 → undefined) */
160
181
  checkpoints?: { enabled: boolean; auto: boolean; list: CheckpointMeta[] };
182
+ /** 结构化追踪(revive-observability-tracing;capabilities.tracing 开时填充,否则 undefined) */
183
+ trace?: { spans: TraceSpan[]; metrics: TraceMetrics };
161
184
  }
162
185
  export interface McpServerConfig { transport: 'http' | 'sse' | 'websocket'; url: string; name?: string; requestInit?: any; }
163
186
 
@@ -313,11 +336,21 @@ export interface CheckpointMeta {
313
336
  timestamp: number;
314
337
  messageCount: number;
315
338
  }
339
+ export interface Checkpoint extends CheckpointMeta {
340
+ messages: AgentMessage[];
341
+ windowVals: Record<string, unknown>;
342
+ vfs: Record<string, { content: string; mimeType?: string; updatedAt: number }>;
343
+ todos: { id: string; content: string; status: 'pending' | 'in_progress' | 'completed' }[];
344
+ }
316
345
  export interface CheckpointManager {
317
346
  save(label?: string): number;
318
347
  list(): CheckpointMeta[];
319
348
  restore(id?: number): boolean;
320
349
  canRestore(): boolean;
350
+ /** 导出栈快照(深拷贝,可序列化;供 automation 断点续跑持久化,刷新/崩溃后恢复 restoreLastCheckpoint 能力) */
351
+ exportStack(): Checkpoint[];
352
+ /** 灌入栈快照(刷新/崩溃恢复时重建 checkpoint 栈;重置 nextId 防后续 save id 冲突) */
353
+ importStack(cps: unknown[]): void;
321
354
  }
322
355
  export declare function createCheckpointManager(deps: any): CheckpointManager;
323
356
  export declare function createCheckpointMiddleware(mgr: CheckpointManager): any;
@@ -355,6 +388,10 @@ export interface SessionSnapshot {
355
388
  vfs: Record<string, { content: string; mimeType?: string; updatedAt: number }>;
356
389
  todos: { id: string; content: string; status: 'pending' | 'in_progress' | 'completed' }[];
357
390
  memory: string;
391
+ /** automation 断点续跑:checkpoint 栈快照(刷新/崩溃后恢复 restoreLastCheckpoint 能力);仅 capabilities.automation 开启时写入 */
392
+ checkpoints?: unknown[];
393
+ /** automation 断点续跑:累计 token usage(刷新后续跑预算统计连续) */
394
+ usage?: TokenUsage;
358
395
  }
359
396
  export type StorageEvent =
360
397
  | { type: 'degraded'; reason: string }
@@ -470,6 +507,12 @@ export interface ChatSdkOptions {
470
507
  maxPlanRevisions?: number;
471
508
  /** 模型调用失败自动重试次数(默认 2;网络/429/5xx 重试,4xx 与 abort 不重试) */
472
509
  maxRetries?: number;
510
+ /** token 预算上限(累计 total_tokens 超过 → 停止 agent + emit BUDGET_EXCEEDED;需 capabilities.automation:true) */
511
+ tokenBudget?: number;
512
+ /** 时间预算 ms(从 agent 开始计时,超过 → 停止;需 capabilities.automation:true) */
513
+ timeBudgetMs?: number;
514
+ /** 无人值守错误恢复:致命错误(invoke 抛错)自动 restore_last_checkpoint + 重试次数(默认 1;防单点错误永久中断批量/长任务)。需 capabilities.automation:true */
515
+ maxAutoRetries?: number;
473
516
  /** 同轮工具并发上限(默认 1 串行) */
474
517
  maxParallelTools?: number;
475
518
  /** 模型上下文窗口(token);顶层声明对 llm 实例场景也生效,缺省按 model 名查表。影响 offload 阈值与压缩触发 */
@@ -477,7 +520,7 @@ export interface ChatSdkOptions {
477
520
  /** 模型最大输出(token);顶层声明对 llm 实例场景也生效,缺省按 model 名查表 */
478
521
  maxOutputTokens?: number;
479
522
  /** 子 agent 委派(默认开启;{ enabled: false } 关闭) */
480
- capabilities?: { dataOps?: boolean; fetch?: boolean; planning?: boolean; missionAnchor?: boolean; skills?: boolean; vfs?: boolean; summarization?: boolean; memory?: boolean; subagent?: boolean; verify?: boolean; domInspect?: boolean; workingMemory?: boolean };
523
+ capabilities?: { dataOps?: boolean; fetch?: boolean; planning?: boolean; missionAnchor?: boolean; skills?: boolean; vfs?: boolean; summarization?: boolean; memory?: boolean; subagent?: boolean; verify?: boolean; domInspect?: boolean; inspectEnv?: boolean; draftWrite?: boolean; tracing?: boolean; todoDeps?: boolean; automation?: boolean; workingMemory?: boolean };
481
524
  subagent?: { enabled?: boolean; allowedTools?: string[]; systemPrompt?: string; temperature?: number; maxTokens?: number; skills?: SkillSpec[]; llm?: LLMConfig | ChatModelLike; maxDepth?: number; maxParallel?: number };
482
525
  /** 预声明子 agent 列表:每个用同主配置方式声明,自动生成 use_<id> 委派工具(与 spawn_agent 共存) */
483
526
  subagents?: SubagentConfig[];
@@ -568,6 +611,12 @@ export interface ChatSdk {
568
611
  restoreLastCheckpoint(): boolean;
569
612
  /** 列出可用 checkpoint(回退点);需开启 checkpoint,未开启返回空数组 */
570
613
  listCheckpoints(): CheckpointMeta[];
614
+ /**
615
+ * 批处理(automation):逐任务跑 agent,每任务前自动 checkpoint,任务间错误隔离(单任务失败记 error 不中断整批)。
616
+ * 适合无人值守批量操作(批量生成/改一批页面)。不经 UI 排队(直接 invoke);返回每个任务结果(成功 reply / 失败 error)。
617
+ * 配合 capabilities.automation + checkpoint 使用。
618
+ */
619
+ batch(tasks: string[], onProgress?: (p: BatchProgress) => void): Promise<BatchResult[]>;
571
620
  /** 运行时订阅 SDK 事件(可多个监听器,返回取消函数);与构造时 onEvent 互补 */
572
621
  hook(handler: SdkEventHandler): () => void;
573
622
  /** 运行时替换主数据配置(如页面切换、schema 变更);立即对数据工具生效,无需重建 agent。需开启 dataOps */
@@ -669,6 +718,36 @@ export declare function defineTool(opts: {
669
718
  }): any;
670
719
  export declare function createDataOps(config: DataConfig, opts?: DataOpsOptions): any[];
671
720
  export declare function filterByToolMode(tools: any[], mode?: 'simple' | 'advanced' | 'minimal'): any[];
721
+ /** 整体 set 写入纯函数:schema 校验 + 快照 + merge/替换 + audit。set_data / write(set) / draft_commit 共用。返回 {ok,hash,data} 或 {ok:false,error} */
722
+ export declare function commitSetToBind(args: { bindRef: unknown; value: unknown; schema: any; allowKeys: string[] | null; snapshots: any[]; maxSnapshots: number; audit: (e: any) => void; dryRun?: boolean; op?: 'set' | 'draft_commit' }): { ok: true; hash: string; data: unknown } | { ok: false; error: string };
723
+ /** 结构化追踪 span(revive-observability-tracing Phase 3) */
724
+ export type SpanType = 'round' | 'model' | 'tool' | 'compression';
725
+ export type SpanStatus = 'ok' | 'error' | 'timeout';
726
+ export interface TraceSpan {
727
+ id: string;
728
+ parentId?: string;
729
+ name: string;
730
+ type: SpanType;
731
+ startTs: number;
732
+ endTs?: number;
733
+ durationMs?: number;
734
+ status: SpanStatus;
735
+ attributes: Record<string, unknown>;
736
+ }
737
+ export interface TraceMetrics {
738
+ rounds: number;
739
+ totalDurationMs: number;
740
+ avgRoundMs: number;
741
+ toolCalls: number;
742
+ toolFailures: number;
743
+ toolSuccessRate: number;
744
+ modelCalls: number;
745
+ retries: number;
746
+ compressions: number;
747
+ totalTokens?: { prompt: number; completion: number; total: number };
748
+ }
749
+ /** 从 TraceSpan[] 聚合 metrics(纯函数:轮次/延迟/工具成功率/重试/压缩/token) */
750
+ export declare function getTraceMetrics(spans: TraceSpan[]): TraceMetrics;
672
751
  // ============ 通用 JSON 操作纯函数(jsonUtils,refactor-module-extraction 从 dataOps 抽离;零依赖,经 ./query subpath 按需引入)============
673
752
  export type EditOp = 'set' | 'remove' | 'merge' | 'append';
674
753
  export declare const UNSAFE_KEYS: Set<string>;
@@ -753,12 +832,20 @@ export interface SdkEvents {
753
832
  hook(handler: (e: any) => void): () => void;
754
833
  }
755
834
  export declare function createSdkEvents(onEvent?: (e: any) => void): SdkEvents;
756
- export declare function selectBuiltinTools(caps: { dataOps?: boolean; fetch?: boolean; domInspect?: boolean } | undefined, dataOps: any[], fetchDocs: any[], dom?: any[]): any[];
835
+ export declare function selectBuiltinTools(caps: { dataOps?: boolean; fetch?: boolean; domInspect?: boolean; inspectEnv?: boolean } | undefined, dataOps: any[], fetchDocs: any[], dom?: any[], inspect?: any[]): any[];
757
836
  export declare function createUsageHintsMiddleware(caps: { planning?: boolean; dataOps?: boolean; subagent?: boolean } | undefined, hasDataOps: boolean, toolMode?: 'simple' | 'advanced' | 'minimal'): any;
758
837
  export declare const fetchDocTools: any[];
759
838
  /** DOM 读取工具 get_dom(随 capabilities.domInspect 装配,opt-in) */
760
839
  export declare const domTools: any[];
761
840
  export declare const domToolsStatic: any[];
841
+ /** 环境探查工具 inspect_env(随 capabilities.inspectEnv 默认装配,默认开;排查 window/location/调试变量) */
842
+ export declare const inspectTools: any[];
843
+ /** 单个 inspect_env 工具(inspectTools 数组的元素) */
844
+ export declare const inspectEnvTool: any;
845
+ /** 纯函数:安全序列化任意值(跳过 function/DOM,防循环引用,截断)—— inspect_env 读 window[key] 时用 */
846
+ export declare function safeSerialize(value: unknown, depth?: number, maxLen?: number, seen?: WeakSet<object>): unknown;
847
+ /** 环境摘要(location/navigator/viewport/document);inspect_env 无参时返回,可传 win 注入测试 */
848
+ export declare function getEnvSummary(win?: Window & typeof globalThis): Record<string, unknown>;
762
849
  export declare const getDomTool: any;
763
850
  /** 纯函数:DOM Element → 结构化 DomNode(可单测,与浏览器解耦) */
764
851
  export declare function domToStructure(node: Element | null, opts: { depth: number; attrs?: string[]; includeText?: boolean }): DomNode | null;