cli-jaw 2.17.41 → 2.17.42

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 (167) hide show
  1. package/README.md +3 -3
  2. package/dist/bin/commands/browser.js +52 -5
  3. package/dist/bin/commands/browser.js.map +1 -1
  4. package/dist/src/agent/args.js +69 -19
  5. package/dist/src/agent/args.js.map +1 -1
  6. package/dist/src/agent/codex-app-events.js +31 -1
  7. package/dist/src/agent/codex-app-events.js.map +1 -1
  8. package/dist/src/agent/cursor-model-inventory.js +140 -0
  9. package/dist/src/agent/cursor-model-inventory.js.map +1 -0
  10. package/dist/src/agent/grok-models.js +80 -0
  11. package/dist/src/agent/grok-models.js.map +1 -0
  12. package/dist/src/browser/actions.js +383 -20
  13. package/dist/src/browser/actions.js.map +1 -1
  14. package/dist/src/browser/grounding-candidate.js +272 -0
  15. package/dist/src/browser/grounding-candidate.js.map +1 -0
  16. package/dist/src/browser/grounding-eval.js +247 -0
  17. package/dist/src/browser/grounding-eval.js.map +1 -0
  18. package/dist/src/browser/image-size.js +63 -0
  19. package/dist/src/browser/image-size.js.map +1 -0
  20. package/dist/src/browser/index.js +1 -0
  21. package/dist/src/browser/index.js.map +1 -1
  22. package/dist/src/browser/occlusion.js +148 -0
  23. package/dist/src/browser/occlusion.js.map +1 -0
  24. package/dist/src/browser/verify-candidate.js +162 -0
  25. package/dist/src/browser/verify-candidate.js.map +1 -0
  26. package/dist/src/browser/vision-input.js +74 -0
  27. package/dist/src/browser/vision-input.js.map +1 -0
  28. package/dist/src/browser/vision-provider.js +75 -0
  29. package/dist/src/browser/vision-provider.js.map +1 -0
  30. package/dist/src/browser/vision.js +360 -47
  31. package/dist/src/browser/vision.js.map +1 -1
  32. package/dist/src/browser/web-ai/candidate-reconcile.js +14 -5
  33. package/dist/src/browser/web-ai/candidate-reconcile.js.map +1 -1
  34. package/dist/src/cli/claude-model-discovery.js +175 -0
  35. package/dist/src/cli/claude-model-discovery.js.map +1 -0
  36. package/dist/src/cli/claude-models.js +46 -0
  37. package/dist/src/cli/claude-models.js.map +1 -1
  38. package/dist/src/cli/registry-live.js +104 -1
  39. package/dist/src/cli/registry-live.js.map +1 -1
  40. package/dist/src/cli/registry.js +28 -5
  41. package/dist/src/cli/registry.js.map +1 -1
  42. package/dist/src/code-mode/host.js +6 -0
  43. package/dist/src/code-mode/host.js.map +1 -1
  44. package/dist/src/code-mode/manager.js +37 -8
  45. package/dist/src/code-mode/manager.js.map +1 -1
  46. package/dist/src/code-mode/providers/catalog.js +53 -1
  47. package/dist/src/code-mode/providers/catalog.js.map +1 -1
  48. package/dist/src/code-mode/providers/codex-app.js +6 -0
  49. package/dist/src/code-mode/providers/codex-app.js.map +1 -1
  50. package/dist/src/code-mode/providers/live-models.js +85 -0
  51. package/dist/src/code-mode/providers/live-models.js.map +1 -0
  52. package/dist/src/code-mode/providers/provider-live-models.js +120 -0
  53. package/dist/src/code-mode/providers/provider-live-models.js.map +1 -0
  54. package/dist/src/code-mode/session.js +37 -0
  55. package/dist/src/code-mode/session.js.map +1 -1
  56. package/dist/src/prompt/templates/a1-system.md +24 -14
  57. package/dist/src/prompt/templates/control-system.md +6 -11
  58. package/dist/src/prompt/templates/employee.md +5 -5
  59. package/dist/src/routes/browser.js +17 -5
  60. package/dist/src/routes/browser.js.map +1 -1
  61. package/package.json +1 -1
  62. package/public/css/activity.css +20 -1
  63. package/public/css/layout.css +7 -3
  64. package/public/dist/.vite/manifest.json +104 -105
  65. package/public/dist/assets/Agent-CQ4EBgY8.js +1 -0
  66. package/public/dist/assets/CodeCanvas-DWsx6sv5.js +2 -0
  67. package/public/dist/assets/DashboardMeta-Dh-tasbY.js +1 -0
  68. package/public/dist/assets/Display-NrqY_IaN.js +1 -0
  69. package/public/dist/assets/{Permissions-BzbnqenZ.js → Permissions-Bh947tUG.js} +1 -1
  70. package/public/dist/assets/Permissions-DzNJCt8K.js +1 -0
  71. package/public/dist/assets/app-BCBnxiGr.css +1 -0
  72. package/public/dist/assets/{app-x5Kray4W.js → app-Q0prKOFx.js} +4 -4
  73. package/public/dist/assets/{bgtask-badge-W9djRQVu.js → bgtask-badge-DAcWaUfS.js} +1 -1
  74. package/public/dist/assets/bgtask-badge-DHA2OQm8.js +1 -0
  75. package/public/dist/assets/{employees--_dmDw_a.js → employees-CWS3Juca.js} +1 -1
  76. package/public/dist/assets/{iframe-renderer-D4BmLtAq.js → iframe-renderer-DCDKBMb7.js} +2 -2
  77. package/public/dist/assets/iframe-renderer-RpvBly2x.js +1 -0
  78. package/public/dist/assets/manager-Nk7-RYPs.css +1 -0
  79. package/public/dist/assets/manager-XkR-DRaQ.js +5 -0
  80. package/public/dist/assets/manager-shortcuts-jsiX-zV6.js +1 -0
  81. package/public/dist/assets/memory-4YH8sz0L.js +1 -0
  82. package/public/dist/assets/{memory-DENQWzM8.js → memory-DhNdKZLO.js} +1 -1
  83. package/public/dist/assets/{message-history-BsrLcGJj.js → message-history-DbRTl1P0.js} +1 -1
  84. package/public/dist/assets/message-history-lVcLpAw8.js +1 -0
  85. package/public/dist/assets/{render-CF6Q1oIh.js → render-DP8SJtdZ.js} +1 -1
  86. package/public/dist/assets/settings--EGy3_B9.js +1 -0
  87. package/public/dist/assets/settings-85n9NjvX.js +1 -0
  88. package/public/dist/assets/{settings-B-C_jdZR.js → settings-C9_D-pn0.js} +32 -32
  89. package/public/dist/assets/settings-core-8wBl1mg-.js +1 -0
  90. package/public/dist/assets/{settings-core-BzAJLsKN.js → settings-core-BcVD2FgV.js} +1 -1
  91. package/public/dist/assets/{settings-embedding-dEMyByVi.js → settings-embedding-BSpq785l.js} +1 -1
  92. package/public/dist/assets/{settings-embedding-BSA42oKM.css → settings-embedding-LIMq5ebM.css} +1 -1
  93. package/public/dist/assets/{sidebar-fFEOpvJl.js → sidebar-BVhLb5Ft.js} +3 -3
  94. package/public/dist/assets/skills-6GFkHTlQ.js +1 -0
  95. package/public/dist/assets/{skills-Da_b06ci.js → skills-X7qxmHka.js} +1 -1
  96. package/public/dist/assets/{slash-commands-BbPUHHF4.js → slash-commands-BnDH4IU_.js} +1 -1
  97. package/public/dist/assets/slash-commands-qu8fPAZ3.js +1 -0
  98. package/public/dist/assets/{trace-drawer-B-QmzUfP.js → trace-drawer-DasaS1z4.js} +1 -1
  99. package/public/dist/assets/{ui-CkRUrIfp.js → ui-BtiBTXng.js} +1 -1
  100. package/public/dist/assets/ui-BucJ1zMA.js +1 -0
  101. package/public/dist/index.html +2 -2
  102. package/public/dist/manager/index.html +3 -3
  103. package/public/dist/settings/index.html +2 -2
  104. package/public/js/features/settings.ts +16 -0
  105. package/public/manager/src/App.tsx +10 -12
  106. package/public/manager/src/AppChrome.tsx +2 -3
  107. package/public/manager/src/InstancePreview.tsx +47 -0
  108. package/public/manager/src/SidebarRailRouter.tsx +34 -30
  109. package/public/manager/src/code/CodeComposer.tsx +31 -6
  110. package/public/manager/src/code/CodeSessionList.tsx +25 -7
  111. package/public/manager/src/code/CodeToastHost.tsx +49 -0
  112. package/public/manager/src/code/CodeTranscript.tsx +136 -26
  113. package/public/manager/src/code/CodeWorkbench.tsx +16 -2
  114. package/public/manager/src/code/ComposerFooter.tsx +130 -46
  115. package/public/manager/src/code/ContextUsageMeter.tsx +72 -0
  116. package/public/manager/src/code/ProviderGlyph.tsx +58 -0
  117. package/public/manager/src/code/code-composer.css +159 -175
  118. package/public/manager/src/code/code-controller-runtime.ts +3 -1
  119. package/public/manager/src/code/code-session-state.ts +7 -1
  120. package/public/manager/src/code/code-toasts.ts +73 -0
  121. package/public/manager/src/code/code-workbench.css +42 -1
  122. package/public/manager/src/code/code.css +130 -15
  123. package/public/manager/src/code/context-usage.ts +74 -0
  124. package/public/manager/src/code/pending-user-item.ts +46 -0
  125. package/public/manager/src/code/session-order.ts +70 -0
  126. package/public/manager/src/code/tool-summary.ts +101 -0
  127. package/public/manager/src/code/use-dictation.ts +130 -0
  128. package/public/manager/src/components/CommandCenter.tsx +4 -8
  129. package/public/manager/src/components/InstanceDetailPanel.tsx +0 -18
  130. package/public/manager/src/components/Workbench.tsx +6 -10
  131. package/public/manager/src/components/WorkbenchHeader.tsx +0 -11
  132. package/public/manager/src/dashboard-settings/dashboard-settings-ui.ts +3 -1
  133. package/public/manager/src/hooks/useDashboardView.ts +38 -38
  134. package/public/manager/src/manager-components.css +0 -8
  135. package/public/manager/src/manager-shortcut-runner.ts +0 -1
  136. package/public/manager/src/manager-shortcuts.ts +0 -2
  137. package/public/manager/src/settings/pages/Agent.tsx +5 -2
  138. package/public/manager/src/settings/pages/DashboardMeta.tsx +20 -1
  139. package/public/manager/src/settings/pages/Permissions.tsx +23 -4
  140. package/public/manager/src/settings/pages/components/agent/PermissionQuickSection.tsx +6 -2
  141. package/public/manager/src/settings/pages/components/agent/agent-save.ts +24 -1
  142. package/public/manager/src/settings/settings-icons.ts +3 -1
  143. package/public/manager/src/settings/settings-registry.ts +3 -3
  144. package/public/manager/src/settings-controls.css +0 -1
  145. package/public/manager/src/settings-standalone.tsx +8 -8
  146. package/public/manager/src/types.ts +0 -1
  147. package/scripts/check-private-boundary.mjs +101 -0
  148. package/scripts/grounding-eval.mjs +223 -0
  149. package/public/dist/assets/Agent-B8ZEWJ6B.js +0 -1
  150. package/public/dist/assets/CodeCanvas-Bj3lTSu6.js +0 -2
  151. package/public/dist/assets/DashboardMeta-CmZavI4H.js +0 -1
  152. package/public/dist/assets/Display-DFkjKcMk.js +0 -1
  153. package/public/dist/assets/Permissions-CJftCO6p.js +0 -1
  154. package/public/dist/assets/app-DVbrIl8f.css +0 -1
  155. package/public/dist/assets/bgtask-badge-CuAc8bAl.js +0 -1
  156. package/public/dist/assets/iframe-renderer-By2WO5bd.js +0 -1
  157. package/public/dist/assets/manager-CxLXWCGi.css +0 -1
  158. package/public/dist/assets/manager-DA3dF3eN.js +0 -5
  159. package/public/dist/assets/manager-shortcuts-CzGkE0ZG.js +0 -1
  160. package/public/dist/assets/memory-thjr2apY.js +0 -1
  161. package/public/dist/assets/message-history-CfU7_P5t.js +0 -1
  162. package/public/dist/assets/settings-DXA5L4DR.js +0 -1
  163. package/public/dist/assets/settings-Dy_IaNVH.js +0 -1
  164. package/public/dist/assets/settings-core-D7sAQqhC.js +0 -1
  165. package/public/dist/assets/skills-BcIievZp.js +0 -1
  166. package/public/dist/assets/slash-commands-B-5Shayl.js +0 -1
  167. package/public/dist/assets/ui-CJLdMfRx.js +0 -1
