@webskill/sdk 0.11.0 → 0.13.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.
Files changed (33) hide show
  1. package/dist/agent.d.ts +3 -3
  2. package/dist/agent.js +3 -3
  3. package/dist/browser.d.ts +29 -6
  4. package/dist/browser.js +629 -75
  5. package/dist/{catalogComponents-BFoqpT1v-CjUBZ3bc.js → catalogComponents-BgAJN0p8-CYEXSk45.js} +606 -926
  6. package/dist/{dist-DTHZS2k1.js → dist-DqcL6jKO.js} +155 -39
  7. package/dist/{dist-B-cOu08W.js → dist-ExSQky4C.js} +754 -69
  8. package/dist/{dist-qnlI2Iup.js → dist-GK6dtjRv.js} +222 -9
  9. package/dist/{echarts-DhNm2ene.js → echarts-De78wXqV.js} +599 -61
  10. package/dist/governance.d.ts +3 -3
  11. package/dist/{index-DACk2_XZ.d.ts → index-C3XdItd_.d.ts} +92 -8
  12. package/dist/{index-D3mONFHD.d.ts → index-DkvBhJQy.d.ts} +187 -6
  13. package/dist/{index-DWbs58LF.d.ts → index-iBm9tJL_.d.ts} +122 -23
  14. package/dist/index.d.ts +4 -4
  15. package/dist/index.js +3 -3
  16. package/dist/mcp.d.ts +47 -3
  17. package/dist/mcp.js +79 -2
  18. package/dist/node.d.ts +3 -3
  19. package/dist/node.js +9 -3
  20. package/dist/{openUiLibrary-D5u8oIvx-BLOAQCho.js → openUiLibrary-BKXW7Iwx-CWWBVOkE.js} +3 -3
  21. package/dist/processSandboxEntry.js +2 -1
  22. package/dist/sandboxWorkerEntry.js +2 -1
  23. package/dist/{skillVersionStore-D-qHk9ZE-BcmFLykd.d.ts → skillVersionStore-D-qHk9ZE-DheTIwAB.d.ts} +1 -1
  24. package/dist/testing.d.ts +1 -1
  25. package/dist/{types-C26b05fW-CdrRCRDb.d.ts → types-DLctJep_-B5G4uk2u.d.ts} +3 -2
  26. package/dist/ui-react.d.ts +13 -4
  27. package/dist/ui-react.js +77 -259
  28. package/dist/ui-vue.d.ts +1 -1
  29. package/dist/ui-vue.js +1 -1
  30. package/dist/ui.d.ts +4 -4
  31. package/dist/ui.js +3 -3
  32. package/dist/{webskillLitCatalog-DME6PBkV-CmYNLlIT.js → webskillLitCatalog-D_zCqeQF-C9lrvvMr.js} +2 -2
  33. package/package.json +2 -1
@@ -1,5 +1,5 @@
1
1
  import { M as messageOf, P as parseSkillMarkdown, g as assertRemoteUrlAllowed, h as WebSkillError, k as isValidSkillName } from "./dist-Bev6i6Ip.js";
2
- import { f as DEFAULT_MAX_DATA_SOURCE_BYTES } from "./dist-B-cOu08W.js";
2
+ import { f as DEFAULT_MAX_DATA_SOURCE_BYTES } from "./dist-ExSQky4C.js";
3
3
 
4
4
  //#region ../agent/dist/index.js
5
5
  const STATUSES = [
@@ -108,7 +108,7 @@ const TODO_SYSTEM_PROMPT = [
108
108
  "2. `update` an item to `in-progress` right before you start it, and to `completed` right after it succeeds.",
109
109
  "3. Only one item may be `in-progress`; the runtime demotes the others automatically, so never rely on marking several.",
110
110
  "4. Never mark an item `completed` before its work actually succeeded. If a step fails, keep it `in-progress` and explain.",
111
- "5. `clear` the list once the whole request is answered, or when the user abandons it.",
111
+ "5. Settle every remaining item first (rule 4 still applies), then `clear` the list once the whole request is answered, or when the user abandons it.",
112
112
  "",
113
113
  "Skip the list for single-step requests, plain questions and trivial lookups — it only adds noise there."
114
114
  ].join("\n");
@@ -259,6 +259,7 @@ function createTodoToolSource(options = {}) {
259
259
  inputSchema: INPUT_SCHEMA$4
260
260
  }]),
