@refrainai/cli 0.4.1 → 0.4.3

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 (83) hide show
  1. package/dist/{ai-model-FM6GWCID.js → ai-model-DP5PKGM6.js} +2 -2
  2. package/dist/{chunk-IGFCYKHC.js → chunk-5CKPPEYP.js} +262 -305
  3. package/dist/chunk-5CKPPEYP.js.map +1 -0
  4. package/dist/{chunk-7UCVPKD4.js → chunk-6FGCPMBU.js} +34 -74
  5. package/dist/chunk-6FGCPMBU.js.map +1 -0
  6. package/dist/{chunk-2BVDAJZT.js → chunk-A5X2VF5G.js} +9 -6
  7. package/dist/chunk-A5X2VF5G.js.map +1 -0
  8. package/dist/{chunk-H47NWH7N.js → chunk-AOCGSFRM.js} +611 -73
  9. package/dist/chunk-AOCGSFRM.js.map +1 -0
  10. package/dist/{chunk-CLYJHKPY.js → chunk-CMWLFQXD.js} +43 -42
  11. package/dist/chunk-CMWLFQXD.js.map +1 -0
  12. package/dist/chunk-GC7I5SGK.js +1146 -0
  13. package/dist/chunk-GC7I5SGK.js.map +1 -0
  14. package/dist/{chunk-WEYR56ZN.js → chunk-HHRHHFSK.js} +4 -4
  15. package/dist/chunk-IGJNT457.js +30 -0
  16. package/dist/chunk-IGJNT457.js.map +1 -0
  17. package/dist/{chunk-UGPXCQY3.js → chunk-KFNW4XR2.js} +13 -4
  18. package/dist/chunk-KFNW4XR2.js.map +1 -0
  19. package/dist/{chunk-RT664YIO.js → chunk-LZDZGI4M.js} +3 -1
  20. package/dist/chunk-LZDZGI4M.js.map +1 -0
  21. package/dist/{chunk-RYIJPYM3.js → chunk-MYITSQYV.js} +25 -8
  22. package/dist/chunk-MYITSQYV.js.map +1 -0
  23. package/dist/chunk-NRKZJVPE.js +74 -0
  24. package/dist/chunk-NRKZJVPE.js.map +1 -0
  25. package/dist/chunk-RBZK7T76.js +349 -0
  26. package/dist/chunk-RBZK7T76.js.map +1 -0
  27. package/dist/{chunk-HQDXLWAY.js → chunk-SDV3X5UN.js} +2 -2
  28. package/dist/{chunk-Z33FCOTZ.js → chunk-VVXNFUPL.js} +4 -2
  29. package/dist/chunk-VVXNFUPL.js.map +1 -0
  30. package/dist/chunk-YTVEYQGA.js +64 -0
  31. package/dist/chunk-YTVEYQGA.js.map +1 -0
  32. package/dist/{chunk-DJVUITRB.js → chunk-ZEBQWBEU.js} +898 -1135
  33. package/dist/chunk-ZEBQWBEU.js.map +1 -0
  34. package/dist/cli.js +5 -5
  35. package/dist/{compose-MTSIJY5D.js → compose-AVX5RU67.js} +9 -7
  36. package/dist/{compose-MTSIJY5D.js.map → compose-AVX5RU67.js.map} +1 -1
  37. package/dist/extraction-prompt-VDCKIFLB.js +17 -0
  38. package/dist/extraction-prompt-VDCKIFLB.js.map +1 -0
  39. package/dist/{fix-runbook-ZSBOTLC2.js → fix-runbook-6L5ZMA5G.js} +12 -10
  40. package/dist/{fix-runbook-ZSBOTLC2.js.map → fix-runbook-6L5ZMA5G.js.map} +1 -1
  41. package/dist/prompts-AGUYYIOM.js +13 -0
  42. package/dist/runbook-builder-2ZLE2AEO.js +11 -0
  43. package/dist/{runbook-data-helpers-KRR2SH76.js → runbook-data-helpers-5UAO65TZ.js} +3 -3
  44. package/dist/{runbook-executor-K7T6RJWJ.js → runbook-executor-OJXJTN6A.js} +41 -444
  45. package/dist/runbook-executor-OJXJTN6A.js.map +1 -0
  46. package/dist/{runbook-generator-MPXJBQ5N.js → runbook-generator-UIHWBEYC.js} +61 -136
  47. package/dist/runbook-generator-UIHWBEYC.js.map +1 -0
  48. package/dist/{runbook-schema-3T6TP3JJ.js → runbook-schema-X7DW725O.js} +2 -2
  49. package/dist/runbook-store-S24PXIHD.js +11 -0
  50. package/dist/{schema-5G6UQSPT.js → schema-XFSD5EWN.js} +2 -2
  51. package/dist/{server-AG3LXQBI.js → server-MULT5ZWG.js} +1176 -128
  52. package/dist/server-MULT5ZWG.js.map +1 -0
  53. package/dist/{tenant-ai-config-QPFEJUVJ.js → tenant-ai-config-4NHKRW7O.js} +4 -4
  54. package/dist/tenant-ai-config-4NHKRW7O.js.map +1 -0
  55. package/dist/yaml-patcher-GOCLYKZZ.js +18 -0
  56. package/dist/yaml-patcher-GOCLYKZZ.js.map +1 -0
  57. package/package.json +3 -2
  58. package/dist/chunk-2BVDAJZT.js.map +0 -1
  59. package/dist/chunk-7UCVPKD4.js.map +0 -1
  60. package/dist/chunk-CLYJHKPY.js.map +0 -1
  61. package/dist/chunk-DJVUITRB.js.map +0 -1
  62. package/dist/chunk-H47NWH7N.js.map +0 -1
  63. package/dist/chunk-IGFCYKHC.js.map +0 -1
  64. package/dist/chunk-RT664YIO.js.map +0 -1
  65. package/dist/chunk-RYIJPYM3.js.map +0 -1
  66. package/dist/chunk-UGPXCQY3.js.map +0 -1
  67. package/dist/chunk-VPK2MQAZ.js +0 -589
  68. package/dist/chunk-VPK2MQAZ.js.map +0 -1
  69. package/dist/chunk-Z33FCOTZ.js.map +0 -1
  70. package/dist/runbook-executor-K7T6RJWJ.js.map +0 -1
  71. package/dist/runbook-generator-MPXJBQ5N.js.map +0 -1
  72. package/dist/runbook-store-G5GUOWRR.js +0 -11
  73. package/dist/server-AG3LXQBI.js.map +0 -1
  74. package/dist/yaml-patcher-VGUS2JGH.js +0 -15
  75. /package/dist/{ai-model-FM6GWCID.js.map → ai-model-DP5PKGM6.js.map} +0 -0
  76. /package/dist/{chunk-WEYR56ZN.js.map → chunk-HHRHHFSK.js.map} +0 -0
  77. /package/dist/{chunk-HQDXLWAY.js.map → chunk-SDV3X5UN.js.map} +0 -0
  78. /package/dist/{runbook-data-helpers-KRR2SH76.js.map → prompts-AGUYYIOM.js.map} +0 -0
  79. /package/dist/{runbook-schema-3T6TP3JJ.js.map → runbook-builder-2ZLE2AEO.js.map} +0 -0
  80. /package/dist/{runbook-store-G5GUOWRR.js.map → runbook-data-helpers-5UAO65TZ.js.map} +0 -0
  81. /package/dist/{schema-5G6UQSPT.js.map → runbook-schema-X7DW725O.js.map} +0 -0
  82. /package/dist/{tenant-ai-config-QPFEJUVJ.js.map → runbook-store-S24PXIHD.js.map} +0 -0
  83. /package/dist/{yaml-patcher-VGUS2JGH.js.map → schema-XFSD5EWN.js.map} +0 -0