@@ -0,0 +1,272 @@
1
+ /**
2
+ * src/browser/grounding-candidate.ts — the shape a grounding answer takes, and
3
+ * how it is recovered from model output.
4
+ *
5
+ * Two things were wrong with the previous extractor, and both are structural
6
+ * rather than cosmetic.
7
+ *
8
+ * It matched with `/\{[^{}]*"found"...\}/`. The `[^{}]*` class cannot cross a
9
+ * nested object, so a well-formed `{"found":true,"bbox":{...},"point":{...}}`
10
+ * could never match at all — the richer schema was unreachable no matter what
11
+ * the model returned. It also required canonical key order and rejected
12
+ * negative numbers.
13
+ *
14
+ * And nothing bounded the coordinate. A hallucinated `{"x":99999}` was
15
+ * converted and clicked.
16
+ *
17
+ * On bbox: it is carried for verification, cropping, and size sanity — NOT as
18
+ * an accuracy mechanism. A controlled comparison (GUI-Actor, same training
19
+ * recipe) scores bbox output below point output, so asking a model for a box
20
+ * does not make its answer better. The box earns its place by letting us
21
+ * reconcile against element geometry and re-crop for a second look.
22
+ */
23
+ /** Below this, a candidate must be verified before it is acted on. */
24
+ export const LOW_CONFIDENCE_THRESHOLD = 0.75;
25
+ /** A point-only answer carries no extent, so it starts as a coin flip. */
26
+ const POINT_ONLY_CONFIDENCE = 0.5;
27
+ const BBOX_CONFIDENCE = 0.8;
28
+ /**
29
+ * Beyond this, a coordinate is not a plausible screen position. Finiteness is
30
+ * too weak a gate: `1e308` is finite, and a bbox that size yields a center of
31
+ * `5e307` which then flows into a click.
32
+ */
33
+ export const MAX_PLAUSIBLE_COORDINATE = 100_000;
34
+ function plausible(n) {
35
+ return Math.abs(n) <= MAX_PLAUSIBLE_COORDINATE;
36
+ }
37
+ function isRecord(value) {
38
+ return Boolean(value && typeof value === 'object' && !Array.isArray(value));
39
+ }
40
+ function finiteNumber(value) {
41
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
42
+ }
43
+ function normalizePoint(value) {
44
+ if (!isRecord(value))
45
+ return null;
46
+ const x = finiteNumber(value['x']);
47
+ const y = finiteNumber(value['y']);
48
+ if (x === null || y === null)
49
+ return null;
50
+ return plausible(x) && plausible(y) ? { x, y } : null;
51
+ }
52
+ function normalizeBBox(value) {
53
+ if (!isRecord(value))
54
+ return null;
55
+ const x = finiteNumber(value['x']);
56
+ const y = finiteNumber(value['y']);
57
+ const width = finiteNumber(value['width']);
58
+ const height = finiteNumber(value['height']);
59
+ if (x === null || y === null || width === null || height === null)
60
+ return null;
61
+ // A zero-area box carries no extent, which is the only thing a box is for.
62
+ if (width <= 0 || height <= 0)
63
+ return null;
64
+ // A box larger than any screen is a confused answer, not a big target.
65
+ if (![x, y, width, height].every(plausible))
66
+ return null;
67
+ return { x, y, width, height };
68
+ }
69
+ function centerOfBBox(bbox) {
70
+ return { x: Math.round(bbox.x + bbox.width / 2), y: Math.round(bbox.y + bbox.height / 2) };
71
+ }
72
+ function clampConfidence(value, fallback) {
73
+ const n = finiteNumber(value);
74
+ return n === null ? fallback : Math.max(0, Math.min(1, n));
75
+ }
76
+ /**
77
+ * Accepts the current shape and the legacy `{found,x,y}` one.
78
+ *
79
+ * A legacy answer is normalized rather than rejected, but it is marked:
80
+ * `kind: 'coordinate'`, `point_only` in riskFlags, and a confidence that fails
81
+ * the gate. It says where to click without saying how big the thing is, and
82
+ * that difference should survive into the decision.
83
+ */
84
+ export function normalizeCandidate(raw) {
85
+ if (!isRecord(raw))
86
+ return null;
87
+ if (typeof raw['found'] !== 'boolean')
88
+ return null;
89
+ if (!raw['found']) {
90
+ return {
91
+ schemaVersion: 'grounding-candidate-v1',
92
+ found: false,
93
+ kind: 'not_found',
94
+ bbox: null,
95
+ point: { x: 0, y: 0 },
96
+ confidence: 0,
97
+ description: typeof raw['description'] === 'string' ? raw['description'] : 'not found',
98
+ reason: typeof raw['reason'] === 'string' ? raw['reason'] : 'target_not_found',
99
+ riskFlags: [],
100
+ };
101
+ }
102
+ const bbox = normalizeBBox(raw['bbox']);
103
+ const explicitPoint = normalizePoint(raw['point']);
104
+ const legacyPoint = normalizePoint(raw); // top-level {x, y}
105
+ const point = explicitPoint ?? legacyPoint ?? (bbox ? centerOfBBox(bbox) : null);
106
+ if (!point)
107
+ return null;
108
+ // Two stated locations that disagree is evidence of a confused answer.
109
+ // Prefer the richer field, but say so rather than resolving it silently.
110
+ const disagrees = Boolean(explicitPoint && legacyPoint &&
111
+ (explicitPoint.x !== legacyPoint.x || explicitPoint.y !== legacyPoint.y));
112
+ const pointOnly = !bbox;
113
+ const candidate = {
114
+ schemaVersion: 'grounding-candidate-v1',
115
+ found: true,
116
+ kind: bbox ? 'grounding_bbox' : 'coordinate',
117
+ bbox,
118
+ point,
119
+ confidence: clampConfidence(raw['confidence'], pointOnly ? POINT_ONLY_CONFIDENCE : BBOX_CONFIDENCE),
120
+ riskFlags: [
121
+ ...(pointOnly ? ['point_only'] : []),
122
+ ...(disagrees ? ['conflicting_point'] : []),
123
+ ],
124
+ };
125
+ if (typeof raw['description'] === 'string')
126
+ candidate.description = raw['description'];
127
+ if (typeof raw['reason'] === 'string')
128
+ candidate.reason = raw['reason'];
129
+ return candidate;
130
+ }
131
+ /**
132
+ * Scan out balanced JSON objects, tracking string state and escapes so a brace
133
+ * inside a string literal does not open or close a span.
134
+ *
135
+ * Emits nested objects as well as depth-0 ones, innermost first within a span.
136
+ * Models routinely wrap the answer — `{"result":{...}}`, `{"candidates":[...]}`
137
+ * — and a depth-0-only scan silently loses those, which the regex it replaced
138
+ * happened to handle.
139
+ *
140
+ * A stray quote is the hard case. Model text quotes page content ("the 15\"
141
+ * monitor"), and stdout truncation can cut inside a string literal, either of
142
+ * which leaves an odd quote count that inverts string tracking for everything
143
+ * after it. Tracking from the start of the text would then hide the real
144
+ * answer entirely, so the scan is also run from each subsequent `{` as a
145
+ * fresh origin, and any span that parses is kept.
146
+ */
147
+ export function extractJsonObjects(text) {
148
+ const found = new Set();
149
+ const out = [];
150
+ for (const span of scanFrom(text, 0)) {
151
+ if (!found.has(span)) {
152
+ found.add(span);
153
+ out.push(span);
154
+ }
155
+ }
156
+ // Re-scan from each opening brace. A prior stray quote can only desync the
157
+ // tracker to the LEFT of a given origin, so restarting recovers the spans
158
+ // it swallowed. Bounded to keep a pathological input from going quadratic.
159
+ let origins = 0;
160
+ for (let i = 0; i < text.length && origins < MAX_RESCAN_ORIGINS; i++) {
161
+ if (text[i] !== '{')
162
+ continue;
163
+ origins += 1;
164
+ for (const span of scanFrom(text, i)) {
165
+ if (!found.has(span)) {
166
+ found.add(span);
167
+ out.push(span);
168
+ }
169
+ }
170
+ }
171
+ return out;
172
+ }
173
+ /** Restart budget for the stray-quote recovery above. */
174
+ const MAX_RESCAN_ORIGINS = 64;
175
+ function scanFrom(text, from) {
176
+ const objects = [];
177
+ const starts = [];
178
+ let inString = false;
179
+ let escaped = false;
180
+ for (let i = from; i < text.length; i++) {
181
+ const ch = text[i];
182
+ if (escaped) {
183
+ escaped = false;
184
+ continue;
185
+ }
186
+ if (inString && ch === '\\') {
187
+ escaped = true;
188
+ continue;
189
+ }
190
+ if (ch === '"') {
191
+ inString = !inString;
192
+ continue;
193
+ }
194
+ if (inString)
195
+ continue;
196
+ if (ch === '{') {
197
+ starts.push(i);
198
+ }
199
+ else if (ch === '}') {
200
+ const start = starts.pop();
201
+ if (start === undefined)
202
+ continue; // stray closer
203
+ objects.push(text.slice(start, i + 1));
204
+ }
205
+ }
206
+ return objects;
207
+ }
208
+ /**
209
+ * Recover a candidate from arbitrary model text.
210
+ *
211
+ * Prefers a located answer over a not-found one, and only then prefers the
212
+ * later of two equally useful candidates.
213
+ *
214
+ * Ordering alone is not enough here. The prompt itself contains a literal
215
+ * `{"found":false,...}` template, so any echo of the instructions parses as a
216
+ * perfectly valid not-found answer — and taking simply the last one turns a
217
+ * successful lookup into "target not found". Preferring `found: true` is what
218
+ * actually resolves that, not the scan direction.
219
+ *
220
+ * A malformed span is skipped rather than aborting the scan: a stray quote in
221
+ * quoted page text can desynchronize string tracking for the rest of the
222
+ * input, so a later object may be the only parseable one.
223
+ */
224
+ export function parseCandidate(text) {
225
+ const objects = extractJsonObjects(text);
226
+ let fallback = null;
227
+ for (let i = objects.length - 1; i >= 0; i--) {
228
+ let parsed;
229
+ try {
230
+ parsed = JSON.parse(objects[i]);
231
+ }
232
+ catch {
233
+ continue;
234
+ }
235
+ const candidate = normalizeCandidate(parsed);
236
+ if (!candidate)
237
+ continue;
238
+ if (candidate.found)
239
+ return candidate;
240
+ fallback ??= candidate;
241
+ }
242
+ return fallback;
243
+ }
244
+ /**
245
+ * Reject a point that cannot be on screen.
246
+ *
247
+ * The old path converted and clicked whatever came back, so a hallucinated
248
+ * coordinate produced a click at an arbitrary place. Bounds are checked in the
249
+ * candidate's own frame — image pixels when a clip was captured, otherwise the
250
+ * viewport scaled by device pixel ratio.
251
+ */
252
+ export function validateCandidate(candidate, frame) {
253
+ if (!candidate.found)
254
+ return candidate;
255
+ const { x, y } = candidate.point;
256
+ const inside = x >= 0 && y >= 0 && x <= frame.width && y <= frame.height;
257
+ if (inside)
258
+ return candidate;
259
+ return {
260
+ ...candidate,
261
+ found: false,
262
+ kind: 'not_found',
263
+ confidence: 0,
264
+ reason: `point (${x}, ${y}) is outside the ${frame.width}x${frame.height} capture`,
265
+ riskFlags: [...candidate.riskFlags, 'out_of_bounds'],
266
+ };
267
+ }
268
+ /** A candidate that must be verified before it is acted on. */
269
+ export function isLowConfidence(candidate, threshold = LOW_CONFIDENCE_THRESHOLD) {
270
+ return candidate.confidence < threshold || candidate.riskFlags.includes('point_only');
271
+ }
272
+ //# sourceMappingURL=grounding-candidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grounding-candidate.js","sourceRoot":"","sources":["../../../src/browser/grounding-candidate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * src/browser/grounding-eval.ts — scoring for the grounding harness.
3
+ *
4
+ * Every phase in this work shipped on unit evidence with the same admitted
5
+ * gap: the pipeline seam needs a live browser and a model spawn, so nothing
6
+ * measured whether grounding actually works. This is the scoring half of the
7
+ * thing that measures it. The runner is separate and lives in scripts/, so the
8
+ * arithmetic here stays testable without Chrome.
9
+ *
10
+ * The measurement that matters is NOT "did the call return success". A click
11
+ * that lands on the wrong element also returns success, which is the failure
12
+ * this whole stack was opened to address. So a case declares the element it
13
+ * expects, and a run is scored against what was actually clicked.
14
+ *
15
+ * Abstention is a first-class outcome, not a failure. Refusing an ambiguous
16
+ * target, an occluded one, or a stale observation is the pipeline working.
17
+ * Folding those into "failed" would make every guard look like a regression
18
+ * and reward a system that clicks confidently regardless.
19
+ */
20
+ /**
21
+ * Percentile by nearest-rank on a sorted sample.
22
+ *
23
+ * Deliberately not interpolating: with a handful of cases an interpolated p95
24
+ * reports a duration that never happened, which reads as precision the sample
25
+ * does not have.
26
+ */
27
+ export function percentile(sortedMs, p) {
28
+ if (sortedMs.length === 0)
29
+ return 0;
30
+ const rank = Math.ceil((p / 100) * sortedMs.length);
31
+ const index = Math.min(Math.max(rank, 1), sortedMs.length) - 1;
32
+ return sortedMs[index];
33
+ }
34
+ export function scoreRun(results) {
35
+ const counts = { verified: 0, misclicked: 0, abstained: 0, groundingFailed: 0, errored: 0 };
36
+ const durations = [];
37
+ const group = () => ({ scored: 0, verified: 0, misclicked: 0, abstained: 0, groundingFailed: 0, verifiedRate: 0, misclickRate: 0 });
38
+ const click = group();
39
+ const refusal = group();
40
+ const errors = new Set();
41
+ for (const r of results) {
42
+ // `expected: 'abstain'` marks a case whose correct answer is a refusal.
43
+ const bucket = r.expected === 'abstain' ? refusal : click;
44
+ switch (r.outcome.kind) {
45
+ case 'verified':
46
+ counts.verified += 1;
47
+ bucket.verified += 1;
48
+ bucket.scored += 1;
49
+ break;
50
+ case 'misclick':
51
+ counts.misclicked += 1;
52
+ bucket.misclicked += 1;
53
+ bucket.scored += 1;
54
+ break;
55
+ case 'abstained':
56
+ counts.abstained += 1;
57
+ bucket.abstained += 1;
58
+ bucket.scored += 1;
59
+ break;
60
+ // A grounding failure stays in the denominator. It is a defect in
61
+ // the thing being measured, so excluding it would let a pipeline
62
+ // that grounds nothing report a clean sheet.
63
+ case 'grounding-failure':
64
+ counts.groundingFailed += 1;
65
+ bucket.groundingFailed += 1;
66
+ bucket.scored += 1;
67
+ break;
68
+ case 'errored':
69
+ counts.errored += 1;
70
+ errors.add(r.outcome.error);
71
+ break;
72
+ }
73
+ // An errored case measures the harness, not the pipeline, so its
74
+ // duration would skew the latency picture.
75
+ if (r.outcome.kind !== 'errored')
76
+ durations.push(r.outcome.ms);
77
+ }
78
+ // Errors are excluded from the denominator. A case the harness could not
79
+ // run is not evidence that grounding failed, and counting it as one would
80
+ // let a broken fixture look like a regression.
81
+ const scored = counts.verified + counts.misclicked + counts.abstained + counts.groundingFailed;
82
+ durations.sort((a, b) => a - b);
83
+ for (const g of [click, refusal]) {
84
+ g.verifiedRate = g.scored === 0 ? 0 : g.verified / g.scored;
85
+ g.misclickRate = g.scored === 0 ? 0 : g.misclicked / g.scored;
86
+ }
87
+ return {
88
+ total: results.length,
89
+ scored,
90
+ ...counts,
91
+ // All three headline rates are scoped to click cases. Blending them
92
+ // with refusal cases produced numbers that could not be read.
93
+ verifiedRate: click.verifiedRate,
94
+ misclickRate: click.misclickRate,
95
+ abstentionRate: click.scored === 0 ? 0 : click.abstained / click.scored,
96
+ latency: durations.length
97
+ ? { p50: percentile(durations, 50), p95: percentile(durations, 95), max: durations[durations.length - 1] }
98
+ : null,
99
+ click,
100
+ refusal,
101
+ errors: [...errors],
102
+ };
103
+ }
104
+ /**
105
+ * Decide a case outcome from what the pipeline returned.
106
+ *
107
+ * The refusal codes are named rather than pattern-matched on prose, so a
108
+ * reworded message cannot silently reclassify a refusal as a failure.
109
+ */
110
+ export const ABSTENTION_CODES = new Set([
111
+ 'COMPUTER_TARGET_AMBIGUOUS',
112
+ 'COMPUTER_TARGET_COVERED',
113
+ 'COMPUTER_VERIFY_DISAGREED',
114
+ 'COMPUTER_OBSERVATION_EXPIRED',
115
+ 'COMPUTER_OBSERVATION_STALE',
116
+ // Declining because the geometry was only partly captured, so a single
117
+ // containing element could not be concluded safely. A refusal, not a
118
+ // failure: the pipeline knew what it did not know.
119
+ 'COMPUTER_GEOMETRY_TRUNCATED',
120
+ ]);
121
+ /**
122
+ * The pipeline looked and did not find it.
123
+ *
124
+ * Separate from the abstention codes above because it is a different claim:
125
+ * those say "I found something and declined to act", this says "there was
126
+ * nothing to act on". A reader chasing a missing button needs to know which.
127
+ */
128
+ export const NOT_FOUND_CODE = 'COMPUTER_TARGET_NOT_FOUND';
129
+ /**
130
+ * The call could not be completed for reasons that have nothing to do with
131
+ * the page: a capture that could not be measured, a viewport that could not be
132
+ * read, a scale factor that was absent.
133
+ *
134
+ * These used to arrive with no code at all, which made them indistinguishable
135
+ * from a refusal — an infrastructure failure scored as commendable restraint,
136
+ * and printed to a human as a missing element.
137
+ */
138
+ export const INFRASTRUCTURE_CODES = new Set([
139
+ 'COMPUTER_CAPTURE_UNMEASURABLE',
140
+ 'COMPUTER_VIEWPORT_UNAVAILABLE',
141
+ 'COMPUTER_CAPTURE_NO_DPR',
142
+ ]);
143
+ /**
144
+ * The pipeline produced an answer that was wrong on its face.
145
+ *
146
+ * `COMPUTER_CANDIDATE_OUT_OF_BOUNDS` fires when the model returns a point
147
+ * outside the frame it was shown. That is a defect in the thing being
148
+ * measured, not in the environment measuring it — grouping it with the
149
+ * capture failures would take a real grounding defect out of the denominator
150
+ * and blame the harness for it.
151
+ */
152
+ export const GROUNDING_FAILURE_CODES = new Set([
153
+ 'COMPUTER_CANDIDATE_OUT_OF_BOUNDS',
154
+ ]);
155
+ export function classifyFailure(code) {
156
+ // An absent code and an unrecognised one are different situations. The
157
+ // first says the responder does not speak this protocol — an older server,
158
+ // most likely, since this runner talks to a separately built one over
159
+ // HTTP. The second says it speaks a newer dialect. Collapsing them would
160
+ // let a version skew silently reinstate the mis-scoring this fixes.
161
+ if (!code)
162
+ return 'uncoded';
163
+ if (ABSTENTION_CODES.has(code))
164
+ return 'abstention';
165
+ if (code === NOT_FOUND_CODE)
166
+ return 'not-found';
167
+ if (GROUNDING_FAILURE_CODES.has(code))
168
+ return 'grounding-failure';
169
+ if (INFRASTRUCTURE_CODES.has(code))
170
+ return 'infrastructure';
171
+ return 'unknown';
172
+ }
173
+ export function classify(response, expected, ms, clickedRef) {
174
+ if (response.success !== true) {
175
+ const kind = classifyFailure(response.code);
176
+ if (kind === 'abstention') {
177
+ return { kind: 'abstained', ms, reason: response.code };
178
+ }
179
+ if (kind === 'infrastructure') {
180
+ // The harness could not ask the question. That is not evidence
181
+ // about grounding in either direction, and scoring it as
182
+ // restraint made a broken capture look like good judgement.
183
+ return { kind: 'errored', ms, error: response.code };
184
+ }
185
+ if (kind === 'grounding-failure') {
186
+ return { kind: 'grounding-failure', ms, reason: response.code };
187
+ }
188
+ if (kind === 'not-found') {
189
+ // Expected-aware, because the same code means opposite things.
190
+ // On a case that should have declined, not finding the target IS
191
+ // the right answer. On a case where the element is present and
192
+ // described, failing to find it is a grounding failure — filing it
193
+ // as an abstention credits restraint that was never exercised and
194
+ // keeps it out of the misclick denominator, so a pipeline that
195
+ // grounds nothing reports a clean sheet.
196
+ return expected === 'abstain'
197
+ ? { kind: 'abstained', ms, reason: response.code }
198
+ : { kind: 'grounding-failure', ms, reason: response.code };
199
+ }
200
+ if (kind === 'uncoded' && response.reason) {
201
+ // A `success:false` body carrying prose and no code. Every current
202
+ // source path names its failures, so this means the responder is
203
+ // older than the naming — which is exactly the case where the
204
+ // prose could be describing a capture failure. Scoring it as an
205
+ // abstention is the mistake this function was rewritten to stop,
206
+ // so it is surfaced as unscoreable rather than credited.
207
+ return { kind: 'errored', ms, error: `uncoded failure: ${response.reason}` };
208
+ }
209
+ // An unrecognised code is forward compatibility, not breakage: this
210
+ // build cannot judge a dialect it does not know, and hard-failing
211
+ // would make the harness brittle against its own future.
212
+ if (response.reason)
213
+ return { kind: 'abstained', ms, reason: response.reason };
214
+ return { kind: 'errored', ms, error: 'no reason given' };
215
+ }
216
+ const got = clickedRef ?? response.ref;
217
+ // Success without an identifiable target cannot be scored. Calling it
218
+ // verified would be the exact assumption this harness exists to test.
219
+ if (!got)
220
+ return { kind: 'errored', ms, error: 'clicked but no element identity was reported' };
221
+ return got === expected ? { kind: 'verified', ms } : { kind: 'misclick', ms, got };
222
+ }
223
+ /** One line per rate, plus the caveat the numbers need to be read with. */
224
+ export function formatReport(report) {
225
+ const pct = (n) => `${(n * 100).toFixed(1)}%`;
226
+ const lines = [
227
+ `cases ${report.total} (${report.scored} scored, ${report.errored} errored)`,
228
+ `verified ${report.verified} (${pct(report.verifiedRate)})`,
229
+ `misclicked ${report.misclicked} (${pct(report.misclickRate)})`,
230
+ `abstained ${report.abstained} (${pct(report.abstentionRate)} of cases that should have clicked)`,
231
+ ];
232
+ if (report.groundingFailed > 0) {
233
+ lines.push(`not grounded ${report.groundingFailed} (the target was there and the pipeline could not find it)`);
234
+ }
235
+ if (report.latency) {
236
+ lines.push(`latency p50 ${report.latency.p50}ms p95 ${report.latency.p95}ms max ${report.latency.max}ms`);
237
+ }
238
+ lines.push('', `when clicking ${report.click.verified}/${report.click.scored} right, ${report.click.misclicked} wrong`, `when refusing ${report.refusal.verified}/${report.refusal.scored} correctly declined, ${report.refusal.misclicked} clicked anyway`);
239
+ if (report.errors.length > 0) {
240
+ lines.push('', 'could not be scored:');
241
+ for (const e of report.errors)
242
+ lines.push(` ${e}`);
243
+ }
244
+ lines.push('', 'An abstention is the pipeline declining, not failing. Read the misclick', 'rate first: a wrong click is worse than no click.');
245
+ return lines.join('\n');
246
+ }
247
+ //# sourceMappingURL=grounding-eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grounding-eval.js","sourceRoot":"","sources":["../../../src/browser/grounding-eval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA2FH;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,QAAkB,EAAE,CAAS;IACpD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/D,OAAO,QAAQ,CAAC,KAAK,CAAW,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAqB;IAC1C,MAAM,MAAM,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC5F,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,GAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;IACjJ,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACtB,wEAAwE;QACxE,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;QAC1D,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,UAAU;gBAAE,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;gBAAC,MAAM;YACvF,KAAK,UAAU;gBAAE,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;gBAAC,MAAM;YAC3F,KAAK,WAAW;gBAAE,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;gBAAC,MAAM;YAC1F,kEAAkE;YAClE,iEAAiE;YACjE,6CAA6C;YAC7C,KAAK,mBAAmB;gBAAE,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;gBAAC,MAAM;YAC9G,KAAK,SAAS;gBAAE,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;gBAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAAC,MAAM;QAC5E,CAAC;QACD,iEAAiE;QACjE,2CAA2C;QAC3C,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,yEAAyE;IACzE,0EAA0E;IAC1E,+CAA+C;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,eAAe,CAAC;IAC/F,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QAC/B,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;QAC5D,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAClE,CAAC;IAED,OAAO;QACH,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,MAAM;QACN,GAAG,MAAM;QACT,oEAAoE;QACpE,8DAA8D;QAC9D,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,cAAc,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,MAAM;QACvE,OAAO,EAAE,SAAS,CAAC,MAAM;YACrB,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAW,EAAE;YACpH,CAAC,CAAC,IAAI;QACV,KAAK;QACL,OAAO;QACP,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;KACtB,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IACpC,2BAA2B;IAC3B,yBAAyB;IACzB,2BAA2B;IAC3B,8BAA8B;IAC9B,4BAA4B;IAC5B,uEAAuE;IACvE,qEAAqE;IACrE,mDAAmD;IACnD,6BAA6B;CAChC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,2BAA2B,CAAC;AAE1D;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACxC,+BAA+B;IAC/B,+BAA+B;IAC/B,yBAAyB;CAC5B,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IAC3C,kCAAkC;CACrC,CAAC,CAAC;AAaH,MAAM,UAAU,eAAe,CAAC,IAA+B;IAC3D,uEAAuE;IACvE,2EAA2E;IAC3E,sEAAsE;IACtE,yEAAyE;IACzE,oEAAoE;IACpE,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC;IACpD,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,WAAW,CAAC;IAChD,IAAI,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,mBAAmB,CAAC;IAClE,IAAI,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,gBAAgB,CAAC;IAC5D,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,QAAQ,CACpB,QAA6E,EAC7E,QAAgB,EAChB,EAAU,EACV,UAAmB;IAEnB,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YACxB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAc,EAAE,CAAC;QACtE,CAAC;QACD,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;YAC5B,+DAA+D;YAC/D,yDAAyD;YACzD,4DAA4D;YAC5D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAc,EAAE,CAAC;QACnE,CAAC;QACD,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;YAC/B,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAc,EAAE,CAAC;QAC9E,CAAC;QACD,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACvB,+DAA+D;YAC/D,iEAAiE;YACjE,+DAA+D;YAC/D,mEAAmE;YACnE,kEAAkE;YAClE,+DAA+D;YAC/D,yCAAyC;YACzC,OAAO,QAAQ,KAAK,SAAS;gBACzB,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAc,EAAE;gBAC5D,CAAC,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAc,EAAE,CAAC;QAC7E,CAAC;QACD,IAAI,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACxC,mEAAmE;YACnE,iEAAiE;YACjE,8DAA8D;YAC9D,gEAAgE;YAChE,iEAAiE;YACjE,yDAAyD;YACzD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,oBAAoB,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACjF,CAAC;QACD,oEAAoE;QACpE,kEAAkE;QAClE,yDAAyD;QACzD,IAAI,QAAQ,CAAC,MAAM;YAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC/E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC7D,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,IAAI,QAAQ,CAAC,GAAG,CAAC;IACvC,sEAAsE;IACtE,sEAAsE;IACtE,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,8CAA8C,EAAE,CAAC;IAChG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;AACvF,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,YAAY,CAAC,MAAkB;IAC3C,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACtD,MAAM,KAAK,GAAG;QACV,mBAAmB,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,OAAO,WAAW;QACtF,mBAAmB,MAAM,CAAC,QAAQ,KAAK,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG;QAClE,mBAAmB,MAAM,CAAC,UAAU,KAAK,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG;QACpE,mBAAmB,MAAM,CAAC,SAAS,KAAK,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,qCAAqC;KAC1G,CAAC;IACF,IAAI,MAAM,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,CAAC,eAAe,4DAA4D,CAAC,CAAC;IACtH,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IACxH,CAAC;IACD,KAAK,CAAC,IAAI,CACN,EAAE,EACF,mBAAmB,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,WAAW,MAAM,CAAC,KAAK,CAAC,UAAU,QAAQ,EACzG,mBAAmB,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,wBAAwB,MAAM,CAAC,OAAO,CAAC,UAAU,iBAAiB,CACxI,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC;QACvC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,yEAAyE,EAAE,mDAAmD,CAAC,CAAC;IAC/I,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * src/browser/image-size.ts — read pixel dimensions from a capture file.
3
+ *
4
+ * Kept out of actions.ts so it can be tested without the CDP layer.
5
+ *
6
+ * This exists because the bounds check needs the frame the model actually saw.
7
+ * The requested clip is not that frame: Playwright trims a clip to the viewport
8
+ * before capture, and the route accepts an array clip whose `.width` is
9
+ * undefined — and comparing a number against `undefined` is always false, so
10
+ * such a bound looks present while checking nothing.
11
+ */
12
+ import fs from 'fs';
13
+ /**
14
+ * Returns null when the size cannot be read. Callers must fail closed on null:
15
+ * a plausible-looking default would be worse than admitting it is unknown.
16
+ */
17
+ export function imageSize(filepath) {
18
+ let head;
19
+ try {
20
+ const fd = fs.openSync(filepath, 'r');
21
+ try {
22
+ const buffer = Buffer.alloc(65536);
23
+ const read = fs.readSync(fd, buffer, 0, buffer.length, 0);
24
+ head = buffer.subarray(0, read);
25
+ }
26
+ finally {
27
+ fs.closeSync(fd);
28
+ }
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ // PNG: 8-byte signature, then an IHDR chunk whose data begins at byte 16.
34
+ if (head.length >= 24 && head.readUInt32BE(0) === 0x89504e47) {
35
+ return { width: head.readUInt32BE(16), height: head.readUInt32BE(20) };
36
+ }
37
+ // JPEG: walk the segment chain to a start-of-frame marker.
38
+ if (head.length >= 4 && head[0] === 0xff && head[1] === 0xd8) {
39
+ let i = 2;
40
+ while (i + 9 < head.length) {
41
+ if (head[i] !== 0xff) {
42
+ i += 1;
43
+ continue;
44
+ }
45
+ const marker = head[i + 1];
46
+ // Standalone markers carry no length field.
47
+ if (marker === 0xd8 || marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7)) {
48
+ i += 2;
49
+ continue;
50
+ }
51
+ const length = head.readUInt16BE(i + 2);
52
+ if (length < 2)
53
+ return null; // malformed chain
54
+ // SOF0..SOF15, excluding DHT (c4), JPG (c8) and DAC (cc).
55
+ if (marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc) {
56
+ return { height: head.readUInt16BE(i + 5), width: head.readUInt16BE(i + 7) };
57
+ }
58
+ i += 2 + length;
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+ //# sourceMappingURL=image-size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-size.js","sourceRoot":"","sources":["../../../src/browser/image-size.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACtC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC1D,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACP,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAExB,0EAA0E;IAC1E,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;QAC3D,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3E,CAAC;IAED,2DAA2D;IAC3D,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3D,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAAC,CAAC,IAAI,CAAC,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAW,CAAC;YACrC,4CAA4C;YAC5C,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC;gBAAC,CAAC,IAAI,CAAC,CAAC;gBAAC,SAAS;YAAC,CAAC;YACnG,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxC,IAAI,MAAM,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC,CAAC,kBAAkB;YAC/C,0DAA0D;YAC1D,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC5F,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACjF,CAAC;YACD,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QACpB,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -5,6 +5,7 @@ export { cleanupIdleTabs, isPinned, parseTabDuration, pinTab, selectTabsForClean
5
5
  export * from './primitives.js';
6
6
  export { snapshot, screenshot, click, type, press, hover, navigate, evaluate, getPageText, mouseClick, getDom, waitForSelector, waitForText, reload, resize, scroll, select, drag, mouseMove, mouseDown, mouseUp, getConsole, getNetwork, } from './actions.js';
7
7
  export { visionClick, extractCoordinates } from './vision.js';
8
+ export { sanitizeTarget, appendBounded, MAX_TARGET_LENGTH, MAX_CODEX_STDOUT_BYTES } from './vision-input.js';
8
9
  export * as adaptiveFetch from './adaptive-fetch/index.js';
9
10
  export * as webAi from './web-ai/index.js';
10
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/browser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EACtD,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EACxC,uBAAuB,EAAE,oBAAoB,EAAE,mBAAmB,EAClE,2BAA2B,EAC3B,aAAa,EAAE,YAAY,EAAE,SAAS,EACtC,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,qBAAqB,EAC7D,uBAAuB,EAAE,sBAAsB,EAC/C,aAAa,EAAE,iBAAiB,EAAE,cAAc,GACnD,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAE,4BAA4B,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAElG,OAAO,EACH,eAAe,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,oBAAoB,EAAE,QAAQ,GACtF,MAAM,oBAAoB,CAAC;AAE5B,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EACH,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EACxC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EACtC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW,EAChD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EACpC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GACxD,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/browser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EACtD,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EACxC,uBAAuB,EAAE,oBAAoB,EAAE,mBAAmB,EAClE,2BAA2B,EAC3B,aAAa,EAAE,YAAY,EAAE,SAAS,EACtC,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,qBAAqB,EAC7D,uBAAuB,EAAE,sBAAsB,EAC/C,aAAa,EAAE,iBAAiB,EAAE,cAAc,GACnD,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAE,4BAA4B,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAElG,OAAO,EACH,eAAe,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,oBAAoB,EAAE,QAAQ,GACtF,MAAM,oBAAoB,CAAC;AAE5B,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EACH,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EACxC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EACtC,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW,EAChD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EACpC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GACxD,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC7G,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC"}