261
261
  canHandle: (name) => name === MANAGE_TODO_TOOL,
262
+ argCaptureTrust: (name) => name === "manage_todo" ? { tier: "reviewed" } : void 0,
262
263
  call
263
264
  };
264
265
  }
@@ -313,6 +314,69 @@ function previewOf(draft) {
313
314
  return sections.join("\n\n");
314
315
  }
315
316
  /**
317
+ * 工具名硬校(FR-30.4 / AC-30.8)。
318
+ *
319
+ * 只做**集合包含**:不比次数、不比顺序(AC-30.9),也不比参数(AC-30.10)。
320
+ * 模型把参数泛化成占位符是正常的技能写法,机械比对会把正确的技能判失败。
321
+ * 代价见需求 §7:工具名对、参数编得不对的情形本层拦不住,由确认卡兜底。
322
+ */
323
+ function assertStepsAreBackedByTrace(draft, records) {
324
+ const claimed = draft.steps ?? [];
325
+ if (claimed.length === 0) return;
326
+ const executed = new Set(records.map((r) => r.tool));
327
+ const unknown = [...new Set(claimed.map((s) => s.tool).filter((tool) => !executed.has(tool)))];
328
+ if (unknown.length === 0) return;
329
+ fail(`The skill claims tools that were never called in this session: ${unknown.join(", ")}. Tools actually called: ${executed.size === 0 ? "(none)" : [...executed].sort().join(", ")}. Rewrite the skill using only the tools above.`, {
330
+ claimed: unknown,
331
+ executed: [...executed].sort()
332
+ });
333
+ }
334
+ /**
335
+ * 超限步骤拒收(FR-30.2 / AC-30.3)。
336
+ *
337
+ * 留存超过体积上限时 `args` 是空的,只剩一个工具名。放它过去等于产出一个
338
+ * 「知道调了什么、不知道传了什么」的步骤——那比没有这一步更糟,因为它看起来是完整的。
339
+ * 同名工具只要还有一条没超限的记录就不算超限:那条记录足以说明参数长什么样。
340
+ */
341
+ function assertStepsAreNotTruncated(draft, records) {
342
+ const claimed = draft.steps ?? [];
343
+ if (claimed.length === 0) return;
344
+ const usable = new Set(records.filter((r) => r.truncated !== true).map((r) => r.tool));
345
+ const truncated = [...new Set(claimed.map((s) => s.tool).filter((tool) => !usable.has(tool)))];
346
+ if (truncated.length === 0) return;
347
+ fail(`The arguments of these tool calls were too large to record, so the skill cannot state them: ${truncated.join(", ")}. Rewrite the skill without these steps.`, { truncated });
348
+ }
349
+ /**
350
+ * 确认卡证据(AC-30.12 / AC-30.13):逐条列出模型**写进技能的**步骤,
351
+ * 并标注它是否有轨迹背书。轨迹里有而模型没写的步骤不出现在这里,
352
+ * 也不会被补进 `SKILL.md`——生成的是模型的技能,不是会话的录像(AC-30.11)。
353
+ *
354
+ * 校验通过后每一步都有背书,所以 `'model'` 只会出现在**轨迹读不到**时:
355
+ * 那种情况下不能把存储故障当成「模型在撞骗」而拦截,但必须在卡上说清楚
356
+ * 这些步骤一步都没背书,否则用户会把未校验的草稿当成已核实的。
357
+ */
358
+ function buildTraceEvidence(draft, records) {
359
+ const claimed = draft.steps ?? [];
360
+ if (claimed.length === 0) return void 0;
361
+ const byTool = /* @__PURE__ */ new Map();
362
+ for (const record of records ?? []) {
363
+ if (record.truncated === true || byTool.has(record.tool)) continue;
364
+ byTool.set(record.tool, record);
365
+ }
366
+ return { steps: claimed.map((step) => {
367
+ const record = byTool.get(step.tool);
368
+ return {
369
+ tool: step.tool,
370
+ evidence: record === void 0 ? "model" : "trace",
371
+ ...record !== void 0 ? {
372
+ traceArgs: record.args,
373
+ redacted: record.redacted
374
+ } : {},
375
+ ...step.args !== void 0 ? { draftArgs: step.args } : {}
376
+ };
377
+ }) };
378
+ }
379
+ /**
316
380
  * 技能自动生成策略。生成动作是策略而不是内核:它不进入 `AgentLoop`,
317
381
  * 而是经既有的 `ExternalToolSource` 扩展点接入(设计 02 §0)。
318
382
  *
@@ -337,18 +401,27 @@ var SkillGenerator = class {
337
401
  if (!sink) throw new WebSkillError("SKILL_GENERATION_DISABLED", "Skill generation is enabled but this host did not provide a candidate store");
338
402
  if (this.#used >= this.#maxPerSession) throw new WebSkillError("SKILL_GENERATION_LIMIT_EXCEEDED", `This session already generated ${this.#maxPerSession} skills, which is the configured limit`);
339
403
  validateDraft(draft);
404
+ const sessionId = this.#options.sessionId?.();
405
+ const trace = await this.#readSteps(sessionId);
406
+ if (trace.available && trace.records !== void 0) {
407
+ assertStepsAreBackedByTrace(draft, trace.records);
408
+ assertStepsAreNotTruncated(draft, trace.records);
409
+ }
340
410
  this.#used += 1;
411
+ const evidence = trace.available ? buildTraceEvidence(draft, trace.records) : void 0;
341
412
  this.#requestSeq += 1;
342
413
  const response = await this.#options.ui.request({
343
414
  type: "authorize",
344
415
  id: `skill-generation-${this.#requestSeq}`,
345
416
  capability: "confirm",
346
417
  message: this.#options.messages?.confirmSkill?.(draft) ?? defaultConfirmSkill(draft),
347
- details: { preview: previewOf(draft) }
418
+ details: {
419
+ preview: previewOf(draft),
420
+ ...evidence !== void 0 ? { traceEvidence: evidence } : {}
421
+ }
348
422
  });
349
423
  if (response.cancelled === true || response.value === false) return { status: "declined" };
350
424
  const confirmedAt = (this.#options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
351
- const sessionId = this.#options.sessionId?.();
352
425
  const { id } = await sink.submit({
353
426
  draft,
354
427
  confirmedAt,
@@ -360,6 +433,24 @@ var SkillGenerator = class {
360
433
  name: draft.name
361
434
  };
362
435
  }
436
+ /**
437
+ * 读不到轨迹(存储故障 / 没有会话号)时 `records` 为 `undefined`,含义是**不校验**,
438
+ * 而不是空数组(= 全部判失败):存储故障不该表现成「模型在撒谎」。
439
+ * 真正跑了零个工具的会话由 `[]` 表达,那种情况该拦就拦。
440
+ */
441
+ async #readSteps(sessionId) {
442
+ const reader = this.#options.steps;
443
+ if (reader === void 0) return { available: false };
444
+ if (sessionId === void 0) return { available: true };
445
+ try {
446
+ return {
447
+ available: true,
448
+ records: await reader.listBySession(sessionId)
449
+ };
450
+ } catch {
451
+ return { available: true };
452
+ }
453
+ }
363
454
  };
