@tangle-network/browser-agent-driver 0.32.0 → 0.33.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 (116) hide show
  1. package/dist/artifacts/filesystem-sink.d.ts +1 -1
  2. package/dist/artifacts/filesystem-sink.js +1 -1
  3. package/dist/brain/index.d.ts +7 -12
  4. package/dist/brain/index.d.ts.map +1 -1
  5. package/dist/brain/index.js +42 -67
  6. package/dist/brain/index.js.map +1 -1
  7. package/dist/browser-launch.js +1 -3
  8. package/dist/browser-launch.js.map +1 -1
  9. package/dist/captcha.d.ts.map +1 -1
  10. package/dist/captcha.js +1 -3
  11. package/dist/captcha.js.map +1 -1
  12. package/dist/cli-attach.d.ts +2 -2
  13. package/dist/cli-attach.js +2 -2
  14. package/dist/cli-design-audit.js +6 -6
  15. package/dist/cli-design-audit.js.map +1 -1
  16. package/dist/cli.js +26 -28
  17. package/dist/cli.js.map +1 -1
  18. package/dist/config.d.ts +5 -3
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +1 -0
  21. package/dist/config.js.map +1 -1
  22. package/dist/design/audit/build-result.d.ts +3 -0
  23. package/dist/design/audit/build-result.d.ts.map +1 -1
  24. package/dist/design/audit/build-result.js +10 -2
  25. package/dist/design/audit/build-result.js.map +1 -1
  26. package/dist/design/audit/evaluate.d.ts +5 -2
  27. package/dist/design/audit/evaluate.d.ts.map +1 -1
  28. package/dist/design/audit/evaluate.js +9 -3
  29. package/dist/design/audit/evaluate.js.map +1 -1
  30. package/dist/design/audit/patches/generate.d.ts +12 -0
  31. package/dist/design/audit/patches/generate.d.ts.map +1 -1
  32. package/dist/design/audit/patches/generate.js +16 -9
  33. package/dist/design/audit/patches/generate.js.map +1 -1
  34. package/dist/design/audit/pipeline.d.ts +3 -3
  35. package/dist/design/audit/pipeline.d.ts.map +1 -1
  36. package/dist/design/audit/pipeline.js +4 -3
  37. package/dist/design/audit/pipeline.js.map +1 -1
  38. package/dist/drivers/cursor-overlay.d.ts +1 -1
  39. package/dist/drivers/cursor-overlay.d.ts.map +1 -1
  40. package/dist/drivers/cursor-overlay.js +2 -2
  41. package/dist/drivers/extract-with-index.d.ts +4 -7
  42. package/dist/drivers/extract-with-index.d.ts.map +1 -1
  43. package/dist/drivers/extract-with-index.js +4 -7
  44. package/dist/drivers/extract-with-index.js.map +1 -1
  45. package/dist/drivers/overlay-label.d.ts +3 -4
  46. package/dist/drivers/overlay-label.d.ts.map +1 -1
  47. package/dist/drivers/overlay-label.js.map +1 -1
  48. package/dist/drivers/playwright.d.ts +2 -2
  49. package/dist/drivers/playwright.d.ts.map +1 -1
  50. package/dist/drivers/playwright.js +10 -24
  51. package/dist/drivers/playwright.js.map +1 -1
  52. package/dist/drivers/som-overlay.d.ts +2 -3
  53. package/dist/drivers/som-overlay.d.ts.map +1 -1
  54. package/dist/drivers/som-overlay.js +2 -3
  55. package/dist/drivers/som-overlay.js.map +1 -1
  56. package/dist/drivers/types.d.ts +3 -9
  57. package/dist/drivers/types.d.ts.map +1 -1
  58. package/dist/multi-actor.d.ts.map +1 -1
  59. package/dist/multi-actor.js +2 -3
  60. package/dist/multi-actor.js.map +1 -1
  61. package/dist/run-state.d.ts +3 -32
  62. package/dist/run-state.d.ts.map +1 -1
  63. package/dist/run-state.js +5 -39
  64. package/dist/run-state.js.map +1 -1
  65. package/dist/runner/completion-language.d.ts +2 -0
  66. package/dist/runner/completion-language.d.ts.map +1 -0
  67. package/dist/runner/completion-language.js +5 -0
  68. package/dist/runner/completion-language.js.map +1 -0
  69. package/dist/runner/direct-start.d.ts +19 -0
  70. package/dist/runner/direct-start.d.ts.map +1 -0
  71. package/dist/runner/direct-start.js +295 -0
  72. package/dist/runner/direct-start.js.map +1 -0
  73. package/dist/runner/events.d.ts +3 -6
  74. package/dist/runner/events.d.ts.map +1 -1
  75. package/dist/runner/events.js.map +1 -1
  76. package/dist/runner/fan-out.d.ts +6 -9
  77. package/dist/runner/fan-out.d.ts.map +1 -1
  78. package/dist/runner/fan-out.js +7 -15
  79. package/dist/runner/fan-out.js.map +1 -1
  80. package/dist/runner/goal-decomposer.d.ts +0 -1
  81. package/dist/runner/goal-decomposer.d.ts.map +1 -1
  82. package/dist/runner/goal-decomposer.js +0 -1
  83. package/dist/runner/goal-decomposer.js.map +1 -1
  84. package/dist/runner/google-flights-preflight.d.ts +35 -0
  85. package/dist/runner/google-flights-preflight.d.ts.map +1 -0
  86. package/dist/runner/google-flights-preflight.js +411 -0
  87. package/dist/runner/google-flights-preflight.js.map +1 -0
  88. package/dist/runner/interrupt-controller.d.ts +1 -1
  89. package/dist/runner/interrupt-controller.js +1 -1
  90. package/dist/runner/overlay-narration.d.ts +1 -1
  91. package/dist/runner/overlay-narration.js +1 -1
  92. package/dist/runner/parallel-runner.d.ts +3 -6
  93. package/dist/runner/parallel-runner.d.ts.map +1 -1
  94. package/dist/runner/parallel-runner.js +2 -3
  95. package/dist/runner/parallel-runner.js.map +1 -1
  96. package/dist/runner/pattern-extractor.d.ts +2 -2
  97. package/dist/runner/pattern-extractor.js +2 -2
  98. package/dist/runner/runner.d.ts +15 -39
  99. package/dist/runner/runner.d.ts.map +1 -1
  100. package/dist/runner/runner.js +208 -255
  101. package/dist/runner/runner.js.map +1 -1
  102. package/dist/runner/stream-webhook.d.ts +1 -1
  103. package/dist/runner/stream-webhook.js +1 -1
  104. package/dist/skills/domain-loader.d.ts +1 -2
  105. package/dist/skills/domain-loader.d.ts.map +1 -1
  106. package/dist/skills/domain-loader.js +1 -2
  107. package/dist/skills/domain-loader.js.map +1 -1
  108. package/dist/telemetry/schema.d.ts +2 -2
  109. package/dist/telemetry/schema.js +2 -2
  110. package/dist/test-runner.d.ts +4 -5
  111. package/dist/test-runner.d.ts.map +1 -1
  112. package/dist/test-runner.js +2 -3
  113. package/dist/test-runner.js.map +1 -1
  114. package/dist/types.d.ts +21 -21
  115. package/dist/types.d.ts.map +1 -1
  116. package/package.json +5 -2
