@browserbasehq/orca 3.5.1-preview.0 → 3.6.0-gemini-cua

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 (186) hide show
  1. package/README.md +0 -12
  2. package/dist/cjs/lib/utils.d.ts +6 -0
  3. package/dist/cjs/lib/utils.js +11 -0
  4. package/dist/cjs/lib/utils.js.map +1 -1
  5. package/dist/cjs/lib/v3/agent/AgentProvider.js +4 -3
  6. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  7. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +10 -9
  8. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  9. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +124 -28
  10. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  11. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js +10 -1
  12. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  13. package/dist/cjs/lib/v3/cache/ActCache.js +1 -1
  14. package/dist/cjs/lib/v3/cache/ActCache.js.map +1 -1
  15. package/dist/cjs/lib/v3/cache/utils.d.ts +7 -0
  16. package/dist/cjs/lib/v3/cache/utils.js +19 -0
  17. package/dist/cjs/lib/v3/cache/utils.js.map +1 -1
  18. package/dist/cjs/lib/v3/handlers/v3AgentHandler.d.ts +2 -1
  19. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +25 -9
  20. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  21. package/dist/cjs/lib/v3/index.d.ts +2 -2
  22. package/dist/cjs/lib/v3/index.js.map +1 -1
  23. package/dist/cjs/lib/v3/launch/local.js +1 -0
  24. package/dist/cjs/lib/v3/launch/local.js.map +1 -1
  25. package/dist/cjs/lib/v3/llm/LLMProvider.js +1 -0
  26. package/dist/cjs/lib/v3/llm/LLMProvider.js.map +1 -1
  27. package/dist/cjs/lib/v3/llm/aisdk.js +4 -0
  28. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  29. package/dist/cjs/lib/v3/llm/anthropicOptions.d.ts +57 -0
  30. package/dist/cjs/lib/v3/llm/anthropicOptions.js +115 -0
  31. package/dist/cjs/lib/v3/llm/anthropicOptions.js.map +1 -0
  32. package/dist/cjs/lib/v3/types/public/agent.d.ts +1 -1
  33. package/dist/cjs/lib/v3/types/public/agent.js +2 -0
  34. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  35. package/dist/cjs/lib/v3/types/public/model.d.ts +3 -2
  36. package/dist/cjs/lib/v3/types/public/model.js.map +1 -1
  37. package/dist/cjs/lib/v3/understudy/page.js +1 -1
  38. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  39. package/dist/cjs/lib/v3/v3.js +4 -1
  40. package/dist/cjs/lib/v3/v3.js.map +1 -1
  41. package/dist/cjs/lib/v3/verifier/errorTaxonomy.d.ts +35 -0
  42. package/dist/cjs/lib/v3/verifier/errorTaxonomy.js +291 -0
  43. package/dist/cjs/lib/v3/verifier/errorTaxonomy.js.map +1 -0
  44. package/dist/cjs/lib/v3/verifier/evidence.d.ts +44 -0
  45. package/dist/cjs/lib/v3/verifier/evidence.js +432 -0
  46. package/dist/cjs/lib/v3/verifier/evidence.js.map +1 -0
  47. package/dist/cjs/lib/v3/verifier/index.d.ts +1 -1
  48. package/dist/cjs/lib/v3/verifier/index.js.map +1 -1
  49. package/dist/cjs/lib/v3/verifier/prompts/batchedRelevance.d.ts +21 -0
  50. package/dist/cjs/lib/v3/verifier/prompts/batchedRelevance.js +71 -0
  51. package/dist/cjs/lib/v3/verifier/prompts/batchedRelevance.js.map +1 -0
  52. package/dist/cjs/lib/v3/verifier/prompts/firstPointOfFailure.d.ts +3 -0
  53. package/dist/cjs/lib/v3/verifier/prompts/firstPointOfFailure.js +166 -0
  54. package/dist/cjs/lib/v3/verifier/prompts/firstPointOfFailure.js.map +1 -0
  55. package/dist/cjs/lib/v3/verifier/prompts/fusedJudgment.d.ts +35 -0
  56. package/dist/cjs/lib/v3/verifier/prompts/fusedJudgment.js +158 -0
  57. package/dist/cjs/lib/v3/verifier/prompts/fusedJudgment.js.map +1 -0
  58. package/dist/cjs/lib/v3/verifier/prompts/fusedOutcome.d.ts +26 -0
  59. package/dist/cjs/lib/v3/verifier/prompts/fusedOutcome.js +137 -0
  60. package/dist/cjs/lib/v3/verifier/prompts/fusedOutcome.js.map +1 -0
  61. package/dist/cjs/lib/v3/verifier/prompts/index.d.ts +8 -0
  62. package/dist/cjs/lib/v3/verifier/prompts/index.js +22 -0
  63. package/dist/cjs/lib/v3/verifier/prompts/index.js.map +1 -0
  64. package/dist/cjs/lib/v3/verifier/prompts/perCriterionScore.d.ts +23 -0
  65. package/dist/cjs/lib/v3/verifier/prompts/perCriterionScore.js +77 -0
  66. package/dist/cjs/lib/v3/verifier/prompts/perCriterionScore.js.map +1 -0
  67. package/dist/cjs/lib/v3/verifier/prompts/render.d.ts +23 -0
  68. package/dist/cjs/lib/v3/verifier/prompts/render.js +45 -0
  69. package/dist/cjs/lib/v3/verifier/prompts/render.js.map +1 -0
  70. package/dist/cjs/lib/v3/verifier/prompts/rubricGeneration.d.ts +16 -0
  71. package/dist/cjs/lib/v3/verifier/prompts/rubricGeneration.js +321 -0
  72. package/dist/cjs/lib/v3/verifier/prompts/rubricGeneration.js.map +1 -0
  73. package/dist/cjs/lib/v3/verifier/prompts/taskValidity.d.ts +1 -0
  74. package/dist/cjs/lib/v3/verifier/prompts/taskValidity.js +116 -0
  75. package/dist/cjs/lib/v3/verifier/prompts/taskValidity.js.map +1 -0
  76. package/dist/cjs/lib/v3/verifier/rubricVerifier.d.ts +91 -0
  77. package/dist/cjs/lib/v3/verifier/rubricVerifier.js +1645 -0
  78. package/dist/cjs/lib/v3/verifier/rubricVerifier.js.map +1 -0
  79. package/dist/cjs/lib/v3/verifier/trajectory.d.ts +3 -3
  80. package/dist/cjs/lib/v3/verifier/trajectory.js +26 -26
  81. package/dist/cjs/lib/v3/verifier/trajectory.js.map +1 -1
  82. package/dist/cjs/lib/v3/verifier/types.d.ts +163 -15
  83. package/dist/cjs/lib/v3/verifier/types.js +0 -7
  84. package/dist/cjs/lib/v3/verifier/types.js.map +1 -1
  85. package/dist/cjs/lib/v3Evaluator.d.ts +5 -0
  86. package/dist/cjs/lib/v3Evaluator.js +47 -7
  87. package/dist/cjs/lib/v3Evaluator.js.map +1 -1
  88. package/dist/cjs/lib/version.d.ts +1 -1
  89. package/dist/cjs/lib/version.js +1 -1
  90. package/dist/cjs/lib/version.js.map +1 -1
  91. package/dist/esm/lib/utils.d.ts +6 -0
  92. package/dist/esm/lib/utils.js +10 -0
  93. package/dist/esm/lib/utils.js.map +1 -1
  94. package/dist/esm/lib/v3/agent/AgentProvider.js +4 -3
  95. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  96. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +10 -9
  97. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  98. package/dist/esm/lib/v3/agent/GoogleCUAClient.js +124 -28
  99. package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  100. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js +10 -1
  101. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  102. package/dist/esm/lib/v3/cache/ActCache.js +2 -2
  103. package/dist/esm/lib/v3/cache/ActCache.js.map +1 -1
  104. package/dist/esm/lib/v3/cache/utils.d.ts +7 -0
  105. package/dist/esm/lib/v3/cache/utils.js +18 -0
  106. package/dist/esm/lib/v3/cache/utils.js.map +1 -1
  107. package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +2 -1
  108. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +25 -9
  109. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  110. package/dist/esm/lib/v3/index.d.ts +2 -2
  111. package/dist/esm/lib/v3/index.js.map +1 -1
  112. package/dist/esm/lib/v3/launch/local.js +1 -0
  113. package/dist/esm/lib/v3/launch/local.js.map +1 -1
  114. package/dist/esm/lib/v3/llm/LLMProvider.js +1 -0
  115. package/dist/esm/lib/v3/llm/LLMProvider.js.map +1 -1
  116. package/dist/esm/lib/v3/llm/aisdk.js +4 -0
  117. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  118. package/dist/esm/lib/v3/llm/anthropicOptions.d.ts +57 -0
  119. package/dist/esm/lib/v3/llm/anthropicOptions.js +106 -0
  120. package/dist/esm/lib/v3/llm/anthropicOptions.js.map +1 -0
  121. package/dist/esm/lib/v3/types/public/agent.d.ts +1 -1
  122. package/dist/esm/lib/v3/types/public/agent.js +2 -0
  123. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  124. package/dist/esm/lib/v3/types/public/model.d.ts +3 -2
  125. package/dist/esm/lib/v3/types/public/model.js.map +1 -1
  126. package/dist/esm/lib/v3/understudy/page.js +1 -1
  127. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  128. package/dist/esm/lib/v3/v3.js +4 -1
  129. package/dist/esm/lib/v3/v3.js.map +1 -1
  130. package/dist/esm/lib/v3/verifier/errorTaxonomy.d.ts +35 -0
  131. package/dist/esm/lib/v3/verifier/errorTaxonomy.js +285 -0
  132. package/dist/esm/lib/v3/verifier/errorTaxonomy.js.map +1 -0
  133. package/dist/esm/lib/v3/verifier/evidence.d.ts +44 -0
  134. package/dist/esm/lib/v3/verifier/evidence.js +393 -0
  135. package/dist/esm/lib/v3/verifier/evidence.js.map +1 -0
  136. package/dist/esm/lib/v3/verifier/index.d.ts +1 -1
  137. package/dist/esm/lib/v3/verifier/index.js.map +1 -1
  138. package/dist/esm/lib/v3/verifier/prompts/batchedRelevance.d.ts +21 -0
  139. package/dist/esm/lib/v3/verifier/prompts/batchedRelevance.js +68 -0
  140. package/dist/esm/lib/v3/verifier/prompts/batchedRelevance.js.map +1 -0
  141. package/dist/esm/lib/v3/verifier/prompts/firstPointOfFailure.d.ts +3 -0
  142. package/dist/esm/lib/v3/verifier/prompts/firstPointOfFailure.js +162 -0
  143. package/dist/esm/lib/v3/verifier/prompts/firstPointOfFailure.js.map +1 -0
  144. package/dist/esm/lib/v3/verifier/prompts/fusedJudgment.d.ts +35 -0
  145. package/dist/esm/lib/v3/verifier/prompts/fusedJudgment.js +155 -0
  146. package/dist/esm/lib/v3/verifier/prompts/fusedJudgment.js.map +1 -0
  147. package/dist/esm/lib/v3/verifier/prompts/fusedOutcome.d.ts +26 -0
  148. package/dist/esm/lib/v3/verifier/prompts/fusedOutcome.js +134 -0
  149. package/dist/esm/lib/v3/verifier/prompts/fusedOutcome.js.map +1 -0
  150. package/dist/esm/lib/v3/verifier/prompts/index.d.ts +8 -0
  151. package/dist/esm/lib/v3/verifier/prompts/index.js +9 -0
  152. package/dist/esm/lib/v3/verifier/prompts/index.js.map +1 -0
  153. package/dist/esm/lib/v3/verifier/prompts/perCriterionScore.d.ts +23 -0
  154. package/dist/esm/lib/v3/verifier/prompts/perCriterionScore.js +74 -0
  155. package/dist/esm/lib/v3/verifier/prompts/perCriterionScore.js.map +1 -0
  156. package/dist/esm/lib/v3/verifier/prompts/render.d.ts +23 -0
  157. package/dist/esm/lib/v3/verifier/prompts/render.js +41 -0
  158. package/dist/esm/lib/v3/verifier/prompts/render.js.map +1 -0
  159. package/dist/esm/lib/v3/verifier/prompts/rubricGeneration.d.ts +16 -0
  160. package/dist/esm/lib/v3/verifier/prompts/rubricGeneration.js +318 -0
  161. package/dist/esm/lib/v3/verifier/prompts/rubricGeneration.js.map +1 -0
  162. package/dist/esm/lib/v3/verifier/prompts/taskValidity.d.ts +1 -0
  163. package/dist/esm/lib/v3/verifier/prompts/taskValidity.js +113 -0
  164. package/dist/esm/lib/v3/verifier/prompts/taskValidity.js.map +1 -0
  165. package/dist/esm/lib/v3/verifier/rubricVerifier.d.ts +91 -0
  166. package/dist/esm/lib/v3/verifier/rubricVerifier.js +1640 -0
  167. package/dist/esm/lib/v3/verifier/rubricVerifier.js.map +1 -0
  168. package/dist/esm/lib/v3/verifier/trajectory.d.ts +3 -3
  169. package/dist/esm/lib/v3/verifier/trajectory.js +26 -26
  170. package/dist/esm/lib/v3/verifier/trajectory.js.map +1 -1
  171. package/dist/esm/lib/v3/verifier/types.d.ts +163 -15
  172. package/dist/esm/lib/v3/verifier/types.js +0 -7
  173. package/dist/esm/lib/v3/verifier/types.js.map +1 -1
  174. package/dist/esm/lib/v3Evaluator.d.ts +5 -0
  175. package/dist/esm/lib/v3Evaluator.js +47 -7
  176. package/dist/esm/lib/v3Evaluator.js.map +1 -1
  177. package/dist/esm/lib/version.d.ts +1 -1
  178. package/dist/esm/lib/version.js +1 -1
  179. package/dist/esm/lib/version.js.map +1 -1
  180. package/package.json +8 -8
  181. package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.d.ts +0 -24
  182. package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.js +0 -31
  183. package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.js.map +0 -1
  184. package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.d.ts +0 -24
  185. package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.js +0 -28
  186. package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.js.map +0 -1