364
455
  /**
365
456
  * 技能自动生成的系统提示词。默认不注册工具,因此这段提示词只在
@@ -419,6 +510,25 @@ const INPUT_SCHEMA$3 = {
419
510
  required: ["path", "content"],
420
511
  additionalProperties: false
421
512
  }
513
+ },
514
+ steps: {
515
+ type: "array",
516
+ description: "The tool calls this skill performs, in the order the SKILL.md describes them",
517
+ items: {
518
+ type: "object",
519
+ properties: {
520
+ tool: {
521
+ type: "string",
522
+ description: "The exact tool name, as it appeared in this conversation"
523
+ },
524
+ args: {
525
+ type: "object",
526
+ description: "The arguments this step passes to the tool"
527
+ }
528
+ },
529
+ required: ["tool"],
530
+ additionalProperties: false
531
+ }
422
532
  }
423
533
  },
424
534
  required: [
@@ -441,11 +551,14 @@ function toolError$3(code, message) {
441
551
  function readDraft(args) {
442
552
  const { name, description, content } = args;
443
553
  if (typeof name !== "string" || typeof description !== "string" || typeof content !== "string") return "The \"name\", \"description\" and \"content\" arguments are required and must be strings";
554
+ const steps = readSteps(args["steps"]);
555
+ if (typeof steps === "string") return steps;
444
556
  const rawFiles = args["files"];
445
557
  if (rawFiles === void 0) return {
446
558
  name,
447
559
  description,
448
- content
560
+ content,
561
+ ...steps
449
562
  };
450
563
  if (!Array.isArray(rawFiles)) return "The \"files\" argument must be an array";
451
564
  const files = [];
@@ -462,9 +575,28 @@ function readDraft(args) {
462
575
  name,
463
576
  description,
464
577
  content,
465
- files
578
+ files,
579
+ ...steps
466
580
  };
467
581
  }
582
+ function readSteps(raw) {
583
+ if (raw === void 0) return {};
584
+ if (!Array.isArray(raw)) return "The \"steps\" argument must be an array";
585
+ const steps = [];
586
+ for (const entry of raw) {
587
+ if (typeof entry !== "object" || entry === null) return "Every entry in \"steps\" must be an object";
588
+ const record = entry;
589
+ const tool = record["tool"];
590
+ if (typeof tool !== "string" || tool.trim() === "") return "Every step needs a non-empty \"tool\" name";
591
+ const stepArgs = record["args"];
592
+ if (stepArgs !== void 0 && (typeof stepArgs !== "object" || stepArgs === null || Array.isArray(stepArgs))) return "A step's \"args\" must be an object";
593
+ steps.push({
594
+ tool,
595
+ ...stepArgs !== void 0 ? { args: stepArgs } : {}
596
+ });
597
+ }
598
+ return { steps };
599
+ }
468
600
  /**
469
601
  * 把技能自动生成接到既有的工具协议上(设计 02 §1.3)。
470
602
  *
@@ -511,6 +643,7 @@ function createSkillGenerationToolSource(options) {
511
643
  inputSchema: INPUT_SCHEMA$3
512
644
  }]),
513
645
  canHandle: (name) => name === GENERATE_SKILL_TOOL,
646
+ argCaptureTrust: (name) => name === "generate_skill" ? { tier: "reviewed" } : void 0,
514
647
  call
515
648
  };
516
649
  }
@@ -713,6 +846,7 @@ function createDelegationToolSource(options) {
713
846
  inputSchema: INPUT_SCHEMA$2
714
847
  }]),
715
848
  canHandle: (name) => name === DELEGATE_TASK_TOOL,
849
+ argCaptureTrust: (name) => name === "delegate_task" ? { tier: "reviewed" } : void 0,
716
850
  call
717
851
  };
718
852
  }
@@ -741,6 +875,30 @@ function withDelegationOrigin(bridge, origin) {
741
875
  };
742
876
  }
743
877
  /**
878
+ * 帧指称的展示形式(分册 18 FR-18.2)。
879
+ *
880
+ * 感知与操作两侧各自声明自己的 scope 类型(那是刻意的,见各自 types.ts),
881
+ * 但「一条帧路径写成给人看的字符串」只能有一份实现——
882
+ * 两处各写一遍,审计里的帧名和确认卡里的帧名就会慢慢对不上。
883
+ */
884
+ /**
885
+ * 帧路径的稳定展示串:`'self'` / `'#a'` / `'#a >>> #b'`。
886
+ *
887
+ * `>>>` **只是展示分隔符**:CSS 选择器里可以合法出现任意字符,
888
+ * 反向解析这个串取回路径是不成立的,实现层一律传原始形状(D-18-1)。
889
+ * @experimental
890
+ */
891
+ function frameLabel(frame) {
892
+ if (typeof frame === "string") return frame;
893
+ if (frame.length === 0) return "self";
894
+ return frame.join(" >>> ");
895
+ }
896
+ /** 把两种形状归一成逐层选择器数组;`'self'` 与空数组都归一成空数组 @experimental */
897
+ function frameSteps(frame) {
898
+ if (typeof frame === "string") return frame === "self" ? [] : [frame];
899
+ return frame;
900
+ }
901
+ /**
744
902
  * 两种形状归一成帧列表;旧形状等价于一条 `frame:'self'`(FR-24.1)。
745
903
  *
746
904
  * **这是判别的单一来源。** 散在各处写 `'frames' in scope` 会让
@@ -803,7 +961,7 @@ var PagePerceptionPolicy = class {
803
961
  at: this.#options.now?.() ?? (/* @__PURE__ */ new Date()).toISOString(),