@@ -6,7 +6,7 @@
6
6
  * ├── {testId}/
7
7
  * │ ├── turn-05.jpg
8
8
  * │ ├── recording.webm
9
- * │ ├── events.jsonl ← Gen 5: sub-turn TurnEvents from the bus
9
+ * │ ├── events.jsonl ← sub-turn TurnEvents from the bus
10
10
  * │ └── trajectory.json
11
11
  * ├── suite/
12
12
  * │ ├── report.json
@@ -6,7 +6,7 @@
6
6
  * ├── {testId}/
7
7
  * │ ├── turn-05.jpg
8
8
  * │ ├── recording.webm
9
- * │ ├── events.jsonl ← Gen 5: sub-turn TurnEvents from the bus
9
+ * │ ├── events.jsonl ← sub-turn TurnEvents from the bus
10
10
  * │ └── trajectory.json
11
11
  * ├── suite/
12
12
  * │ ├── report.json
@@ -91,9 +91,8 @@ export declare class Brain {
91
91
  * non-streaming — that every OpenAI-compatible proxy is guaranteed to serve.
92
92
  *
93
93
  * The single source of truth for "we're talking to a proxy, be conservative
94
- * about API features" both `createForceNonStreamingFetch()` (the Gen 30
95
- * streaming-default fix) and the `forceReasoning` gate above route through
96
- * this predicate.
94
+ * about API features"; both `createForceNonStreamingFetch()` and the
95
+ * `forceReasoning` gate route through this predicate.
97
96
  */