@@ -5,6 +5,8 @@
5
5
  * Hybrid runs preserve tool-return text/JSON evidence, while CUA runs preserve
6
6
  * screenshots sent to the provider plus independent harness probes.
7
7
  */
8
+ import type { LLMClient } from "../llm/LLMClient.js";
9
+ import type { LogLine } from "../types/public/logs.js";
8
10
  /** Token usage for one or more LLM calls. Matches AgentResult.usage shape. */
9
11
  export interface TrajectoryUsage {
10
12
  input_tokens: number;
@@ -123,12 +125,15 @@ export type TrajectoryStatus = "complete" | "aborted" | "stalled" | "error";
123
125
  * The on-disk layout is one directory per task:
124
126
  *
125
127
  * .trajectories/<run-id>/<task-id>/
126
- * ├── task_data.json — TaskSpec + result metadata
127
- * ├── trajectory.json — this object, with screenshotPath instead of bytes
128
- * ├── screenshots/ — step probe/agent images plus final observation
128
+ * ├── task_data.json — TaskSpec + result metadata
129
+ * ├── trajectory.json — this object, with image paths instead of bytes
130
+ * ├── screenshots/
131
+ * │ ├── probe/<N>.png — tier-2 probe screenshot per step
132
+ * │ ├── probe/final.png — final terminal observation screenshot
133
+ * │ └── agent/<N>.png — tier-1 image the model received per step
129
134
  * ├── scores/
130
- * │ └── result.json — Result from V3Evaluator.verify()
131
- * └── core.log — captured action log
135
+ * │ └── result.json — Result from V3Evaluator.verify()
136
+ * └── core.log — captured action log
132
137
  */
133
138
  export interface Trajectory {
134
139
  task: TaskSpec;
@@ -139,6 +144,70 @@ export interface Trajectory {
139
144
  status: TrajectoryStatus;
140
145
  usage: TrajectoryUsage;
141
146
  }
147
+ /** A single screenshot kept by Step 1, ready for downstream relevance scoring. */
148
+ export interface CanonicalScreenshot {
149
+ /** 0-based position in the kept-screenshots array. Stable across the pipeline. */
150
+ canonicalIndex: number;
151
+ /**
152
+ * 0-based position in `Trajectory.steps` this screenshot came from
153
+ * (steps.length for the final observation). Lets downstream prompts
154
+ * cross-reference the action history.
155
+ */
156
+ originalStepIndex: number;
157
+ /** The resized PNG/JPEG buffer (or native bytes if sharp unavailable). */
158
+ bytes: Buffer;
159
+ /** MIME media type. Always "image/png" after the optional resize. */
160
+ mediaType: string;
161
+ /** Reason this frame was kept: "first" / "last" / "diverges". */
162
+ keptReason: "first" | "last" | "diverges" | "no-dedup";
163
+ }
164
+ /**
165
+ * A text evidence point sourced from tier-2 probes or tier-1 tool outputs.
166
+ * These feed the same relevance + scoring path as screenshots, letting DOM
167
+ * and hybrid agents preserve extract/aria/tool-return evidence without a
168
+ * separate verifier architecture.
169
+ */
170
+ export interface CanonicalTextEvidence {
171
+ /** 0-based position in the combined evidence-point array. */
172
+ canonicalIndex: number;
173
+ originalStepIndex: number;
174
+ /** Where the text came from. */
175
+ source: "probe-aria" | "agent-text" | "agent-json" | "tool-output";
176
+ /** The text payload, already truncated. */
177
+ content: string;
178
+ }
179
+ export type CanonicalEvidence = CanonicalScreenshot | CanonicalTextEvidence;
180
+ /** Result of Step 1 evidence loading. */
181
+ export interface EvidenceLoadResult {
182
+ /** Kept frames, in chronological order. */
183
+ screenshots: CanonicalScreenshot[];
184
+ /**
185
+ * Maps trajectory step position → canonical index in `screenshots`. Steps
186
+ * whose screenshots were deduplicated point to the surviving canonical frame
187
+ * (typically the prior kept frame). Useful for "find me the screenshot for
188
+ * step K" lookups in downstream prompts.
189
+ */
190
+ stepIndexToCanonical: Map<number, number>;
191
+ /** Number of original frames considered. */
192
+ originalCount: number;
193
+ /** Number of frames kept post-dedup (== screenshots.length). */
194
+ keptCount: number;
195
+ /** Effective thresholds used (resolved from env). */
196
+ thresholds: {
197
+ ssim: number;
198
+ mse: number;
199
+ resize: number;
200
+ };
201
+ }
202
+ /** Options for evidence loading; primarily test seams over the defaults. */
203
+ export interface EvidenceLoadOptions {
204
+ /** SSIM similarity threshold for dedup (default 0.75). */
205
+ ssimThreshold?: number;
206
+ /** MSE similarity threshold for dedup (default 30). */
207
+ mseThreshold?: number;
208
+ /** Scale factor applied before relevance scoring (default 0.7). */
209
+ imageResize?: number;
210
+ }
142
211
  /** Score for a single rubric criterion after evidence analysis + rescoring. */
143
212
  export interface CriterionScore {
144
213
  /** Matches RubricCriterion.criterion (the criterion's short name). */
@@ -146,9 +215,9 @@ export interface CriterionScore {
146
215
  /** Maximum possible points for this criterion. */
147
216
  maxPoints: number;
148
217
  /**
149
- * Points earned post-evidence-analysis (paper's post_image_earned_points).
150
- * Null if the criterion was conditional and its condition wasn't met (excluded
151
- * from both numerator and denominator in the process score).
218
+ * Points earned after evidence analysis. Null when the criterion is
219
+ * conditional and its condition was not met excluded from both numerator
220
+ * and denominator in the process score.
152
221
  */
153
222
  earnedPoints: number | null;
154
223
  /** Verifier's explanation for the score. */
@@ -160,15 +229,14 @@ export interface CriterionScore {
160
229
  conditionMet?: boolean;
161
230
  /**
162
231
  * Set when the verifier had no evidence to ground this criterion in either
163
- * tier. Per paper §2, treated as uncontrollable failure full credit, but
164
- * surfaced here so dashboards can flag low-confidence results.
232
+ * tier. Treated as uncontrollable failure (full credit) but surfaced here
233
+ * so dashboards can flag low-confidence results.
165
234
  */
166
235
  evidenceInsufficient?: boolean;
167
236
  }
168
237
  /**
169
- * First-point-of-failure analysis (paper Step 9a). Identifies the earliest
170
- * step where the agent's trajectory went off-track, using a structured error
171
- * taxonomy (7 top-level categories, 1.1–7.4 sub-codes).
238
+ * Earliest step where the agent's trajectory went off-track, classified
239
+ * against the error taxonomy (7 top-level categories, 1.1–7.4 sub-codes).
172
240
  */
173
241
  export interface FirstPointOfFailure {
174
242
  stepIndex: number;
@@ -212,25 +280,31 @@ export interface VerifierFinding {
212
280
  /** Stable debugging summary emitted by verifier backends. */
213
281
  export interface VerifierRawSteps {
214
282
  backend?: "legacy" | "verifier";
283
+ reason?: string;
215
284
  primaryIntent?: string;
216
285
  reasoning?: string;
217
286
  rubricSource?: "precomputed" | "generated" | "none";
218
- approach?: "a" | "b";
287
+ approach?: "a" | "b" | "outcome-only";
219
288
  optionalsMode?: "folded" | "separate" | "skip";
220
289
  totalEarned?: number;
221
290
  totalMax?: number;
222
291
  evidenceImages?: number;
223
292
  evidenceTexts?: number;
224
293
  evidenceOriginalScreenshots?: number;
294
+ screenshotsAttached?: number;
225
295
  legacyEvaluation?: string;
226
296
  screenshotCount?: number;
227
297
  }
228
- /** Task-validity classification (paper Step 10). */
298
+ /** Task-validity classification: whether the task is even answerable. */
229
299
  export interface TaskValidity {
230
300
  /** True if the task is underspecified / has multiple valid interpretations. */
231
301
  isAmbiguous: boolean;
302
+ /** Explanation for why the task is ambiguous, when available. */
303
+ ambiguityReason?: string;
232
304
  /** True if the task is impossible / illegal / NSFW / otherwise infeasible. */
233
305
  isInvalid: boolean;
306
+ /** Explanation for why the task is invalid, when available. */
307
+ invalidReason?: string;
234
308
  /** Optional sub-codes from the task-classification taxonomy. */
235
309
  ambiguityCodes?: string[];
236
310
  invalidTaskCodes?: string[];
@@ -279,3 +353,77 @@ export interface EvaluationResult {
279
353
  export interface Verifier {
280
354
  verify(trajectory: Trajectory): Promise<EvaluationResult>;
281
355
  }
356
+ export interface RubricVerifierOptions {
357
+ /** Factory that returns a configured LLMClient. Called per pipeline step so callers can supply step-specific clients. */
358
+ getClient: () => LLMClient;
359
+ /** Optional factory for rubric generation so callers can route it to a stronger model. */
360
+ getRubricGenClient?: () => LLMClient;
361
+ /** Logger; defaults to a no-op so the verifier stays quiet inside V3Evaluator. */
362
+ logger?: (line: LogLine) => void;
363
+ /**
364
+ * Override any verifier knob. Env vars supply the defaults; values here win.
365
+ * Useful for tests and for cross-verify sweeps that want different budgets
366
+ * per run.
367
+ */
368
+ config?: Partial<VerifierConfig>;
369
+ }
370
+ /**
371
+ * Resolved verifier knobs. Constructed once from env (and optional overrides)
372
+ * by RubricVerifier's constructor; subsequent verify() calls can pass a
373
+ * Partial to shift any field.
374
+ */
375
+ export interface VerifierConfig {
376
+ /** Which pipeline path to take: per-criterion (a), fused (b), or skip rubric entirely (outcome-only). */
377
+ approach: "a" | "b" | "outcome-only";
378
+ /** Folded (in fused call), separate (own calls), or skip (omit). */
379
+ optionalSteps: "folded" | "separate" | "skip";
380
+ /** Top-K evidence points selected per criterion. */
381
+ topK: number;
382
+ /** Batch size for the relevance-scoring LLM call. */
383
+ relevanceBatchSize: number;
384
+ /** Image cap on the outcome-only path. */
385
+ outcomeMaxImages: number;
386
+ /** Concurrent LLM calls across batches / criteria. */
387
+ maxParallel: number;
388
+ /** Token budgets for the three evidence channels. */
389
+ evidenceTokenBudget: number;
390
+ outcomeEvidenceTokenBudget: number;
391
+ actionHistoryTokenBudget: number;
392
+ /** Per-section character limits applied during evidence-text assembly. */
393
+ truncation: {
394
+ /** Master switch: when true, all per-section limits go to MAX_SAFE_INTEGER. */
395
+ disabled: boolean;
396
+ evidenceTextPreview: number;
397
+ groupedEvidenceText: number;
398
+ buildEvidenceText: number;
399
+ buildEvidenceAria: number;
400
+ actionHistoryReasoning: number;
401
+ };
402
+ }
403
+ export interface ErrorTaxonomySubCategory {
404
+ /** Sub-code (e.g., "2.3"). */
405
+ code: string;
406
+ /** Human-readable name (e.g., "Output fabrication"). */
407
+ name: string;
408
+ /** Detailed description ported from the .md. Markdown formatting preserved. */
409
+ description: string;
410
+ }
411
+ export interface ErrorTaxonomyCategory {
412
+ /** Top-level number (1-8). */
413
+ number: number;
414
+ /** Top-level name (e.g., "Hallucination Errors"). */
415
+ name: string;
416
+ /** One-sentence summary of the category. */
417
+ summary: string;
418
+ /** Sub-categories. The last one is always an "Other" catch-all. */
419
+ subCategories: ErrorTaxonomySubCategory[];
420
+ }
421
+ export interface ParseFailureStepNumbersOptions {
422
+ /**
423
+ * Maximum unique step numbers to expand from ranges. Protects the verifier
424
+ * from malformed model output such as "0-2147483647".
425
+ */
426
+ maxExpandedSteps?: number;
427
+ /** Optional inclusive upper bound for accepted step numbers. */
428
+ maxStep?: number;
429
+ }
@@ -1,9 +1,2 @@
1
- /**
2
- * Shared verifier types for trajectories, rubrics, evidence, and results.
3
- *
4
- * The verifier consumes saved trajectories instead of a live browser. DOM and
5
- * Hybrid runs preserve tool-return text/JSON evidence, while CUA runs preserve
6
- * screenshots sent to the provider plus independent harness probes.
7
- */
8
1
  export {};
9
2
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../lib/v3/verifier/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG","sourcesContent":["/**\n * Shared verifier types for trajectories, rubrics, evidence, and results.\n *\n * The verifier consumes saved trajectories instead of a live browser. DOM and\n * Hybrid runs preserve tool-return text/JSON evidence, while CUA runs preserve\n * screenshots sent to the provider plus independent harness probes.\n */\n\n/** Token usage for one or more LLM calls. Matches AgentResult.usage shape. */\nexport interface TrajectoryUsage {\n input_tokens: number;\n output_tokens: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n inference_time_ms?: number;\n}\n\n/** A single criterion in a Stagehand rubric. */\nexport interface RubricCriterion {\n /** Short name of the criterion (e.g., \"Add ground beef to cart\"). */\n criterion: string;\n /** What to evaluate and how to award partial credit. */\n description: string;\n /** Maximum points for this criterion. */\n maxPoints: number;\n /**\n * Applicability rule for situational criteria. When this condition is not\n * met, the criterion is excluded from scoring rather than counted as failed.\n */\n condition?: string;\n}\n\n/** A rubric — list of criteria for a task. */\nexport interface Rubric {\n items: RubricCriterion[];\n}\n\n/**\n * Spec for a single task being verified. Carried both at runtime and into the\n * verifier alongside the trajectory.\n */\nexport interface TaskSpec {\n /** Stable identifier (e.g., \"united_13\" for WebTailBench, task_id for Mind2Web). */\n id: string;\n /** Task instruction shown to the agent. */\n instruction: string;\n /** Starting URL, if any. */\n initUrl?: string;\n /** Rubric carried by the dataset or generated by a verifier backend. */\n precomputedRubric?: Rubric;\n /** Optional reference answer (set when dataset ships one). */\n expectedAnswer?: string;\n}\n\n/**\n * A single modality unit in tier-1 agent evidence. Mirrors the shape of\n * ModelMessage content parts so we can reproduce what the LLM ingested.\n */\nexport type AgentEvidenceModality =\n | { type: \"text\"; content: string }\n | { type: \"image\"; bytes: Buffer; mediaType: string }\n | { type: \"json\"; content: unknown };\n\n/**\n * Tier 1 — exactly the bytes/strings/objects the agent's LLM ingested as the\n * tool result for this step.\n *\n * Modes:\n * - CUA: usually a single image modality (the screenshot sent to the provider).\n * - Hybrid: tool result with optional screenshotBase64 → one image + one text.\n * - DOM: tool returns (extract JSON, ariaTree text, etc.) → text/json modalities.\n */\nexport interface AgentEvidence {\n modalities: AgentEvidenceModality[];\n}\n\n/**\n * Tier 2 — independent harness probes around this step.\n *\n * If a probe wasn't captured, the field is absent (not null).\n */\nexport interface ProbeEvidence {\n /** URL after the step's tool execution. */\n url?: string;\n /**\n * Bus screenshot captured after the step. Path on disk is preferred once\n * persisted; in-memory Buffer is used during a live run.\n */\n screenshot?: Buffer;\n /** Reference to the persisted screenshot file under the trajectory dir. */\n screenshotPath?: string;\n /** Accessibility tree snapshot. */\n ariaTree?: string;\n /** Verifier-requested probes, keyed by criterion id. */\n onDemand?: Record<string, unknown>;\n}\n\n/** Outcome of a single tool execution as seen by the harness. */\nexport interface ToolOutput {\n ok: boolean;\n /**\n * The tool's return value. Same payload that flowed into agentEvidence\n * modalities, but in its native shape (e.g., the extract result, the act\n * describe-string) rather than serialized for the LLM.\n */\n result: unknown;\n error?: string;\n}\n\n/** One step in a trajectory: action + reasoning + evidence + outcome. */\nexport interface TrajectoryStep {\n actionName: string;\n actionArgs: Record<string, unknown>;\n /** From AgentAction.reasoning. May be empty for tools that don't surface reasoning. */\n reasoning: string;\n agentEvidence: AgentEvidence;\n probeEvidence: ProbeEvidence;\n toolOutput: ToolOutput;\n}\n\n/** Terminal status of the agent run. */\nexport type TrajectoryStatus = \"complete\" | \"aborted\" | \"stalled\" | \"error\";\n\n/**\n * Full trajectory for one task run.\n *\n * The on-disk layout is one directory per task:\n *\n * .trajectories/<run-id>/<task-id>/\n * ├── task_data.json — TaskSpec + result metadata\n * ├── trajectory.json — this object, with screenshotPath instead of bytes\n * ├── screenshots/ — step probe/agent images plus final observation\n * ├── scores/\n * │ └── result.json — Result from V3Evaluator.verify()\n * └── core.log — captured action log\n */\nexport interface Trajectory {\n task: TaskSpec;\n steps: TrajectoryStep[];\n finalAnswer?: string;\n /** Terminal page observation captured after the agent finishes. */\n finalObservation?: ProbeEvidence;\n status: TrajectoryStatus;\n usage: TrajectoryUsage;\n}\n\n/** Score for a single rubric criterion after evidence analysis + rescoring. */\nexport interface CriterionScore {\n /** Matches RubricCriterion.criterion (the criterion's short name). */\n criterion: string;\n /** Maximum possible points for this criterion. */\n maxPoints: number;\n /**\n * Points earned post-evidence-analysis (paper's post_image_earned_points).\n * Null if the criterion was conditional and its condition wasn't met (excluded\n * from both numerator and denominator in the process score).\n */\n earnedPoints: number | null;\n /** Verifier's explanation for the score. */\n explanation: string;\n /**\n * True if the criterion is conditional and its condition was determined to\n * be met. Absent for non-conditional criteria.\n */\n conditionMet?: boolean;\n /**\n * Set when the verifier had no evidence to ground this criterion in either\n * tier. Per paper §2, treated as uncontrollable failure → full credit, but\n * surfaced here so dashboards can flag low-confidence results.\n */\n evidenceInsufficient?: boolean;\n}\n\n/**\n * First-point-of-failure analysis (paper Step 9a). Identifies the earliest\n * step where the agent's trajectory went off-track, using a structured error\n * taxonomy (7 top-level categories, 1.1–7.4 sub-codes).\n */\nexport interface FirstPointOfFailure {\n stepIndex: number;\n /** Sub-code from the error taxonomy (e.g., \"2.3\" for a specific hallucination type). */\n errorCode: string;\n /** Top-level category name (Selection, Hallucination, etc.). */\n category: string;\n /** Verifier's reasoning for selecting this point. */\n description?: string;\n}\n\n/**\n * Structured observation surfaced by the verifier that another agent or\n * tooling could act on. Findings are emitted opportunistically by Step 8\n * (outcome verification) when the verifier notices actionable patterns —\n * repeated tool-call failures, ambiguous task specs, evidence gaps, etc.\n *\n * Not produced for every task: when nothing actionable surfaces, the\n * `findings` array on the EvaluationResult is empty. Consumers should treat the\n * field as advisory, not as part of the formal score.\n */\nexport interface VerifierFinding {\n /**\n * Category of the observation. Open-ended enum — additional categories may\n * be added as verifier backends surface new failure modes.\n */\n category:\n | \"agent_tool_usage\" // agent's tool calls had repeated issues (misclicks, wrong args, retries)\n | \"agent_strategy\" // higher-level planning / decision-making problems\n | \"rubric_quality\" // criteria were overly strict, ambiguous, or contradictory\n | \"trajectory_capture\" // gaps in evidence (missing screenshots, empty steps)\n | \"task_specification\" // task instruction was ambiguous / under- or over-specified\n | \"verifier_uncertainty\" // verifier itself couldn't confidently decide\n | \"other\";\n /** Impact: info (FYI), warning (worth investigating), blocking (broke the task). */\n severity: \"info\" | \"warning\" | \"blocking\";\n /** What the verifier noticed. Plain prose, grounded in evidence from the trajectory. */\n description: string;\n /**\n * Optional concrete next action another agent could take. Should be\n * specific enough that it can be acted on without further reasoning —\n * e.g., \"Try double_click instead of triple_click to clear placeholder\n * text on this form field.\"\n */\n suggestedAction?: string;\n /** Step indices in the trajectory where this pattern showed up. */\n relatedSteps?: number[];\n}\n\n/** Stable debugging summary emitted by verifier backends. */\nexport interface VerifierRawSteps {\n backend?: \"legacy\" | \"verifier\";\n primaryIntent?: string;\n reasoning?: string;\n rubricSource?: \"precomputed\" | \"generated\" | \"none\";\n approach?: \"a\" | \"b\";\n optionalsMode?: \"folded\" | \"separate\" | \"skip\";\n totalEarned?: number;\n totalMax?: number;\n evidenceImages?: number;\n evidenceTexts?: number;\n evidenceOriginalScreenshots?: number;\n legacyEvaluation?: string;\n screenshotCount?: number;\n}\n\n/** Task-validity classification (paper Step 10). */\nexport interface TaskValidity {\n /** True if the task is underspecified / has multiple valid interpretations. */\n isAmbiguous: boolean;\n /** True if the task is impossible / illegal / NSFW / otherwise infeasible. */\n isInvalid: boolean;\n /** Optional sub-codes from the task-classification taxonomy. */\n ambiguityCodes?: string[];\n invalidTaskCodes?: string[];\n}\n\n/**\n * Evaluator output. Legacy evaluation may only populate outcome fields; richer\n * verifier backends can also populate process scoring and diagnostics.\n *\n * Process and outcome are deliberately independent when both are present:\n * an agent can follow the right steps but get blocked (high process, low\n * outcome), or succeed through an unexpected path (variable process, high\n * outcome).\n */\nexport interface EvaluationResult {\n /** Did the agent accomplish the task from the user's perspective? */\n outcomeSuccess: boolean;\n /** Human-readable explanation for the outcome. */\n explanation?: string;\n /** Aggregated earned/max across applicable criteria, in [0, 1]. */\n processScore?: number;\n /** Per-criterion breakdown after rescoring. */\n perCriterion?: CriterionScore[];\n /** Step 9a — first step where the trajectory went off-track, if any. */\n firstPointOfFailure?: FirstPointOfFailure;\n /** Step 10 — task-itself ambiguity / validity. */\n taskValidity?: TaskValidity;\n /**\n * Ids (RubricCriterion.criterion strings) of criteria where neither tier of\n * evidence resolved the question. Treated as uncontrollable → full credit,\n * but flagged here so consumers can decide whether to discount the score.\n */\n evidenceInsufficient?: string[];\n /**\n * Structured observations from the verifier that a downstream tool or\n * follow-up agent could act on. Opportunistic — empty when the verifier\n * doesn't notice anything actionable. Not part of the score; advisory.\n */\n findings?: VerifierFinding[];\n /** Debugging summary from the active evaluator backend. */\n rawSteps?: VerifierRawSteps;\n}\n\n/**\n * Verifier interface. Implementations consume a Trajectory and return an\n * EvaluationResult — they MUST NOT touch a live browser.\n */\nexport interface Verifier {\n verify(trajectory: Trajectory): Promise<EvaluationResult>;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../lib/v3/verifier/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Shared verifier types for trajectories, rubrics, evidence, and results.\n *\n * The verifier consumes saved trajectories instead of a live browser. DOM and\n * Hybrid runs preserve tool-return text/JSON evidence, while CUA runs preserve\n * screenshots sent to the provider plus independent harness probes.\n */\nimport type { LLMClient } from \"../llm/LLMClient.js\";\nimport type { LogLine } from \"../types/public/logs.js\";\n\n/** Token usage for one or more LLM calls. Matches AgentResult.usage shape. */\nexport interface TrajectoryUsage {\n input_tokens: number;\n output_tokens: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n inference_time_ms?: number;\n}\n\n/** A single criterion in a Stagehand rubric. */\nexport interface RubricCriterion {\n /** Short name of the criterion (e.g., \"Add ground beef to cart\"). */\n criterion: string;\n /** What to evaluate and how to award partial credit. */\n description: string;\n /** Maximum points for this criterion. */\n maxPoints: number;\n /**\n * Applicability rule for situational criteria. When this condition is not\n * met, the criterion is excluded from scoring rather than counted as failed.\n */\n condition?: string;\n}\n\n/** A rubric — list of criteria for a task. */\nexport interface Rubric {\n items: RubricCriterion[];\n}\n\n/**\n * Spec for a single task being verified. Carried both at runtime and into the\n * verifier alongside the trajectory.\n */\nexport interface TaskSpec {\n /** Stable identifier (e.g., \"united_13\" for WebTailBench, task_id for Mind2Web). */\n id: string;\n /** Task instruction shown to the agent. */\n instruction: string;\n /** Starting URL, if any. */\n initUrl?: string;\n /** Rubric carried by the dataset or generated by a verifier backend. */\n precomputedRubric?: Rubric;\n /** Optional reference answer (set when dataset ships one). */\n expectedAnswer?: string;\n}\n\n/**\n * A single modality unit in tier-1 agent evidence. Mirrors the shape of\n * ModelMessage content parts so we can reproduce what the LLM ingested.\n */\nexport type AgentEvidenceModality =\n | { type: \"text\"; content: string }\n | { type: \"image\"; bytes: Buffer; mediaType: string }\n | { type: \"json\"; content: unknown };\n\n/**\n * Tier 1 — exactly the bytes/strings/objects the agent's LLM ingested as the\n * tool result for this step.\n *\n * Modes:\n * - CUA: usually a single image modality (the screenshot sent to the provider).\n * - Hybrid: tool result with optional screenshotBase64 → one image + one text.\n * - DOM: tool returns (extract JSON, ariaTree text, etc.) → text/json modalities.\n */\nexport interface AgentEvidence {\n modalities: AgentEvidenceModality[];\n}\n\n/**\n * Tier 2 — independent harness probes around this step.\n *\n * If a probe wasn't captured, the field is absent (not null).\n */\nexport interface ProbeEvidence {\n /** URL after the step's tool execution. */\n url?: string;\n /**\n * Bus screenshot captured after the step. Path on disk is preferred once\n * persisted; in-memory Buffer is used during a live run.\n */\n screenshot?: Buffer;\n /** Reference to the persisted screenshot file under the trajectory dir. */\n screenshotPath?: string;\n /** Accessibility tree snapshot. */\n ariaTree?: string;\n /** Verifier-requested probes, keyed by criterion id. */\n onDemand?: Record<string, unknown>;\n}\n\n/** Outcome of a single tool execution as seen by the harness. */\nexport interface ToolOutput {\n ok: boolean;\n /**\n * The tool's return value. Same payload that flowed into agentEvidence\n * modalities, but in its native shape (e.g., the extract result, the act\n * describe-string) rather than serialized for the LLM.\n */\n result: unknown;\n error?: string;\n}\n\n/** One step in a trajectory: action + reasoning + evidence + outcome. */\nexport interface TrajectoryStep {\n actionName: string;\n actionArgs: Record<string, unknown>;\n /** From AgentAction.reasoning. May be empty for tools that don't surface reasoning. */\n reasoning: string;\n agentEvidence: AgentEvidence;\n probeEvidence: ProbeEvidence;\n toolOutput: ToolOutput;\n}\n\n/** Terminal status of the agent run. */\nexport type TrajectoryStatus = \"complete\" | \"aborted\" | \"stalled\" | \"error\";\n\n/**\n * Full trajectory for one task run.\n *\n * The on-disk layout is one directory per task:\n *\n * .trajectories/<run-id>/<task-id>/\n * ├── task_data.json — TaskSpec + result metadata\n * ├── trajectory.json — this object, with image paths instead of bytes\n * ├── screenshots/\n * │ ├── probe/<N>.png — tier-2 probe screenshot per step\n * │ ├── probe/final.png — final terminal observation screenshot\n * │ └── agent/<N>.png — tier-1 image the model received per step\n * ├── scores/\n * │ └── result.json — Result from V3Evaluator.verify()\n * └── core.log — captured action log\n */\nexport interface Trajectory {\n task: TaskSpec;\n steps: TrajectoryStep[];\n finalAnswer?: string;\n /** Terminal page observation captured after the agent finishes. */\n finalObservation?: ProbeEvidence;\n status: TrajectoryStatus;\n usage: TrajectoryUsage;\n}\n\n/** A single screenshot kept by Step 1, ready for downstream relevance scoring. */\nexport interface CanonicalScreenshot {\n /** 0-based position in the kept-screenshots array. Stable across the pipeline. */\n canonicalIndex: number;\n /**\n * 0-based position in `Trajectory.steps` this screenshot came from\n * (steps.length for the final observation). Lets downstream prompts\n * cross-reference the action history.\n */\n originalStepIndex: number;\n /** The resized PNG/JPEG buffer (or native bytes if sharp unavailable). */\n bytes: Buffer;\n /** MIME media type. Always \"image/png\" after the optional resize. */\n mediaType: string;\n /** Reason this frame was kept: \"first\" / \"last\" / \"diverges\". */\n keptReason: \"first\" | \"last\" | \"diverges\" | \"no-dedup\";\n}\n\n/**\n * A text evidence point sourced from tier-2 probes or tier-1 tool outputs.\n * These feed the same relevance + scoring path as screenshots, letting DOM\n * and hybrid agents preserve extract/aria/tool-return evidence without a\n * separate verifier architecture.\n */\nexport interface CanonicalTextEvidence {\n /** 0-based position in the combined evidence-point array. */\n canonicalIndex: number;\n originalStepIndex: number;\n /** Where the text came from. */\n source: \"probe-aria\" | \"agent-text\" | \"agent-json\" | \"tool-output\";\n /** The text payload, already truncated. */\n content: string;\n}\n\nexport type CanonicalEvidence = CanonicalScreenshot | CanonicalTextEvidence;\n\n/** Result of Step 1 evidence loading. */\nexport interface EvidenceLoadResult {\n /** Kept frames, in chronological order. */\n screenshots: CanonicalScreenshot[];\n /**\n * Maps trajectory step position → canonical index in `screenshots`. Steps\n * whose screenshots were deduplicated point to the surviving canonical frame\n * (typically the prior kept frame). Useful for \"find me the screenshot for\n * step K\" lookups in downstream prompts.\n */\n stepIndexToCanonical: Map<number, number>;\n /** Number of original frames considered. */\n originalCount: number;\n /** Number of frames kept post-dedup (== screenshots.length). */\n keptCount: number;\n /** Effective thresholds used (resolved from env). */\n thresholds: {\n ssim: number;\n mse: number;\n resize: number;\n };\n}\n\n/** Options for evidence loading; primarily test seams over the defaults. */\nexport interface EvidenceLoadOptions {\n /** SSIM similarity threshold for dedup (default 0.75). */\n ssimThreshold?: number;\n /** MSE similarity threshold for dedup (default 30). */\n mseThreshold?: number;\n /** Scale factor applied before relevance scoring (default 0.7). */\n imageResize?: number;\n}\n\n/** Score for a single rubric criterion after evidence analysis + rescoring. */\nexport interface CriterionScore {\n /** Matches RubricCriterion.criterion (the criterion's short name). */\n criterion: string;\n /** Maximum possible points for this criterion. */\n maxPoints: number;\n /**\n * Points earned after evidence analysis. Null when the criterion is\n * conditional and its condition was not met — excluded from both numerator\n * and denominator in the process score.\n */\n earnedPoints: number | null;\n /** Verifier's explanation for the score. */\n explanation: string;\n /**\n * True if the criterion is conditional and its condition was determined to\n * be met. Absent for non-conditional criteria.\n */\n conditionMet?: boolean;\n /**\n * Set when the verifier had no evidence to ground this criterion in either\n * tier. Treated as uncontrollable failure (full credit) but surfaced here\n * so dashboards can flag low-confidence results.\n */\n evidenceInsufficient?: boolean;\n}\n\n/**\n * Earliest step where the agent's trajectory went off-track, classified\n * against the error taxonomy (7 top-level categories, 1.1–7.4 sub-codes).\n */\nexport interface FirstPointOfFailure {\n stepIndex: number;\n /** Sub-code from the error taxonomy (e.g., \"2.3\" for a specific hallucination type). */\n errorCode: string;\n /** Top-level category name (Selection, Hallucination, etc.). */\n category: string;\n /** Verifier's reasoning for selecting this point. */\n description?: string;\n}\n\n/**\n * Structured observation surfaced by the verifier that another agent or\n * tooling could act on. Findings are emitted opportunistically by Step 8\n * (outcome verification) when the verifier notices actionable patterns —\n * repeated tool-call failures, ambiguous task specs, evidence gaps, etc.\n *\n * Not produced for every task: when nothing actionable surfaces, the\n * `findings` array on the EvaluationResult is empty. Consumers should treat the\n * field as advisory, not as part of the formal score.\n */\nexport interface VerifierFinding {\n /**\n * Category of the observation. Open-ended enum — additional categories may\n * be added as verifier backends surface new failure modes.\n */\n category:\n | \"agent_tool_usage\" // agent's tool calls had repeated issues (misclicks, wrong args, retries)\n | \"agent_strategy\" // higher-level planning / decision-making problems\n | \"rubric_quality\" // criteria were overly strict, ambiguous, or contradictory\n | \"trajectory_capture\" // gaps in evidence (missing screenshots, empty steps)\n | \"task_specification\" // task instruction was ambiguous / under- or over-specified\n | \"verifier_uncertainty\" // verifier itself couldn't confidently decide\n | \"other\";\n /** Impact: info (FYI), warning (worth investigating), blocking (broke the task). */\n severity: \"info\" | \"warning\" | \"blocking\";\n /** What the verifier noticed. Plain prose, grounded in evidence from the trajectory. */\n description: string;\n /**\n * Optional concrete next action another agent could take. Should be\n * specific enough that it can be acted on without further reasoning —\n * e.g., \"Try double_click instead of triple_click to clear placeholder\n * text on this form field.\"\n */\n suggestedAction?: string;\n /** Step indices in the trajectory where this pattern showed up. */\n relatedSteps?: number[];\n}\n\n/** Stable debugging summary emitted by verifier backends. */\nexport interface VerifierRawSteps {\n backend?: \"legacy\" | \"verifier\";\n reason?: string;\n primaryIntent?: string;\n reasoning?: string;\n rubricSource?: \"precomputed\" | \"generated\" | \"none\";\n approach?: \"a\" | \"b\" | \"outcome-only\";\n optionalsMode?: \"folded\" | \"separate\" | \"skip\";\n totalEarned?: number;\n totalMax?: number;\n evidenceImages?: number;\n evidenceTexts?: number;\n evidenceOriginalScreenshots?: number;\n screenshotsAttached?: number;\n legacyEvaluation?: string;\n screenshotCount?: number;\n}\n\n/** Task-validity classification: whether the task is even answerable. */\nexport interface TaskValidity {\n /** True if the task is underspecified / has multiple valid interpretations. */\n isAmbiguous: boolean;\n /** Explanation for why the task is ambiguous, when available. */\n ambiguityReason?: string;\n /** True if the task is impossible / illegal / NSFW / otherwise infeasible. */\n isInvalid: boolean;\n /** Explanation for why the task is invalid, when available. */\n invalidReason?: string;\n /** Optional sub-codes from the task-classification taxonomy. */\n ambiguityCodes?: string[];\n invalidTaskCodes?: string[];\n}\n\n/**\n * Evaluator output. Legacy evaluation may only populate outcome fields; richer\n * verifier backends can also populate process scoring and diagnostics.\n *\n * Process and outcome are deliberately independent when both are present:\n * an agent can follow the right steps but get blocked (high process, low\n * outcome), or succeed through an unexpected path (variable process, high\n * outcome).\n */\nexport interface EvaluationResult {\n /** Did the agent accomplish the task from the user's perspective? */\n outcomeSuccess: boolean;\n /** Human-readable explanation for the outcome. */\n explanation?: string;\n /** Aggregated earned/max across applicable criteria, in [0, 1]. */\n processScore?: number;\n /** Per-criterion breakdown after rescoring. */\n perCriterion?: CriterionScore[];\n /** Step 9a — first step where the trajectory went off-track, if any. */\n firstPointOfFailure?: FirstPointOfFailure;\n /** Step 10 — task-itself ambiguity / validity. */\n taskValidity?: TaskValidity;\n /**\n * Ids (RubricCriterion.criterion strings) of criteria where neither tier of\n * evidence resolved the question. Treated as uncontrollable → full credit,\n * but flagged here so consumers can decide whether to discount the score.\n */\n evidenceInsufficient?: string[];\n /**\n * Structured observations from the verifier that a downstream tool or\n * follow-up agent could act on. Opportunistic — empty when the verifier\n * doesn't notice anything actionable. Not part of the score; advisory.\n */\n findings?: VerifierFinding[];\n /** Debugging summary from the active evaluator backend. */\n rawSteps?: VerifierRawSteps;\n}\n\n/**\n * Verifier interface. Implementations consume a Trajectory and return an\n * EvaluationResult — they MUST NOT touch a live browser.\n */\nexport interface Verifier {\n verify(trajectory: Trajectory): Promise<EvaluationResult>;\n}\n\nexport interface RubricVerifierOptions {\n /** Factory that returns a configured LLMClient. Called per pipeline step so callers can supply step-specific clients. */\n getClient: () => LLMClient;\n /** Optional factory for rubric generation so callers can route it to a stronger model. */\n getRubricGenClient?: () => LLMClient;\n /** Logger; defaults to a no-op so the verifier stays quiet inside V3Evaluator. */\n logger?: (line: LogLine) => void;\n /**\n * Override any verifier knob. Env vars supply the defaults; values here win.\n * Useful for tests and for cross-verify sweeps that want different budgets\n * per run.\n */\n config?: Partial<VerifierConfig>;\n}\n\n/**\n * Resolved verifier knobs. Constructed once from env (and optional overrides)\n * by RubricVerifier's constructor; subsequent verify() calls can pass a\n * Partial to shift any field.\n */\nexport interface VerifierConfig {\n /** Which pipeline path to take: per-criterion (a), fused (b), or skip rubric entirely (outcome-only). */\n approach: \"a\" | \"b\" | \"outcome-only\";\n /** Folded (in fused call), separate (own calls), or skip (omit). */\n optionalSteps: \"folded\" | \"separate\" | \"skip\";\n /** Top-K evidence points selected per criterion. */\n topK: number;\n /** Batch size for the relevance-scoring LLM call. */\n relevanceBatchSize: number;\n /** Image cap on the outcome-only path. */\n outcomeMaxImages: number;\n /** Concurrent LLM calls across batches / criteria. */\n maxParallel: number;\n /** Token budgets for the three evidence channels. */\n evidenceTokenBudget: number;\n outcomeEvidenceTokenBudget: number;\n actionHistoryTokenBudget: number;\n /** Per-section character limits applied during evidence-text assembly. */\n truncation: {\n /** Master switch: when true, all per-section limits go to MAX_SAFE_INTEGER. */\n disabled: boolean;\n evidenceTextPreview: number;\n groupedEvidenceText: number;\n buildEvidenceText: number;\n buildEvidenceAria: number;\n actionHistoryReasoning: number;\n };\n}\n\nexport interface ErrorTaxonomySubCategory {\n /** Sub-code (e.g., \"2.3\"). */\n code: string;\n /** Human-readable name (e.g., \"Output fabrication\"). */\n name: string;\n /** Detailed description ported from the .md. Markdown formatting preserved. */\n description: string;\n}\n\nexport interface ErrorTaxonomyCategory {\n /** Top-level number (1-8). */\n number: number;\n /** Top-level name (e.g., \"Hallucination Errors\"). */\n name: string;\n /** One-sentence summary of the category. */\n summary: string;\n /** Sub-categories. The last one is always an \"Other\" catch-all. */\n subCategories: ErrorTaxonomySubCategory[];\n}\n\nexport interface ParseFailureStepNumbersOptions {\n /**\n * Maximum unique step numbers to expand from ranges. Protects the verifier\n * from malformed model output such as \"0-2147483647\".\n */\n maxExpandedSteps?: number;\n /** Optional inclusive upper bound for accepted step numbers. */\n maxStep?: number;\n}\n"]}
@@ -19,7 +19,10 @@ export type V3EvaluatorConstructorOptions = V3EvaluatorOptions & {
19
19
  modelClientOptions?: ClientOptions;
20
20
  };
21
21
  export declare class V3Evaluator implements Verifier {
22
+ private readonly v3;
22
23
  private readonly backend;
24
+ private readonly modelName;
25
+ private readonly modelClientOptions;
23
26
  private readonly legacyEvaluator;
24
27
  constructor(v3: V3, modelNameOrOptions?: AvailableModel | V3EvaluatorConstructorOptions, modelClientOptions?: ClientOptions, options?: V3EvaluatorOptions);
25
28
  ask(options: EvaluateOptions): Promise<LegacyEvaluationResult>;
@@ -28,5 +31,7 @@ export declare class V3Evaluator implements Verifier {
28
31
  generateRubric(taskSpec: TaskSpec): Promise<Rubric>;
29
32
  private getLegacyBackend;
30
33
  private unavailableVerifierBackend;
34
+ private getClient;
35
+ private getRubricGenClient;
31
36
  private verifyTrajectoryWithLegacyEvaluator;
32
37
  }
@@ -1,13 +1,27 @@
1
+ import { LLMProvider } from "./v3/llm/LLMProvider.js";
1
2
  import { StagehandInvalidArgumentError } from "./v3/types/public/sdkErrors.js";
2
3
  import { LegacyV3Evaluator } from "./v3LegacyEvaluator.js";
4
+ import { RubricVerifier } from "./v3/verifier/rubricVerifier.js";
3
5
  const EVALUATOR_BACKEND_ENV = "STAGEHAND_EVALUATOR_BACKEND";
4
6
  const DEFAULT_EVALUATOR_BACKEND = "legacy";
5
7
  export class V3Evaluator {
8
+ v3;
6
9
  backend;
10
+ modelName;
11
+ modelClientOptions;
7
12
  legacyEvaluator;
8
13
  constructor(v3, modelNameOrOptions, modelClientOptions, options) {
9
14
  const normalizedOptions = normalizeConstructorOptions(modelNameOrOptions, modelClientOptions, options);
10
15
  this.backend = resolveEvaluatorBackend(normalizedOptions.backend);
16
+ this.v3 = v3;
17
+ this.modelName =
18
+ normalizedOptions.modelName ||
19
+ "google/gemini-2.5-flash";
20
+ this.modelClientOptions = normalizedOptions.modelClientOptions || {
21
+ apiKey: process.env.GEMINI_API_KEY ||
22
+ process.env.GOOGLE_GENERATIVE_AI_API_KEY ||
23
+ "",
24
+ };
11
25
  this.legacyEvaluator = new LegacyV3Evaluator(v3, normalizedOptions.modelName, normalizedOptions.modelClientOptions);
12
26
  }
13
27
  async ask(options) {
@@ -21,18 +35,26 @@ export class V3Evaluator {
21
35
  if (this.backend === "legacy") {
22
36
  return this.verifyTrajectoryWithLegacyEvaluator(trajectory, taskSpec);
23
37
  }
24
- return this.unavailableVerifierBackend("verify");
38
+ const verifier = new RubricVerifier({
39
+ getClient: () => this.getClient(),
40
+ getRubricGenClient: () => this.getRubricGenClient(),
41
+ });
42
+ return verifier.verify(trajectory);
25
43
  }
26
44
  async generateRubric(taskSpec) {
27
45
  if (!taskSpec?.id) {
28
46
  throw new StagehandInvalidArgumentError("TaskSpec.id is required for rubric generation");
29
47
  }
30
- if (this.backend === "verifier") {
31
- return this.unavailableVerifierBackend("generateRubric");
48
+ if (this.backend === "legacy") {
49
+ return {
50
+ items: [legacyTaskCompletionCriterion(taskSpec)],
51
+ };
32
52
  }
33
- return {
34
- items: [legacyTaskCompletionCriterion(taskSpec)],
35
- };
53
+ const verifier = new RubricVerifier({
54
+ getClient: () => this.getClient(),
55
+ getRubricGenClient: () => this.getRubricGenClient(),
56
+ });
57
+ return verifier.generateRubric(taskSpec);
36
58
  }
37
59
  getLegacyBackend(methodName) {
38
60
  if (this.backend === "legacy") {
@@ -41,7 +63,25 @@ export class V3Evaluator {
41
63
  return this.unavailableVerifierBackend(methodName);
42
64
  }
43
65
  unavailableVerifierBackend(methodName) {
44
- throw new StagehandInvalidArgumentError(`V3Evaluator.${methodName}() was configured with ${EVALUATOR_BACKEND_ENV}=verifier, but the verifier backend is not available in this build. Use "legacy" or install the verifier backend PR.`);
66
+ throw new StagehandInvalidArgumentError(`V3Evaluator.${methodName}() was configured with ${EVALUATOR_BACKEND_ENV}=verifier, but the verifier backend only supports verify() and generateRubric(). Use "legacy" for ask()/batchAsk().`);
67
+ }
68
+ getClient() {
69
+ const provider = new LLMProvider(this.v3.logger);
70
+ return provider.getClient(this.modelName, this.modelClientOptions);
71
+ }
72
+ getRubricGenClient() {
73
+ const override = process.env.VERIFIER_RUBRIC_MODEL;
74
+ if (!override)
75
+ return this.getClient();
76
+ const provider = new LLMProvider(this.v3.logger);
77
+ const overrideProvider = override.includes("/")
78
+ ? override.slice(0, override.indexOf("/"))
79
+ : undefined;
80
+ const defaultProvider = this.modelName.includes("/")
81
+ ? this.modelName.slice(0, this.modelName.indexOf("/"))
82
+ : undefined;
83
+ const sameProvider = overrideProvider !== undefined && overrideProvider === defaultProvider;
84
+ return provider.getClient(override, sameProvider ? this.modelClientOptions : undefined);
45
85
  }
46
86
  async verifyTrajectoryWithLegacyEvaluator(trajectory, taskSpec) {
47
87
  const screenshots = collectLegacyScreenshots(trajectory);
@@ -1 +1 @@
1
- {"version":3,"file":"v3Evaluator.js","sourceRoot":"","sources":["../../../lib/v3Evaluator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AvailableModel, ClientOptions } from \"./v3/types/public/model.js\";\nimport type {\n EvaluateOptions,\n BatchAskOptions,\n EvaluationResult as LegacyEvaluationResult,\n} from \"./v3/types/private/evaluator.js\";\nimport { V3 } from \"./v3/v3.js\";\nimport { StagehandInvalidArgumentError } from \"./v3/types/public/sdkErrors.js\";\nimport { LegacyV3Evaluator } from \"./v3LegacyEvaluator.js\";\nimport type {\n Trajectory,\n TaskSpec,\n EvaluationResult,\n Rubric,\n Verifier,\n AgentEvidenceModality,\n VerifierFinding,\n} from \"./v3/verifier/index.js\";\n\nconst EVALUATOR_BACKEND_ENV = \"STAGEHAND_EVALUATOR_BACKEND\";\nconst DEFAULT_EVALUATOR_BACKEND: V3EvaluatorBackend = \"legacy\";\n\nexport type V3EvaluatorBackend = \"legacy\" | \"verifier\";\n\nexport type V3EvaluatorOptions = {\n /**\n * Selects the evaluator implementation.\n *\n * \"legacy\" preserves the existing screenshot/text YES/NO evaluator.\n * \"verifier\" is reserved for the rubric verifier backend.\n *\n * @default process.env.STAGEHAND_EVALUATOR_BACKEND || \"legacy\"\n */\n backend?: V3EvaluatorBackend;\n};\n\nexport type V3EvaluatorConstructorOptions = V3EvaluatorOptions & {\n modelName?: AvailableModel;\n modelClientOptions?: ClientOptions;\n};\n\ntype NormalizedConstructorOptions = {\n modelName?: AvailableModel;\n modelClientOptions?: ClientOptions;\n backend?: V3EvaluatorBackend;\n};\n\nexport class V3Evaluator implements Verifier {\n private readonly backend: V3EvaluatorBackend;\n private readonly legacyEvaluator: LegacyV3Evaluator;\n\n constructor(\n v3: V3,\n modelNameOrOptions?: AvailableModel | V3EvaluatorConstructorOptions,\n modelClientOptions?: ClientOptions,\n options?: V3EvaluatorOptions,\n ) {\n const normalizedOptions = normalizeConstructorOptions(\n modelNameOrOptions,\n modelClientOptions,\n options,\n );\n\n this.backend = resolveEvaluatorBackend(normalizedOptions.backend);\n this.legacyEvaluator = new LegacyV3Evaluator(\n v3,\n normalizedOptions.modelName,\n normalizedOptions.modelClientOptions,\n );\n }\n\n async ask(options: EvaluateOptions): Promise<LegacyEvaluationResult> {\n return this.getLegacyBackend(\"ask\").ask(options);\n }\n\n async batchAsk(options: BatchAskOptions): Promise<LegacyEvaluationResult[]> {\n return this.getLegacyBackend(\"batchAsk\").batchAsk(options);\n }\n\n async verify(trajectory: Trajectory): Promise<EvaluationResult> {\n const taskSpec = assertVerifierInput(trajectory);\n\n if (this.backend === \"legacy\") {\n return this.verifyTrajectoryWithLegacyEvaluator(trajectory, taskSpec);\n }\n\n return this.unavailableVerifierBackend(\"verify\");\n }\n\n async generateRubric(taskSpec: TaskSpec): Promise<Rubric> {\n if (!taskSpec?.id) {\n throw new StagehandInvalidArgumentError(\n \"TaskSpec.id is required for rubric generation\",\n );\n }\n\n if (this.backend === \"verifier\") {\n return this.unavailableVerifierBackend(\"generateRubric\");\n }\n\n return {\n items: [legacyTaskCompletionCriterion(taskSpec)],\n };\n }\n\n private getLegacyBackend(methodName: string): LegacyV3Evaluator {\n if (this.backend === \"legacy\") {\n return this.legacyEvaluator;\n }\n\n return this.unavailableVerifierBackend(methodName);\n }\n\n private unavailableVerifierBackend(methodName: string): never {\n throw new StagehandInvalidArgumentError(\n `V3Evaluator.${methodName}() was configured with ${EVALUATOR_BACKEND_ENV}=verifier, but the verifier backend is not available in this build. Use \"legacy\" or install the verifier backend PR.`,\n );\n }\n\n private async verifyTrajectoryWithLegacyEvaluator(\n trajectory: Trajectory,\n taskSpec: TaskSpec,\n ): Promise<EvaluationResult> {\n const screenshots = collectLegacyScreenshots(trajectory);\n const agentReasoning = renderLegacyAgentReasoning(trajectory);\n const answer = trajectory.finalAnswer;\n\n if (!screenshots.length && !answer) {\n return legacyInsufficientEvidenceResult(\n \"Legacy evaluator compatibility mode had no screenshots or final answer to evaluate.\",\n );\n }\n\n const result = await this.legacyEvaluator.ask({\n question: taskSpec.instruction,\n screenshot: screenshots.length ? screenshots : false,\n answer,\n agentReasoning,\n });\n\n return legacyEvaluationToResult(result, screenshots.length);\n }\n}\n\nfunction normalizeConstructorOptions(\n modelNameOrOptions?: AvailableModel | V3EvaluatorConstructorOptions,\n modelClientOptions?: ClientOptions,\n options?: V3EvaluatorOptions,\n): NormalizedConstructorOptions {\n if (\n modelNameOrOptions &&\n typeof modelNameOrOptions === \"object\" &&\n !Array.isArray(modelNameOrOptions)\n ) {\n return {\n modelName: modelNameOrOptions.modelName,\n modelClientOptions: modelNameOrOptions.modelClientOptions,\n backend: modelNameOrOptions.backend ?? options?.backend,\n };\n }\n\n return {\n modelName: modelNameOrOptions as AvailableModel | undefined,\n modelClientOptions,\n backend: options?.backend,\n };\n}\n\nfunction resolveEvaluatorBackend(\n explicitBackend?: V3EvaluatorBackend,\n): V3EvaluatorBackend {\n const configuredBackend =\n explicitBackend ??\n process.env[EVALUATOR_BACKEND_ENV] ??\n DEFAULT_EVALUATOR_BACKEND;\n const normalizedBackend = configuredBackend.trim().toLowerCase();\n\n if (normalizedBackend === \"legacy\" || normalizedBackend === \"verifier\") {\n return normalizedBackend;\n }\n\n throw new StagehandInvalidArgumentError(\n `Invalid ${EVALUATOR_BACKEND_ENV}=\"${configuredBackend}\". Expected \"legacy\" or \"verifier\".`,\n );\n}\n\nfunction assertVerifierInput(trajectory: Trajectory): TaskSpec {\n if (!trajectory) {\n throw new StagehandInvalidArgumentError(\n \"Trajectory is required for verification\",\n );\n }\n if (!trajectory.task?.id) {\n throw new StagehandInvalidArgumentError(\n \"Trajectory.task.id is required for verification\",\n );\n }\n return trajectory.task;\n}\n\nfunction legacyTaskCompletionCriterion(taskSpec: TaskSpec) {\n return {\n criterion: \"legacy-task-completion\",\n description: `Evaluate whether the task was completed successfully: ${taskSpec.instruction}`,\n maxPoints: 1,\n };\n}\n\nfunction collectLegacyScreenshots(trajectory: Trajectory): Buffer[] {\n const screenshots: Buffer[] = [];\n\n for (const step of trajectory.steps ?? []) {\n if (Buffer.isBuffer(step.probeEvidence?.screenshot)) {\n screenshots.push(step.probeEvidence.screenshot);\n continue;\n }\n\n const agentImage = step.agentEvidence?.modalities?.find(\n (\n modality,\n ): modality is Extract<AgentEvidenceModality, { type: \"image\" }> =>\n modality.type === \"image\" && Buffer.isBuffer(modality.bytes),\n );\n\n if (agentImage) {\n screenshots.push(agentImage.bytes);\n }\n }\n\n if (Buffer.isBuffer(trajectory.finalObservation?.screenshot)) {\n screenshots.push(trajectory.finalObservation.screenshot);\n }\n\n return screenshots;\n}\n\nfunction renderLegacyAgentReasoning(\n trajectory: Trajectory,\n): string | undefined {\n const stepLines = (trajectory.steps ?? []).map((step, i) => {\n const status = step.toolOutput?.ok === false ? \"Tool status: failed\" : \"\";\n const output = step.toolOutput?.error\n ? `Tool error: ${step.toolOutput.error}`\n : `Tool output: ${stringifyForPrompt(step.toolOutput?.result)}`;\n return [\n `Step ${i}: ${step.actionName}`,\n step.reasoning ? `Reasoning: ${step.reasoning}` : undefined,\n status || undefined,\n output,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n });\n\n if (!stepLines.length) {\n return undefined;\n }\n\n return truncateForPrompt(\n `Agent trajectory:\\n${stepLines.join(\"\\n\\n\")}`,\n 16000,\n );\n}\n\nfunction stringifyForPrompt(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n try {\n const serialized = JSON.stringify(value);\n return serialized ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction truncateForPrompt(value: string, maxLength: number): string {\n if (value.length <= maxLength) {\n return value;\n }\n\n return `${value.slice(0, maxLength)}... [truncated]`;\n}\n\nfunction legacyEvaluationToResult(\n result: LegacyEvaluationResult,\n screenshotCount: number,\n): EvaluationResult {\n const outcomeSuccess = result.evaluation === \"YES\";\n const invalid = result.evaluation === \"INVALID\";\n const findings: VerifierFinding[] = invalid\n ? [\n {\n category: \"verifier_uncertainty\",\n severity: \"warning\",\n description: result.reasoning,\n },\n ]\n : [];\n\n return {\n outcomeSuccess,\n explanation: result.reasoning,\n ...(findings.length ? { findings } : {}),\n rawSteps: {\n backend: \"legacy\",\n legacyEvaluation: result.evaluation,\n screenshotCount,\n },\n };\n}\n\nfunction legacyInsufficientEvidenceResult(reason: string): EvaluationResult {\n return {\n outcomeSuccess: false,\n explanation: reason,\n findings: [\n {\n category: \"trajectory_capture\",\n severity: \"blocking\",\n description: reason,\n },\n ],\n rawSteps: {\n backend: \"legacy\",\n legacyEvaluation: \"INVALID\",\n screenshotCount: 0,\n },\n };\n}\n"]}
1
+ {"version":3,"file":"v3Evaluator.js","sourceRoot":"","sources":["../../../lib/v3Evaluator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AvailableModel, ClientOptions } from \"./v3/types/public/model.js\";\nimport type {\n EvaluateOptions,\n BatchAskOptions,\n EvaluationResult as LegacyEvaluationResult,\n} from \"./v3/types/private/evaluator.js\";\nimport { V3 } from \"./v3/v3.js\";\nimport type { LLMClient } from \"./v3/llm/LLMClient.js\";\nimport { LLMProvider } from \"./v3/llm/LLMProvider.js\";\nimport { StagehandInvalidArgumentError } from \"./v3/types/public/sdkErrors.js\";\nimport { LegacyV3Evaluator } from \"./v3LegacyEvaluator.js\";\nimport { RubricVerifier } from \"./v3/verifier/rubricVerifier.js\";\nimport type {\n Trajectory,\n TaskSpec,\n EvaluationResult,\n Rubric,\n Verifier,\n AgentEvidenceModality,\n VerifierFinding,\n} from \"./v3/verifier/index.js\";\n\nconst EVALUATOR_BACKEND_ENV = \"STAGEHAND_EVALUATOR_BACKEND\";\nconst DEFAULT_EVALUATOR_BACKEND: V3EvaluatorBackend = \"legacy\";\n\nexport type V3EvaluatorBackend = \"legacy\" | \"verifier\";\n\nexport type V3EvaluatorOptions = {\n /**\n * Selects the evaluator implementation.\n *\n * \"legacy\" preserves the existing screenshot/text YES/NO evaluator.\n * \"verifier\" is reserved for the rubric verifier backend.\n *\n * @default process.env.STAGEHAND_EVALUATOR_BACKEND || \"legacy\"\n */\n backend?: V3EvaluatorBackend;\n};\n\nexport type V3EvaluatorConstructorOptions = V3EvaluatorOptions & {\n modelName?: AvailableModel;\n modelClientOptions?: ClientOptions;\n};\n\ntype NormalizedConstructorOptions = {\n modelName?: AvailableModel;\n modelClientOptions?: ClientOptions;\n backend?: V3EvaluatorBackend;\n};\n\nexport class V3Evaluator implements Verifier {\n private readonly v3: V3;\n private readonly backend: V3EvaluatorBackend;\n private readonly modelName: AvailableModel;\n private readonly modelClientOptions: ClientOptions | { apiKey: string };\n private readonly legacyEvaluator: LegacyV3Evaluator;\n\n constructor(\n v3: V3,\n modelNameOrOptions?: AvailableModel | V3EvaluatorConstructorOptions,\n modelClientOptions?: ClientOptions,\n options?: V3EvaluatorOptions,\n ) {\n const normalizedOptions = normalizeConstructorOptions(\n modelNameOrOptions,\n modelClientOptions,\n options,\n );\n\n this.backend = resolveEvaluatorBackend(normalizedOptions.backend);\n this.v3 = v3;\n this.modelName =\n normalizedOptions.modelName ||\n (\"google/gemini-2.5-flash\" as AvailableModel);\n this.modelClientOptions = normalizedOptions.modelClientOptions || {\n apiKey:\n process.env.GEMINI_API_KEY ||\n process.env.GOOGLE_GENERATIVE_AI_API_KEY ||\n \"\",\n };\n this.legacyEvaluator = new LegacyV3Evaluator(\n v3,\n normalizedOptions.modelName,\n normalizedOptions.modelClientOptions,\n );\n }\n\n async ask(options: EvaluateOptions): Promise<LegacyEvaluationResult> {\n return this.getLegacyBackend(\"ask\").ask(options);\n }\n\n async batchAsk(options: BatchAskOptions): Promise<LegacyEvaluationResult[]> {\n return this.getLegacyBackend(\"batchAsk\").batchAsk(options);\n }\n\n async verify(trajectory: Trajectory): Promise<EvaluationResult> {\n const taskSpec = assertVerifierInput(trajectory);\n\n if (this.backend === \"legacy\") {\n return this.verifyTrajectoryWithLegacyEvaluator(trajectory, taskSpec);\n }\n\n const verifier = new RubricVerifier({\n getClient: () => this.getClient(),\n getRubricGenClient: () => this.getRubricGenClient(),\n });\n return verifier.verify(trajectory);\n }\n\n async generateRubric(taskSpec: TaskSpec): Promise<Rubric> {\n if (!taskSpec?.id) {\n throw new StagehandInvalidArgumentError(\n \"TaskSpec.id is required for rubric generation\",\n );\n }\n\n if (this.backend === \"legacy\") {\n return {\n items: [legacyTaskCompletionCriterion(taskSpec)],\n };\n }\n\n const verifier = new RubricVerifier({\n getClient: () => this.getClient(),\n getRubricGenClient: () => this.getRubricGenClient(),\n });\n return verifier.generateRubric(taskSpec);\n }\n\n private getLegacyBackend(methodName: string): LegacyV3Evaluator {\n if (this.backend === \"legacy\") {\n return this.legacyEvaluator;\n }\n\n return this.unavailableVerifierBackend(methodName);\n }\n\n private unavailableVerifierBackend(methodName: string): never {\n throw new StagehandInvalidArgumentError(\n `V3Evaluator.${methodName}() was configured with ${EVALUATOR_BACKEND_ENV}=verifier, but the verifier backend only supports verify() and generateRubric(). Use \"legacy\" for ask()/batchAsk().`,\n );\n }\n\n private getClient(): LLMClient {\n const provider = new LLMProvider(this.v3.logger);\n return provider.getClient(this.modelName, this.modelClientOptions);\n }\n\n private getRubricGenClient(): LLMClient {\n const override = process.env.VERIFIER_RUBRIC_MODEL as\n | AvailableModel\n | undefined;\n if (!override) return this.getClient();\n\n const provider = new LLMProvider(this.v3.logger);\n const overrideProvider = override.includes(\"/\")\n ? override.slice(0, override.indexOf(\"/\"))\n : undefined;\n const defaultProvider = this.modelName.includes(\"/\")\n ? this.modelName.slice(0, this.modelName.indexOf(\"/\"))\n : undefined;\n const sameProvider =\n overrideProvider !== undefined && overrideProvider === defaultProvider;\n\n return provider.getClient(\n override,\n sameProvider ? this.modelClientOptions : undefined,\n );\n }\n\n private async verifyTrajectoryWithLegacyEvaluator(\n trajectory: Trajectory,\n taskSpec: TaskSpec,\n ): Promise<EvaluationResult> {\n const screenshots = collectLegacyScreenshots(trajectory);\n const agentReasoning = renderLegacyAgentReasoning(trajectory);\n const answer = trajectory.finalAnswer;\n\n if (!screenshots.length && !answer) {\n return legacyInsufficientEvidenceResult(\n \"Legacy evaluator compatibility mode had no screenshots or final answer to evaluate.\",\n );\n }\n\n const result = await this.legacyEvaluator.ask({\n question: taskSpec.instruction,\n screenshot: screenshots.length ? screenshots : false,\n answer,\n agentReasoning,\n });\n\n return legacyEvaluationToResult(result, screenshots.length);\n }\n}\n\nfunction normalizeConstructorOptions(\n modelNameOrOptions?: AvailableModel | V3EvaluatorConstructorOptions,\n modelClientOptions?: ClientOptions,\n options?: V3EvaluatorOptions,\n): NormalizedConstructorOptions {\n if (\n modelNameOrOptions &&\n typeof modelNameOrOptions === \"object\" &&\n !Array.isArray(modelNameOrOptions)\n ) {\n return {\n modelName: modelNameOrOptions.modelName,\n modelClientOptions: modelNameOrOptions.modelClientOptions,\n backend: modelNameOrOptions.backend ?? options?.backend,\n };\n }\n\n return {\n modelName: modelNameOrOptions as AvailableModel | undefined,\n modelClientOptions,\n backend: options?.backend,\n };\n}\n\nfunction resolveEvaluatorBackend(\n explicitBackend?: V3EvaluatorBackend,\n): V3EvaluatorBackend {\n const configuredBackend =\n explicitBackend ??\n process.env[EVALUATOR_BACKEND_ENV] ??\n DEFAULT_EVALUATOR_BACKEND;\n const normalizedBackend = configuredBackend.trim().toLowerCase();\n\n if (normalizedBackend === \"legacy\" || normalizedBackend === \"verifier\") {\n return normalizedBackend;\n }\n\n throw new StagehandInvalidArgumentError(\n `Invalid ${EVALUATOR_BACKEND_ENV}=\"${configuredBackend}\". Expected \"legacy\" or \"verifier\".`,\n );\n}\n\nfunction assertVerifierInput(trajectory: Trajectory): TaskSpec {\n if (!trajectory) {\n throw new StagehandInvalidArgumentError(\n \"Trajectory is required for verification\",\n );\n }\n if (!trajectory.task?.id) {\n throw new StagehandInvalidArgumentError(\n \"Trajectory.task.id is required for verification\",\n );\n }\n return trajectory.task;\n}\n\nfunction legacyTaskCompletionCriterion(taskSpec: TaskSpec) {\n return {\n criterion: \"legacy-task-completion\",\n description: `Evaluate whether the task was completed successfully: ${taskSpec.instruction}`,\n maxPoints: 1,\n };\n}\n\nfunction collectLegacyScreenshots(trajectory: Trajectory): Buffer[] {\n const screenshots: Buffer[] = [];\n\n for (const step of trajectory.steps ?? []) {\n if (Buffer.isBuffer(step.probeEvidence?.screenshot)) {\n screenshots.push(step.probeEvidence.screenshot);\n continue;\n }\n\n const agentImage = step.agentEvidence?.modalities?.find(\n (\n modality,\n ): modality is Extract<AgentEvidenceModality, { type: \"image\" }> =>\n modality.type === \"image\" && Buffer.isBuffer(modality.bytes),\n );\n\n if (agentImage) {\n screenshots.push(agentImage.bytes);\n }\n }\n\n if (Buffer.isBuffer(trajectory.finalObservation?.screenshot)) {\n screenshots.push(trajectory.finalObservation.screenshot);\n }\n\n return screenshots;\n}\n\nfunction renderLegacyAgentReasoning(\n trajectory: Trajectory,\n): string | undefined {\n const stepLines = (trajectory.steps ?? []).map((step, i) => {\n const status = step.toolOutput?.ok === false ? \"Tool status: failed\" : \"\";\n const output = step.toolOutput?.error\n ? `Tool error: ${step.toolOutput.error}`\n : `Tool output: ${stringifyForPrompt(step.toolOutput?.result)}`;\n return [\n `Step ${i}: ${step.actionName}`,\n step.reasoning ? `Reasoning: ${step.reasoning}` : undefined,\n status || undefined,\n output,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n });\n\n if (!stepLines.length) {\n return undefined;\n }\n\n return truncateForPrompt(\n `Agent trajectory:\\n${stepLines.join(\"\\n\\n\")}`,\n 16000,\n );\n}\n\nfunction stringifyForPrompt(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n try {\n const serialized = JSON.stringify(value);\n return serialized ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction truncateForPrompt(value: string, maxLength: number): string {\n if (value.length <= maxLength) {\n return value;\n }\n\n return `${value.slice(0, maxLength)}... [truncated]`;\n}\n\nfunction legacyEvaluationToResult(\n result: LegacyEvaluationResult,\n screenshotCount: number,\n): EvaluationResult {\n const outcomeSuccess = result.evaluation === \"YES\";\n const invalid = result.evaluation === \"INVALID\";\n const findings: VerifierFinding[] = invalid\n ? [\n {\n category: \"verifier_uncertainty\",\n severity: \"warning\",\n description: result.reasoning,\n },\n ]\n : [];\n\n return {\n outcomeSuccess,\n explanation: result.reasoning,\n ...(findings.length ? { findings } : {}),\n rawSteps: {\n backend: \"legacy\",\n legacyEvaluation: result.evaluation,\n screenshotCount,\n },\n };\n}\n\nfunction legacyInsufficientEvidenceResult(reason: string): EvaluationResult {\n return {\n outcomeSuccess: false,\n explanation: reason,\n findings: [\n {\n category: \"trajectory_capture\",\n severity: \"blocking\",\n description: reason,\n },\n ],\n rawSteps: {\n backend: \"legacy\",\n legacyEvaluation: \"INVALID\",\n screenshotCount: 0,\n },\n };\n}\n"]}
@@ -2,4 +2,4 @@
2
2
  * AUTO-GENERATED — DO NOT EDIT BY HAND
3
3
  * Run `pnpm run gen-version` to refresh.
4
4
  */
5
- export declare const STAGEHAND_VERSION: "3.5.0";
5
+ export declare const STAGEHAND_VERSION: "3.6.0";
@@ -2,5 +2,5 @@
2
2
  * AUTO-GENERATED — DO NOT EDIT BY HAND
3
3
  * Run `pnpm run gen-version` to refresh.
4
4
  */
5
- export const STAGEHAND_VERSION = "3.5.0";
5
+ export const STAGEHAND_VERSION = "3.6.0";
6
6
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../lib/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAgB,CAAC","sourcesContent":["/**\n * AUTO-GENERATED — DO NOT EDIT BY HAND\n * Run `pnpm run gen-version` to refresh.\n */\nexport const STAGEHAND_VERSION = \"3.5.0\" as const;\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../lib/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAgB,CAAC","sourcesContent":["/**\n * AUTO-GENERATED — DO NOT EDIT BY HAND\n * Run `pnpm run gen-version` to refresh.\n */\nexport const STAGEHAND_VERSION = \"3.6.0\" as const;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserbasehq/orca",
3
- "version": "3.5.1-preview.0",
3
+ "version": "3.6.0-gemini-cua",
4
4
  "description": "An AI web browsing framework focused on simplicity and extensibility.",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -35,10 +35,10 @@
35
35
  "build-dom-scripts": "tsx scripts/build-dom-scripts.ts",
36
36
  "build:cjs": "tsx scripts/build-cjs.ts",
37
37
  "build:esm": "tsx scripts/build-esm.ts",
38
- "build": "pnpm --filter @browserbasehq/stagehand run --parallel \"/^build:(esm|cjs)$/\"",
39
- "prepack": "pnpm -w --dir ../.. exec turbo run build --filter=@browserbasehq/stagehand",
38
+ "build": "pnpm --filter @browserbasehq/orca run --parallel \"/^build:(esm|cjs)$/\"",
39
+ "prepack": "pnpm -w --dir ../.. exec turbo run build --filter=@browserbasehq/orca",
40
40
  "example": "node --import tsx -e \"const args=process.argv.slice(1).filter(a=>a!=='--'); const [p]=args; const n=(p||'example').replace(/^\\.\\//,'').replace(/\\.ts$/i,''); import('node:path').then(path=>import(new URL(path.resolve('examples', n + '.ts'), 'file:')));\" --",
41
- "test": "pnpm -w --dir ../.. exec turbo run test:core test:e2e --filter=@browserbasehq/stagehand --",
41
+ "test": "pnpm -w --dir ../.. exec turbo run test:core test:e2e --filter=@browserbasehq/orca --",
42
42
  "test:core": "tsx scripts/test-core.ts",
43
43
  "test:e2e": "tsx scripts/test-e2e.ts",
44
44
  "format": "prettier --write .",
@@ -101,7 +101,7 @@
101
101
  },
102
102
  "optionalDependencies": {
103
103
  "@ai-sdk/amazon-bedrock": "^3.0.73",
104
- "@ai-sdk/anthropic": "^2.0.34",
104
+ "@ai-sdk/anthropic": "^2.0.81",
105
105
  "@ai-sdk/azure": "^2.0.109",
106
106
  "@ai-sdk/cerebras": "^1.0.25",
107
107
  "@ai-sdk/deepseek": "^1.0.23",
@@ -123,7 +123,7 @@
123
123
  "@types/jsdom": "^27.0.0",
124
124
  "@types/node": "^20.11.30",
125
125
  "@types/ws": "^8.5.13",
126
- "@vitest/coverage-v8": "^4.0.8",
126
+ "@vitest/coverage-v8": "^4.1.9",
127
127
  "adm-zip": "^0.5.16",
128
128
  "chalk": "^5.4.1",
129
129
  "eslint": "10.0.2",
@@ -134,8 +134,8 @@
134
134
  "prettier": "^3.2.5",
135
135
  "puppeteer-core": "^24.43.0",
136
136
  "tsx": "*",
137
- "vite": "^7.3.3",
138
- "vitest": "^4.1.6",
137
+ "vite": "^7.3.5",
138
+ "vitest": "^4.1.9",
139
139
  "zod": "^3.25.76 || ^4.2.0"
140
140
  },
141
141
  "repository": {