804
962
  include: frames.flatMap((frame) => [...frame.include]),
805
963
  exclude: frames.flatMap((frame) => [...frame.exclude ?? []]),
806
- ...frames.length > 1 || frames[0]?.frame !== "self" ? { frames: frames.map((frame) => frame.frame) } : {},
964
+ ...frames.length > 1 || frames[0] !== void 0 && frameLabel(frames[0].frame) !== "self" ? { frames: frames.map((frame) => frameLabel(frame.frame)) } : {},
807
965
  nodeCount: nodes.length,
808
966
  ...capture?.images === true ? {
809
967
  images: {
@@ -894,13 +1052,15 @@ function createPagePerceptionToolSource(options) {
894
1052
  }] : []),
895
1053
  systemPrompt: () => Promise.resolve(policy.enabled ? PERCEPTION_SYSTEM_PROMPT : void 0),
896
1054
  canHandle: (name) => name === PERCEIVE_PAGE_TOOL,
1055
+ argCaptureTrust: (name) => name === "perceive_page" ? { tier: "reviewed" } : void 0,
897
1056
  call: async () => {
898
1057
  try {
899
1058
  const budget = await options.imageCapture?.();
900
1059
  const capture = {
901
1060
  images: budget?.enabled === true,
902
1061
  maxImageBytes: budget?.maxImageBytes ?? 0,
903
- maxImages: budget?.maxImages ?? 0
1062
+ maxImages: budget?.maxImages ?? 0,
1063
+ minImageArea: budget?.minImageArea ?? 0
904
1064
  };
905
1065
  const { nodes, images, imagesOmitted, record } = await policy.perceive(capture);
906
1066
  const data = {
@@ -1082,6 +1242,8 @@ const PAGE_ACTION_KINDS = [
1082
1242
  "attach"
1083
1243
  ];
1084
1244
  const declineReason = "Page action was declined by the user.";
1245
+ /** 目标记忆的上限;它在 `act()` 之后立刻就被读走,容量只为防无界增长 */
1246
+ const TARGET_MEMO_LIMIT = 200;
1085
1247
  /**
1086
1248
  * 页面操作策略(需求 23)。
1087
1249
  *
@@ -1093,6 +1255,7 @@ var PageActionPolicy = class {
1093
1255
  #options;
1094
1256
  #records = [];
1095
1257
  #seq = 0;
1258
+ #targetByRef = /* @__PURE__ */ new Map();
1096
1259
  constructor(options) {
1097
1260
  this.#options = options;
1098
1261
  }
@@ -1107,6 +1270,35 @@ var PageActionPolicy = class {
1107
1270
  get records() {
1108
1271
  return this.#records;
1109
1272
  }
1273
+ /**
1274
+ * 目标是不是密码类控件(分册 30)。与确认卡上把值打成掩码用的是**同一个判定**,
1275
+ * 不另立一套敏感字段清单。
1276
+ *
1277
+ * 读的是 `act()` 当时记下的结论而不是事后重查:提交或重绘后句柄会失效,
1278
+ * 重查就会把一次普通填写误判成敏感、把内容丢掉。没操作过的句柄才现查,
1279
+ * 查不到按敏感:不知道就别留存。
1280
+ */
1281
+ isSecretTarget(ref) {
1282
+ const remembered = this.#targetByRef.get(ref);
1283
+ if (remembered !== void 0) return remembered.secret === true;
1284
+ const target = this.#options.executor.describe(ref);
1285
+ return target === void 0 || target.secret === true;
1286
+ }
1287
+ /**
1288
+ * `act()` 当时看到的目标身份(分册 30)。句柄只在本次感知内有效,
1289
+ * 只留句柄等于留了一个换次运行就失效的引用;角色与可访问名才是可重放的那部分。
1290
+ */
1291
+ rememberedTarget(ref) {
1292
+ return this.#targetByRef.get(ref);
1293
+ }
1294
+ #rememberTarget(ref, target) {
1295
+ this.#targetByRef.delete(ref);
1296
+ this.#targetByRef.set(ref, target);
1297
+ if (this.#targetByRef.size > TARGET_MEMO_LIMIT) {
1298
+ const oldest = this.#targetByRef.keys().next();
1299
+ if (oldest.done !== true) this.#targetByRef.delete(oldest.value);
1300
+ }
1301
+ }
1110
1302
  async act(request) {
1111
1303
  if (!this.enabled) throw new WebSkillError("PAGE_ACTION_OUT_OF_SCOPE", "Page actions are not enabled: the host declared no actionable regions.");
1112
1304
  const target = this.#options.executor.describe(request.ref);
@@ -1120,6 +1312,7 @@ var PageActionPolicy = class {
1120
1312
  }, false);
1121
1313
  throw new WebSkillError("PAGE_ACTION_DECLINED", declineReason);
1122
1314
  }
1315
+ this.#rememberTarget(request.ref, target);
1123
1316
  const outcome = await this.#options.executor.execute(request);
1124
1317
  await this.#record(request, outcome, approved);
1125
1318
  return outcome;
@@ -1242,6 +1435,26 @@ function createPageActionToolSource(options) {
1242
1435
  }] : []),