98
97
  private isProxiedOpenAI;
99
98
  /** Get a LLM model instance, optionally with provider/model override (e.g. for CAPTCHA fallback) */
@@ -215,21 +214,17 @@ export declare class Brain {
215
214
  forceVision?: boolean;
216
215
  }): Promise<BrainDecision>;
217
216
  /**
218
- * Gen 13: Vision-first decision path. The screenshot is the primary
217
+ * Vision-first decision path. The screenshot is the primary
219
218
  * observation; DOM snapshot is minimal context (URL, title only in pure
220
219
  * vision mode, or compact DOM in hybrid mode). The LLM outputs
221
220
  * coordinate-based actions (clickAt, typeAt) in 1024×768 virtual space.
222
221
  */
223
222
  private decideVision;
224
223
  /**
225
- * Gen 7: ONE LLM call generates a structured plan for the entire task.
224
+ * Generate a structured plan for the entire task with one LLM call.
226
225
  *
227
226
  * The runner executes the plan deterministically (no LLM between steps),
228
227
  * falling back to per-action `decide()` only when verification fails.
229
- * This is the architectural shift that breaks the "1 LLM call per
230
- * action" assumption — a 9-action task becomes 1 plan call + 9
231
- * deterministic executes instead of 9 LLM calls.
232
- *
233
228
  * Returns null when:
234
229
  * - the LLM response is unparseable JSON (fall through to per-action)
235
230
  * - the plan has zero steps
@@ -280,6 +275,7 @@ export declare class Brain {
280
275
  raw: string;
281
276
  tokensUsed?: number;
282
277
  designSystemScore?: Record<string, unknown>;
278
+ parseError?: string;
283
279
  }>;
284
280
  /**
285
281
  * Extract reusable knowledge from a completed trajectory.
@@ -315,9 +311,8 @@ export declare class Brain {
315
311
  * like MDN, Python docs, W3C spec where the value the agent needs lives in
316
312
  * a `<dl>/<code>/<pre>` block, not in an interactive element)
317
313
  *
318
- * Gen 10C raised the default from 16k to 24k to give planners on extraction
319
- * pages more room before truncation kicks in. The 8k same-page budget remains
320
- * unchanged because by then the LLM has already seen the full snapshot once.
314
+ * New-page callers use a larger default budget; same-page callers can pass a
315
+ * tighter budget after the model has already seen the full snapshot once.
321
316
  */
322
317
  export declare function budgetSnapshot(snapshot: string, maxChars?: number): string;
323
318
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/brain/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/brain/index.ts"],"names":[],"mappings":"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"}
@@ -79,13 +79,13 @@ const DATA_EXTRACTION_RULES = `
79
79
  21. EFFICIENT COMPLETION: When you have enough data to answer the goal, complete immediately. Do not navigate to additional pages for "confirmation" if the data was already extracted or is visible in the current a11y tree. Include all extracted data in the completion result
80
80
  22. EXTRACT BEFORE NAVIGATING: On search results, directory listings, or any page showing multiple items, ALWAYS extract ALL needed data BEFORE clicking into individual items. Use extractWithIndex with a wide query for unknown structure, or runScript with document.querySelectorAll('.result-card') if the structure is well-known. Many sites use anti-bot protection on detail pages but leave listing pages accessible. If you can answer the goal from list-level data, do so without navigating deeper.
81
81
  23. FILTER vs SEARCH: When a goal asks to filter results (e.g., "under $50", "4+ stars"), look for filter controls (sliders, dropdowns, checkboxes in a sidebar or toolbar) rather than typing filter values into the search box. Search boxes are for keyword queries, not numeric filters. After applying a filter: (1) wait 2-3 seconds for results to update, (2) verify the filter took effect by checking the updated results, (3) extract the filtered data. Do NOT keep searching for more filter controls after one is applied — extract and complete
82
- 25. EXTRACTWITHINDEX RECOVERY: If a previous runScript returned null/empty/{x:null} on an extraction task, the selector was wrong. DO NOT retry the same runScript or guess a similar selector — the LLM cannot guess CSS class names that aren't visible in the snapshot. Switch to extractWithIndex with a WIDE query: \`'p, span, dd, code, strong, em'\` plus a \`contains\` filter naming the expected text fragment (e.g. contains: "downloads" for npm download counts, contains: "callbackFn" for MDN method signatures). The response shows you the actual text per element so you can pick by content match. This is the Gen 10 recovery pattern — pick-by-content beats pick-by-selector on every page where the planner couldn't see the data at plan time.`;
82
+ 25. EXTRACTWITHINDEX RECOVERY: If a previous runScript returned null/empty/{x:null} on an extraction task, the selector was wrong. DO NOT retry the same runScript or guess a similar selector — the LLM cannot guess CSS class names that aren't visible in the snapshot. Switch to extractWithIndex with a WIDE query: \`'p, span, dd, code, strong, em'\` plus a \`contains\` filter naming the expected text fragment (e.g. contains: "downloads" for npm download counts, contains: "callbackFn" for MDN method signatures). The response shows you the actual text per element so you can pick by content match. Pick-by-content beats pick-by-selector on pages where the planner couldn't see the data at plan time.`;
83
83
  /** Heavy page rules (19-20, 24): injected when snapshot is large or turn count is high */
84
84
  const HEAVY_PAGE_RULES = `