@@ -5,18 +5,29 @@ import {
5
5
  InMemoryDataStore,
6
6
  classifyFailure,
7
7
  createDebugLogger,
8
- createReviewUserPrompt,
9
- findElementInSnapshot,
8
+ formatAiMetricsSection,
9
+ formatDebugLogSections,
10
10
  formatDuration,
11
- getAgentInstructions,
12
- getInitialUserMessage,
13
- getReviewSystemPrompt,
11
+ formatFailureCategoryDistribution,
12
+ formatPerformanceBottlenecks,
13
+ formatRuntimeEnvironment,
14
14
  noopLogger,
15
- parseAllElements,
16
15
  parseAndAppendToMemory,
16
+ readDebugLog,
17
+ renderOptionsMarkdown,
17
18
  sanitizeBrowserError,
18
19
  sleep
19
- } from "./chunk-DJVUITRB.js";
20
+ } from "./chunk-ZEBQWBEU.js";
21
+ import {
22
+ log,
23
+ promptSelect,
24
+ promptText
25
+ } from "./chunk-NRKZJVPE.js";
26
+ import {
27
+ getModel,
28
+ trackedGenerateObject,
29
+ trackedGenerateText
30
+ } from "./chunk-KFNW4XR2.js";
20
31
  import {
21
32
  filterSnapshot
22
33
  } from "./chunk-XMFCXPYU.js";
@@ -24,22 +35,22 @@ import {
24
35
  createSkills,
25
36
  initBuiltinSkills
26
37
  } from "./chunk-AG3CFMYU.js";
38
+ import {
39
+ buildSelector
40
+ } from "./chunk-RBZK7T76.js";
41
+ import {
42
+ findElementInSnapshot,
43
+ parseAllElements
44
+ } from "./chunk-YTVEYQGA.js";
45
+ import {
46
+ getAgentInstructions,
47
+ getInitialUserMessage
48
+ } from "./chunk-GC7I5SGK.js";
27
49
  import {
28
50
  getLocale,
29
- log,
30
- promptSelect,
31
- promptText,
32
51
  t,
33
52
  tf
34
- } from "./chunk-7UCVPKD4.js";
35
- import {
36
- getModel,
37
- trackedGenerateObject,
38
- trackedGenerateText
39
- } from "./chunk-UGPXCQY3.js";
40
- import {
41
- ParsedRunbookSchema
42
- } from "./chunk-RT664YIO.js";
53
+ } from "./chunk-6FGCPMBU.js";
43
54
 
44
55
  // src/runbook-generator/exploration-agent.ts
45
56
  import { stepCountIs } from "ai";
@@ -49,53 +60,6 @@ import { z as z2 } from "zod";
49
60
  import { tool } from "ai";
50
61
  import { z } from "zod";