1243
1436
  systemPrompt: () => Promise.resolve(policy.enabled ? PAGE_ACTION_SYSTEM_PROMPT : void 0),
1244
1437
  canHandle: (name) => name === PAGE_ACTION_TOOL,
1438
+ argCaptureTrust: (name, args) => {
1439
+ if (name !== "act_on_page") return void 0;
1440
+ const ref = args["ref"];
1441
+ if (typeof ref !== "string") return { tier: "untrusted" };
1442
+ return policy.isSecretTarget(ref) ? { tier: "untrusted" } : { tier: "reviewed" };
1443
+ },
1444
+ captureArgs: (name, args) => {
1445
+ if (name !== "act_on_page") return void 0;
1446
+ const ref = args["ref"];
1447
+ const target = typeof ref === "string" ? policy.rememberedTarget(ref) : void 0;
1448
+ if (target === void 0) return void 0;
1449
+ return {
1450
+ ...args,
1451
+ target: {
1452
+ role: target.role,
1453
+ ...target.name !== void 0 ? { name: target.name } : {},
1454
+ ...target.frame !== void 0 ? { frame: target.frame } : {}
1455
+ }
1456
+ };
1457
+ },
1245
1458
  call: async (_name, args) => {
1246
1459
  const ref = args["ref"];
1247
1460
  const action = args["action"];
@@ -1277,4 +1490,4 @@ function createPageActionToolSource(options) {
1277
1490
  }
1278
1491
 
1279
1492
  //#endregion
1280
- export { createTodoToolSource as C, withDelegationOrigin as E, createSkillGenerationToolSource as S, toFrameScopes as T, TodoStore as _, GENERATE_SKILL_TOOL as a, createPageActionToolSource as b, PAGE_ACTION_SYSTEM_PROMPT as c, PERCEPTION_SYSTEM_PROMPT as d, PageActionPolicy as f, TODO_SYSTEM_PROMPT as g, SkillGenerator as h, DelegationOrchestrator as i, PAGE_ACTION_TOOL as l, SKILL_GENERATION_SYSTEM_PROMPT as m, DELEGATION_SYSTEM_PROMPT as n, MANAGE_TODO_TOOL as o, PagePerceptionPolicy as p, DataSourcePolicy as r, PAGE_ACTION_KINDS as s, DELEGATE_TASK_TOOL as t, PERCEIVE_PAGE_TOOL as u, createDelegationToolSource as v, toActionFrameScopes as w, createPagePerceptionToolSource as x, createHttpDataSourceTransport as y };
1493
+ export { createTodoToolSource as C, toFrameScopes as D, toActionFrameScopes as E, withDelegationOrigin as O, createSkillGenerationToolSource as S, frameSteps as T, TodoStore as _, GENERATE_SKILL_TOOL as a, createPageActionToolSource as b, PAGE_ACTION_SYSTEM_PROMPT as c, PERCEPTION_SYSTEM_PROMPT as d, PageActionPolicy as f, TODO_SYSTEM_PROMPT as g, SkillGenerator as h, DelegationOrchestrator as i, PAGE_ACTION_TOOL as l, SKILL_GENERATION_SYSTEM_PROMPT as m, DELEGATION_SYSTEM_PROMPT as n, MANAGE_TODO_TOOL as o, PagePerceptionPolicy as p, DataSourcePolicy as r, PAGE_ACTION_KINDS as s, DELEGATE_TASK_TOOL as t, PERCEIVE_PAGE_TOOL as u, createDelegationToolSource as v, frameLabel as w, createPagePerceptionToolSource as x, createHttpDataSourceTransport as y };