85
85
  19. FORM FIELD TARGETING: Before typing, verify you are targeting the correct input field using its @ref from the ELEMENTS list. If multiple inputs are visible (e.g., search box + price filter), ensure you select the right one by checking its label or placeholder text in the a11y tree. Never assume focus — always specify the exact @ref
86
86
  20. SECTION NAVIGATION: When you need to find a specific section (e.g., rugby, sports, travel) and the nav links aren't in the truncated a11y tree, use runScript to discover navigation: JSON.stringify(Array.from(document.querySelectorAll('nav a, header a, [role="navigation"] a, .nav a')).slice(0, 30).map(a => ({text: a.textContent.trim(), href: a.href}))). Then navigate directly to the matching section URL
87
87
  24. HEAVY PAGE RECOVERY: If a page takes very long to load or seems stuck, do NOT wait — use runScript to check document.readyState and extract whatever content is already in the DOM. Partial data is better than a timeout. If the page is completely blank, try navigating to a simpler version (mobile site, search page) instead of waiting`;
88
- /** Gen 24: URL-first navigation GENERAL PURPOSE, not site-specific.
88
+ /** URL-first navigation rules for complex forms and search pages.
89
89
  * Teaches the agent to construct search/results URLs from goal text
90
90
  * instead of fighting form UIs. Works on any site with URL parameters. */
91
91
  const URL_FIRST_RULES = `
@@ -139,7 +139,7 @@ EXAMPLE 3 — Batch fill a multi-field form (one turn instead of ten):
139
139
  {"plan":["Fill all visible Personal Info fields","Click Next","Fill Contact step","Submit"],"currentStep":0,"action":{"action":"fill","fields":{"@firstname":"Jordan","@lastname":"Rivera","@dob":"1990-04-15"},"selects":{"@gender":"other"}},"reasoning":"Step 1 of the form has 3 text fields and 1 select all visible at once. Filling them in a single batch action saves 7 turns vs typing each individually.","expectedEffect":"All four Step 1 fields populated with the supplied values"}`;
140
140
  /** Full static prompt (all rules) — used as default when config.systemPrompt is not set */
141
141
  const SYSTEM_PROMPT = CORE_RULES + SEARCH_RULES + DATA_EXTRACTION_RULES + HEAVY_PAGE_RULES + REASONING_SUFFIX;
142
- // Gen 13: Vision-first system prompt (pure coordinate actions).
142
+ // Vision-first system prompt for pure coordinate actions.
143
143
  const VISION_FIRST_PROMPT = `You are a browser automation agent. You operate by looking at screenshots and clicking on elements using pixel coordinates.
144
144
 
145
145
  The screenshot shows the current page state at 1024×768 resolution. You identify elements visually and specify where to click using (x, y) coordinates in this coordinate space.
@@ -239,7 +239,7 @@ REASONING FRAMEWORK:
239
239
  2. Where is the element I need to interact with? Estimate its (x, y) coordinates.
240
240
  3. What is the smallest action that makes progress toward the goal?