51
62
 
52
- // src/browser/selector-builder.ts
53
- var ROLE_TAG_MAP = {
54
- textbox: { tagName: "input", inputType: "text" },
55
- button: { tagName: "button", role: "button" },
56
- link: { tagName: "a", role: "link" },
57
- checkbox: { tagName: "input", inputType: "checkbox" },
58
- radio: { tagName: "input", inputType: "radio" },
59
- combobox: { tagName: "select", role: "combobox" },
60
- searchbox: { tagName: "input", inputType: "search" },
61
- slider: { tagName: "input", inputType: "range" },
62
- spinbutton: { tagName: "input", inputType: "number" },
63
- switch: { tagName: "input", inputType: "checkbox", role: "switch" },
64
- tab: { tagName: "button", role: "tab" },
65
- menuitem: { tagName: "button", role: "menuitem" },
66
- option: { tagName: "option", role: "option" },
67
- heading: { tagName: "h2", role: "heading" },
68
- img: { tagName: "img", role: "img" },
69
- navigation: { tagName: "nav", role: "navigation" },
70
- listitem: { tagName: "li", role: "listitem" }
71
- };
72
- function buildSelector(element) {
73
- const mapping = ROLE_TAG_MAP[element.role];
74
- const tagName = mapping?.tagName ?? element.role;
75
- const selector = { tagName };
76
- if (mapping?.role) {
77
- selector.role = mapping.role;
78
- } else if (element.role !== tagName) {
79
- selector.role = element.role;
80
- }
81
- if (mapping?.inputType) {
82
- selector.inputType = mapping.inputType;
83
- }
84
- if (element.name) {
85
- selector.ariaLabel = element.name;
86
- if (element.role === "button" || element.role === "link") {
87
- selector.innerText = element.name.slice(0, 200);
88
- }
89
- }
90
- if (element.attributes.placeholder) {
91
- selector.placeholder = element.attributes.placeholder;
92
- }
93
- if (element.attributes.name) {
94
- selector.name = element.attributes.name;
95
- }
96
- return selector;
97
- }
98
-
99
63
  // src/harness/loop-detector.ts