241
241
  4. If my last action failed, WHY did it fail? Try a different location or strategy.`;
242
- // Gen 15: Unified vision+DOM prompt. The model sees BOTH the screenshot AND
242
+ // Unified vision+DOM prompt. The model sees BOTH the screenshot AND
243
243
  // the ARIA snapshot with @refs. It can use EITHER coordinate actions (clickAt/
244
244
  // typeAt for visual targets) OR ref actions (click/type/fill for DOM elements).
245
245
  // This lets it pick the best tool per interaction: vision for visual layout,
@@ -427,7 +427,7 @@ export class Brain {
427
427
  scoutModelName;
428
428
  scoutProvider;
429
429
  scoutUseVision;
430
- // Gen 28: per-role model overrides
430
+ // Per-role model overrides.
431
431
  plannerModel;
432
432
  plannerProvider;
433
433
  verifierModel;
@@ -466,7 +466,7 @@ export class Brain {
466
466
  this.scoutModelName = config.scout?.model;
467
467
  this.scoutProvider = config.scout?.provider;
468
468
  this.scoutUseVision = config.scout?.useVision === true;
469
- // Gen 28: per-role model overrides
469
+ // Per-role model overrides.
470
470
  this.plannerModel = config.models?.planner?.model;
471
471
  this.plannerProvider = config.models?.planner?.provider;
472
472
  this.verifierModel = config.models?.verifier?.model;
@@ -530,9 +530,8 @@ export class Brain {
530
530
  * non-streaming — that every OpenAI-compatible proxy is guaranteed to serve.
531
531
  *
532
532
  * The single source of truth for "we're talking to a proxy, be conservative
533
- * about API features" both `createForceNonStreamingFetch()` (the Gen 30
534
- * streaming-default fix) and the `forceReasoning` gate above route through
535
- * this predicate.
533
+ * about API features"; both `createForceNonStreamingFetch()` and the
534
+ * `forceReasoning` gate route through this predicate.
536
535
  */
537
536
  isProxiedOpenAI(providerName) {
538
537
  return providerName === 'openai' && Boolean(this.baseUrl);
@@ -832,9 +831,8 @@ export class Brain {
832
831
  shouldUseNavigationModel(state, extraContext, turnInfo) {
833
832
  if (!this.adaptiveModelRouting || !this.navModelName)
834
833
  return false;
835
- // Gen 22: use cheap model for DOM-only same-page turns (form filling,
836
- // clicking known elements). Keep expensive model for first turn, new
837
- // pages, and error recovery where reasoning matters.
834
+ // Use the navigation model for DOM-only same-page turns. Keep the primary
835
+ // model for first turns, new pages, and error recovery.
838
836
  const isFirstTurn = !turnInfo || turnInfo.current <= 1;
839
837
  const samePageAsPrevious = this.lastDecisionUrl === state.url;
840
838
  const hasError = extraContext?.includes('REJECTED') || extraContext?.includes('ERROR');
@@ -1063,8 +1061,7 @@ export class Brain {
1063
1061
  // Zone 1 (intact): last 2 turns — full content
1064
1062
  // Zone 2 (standard): turns 3-5 back — ELEMENTS stripped from user msgs
1065
1063
  // Zone 3 (deep compact): turns 6+ back — both user and assistant ultra-compacted
1066
- // REVERTED from aggressive 8/20 the hard prune at 20 messages caused
1067
- // Google Flights to lose essential history on 30-turn runs.
1064
+ // Keep enough older history for long multi-step travel workflows.
1068
1065
  const deepCompactBefore = Math.max(0, this.history.length - 10);
1069
1066
  return this.history.map((msg, idx) => {
1070
1067
  // Zone 1: keep recent turns intact
@@ -1182,7 +1179,7 @@ export class Brain {
1182
1179
  });
1183
1180
  }
1184
1181
  async decide(goal, state, extraContext, turnInfo, options) {
1185
- // Gen 13: vision-first or hybrid mode delegate to the vision path
1182
+ // Vision-first and hybrid modes delegate to the vision path.
1186
1183
  if (this.observationMode === 'vision' || this.observationMode === 'hybrid') {
1187
1184
  return this.decideVision(goal, state, extraContext, turnInfo);
1188
1185
  }
@@ -1201,10 +1198,8 @@ export class Brain {
1201
1198
  && diffChanges > 0
1202
1199
  && diffTotal > 0
1203
1200
  && diffChanges / diffTotal < 0.3;
1204
- // Tighter snapshot budget on same-page turns agent already saw the full page.
1205
- // Gen 10C: raised new-page budget from 16k to 24k so extraction tasks (MDN/Python
1206
- // docs/W3C spec) get the full <dl>/<code>/<pre> content the LLM needs to write
1207
- // a working runScript on the first try.
1201
+ // Tighter snapshot budget on same-page turns; new pages keep enough
1202
+ // content for extraction from docs/spec pages.
1208
1203
  const snapshotBudget = samePageAsPrevious ? 8_000 : 24_000;
1209
1204
  let visibleSnapshot;
1210
1205
  let elementsHeader;
@@ -1362,17 +1357,15 @@ ${visibleSnapshot}`;
1362
1357
  };
1363
1358
  }
1364
1359
  /**
1365
- * Gen 13: Vision-first decision path. The screenshot is the primary
1360
+ * Vision-first decision path. The screenshot is the primary
1366
1361
  * observation; DOM snapshot is minimal context (URL, title only in pure
1367
1362
  * vision mode, or compact DOM in hybrid mode). The LLM outputs
1368
1363
  * coordinate-based actions (clickAt, typeAt) in 1024×768 virtual space.
1369
1364
  */
1370
1365
  async decideVision(goal, state, extraContext, turnInfo) {
1371
1366
  this.lastDecisionUrl = state.url;
1372
- // Gen 18: adaptive observation — diff-focused on same-page turns.
1373
- // When the page changed slightly after an action (modal opened, dropdown
1374
- // expanded, content loaded), the DIFF is the signal. Send only what
1375
- // changed instead of the full snapshot. Saves 3-5k tokens per turn.
1367
+ // Adaptive observation: on same-page hybrid turns, send only changed
1368
+ // elements when the diff is small.
1376
1369
  const isHybrid = this.observationMode === 'hybrid';
1377
1370
  const samePageAsPrevious = this.lastDecisionUrl === state.url;
1378
1371
  const isFirstTurn = !turnInfo || turnInfo.current <= 1;
@@ -1437,10 +1430,8 @@ Title: ${state.title}`;
1437
1430
  { type: 'text', text: textContent },
1438
1431
  { type: 'image', image: state.screenshot, mediaType: 'image/jpeg' },
1439
1432
  ];
1440
- // Gen 14: strip ALL screenshots from history. The current turn's
1441
- // screenshot is the only image the model needs old screenshots are
1442
- // dead weight that pushes cumulative token count past the cost cap.
1443
- // This alone fixes 3/5 Gen 13 failures (cost_cap at 101-106k).
1433
+ // Strip old screenshots from history; the current screenshot is the only
1434
+ // image the model needs for this turn.
1444
1435
  const compacted = this.compactHistory().map((msg) => {
1445
1436
  if (msg.role !== 'user' || !Array.isArray(msg.content))
1446
1437
  return msg;
@@ -1454,13 +1445,12 @@ Title: ${state.title}`;
1454
1445
  ...compacted,
1455
1446
  { role: 'user', content: userContent },
1456
1447
  ];
1457
- // REVERTED: vision model cascade to gpt-4.1-mini caused 14x token
1458
- // inflation (99k/turn vs 6.8k/turn). gpt-4.1-mini counts image tokens
1459
- // differently, hitting cost cap in 3 turns. Vision turns stay on main model.
1448
+ // Vision turns stay on the main model because smaller model routes can
1449
+ // count image tokens differently and exhaust the token budget.
1460
1450
  const modelOpts = { provider: this.provider, model: this.modelName };
1461
1451
  const nearingEnd = turnInfo && turnInfo.current >= turnInfo.max - 3;
1462
1452
  const maxTokens = nearingEnd ? 1200 : 600;
1463
- // Gen 15: hybrid uses the unified prompt with both action vocabularies
1453
+ // Hybrid mode uses the unified prompt with both action vocabularies.
1464
1454
  const systemPrompt = isHybrid ? UNIFIED_VISION_DOM_PROMPT : VISION_FIRST_PROMPT;
1465
1455
  const result = await this.generate(systemPrompt, messages, modelOpts, maxTokens);
1466
1456
  const raw = result.text;
@@ -1489,14 +1479,10 @@ Title: ${state.title}`;
1489
1479
  };
1490
1480
  }
1491
1481
  /**
1492
- * Gen 7: ONE LLM call generates a structured plan for the entire task.
1482
+ * Generate a structured plan for the entire task with one LLM call.
1493
1483
  *
1494
1484
  * The runner executes the plan deterministically (no LLM between steps),
1495
1485
  * falling back to per-action `decide()` only when verification fails.
1496
- * This is the architectural shift that breaks the "1 LLM call per
1497
- * action" assumption — a 9-action task becomes 1 plan call + 9
1498
- * deterministic executes instead of 9 LLM calls.
1499
- *
1500
1486
  * Returns null when:
1501
1487
  * - the LLM response is unparseable JSON (fall through to per-action)
1502
1488
  * - the plan has zero steps
@@ -1509,11 +1495,8 @@ Title: ${state.title}`;
1509
1495
  const startedAt = Date.now();