100
64
  function stepHash(step) {
101
65
  const urlPath = extractPath(step.url);
@@ -583,11 +547,16 @@ ${finalSnapshot2}`;
583
547
  data: { extractPrompt: action.extractPrompt.slice(0, 200) }
584
548
  });
585
549
  const snapshot = await browser.snapshot();
586
- const { getModel: getModel2, trackedGenerateObject: trackedGenerateObject2 } = await import("./ai-model-FM6GWCID.js");
550
+ const { getModel: getModel2, trackedGenerateObject: trackedGenerateObject2 } = await import("./ai-model-DP5PKGM6.js");
551
+ const { EXTRACT_SYSTEM_PROMPT } = await import("./extraction-prompt-VDCKIFLB.js");
587
552
  const extractSchema = z.object({ data: z.string() });
588
553
  const aiResult = await trackedGenerateObject2("extraction", {
589
554
  model: getModel2("extraction"),
590
- prompt: `${action.extractPrompt}
555
+ system: EXTRACT_SYSTEM_PROMPT,
556
+ prompt: `${action.extractPrompt}${config.goal ? `
557
+
558
+ \u62BD\u51FA\u306E\u76EE\u6A19:
559
+ ${config.goal}` : ""}
591
560
 
592
561
  \u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8:
593
562
  ${snapshot}`,
@@ -1108,7 +1077,8 @@ async function exploreWithAI(browser, recordedSteps, config, dataStore, download
1108
1077
  paginationTracker,
1109
1078
  onToolCallStart: config.onToolCallStart,
1110
1079
  onToolCallEnd: config.onToolCallEnd,
1111
- skills: config.skills
1080
+ skills: config.skills,
1081
+ goal: config.goal
1112
1082
  };
1113
1083
  const browserTool = createBrowserTool(browser, recordedSteps, toolConfig, dataStore, downloadManager);
1114
1084
  const totalMaxSteps = config.maxIterations * 3;
@@ -1471,7 +1441,7 @@ var InterventionController = class {
1471
1441
  if (data[0] === 113 || data[0] === 3) {
1472
1442
  if (!this.cancelRequested) {
1473
1443
  this.cancelRequested = true;
1474
- log.warn("\u23F9 \u30AD\u30E3\u30F3\u30BB\u30EB\u3092\u8981\u6C42\u3057\u307E\u3057\u305F...");
1444
+ log.warn(t("generator.interventionCancelRequested"));
1475
1445
  this.options.onCancel?.();
1476
1446
  }
1477
1447
  return;
@@ -1479,7 +1449,7 @@ var InterventionController = class {
1479
1449
  if (data[0] === 13 || data[0] === 112) {
1480
1450
  if (!this.pauseRequested) {
1481
1451
  this.pauseRequested = true;
1482
- log.warn("\u23F8 \u4E00\u6642\u505C\u6B62\u3092\u8981\u6C42\u3057\u307E\u3057\u305F\u3002\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3067\u505C\u6B62\u3057\u307E\u3059...");
1452
+ log.warn(t("generator.interventionPauseRequested"));
1483
1453
  }
1484
1454
  }
1485
1455
  };
@@ -1516,24 +1486,24 @@ var InterventionController = class {
1516
1486
  this.options.onPause?.();
1517
1487
  try {
1518
1488
  log.info(
1519
- `--- \u4E00\u6642\u505C\u6B62 (\u30B9\u30C6\u30C3\u30D7 #${currentStepIndex}, URL: ${currentUrl}) ---`
1489
+ tf("generator.interventionPauseHeader", { stepIndex: currentStepIndex, url: currentUrl })
1520
1490
  );
1521
1491
  const action = await promptSelect(
1522
- "\u64CD\u4F5C\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044",
1492
+ t("generator.interventionSelectAction"),
1523
1493
  [
1524
1494
  {
1525
1495
  value: "guidance",
1526
- label: "\u30AC\u30A4\u30C0\u30F3\u30B9\u3092\u5165\u529B\u3057\u3066\u7D9A\u884C",
1527
- hint: "AI\u306E\u63A2\u7D22\u65B9\u91DD\u3092\u4FEE\u6B63"
1496
+ label: t("generator.interventionSelectGuidance"),
1497
+ hint: t("generator.interventionSelectGuidanceHint")
1528
1498
  },
1529
- { value: "abort", label: "\u63A2\u7D22\u3092\u4E2D\u6B62" }
1499
+ { value: "abort", label: t("generator.interventionSelectAbort") }
1530
1500
  ]
1531
1501
  );
1532
1502
  if (action === "abort") {
1533
1503
  return { action: "abort" };
1534
1504
  }
1535
- const guidanceText = await promptText("\u30AC\u30A4\u30C0\u30F3\u30B9 (AI\u3078\u306E\u6307\u793A)", {
1536
- validate: (v) => !v?.trim() ? "\u30AC\u30A4\u30C0\u30F3\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044" : void 0
1505
+ const guidanceText = await promptText(t("generator.interventionGuidancePrompt"), {
1506
+ validate: (v) => !v?.trim() ? t("generator.interventionGuidanceRequired") : void 0
1537
1507
  });
1538
1508
  const record = {
1539
1509
  stepIndex: currentStepIndex,
@@ -1542,7 +1512,7 @@ var InterventionController = class {
1542
1512
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1543
1513
  };
1544
1514
  this.interventions.push(record);
1545
- log.success(`\u30AC\u30A4\u30C0\u30F3\u30B9\u3092\u8A18\u9332\u3057\u307E\u3057\u305F: "${guidanceText.trim()}"`);
1515
+ log.success(tf("generator.interventionGuidanceRecorded", { text: guidanceText.trim() }));
1546
1516
  return { action: "guidance", guidanceText: guidanceText.trim() };
1547
1517
  } finally {
1548
1518
  this.pauseRequested = false;
@@ -1635,6 +1605,7 @@ async function explore(config, options) {
1635
1605
  const maxSteps = config.maxIterations * 3;
1636
1606
  log.step(t("generator.waitingForAI"));
1637
1607
  interventionController.startListening();
1608
+ let lastReportedStepCount = 0;
1638
1609
  const agentStart = performance.now();
1639
1610
  const result = await exploreWithAI(browser, recordedSteps, {
1640
1611
  goal: config.goal,
@@ -1655,15 +1626,17 @@ async function explore(config, options) {
1655
1626
  log.step(tf("generator.exploringStep", { current: stepCount + 1, total: maxSteps }));
1656
1627
  },
1657
1628
  onToolCallEnd: () => {
1658
- const lastStep = recordedSteps[recordedSteps.length - 1];
1659
- if (lastStep && options?.onExplorerStep) {
1629
+ if (!options?.onExplorerStep) return;
1630
+ const newSteps = recordedSteps.slice(lastReportedStepCount);
1631
+ for (const step of newSteps) {
1660
1632
  options.onExplorerStep(
1661
- recordedSteps.length,
1662
- lastStep.action.description ?? lastStep.action.action,
1663
- lastStep
1633
+ step.ordinal + 1,
1634
+ step.action.description ?? step.action.action,
1635
+ step
1664
1636
  ).catch(() => {
1665
1637
  });
1666
1638
  }
1639
+ lastReportedStepCount = recordedSteps.length;
1667
1640
  }
1668
1641
  }, dataStore, downloadManager);
1669
1642
  interventionController.dispose();
@@ -1735,240 +1708,224 @@ async function explore(config, options) {
1735
1708
  }
1736
1709
  }
1737
1710
 
1738
- // src/runbook-generator/runbook-builder.ts
1739
- import { stringify } from "yaml";
1740
- function toActionType(action) {
1741
- switch (action) {
1742
- case "fill":
1743
- case "type":
1744
- return "input";
1745
- case "check":
1746
- case "uncheck":
1747
- case "click":
1748
- return "click";
1749
- case "select":
1750
- return "select";
1751
- case "navigate":
1752
- return "navigate";
1753
- case "scroll":
1754
- return "scroll";
1755
- case "wait":
1756
- return "wait";
1757
- case "extract":
1758
- return "extract";
1759
- case "download":
1760
- return "download";
1761
- case "export":
1762
- return "export";
1763
- case "memory_append":
1764
- case "memory_aggregate":
1765
- return "memory";
1766
- case "key":
1767
- return "key";
1768
- default:
1769
- return "click";
1711
+ // src/runbook-generator/report-generator.ts
1712
+ function formatOutcome(outcome) {
1713
+ switch (outcome) {
1714
+ case "cancelled":
1715
+ return "Cancelled by user";
1716
+ case "goal_achieved":
1717
+ return "Goal achieved";
1718
+ case "goal_not_achieved":
1719
+ return "Goal not achieved";
1720
+ case "error":
1721
+ return "Error";
1770
1722
  }
1771
1723
  }
1772
- function categoryToSource(category) {
1773
- switch (category) {
1774
- case "credential":
1775
- return "prompt";
1776
- case "user_data":
1777
- return "prompt";
1778
- case "fixed":
1779
- return "fixed";
1780
- case "navigation":
1781
- return "fixed";
1782
- default:
1783
- return "prompt";
1784
- }
1724
+ function toReportableSteps(steps) {
1725
+ return steps.map((s) => ({
1726
+ ordinal: s.ordinal + 1,
1727
+ description: `${s.action.action}: ${s.action.description}`,
1728
+ status: s.success ? "success" : "failed",
1729
+ durationMs: s.durationMs ?? 0,
1730
+ error: s.error,
1731
+ failureCategory: s.failureCategory
1732
+ }));
1785
1733
  }
1786
- function buildRunbookYaml(input) {
1787
- const { goal, startUrl, recordedSteps, goalAchieved, stepDelay, reviewResult, humanGuidance, interventions } = input;
1788
- const successfulSteps = recordedSteps.filter((s) => s.success);
1789
- const reviewMap = new Map(
1790
- reviewResult?.reviewedSteps.map((r) => [r.originalOrdinal, r])
1791
- );
1792
- const filteredSteps = reviewResult ? successfulSteps.filter((s) => reviewMap.get(s.ordinal)?.keep !== false) : successfulSteps;
1793
- const variables = {};
1794
- const usedVariableNames = /* @__PURE__ */ new Set();
1795
- filteredSteps.forEach((recorded) => {
1796
- const { action } = recorded;
1797
- const actionType = toActionType(action.action);
1798
- if (actionType === "input" && action.value !== void 0) {
1799
- const varName = action.variableName ?? `input_${recorded.ordinal}`;
1800
- if (!usedVariableNames.has(varName)) {
1801
- usedVariableNames.add(varName);
1802
- const source = categoryToSource(action.inputCategory);
1803
- variables[varName] = {
1804
- source,
1805
- description: action.description,
1806
- ...source === "prompt" && {
1807
- required: true,
1808
- sensitive: action.inputCategory === "credential"
1809
- },
1810
- ...source === "fixed" && { value: action.value }
1811
- };
1812
- }
1734
+ async function generateExplorationReport(input) {
1735
+ const lines = [];
1736
+ lines.push("# Exploration Report");
1737
+ lines.push("");
1738
+ lines.push("## Session Info");
1739
+ lines.push(`- **Date**: ${(/* @__PURE__ */ new Date()).toISOString()}`);
1740
+ lines.push(`- **Goal**: ${input.goal}`);
1741
+ lines.push(`- **Start URL**: ${input.startUrl}`);
1742
+ lines.push(`- **Outcome**: ${formatOutcome(input.outcome)}`);
1743
+ lines.push("");
1744
+ if (input.cliOptions && input.cliOptions.length > 0) {
1745
+ lines.push("## CLI Options");
1746
+ lines.push(...renderOptionsMarkdown(input.cliOptions));
1747
+ lines.push("");
1748
+ }
1749
+ lines.push("## User Feedback");
1750
+ if (input.userFeedback) {
1751
+ lines.push(input.userFeedback);
1752
+ } else {
1753
+ lines.push("(No feedback provided)");
1754
+ }
1755
+ lines.push("");
1756
+ if (input.errorMessage) {
1757
+ lines.push("## Error Details");
1758
+ lines.push("```");
1759
+ lines.push(input.errorMessage);
1760
+ lines.push("```");
1761
+ lines.push("");
1762
+ }
1763
+ const successCount = input.recordedSteps.filter((s) => s.success).length;
1764
+ const failedCount = input.recordedSteps.filter((s) => !s.success).length;
1765
+ lines.push("## Execution Summary");
1766
+ lines.push(`- **Total Steps**: ${input.recordedSteps.length}`);
1767
+ lines.push(`- **Successful**: ${successCount}`);
1768
+ lines.push(`- **Failed**: ${failedCount}`);
1769
+ lines.push(`- **Interventions**: ${input.interventions.length}`);
1770
+ if (input.totalDurationMs !== void 0) {
1771
+ lines.push(`- **Duration**: ${input.totalDurationMs}ms`);
1772
+ }
1773
+ lines.push("");
1774
+ if (input.recordedSteps.length > 0) {
1775
+ lines.push("## Recorded Steps");
1776
+ for (const step of input.recordedSteps) {
1777
+ const tag = step.success ? "DONE" : "FAILED";
1778
+ const errorInfo = !step.success && step.error ? ` \u2014 Error: ${step.error}` : "";
1779
+ const category = step.failureCategory ? ` [${step.failureCategory}]` : "";
1780
+ const duration = step.durationMs !== void 0 ? ` (${step.durationMs}ms)` : "";
1781
+ lines.push(
1782
+ `${step.ordinal + 1}. [${tag}] ${step.action.action}: ${step.action.description} (URL: ${step.url})${duration}${errorInfo}${category}`
1783
+ );
1813
1784
  }
1814
- });
1815
- const steps = filteredSteps.map((recorded, index) => {
1816
- const actionType = toActionType(recorded.action.action);
1817
- const review = reviewMap.get(recorded.ordinal);
1818
- let selector;
1819
- if (recorded.action.selector) {
1820
- const ref = recorded.action.selector.replace("@", "");
1821
- const element = findElementInSnapshot(recorded.snapshotBefore, ref);
1822
- if (element) {
1823
- selector = buildSelector(element);
1824
- } else if (recorded.resolvedElement) {
1825
- selector = recorded.resolvedElement;
1826
- } else {
1827
- selector = { tagName: "unknown" };
1785
+ lines.push("");
1786
+ }
1787
+ if (input.interventions.length > 0) {
1788
+ lines.push("## Interventions");
1789
+ for (const iv of input.interventions) {
1790
+ lines.push(
1791
+ `- **Step ${iv.stepIndex}** (${iv.timestamp}): "${iv.userInstruction}" (URL: ${iv.url})`
1792
+ );
1793
+ }
1794
+ lines.push("");
1795
+ }
1796
+ const debugEntries = input.debugLogPath ? await readDebugLog(input.debugLogPath) : [];
1797
+ const reportableSteps = toReportableSteps(input.recordedSteps);
1798
+ const hasInsights = input.aiMetrics && input.aiMetrics.totalCalls > 0 || reportableSteps.some((s) => s.status === "failed") || reportableSteps.some((s) => s.durationMs > 3e3) || debugEntries.length > 0;
1799
+ if (hasInsights) {
1800
+ lines.push("## System Insights");
1801
+ lines.push("");
1802
+ lines.push("> refrain \u306E\u6A5F\u80FD\u6539\u5584\u30FB\u30D0\u30B0\u4FEE\u6B63\u306E\u305F\u3081\u306E\u5206\u6790\u60C5\u5831");
1803
+ lines.push("");
1804
+ lines.push(...formatRuntimeEnvironment());
1805
+ if (input.aiMetrics && input.aiMetrics.totalCalls > 0) {
1806
+ lines.push(...formatAiMetricsSection(input.aiMetrics));
1807
+ }
1808
+ const failedSteps = reportableSteps.filter((s) => s.status === "failed");
1809
+ lines.push(...formatFailureCategoryDistribution(failedSteps));
1810
+ lines.push(...formatPerformanceBottlenecks(reportableSteps));
1811
+ }
1812
+ lines.push(...formatDebugLogSections(debugEntries));
1813
+ return lines.join("\n");
1814
+ }
1815
+ var SNAPSHOT_PREVIEW_LIMIT = 500;
1816
+ async function generateGenerationReportFile(input) {
1817
+ const lines = [];
1818
+ lines.push("# Generation Report");
1819
+ lines.push("");
1820
+ lines.push("## Session Info");
1821
+ lines.push(`- **Date**: ${(/* @__PURE__ */ new Date()).toISOString()}`);
1822
+ lines.push(`- **Goal**: ${input.goal}`);
1823
+ lines.push(`- **Start URL**: ${input.startUrl}`);
1824
+ lines.push(`- **Outcome**: ${input.goalAchieved ? "Goal achieved" : "Goal not achieved"}`);
1825
+ lines.push(`- **Total Recorded Steps**: ${input.recordedSteps.length}`);
1826
+ lines.push("");
1827
+ if (input.errorMessage) {
1828
+ lines.push("## Error Details");
1829
+ lines.push("```");
1830
+ lines.push(input.errorMessage);
1831
+ lines.push("```");
1832
+ lines.push("");
1833
+ }
1834
+ if (input.generateConfig) {
1835
+ const gc = input.generateConfig;
1836
+ lines.push("## Generation Config");
1837
+ lines.push(`- **Max Iterations**: ${gc.maxIterations}`);
1838
+ if (gc.modelId) lines.push(`- **Model**: ${gc.modelId}${gc.modelProvider ? ` (${gc.modelProvider})` : ""}`);
1839
+ lines.push(`- **Headless**: ${gc.headless}`);
1840
+ lines.push(`- **Stealth**: ${gc.stealth}`);
1841
+ lines.push(`- **Snapshot Filter**: ${gc.snapshotFilter}`);
1842
+ lines.push("");
1843
+ }
1844
+ const successCount = input.recordedSteps.filter((s) => s.success).length;
1845
+ const failedCount = input.recordedSteps.filter((s) => !s.success).length;
1846
+ const totalDurationMs = input.recordedSteps.reduce((sum, s) => sum + (s.durationMs ?? 0), 0);
1847
+ lines.push("## Execution Summary");
1848
+ lines.push(`- **Total Steps**: ${input.recordedSteps.length}`);
1849
+ lines.push(`- **Successful**: ${successCount}`);
1850
+ lines.push(`- **Failed**: ${failedCount}`);
1851
+ lines.push(`- **Duration**: ${totalDurationMs}ms`);
1852
+ lines.push("");
1853
+ if (input.recordedSteps.length > 0) {
1854
+ lines.push("## Recorded Steps");
1855
+ lines.push("");
1856
+ for (const step of input.recordedSteps) {
1857
+ const tag = step.success ? "DONE" : "FAILED";
1858
+ const duration = step.durationMs !== void 0 ? ` (${step.durationMs}ms)` : "";
1859
+ lines.push(`### Step #${step.ordinal + 1} \u2014 [${tag}] ${step.action.action}: ${step.action.description}${duration}`);
1860
+ lines.push("");
1861
+ lines.push(`- **URL**: ${step.url}`);
1862
+ if (step.action.selector) lines.push(`- **Selector**: ${step.action.selector}`);
1863
+ if (step.action.value) lines.push(`- **Value**: ${step.action.value}`);
1864
+ if (step.action.inputCategory) lines.push(`- **Input Category**: ${step.action.inputCategory}`);
1865
+ if (step.action.variableName) lines.push(`- **Variable Name**: ${step.action.variableName}`);
1866
+ if (!step.success && step.error) lines.push(`- **Error**: ${step.error}`);
1867
+ if (step.failureCategory) lines.push(`- **Failure Category**: ${step.failureCategory}`);
1868
+ if (step.snapshotBefore) {
1869
+ const preview = step.snapshotBefore.length > SNAPSHOT_PREVIEW_LIMIT ? `${step.snapshotBefore.slice(0, SNAPSHOT_PREVIEW_LIMIT)}\u2026` : step.snapshotBefore;
1870
+ lines.push("- **Snapshot Preview**:");
1871
+ lines.push("```");
1872
+ lines.push(preview);
1873
+ lines.push("```");
1828
1874
  }
1875
+ lines.push("");
1829
1876
  }
1830
- let value;
1831
- if (actionType === "input" && recorded.action.value !== void 0) {
1832
- const varName = recorded.action.variableName ?? `input_${recorded.ordinal}`;
1833
- value = `{{${varName}}}`;
1877
+ }
1878
+ if (input.reviewResult) {
1879
+ lines.push("## AI Review Summary");
1880
+ lines.push(`- **Goal Achieved**: ${input.reviewResult.goalAchieved ?? "unknown"}`);
1881
+ if (input.reviewResult.summary) {
1882
+ lines.push(`- **Summary**: ${input.reviewResult.summary}`);
1834
1883
  }
1835
- const step = {
1836
- ordinal: index,
1837
- description: recorded.action.description,
1838
- action: {
1839
- type: actionType,
1840
- ...selector && { selector },
1841
- ...actionType === "input" && value !== void 0 && { value },
1842
- ...actionType === "select" && recorded.action.value !== void 0 && {
1843
- optionText: recorded.action.value
1844
- },
1845
- ...actionType === "navigate" && recorded.action.value && {
1846
- url: recorded.action.value
1847
- },
1848
- ...actionType === "extract" && recorded.action.script && {
1849
- script: recorded.action.script
1850
- },
1851
- ...actionType === "download" && recorded.action.downloadPath && {
1852
- downloadPath: recorded.action.downloadPath
1853
- },
1854
- ...actionType === "export" && recorded.action.exportCollection && {
1855
- exportCollection: recorded.action.exportCollection
1856
- },
1857
- ...actionType === "export" && recorded.action.exportFormat && {
1858
- exportFormat: recorded.action.exportFormat
1859
- },
1860
- ...actionType === "export" && recorded.action.exportPath && {
1861
- exportPath: recorded.action.exportPath
1862
- },
1863
- ...actionType === "key" && {
1864
- keys: recorded.action.keys ?? recorded.action.value
1865
- }
1866
- },
1867
- url: recorded.url,
1868
- riskLevel: review?.riskLevel ?? "low",
1869
- requiresConfirmation: review?.requiresConfirmation ?? false
1870
- };
1871
- const captures = buildCaptures(recorded.action.suggestedCaptures);
1872
- if (captures.length > 0) {
1873
- step.captures = captures;
1884
+ lines.push("");
1885
+ if (input.reviewResult.reviewedSteps.length > 0) {
1886
+ lines.push("## Step Review Decisions");
1887
+ lines.push("");
1888
+ lines.push("| # | Keep | Risk | Confirmation | Removal Reason |");
1889
+ lines.push("|---|------|------|-------------|----------------|");
1890
+ for (const rs of input.reviewResult.reviewedSteps) {
1891
+ const keep = rs.keep ? "Yes" : "No";
1892
+ const risk = rs.riskLevel ?? "-";
1893
+ const confirm = rs.requiresConfirmation ? `Yes: ${rs.confirmationReason ?? ""}` : "No";
1894
+ const reason = rs.removalReason ?? "-";
1895
+ lines.push(`| ${rs.originalOrdinal + 1} | ${keep} | ${risk} | ${confirm} | ${reason} |`);
1896
+ }
1897
+ lines.push("");
1874
1898
  }
1875
- if (recorded.action.action === "memory_append" && recorded.action.memoryCollection) {
1876
- step.memoryOperations = [{
1877
- type: "append",
1878
- collection: recorded.action.memoryCollection,
1879
- source: recorded.action.variableName ?? "extractedData"
1880
- }];
1881
- } else if (recorded.action.action === "memory_aggregate" && recorded.action.aggregation) {
1882
- const agg = recorded.action.aggregation;
1883
- step.memoryOperations = [{
1884
- type: "aggregate",
1885
- collection: agg.collection,
1886
- field: agg.field,
1887
- operation: agg.operation,
1888
- outputVariable: agg.outputVariable
1889
- }];
1899
+ if (input.reviewResult.yamlContent) {
1900
+ lines.push("## Generated YAML");
1901
+ lines.push("");
1902
+ lines.push("```yaml");
1903
+ lines.push(input.reviewResult.yamlContent);
1904
+ lines.push("```");
1905
+ lines.push("");
1890
1906
  }
1891
- return step;
1892
- });
1893
- const baseUrl = new URL(startUrl).origin;
1894
- const runbook = {
1895
- title: goal,
1896
- settings: {
1897
- baseUrl,
1898
- defaultTimeout: 1e4,
1899
- pauseBetweenSteps: stepDelay,
1900
- stopOnError: true
1901
- },
1902
- metadata: {
1903
- startUrl,
1904
- goal,
1905
- goalAchieved,
1906
- totalSteps: filteredSteps.length,
1907
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1908
- ...input.skills && input.skills.length > 0 && { skills: input.skills }
1909
- },
1910
- context: input.contextMarkdown
1911
- };
1912
- if (Object.keys(variables).length > 0) {
1913
- runbook.variables = variables;
1914
- }
1915
- runbook.steps = steps;
1916
- const allNotes = [];
1917
- if (humanGuidance && humanGuidance.length > 0) {
1918
- allNotes.push(
1919
- ...humanGuidance.map((g, i) => `[\u65B9\u91DD\u4FEE\u6B63 ${i + 1}] ${g}`)
1920
- );
1921
- }
1922
- if (interventions && interventions.length > 0) {
1923
- allNotes.push(
1924
- ...interventions.map(
1925
- (iv) => `[\u63A2\u7D22\u4E2D\u4ECB\u5165 \u30B9\u30C6\u30C3\u30D7#${iv.stepIndex}] ${iv.userInstruction}`
1926
- )
1927
- );
1928
1907
  }
1929
- if (allNotes.length > 0) {
1930
- runbook.notes = allNotes.join("\n");
1908
+ const reportableSteps = toReportableSteps(input.recordedSteps);
1909
+ const hasInsights = input.aiMetrics && input.aiMetrics.totalCalls > 0 || reportableSteps.some((s) => s.status === "failed") || reportableSteps.some((s) => s.durationMs > 3e3);
1910
+ if (hasInsights) {
1911
+ lines.push("## System Insights");
1912
+ lines.push("");
1913
+ lines.push("> refrain \u306E\u6A5F\u80FD\u6539\u5584\u30FB\u30D0\u30B0\u4FEE\u6B63\u306E\u305F\u3081\u306E\u5206\u6790\u60C5\u5831");
1914
+ lines.push("");
1915
+ lines.push(...formatRuntimeEnvironment());
1916
+ if (input.aiMetrics && input.aiMetrics.totalCalls > 0) {
1917
+ lines.push(...formatAiMetricsSection(input.aiMetrics));
1918
+ }
1919
+ const failedSteps = reportableSteps.filter((s) => s.status === "failed");
1920
+ lines.push(...formatFailureCategoryDistribution(failedSteps));
1921
+ lines.push(...formatPerformanceBottlenecks(reportableSteps));
1931
1922
  }
1932
- ParsedRunbookSchema.parse(runbook);
1933
- return stringify(runbook, { lineWidth: 120 });
1934
- }
1935
- function buildCaptures(suggested) {
1936
- if (!suggested || suggested.length === 0) return [];
1937
- return suggested.map((c) => ({
1938
- name: c.name,
1939
- strategy: c.strategy,
1940
- required: false,
1941
- ...c.description && { description: c.description },
1942
- ...c.pattern && { pattern: c.pattern },
1943
- ...c.group !== void 0 && c.group !== 1 && { group: c.group },
1944
- ...c.prompt && { prompt: c.prompt },
1945
- ...c.expression && { expression: c.expression }
1946
- }));
1947
- }
1948
-
1949
- // src/runbook-generator/prompts.ts
1950
- import { z as z3 } from "zod";
1951
- var reviewResponseSchema = z3.object({
1952
- reviewedSteps: z3.array(z3.object({
1953
- originalOrdinal: z3.number(),
1954
- keep: z3.boolean(),
1955
- removalReason: z3.string().optional(),
1956
- riskLevel: z3.enum(["low", "medium", "high"]),
1957
- requiresConfirmation: z3.boolean(),
1958
- confirmationReason: z3.string().optional()
1959
- })),
1960
- summary: z3.string()
1961
- });
1962
- function createReviewPrompt(goal, recordedSteps, goalAchieved, interventions, locale) {
1963
- const system = getReviewSystemPrompt(locale);
1964
- const userPrompt = createReviewUserPrompt(goal, recordedSteps, goalAchieved, interventions, locale);
1965
- return { system, userPrompt };
1923
+ return lines.join("\n");
1966
1924
  }
1967
1925
 
1968
1926
  export {
1969
1927
  explore,
1970
- buildRunbookYaml,
1971
- reviewResponseSchema,
1972
- createReviewPrompt
1928
+ generateExplorationReport,
1929
+ generateGenerationReportFile
1973
1930
  };
1974
- //# sourceMappingURL=chunk-IGFCYKHC.js.map
1931
+ //# sourceMappingURL=chunk-5CKPPEYP.js.map