1510
1496
  const maxSteps = options?.maxSteps ?? 12;
1511
1497
  const extraContext = options?.extraContext;
1512
- // Snapshot budget for the planner: Gen 10C raised from 12k to 24k. The
1513
- // planner is the most important caller for extraction tasks because it
1514
- // writes the runScript that runs on the first observation. Without enough
1515
- // snapshot context (especially `<dl>/<dt>/<code>/<pre>` content lines that
1516
- // Gen 10C now preserves), the planner emits selectors that don't exist.
1498
+ // Planner snapshots keep enough context for extraction tasks, especially
1499
+ // docs/spec pages with data in `<dl>`, `<code>`, and `<pre>` blocks.
1517
1500
  const snapshot = budgetSnapshot(state.snapshot, 24_000);
1518
1501
  const planSystemPrompt = `You are a planning engine for a browser automation agent.
1519
1502
 
@@ -1584,10 +1567,8 @@ ELEMENTS:
1584
1567
  ${snapshot}
1585
1568
  ${extraContext ? `\n${extraContext}\n` : ''}
1586
1569
  What is the complete plan?`;
1587
- // Gen 20: vision-aware planner. When hybrid mode is active AND a
1588
- // screenshot is available, send the screenshot alongside the DOM so
1589
- // the planner can see the visual layout. This helps on sites like
1590
- // Google Flights where the DOM doesn't convey form structure well.
1570
+ // In vision-capable modes, include the screenshot so the planner can use
1571
+ // visual layout when the DOM does not capture form structure.
1591
1572
  const isVisionPlanner = (this.observationMode === 'hybrid' || this.observationMode === 'vision') && !!state.screenshot;
1592
1573
  const userContent = isVisionPlanner
1593
1574
  ? [
@@ -1595,7 +1576,7 @@ What is the complete plan?`;
1595
1576
  { type: 'image', image: state.screenshot, mediaType: 'image/jpeg' },
1596
1577
  ]
1597
1578
  : userText;
1598
- // Gen 28: planner can use a different model (e.g., Claude Opus for reasoning)
1579
+ // Planner can use its own model override.
1599
1580
  const planModelOpts = this.plannerModel
1600
1581
  ? { provider: (this.plannerProvider || this.provider), model: this.plannerModel }
1601
1582
  : { provider: this.provider, model: this.modelName };
@@ -1855,7 +1836,7 @@ ${budgetSnapshot(state.snapshot)}${siteBoundaryNote ? `\n\n${siteBoundaryNote}`
1855
1836
 
1856
1837
  Was the goal actually achieved? Analyze the current page state carefully.`;
1857
1838
  const userContent = this.buildUserContent(textContent, state.screenshot, true);
1858
- // Gen 28: verifier can use its own model, falls back to nav model, then main
1839
+ // Verifier can use its own model, then the navigation model, then main.
1859
1840
  const verifyProvider = this.verifierProvider
1860
1841
  ? this.verifierProvider
1861
1842
  : (this.adaptiveModelRouting && this.navModelName ? (this.navProvider || this.provider) : undefined);
@@ -1954,7 +1935,7 @@ Audit this page for design quality, UX issues, and visual bugs.`;
1954
1935
  suggestion: String(f.suggestion ?? ''),
1955
1936
  ...(f.cssSelector ? { cssSelector: String(f.cssSelector) } : {}),
1956
1937
  ...(f.cssFix ? { cssFix: String(f.cssFix) } : {}),
1957
- // Gen 3 ROI fields
1938
+ // Optional ROI fields.
1958
1939
  ...(clampScore(f.impact) !== undefined ? { impact: clampScore(f.impact) } : {}),
1959
1940
  ...(clampScore(f.effort) !== undefined ? { effort: clampScore(f.effort) } : {}),
1960
1941
  ...(VALID_BLAST.has(f.blast)
@@ -1978,12 +1959,13 @@ Audit this page for design quality, UX issues, and visual bugs.`;
1978
1959
  designSystemScore,
1979
1960
  };
1980
1961
  }
1981
- catch {
1962
+ catch (err) {
1982
1963
  return {
1983
1964
  score: 5,
1984
1965
  findings: [],
1985
1966
  raw,
1986
1967
  tokensUsed,
1968
+ parseError: err instanceof Error ? err.message : String(err),
1987
1969
  };
1988
1970
  }
1989
1971
  }
@@ -2063,11 +2045,9 @@ Only include facts that are genuinely useful. Quality over quantity. Max 10 fact
2063
2045
  'fill', 'clickSequence',
2064
2046
  'clickAt', 'typeAt',
2065
2047
  'clickLabel', 'typeLabel',
2066
- // Gen 29: macro dispatch. The driver validates the macro name at
2067
- // execute time; here we just accept the shape.
2048
+ // Macro dispatch. The driver validates the macro name at execute time.
2068
2049
  'macro',
2069
- // Gen 33: parallel fan-out. Runner handles dispatch; validator
2070
- // only checks shape (subGoals[] or baseUrl+goalTemplate+items).
2050
+ // Parallel fan-out. Runner handles dispatch; validator checks shape.
2071
2051
  'fanOut',
2072
2052
  ]);
2073
2053
  // Parse strategy: exact → first-{/last-} extraction.
@@ -2251,9 +2231,8 @@ function deduplicateSnapshot(snapshot) {
2251
2231
  * like MDN, Python docs, W3C spec where the value the agent needs lives in
2252
2232
  * a `<dl>/<code>/<pre>` block, not in an interactive element)
2253
2233
  *
2254
- * Gen 10C raised the default from 16k to 24k to give planners on extraction
2255
- * pages more room before truncation kicks in. The 8k same-page budget remains
2256
- * unchanged because by then the LLM has already seen the full snapshot once.
2234
+ * New-page callers use a larger default budget; same-page callers can pass a
2235
+ * tighter budget after the model has already seen the full snapshot once.
2257
2236
  */
2258
2237
  export function budgetSnapshot(snapshot, maxChars = 24_000) {
2259
2238
  // Skip dedup on small snapshots — not enough repetition to justify the O(n) scan
@@ -2437,19 +2416,18 @@ function validateAction(actionType, data) {
2437
2416
  ...(typeof data.intervalMs === 'number' ? { intervalMs: data.intervalMs } : {}),
2438
2417
  };
2439
2418
  }
2440
- // Gen 13: Vision-first coordinate actions
2419
+ // Vision-first coordinate actions.
2441
2420
  case 'clickAt':
2442
2421
  return { action: 'clickAt', x: num(data.x, 0), y: num(data.y, 0) };
2443
2422
  case 'typeAt':
2444
2423
  return { action: 'typeAt', x: num(data.x, 0), y: num(data.y, 0), text: optStr('text') };
2445
- // Gen 23: SoM label-based actions
2424
+ // Set-of-Marks label-based actions.
2446
2425
  case 'clickLabel':
2447
2426
  return { action: 'clickLabel', label: num(data.label, 0) };
2448
2427
  case 'typeLabel':
2449
2428
  return { action: 'typeLabel', label: num(data.label, 0), text: optStr('text') };
2450
- // Gen 29: macro invocation. The driver validates the name + required
2451
- // args at execute time. We only require `name` here because args may
2452
- // legitimately be omitted for macros that declare no params.
2429
+ // Macro invocation. The driver validates the name and required args at
2430
+ // execute time; macros without params may omit args.
2453
2431
  case 'macro': {
2454
2432
  const args = {};
2455
2433
  if (data.args && typeof data.args === 'object' && !Array.isArray(data.args)) {
@@ -2511,11 +2489,8 @@ function isStringRecord(value) {
2511
2489
  return true;
2512
2490
  }
2513
2491
  /**
2514
- * Gen 30: build a fetch-replacement that forces `"stream": false` on every
2515
- * /chat/completions body. Necessary for OpenAI-compatible gateways that
2516
- * default to SSE streaming when the client omits the field (observed on
2517
- * router.tangle.tools). The AI SDK's generateText path does not handle
2518
- * SSE, and we can't rely on the gateway respecting the absence of `stream`.
2492
+ * Build a fetch replacement that forces `"stream": false` on chat completions
2493
+ * bodies for OpenAI-compatible gateways that default to SSE streaming.
2519
2494
  */
2520
2495
  function createForceNonStreamingFetch() {
2521
2496
  return async (input, init) => {