@browserbasehq/orca 3.2.1-preview.3 → 3.4.0-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/dist/cjs/lib/inference.js +1 -8
  2. package/dist/cjs/lib/inference.js.map +1 -1
  3. package/dist/cjs/lib/prompt.js +3 -1
  4. package/dist/cjs/lib/prompt.js.map +1 -1
  5. package/dist/cjs/lib/v3/agent/AgentProvider.js +3 -0
  6. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  7. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js +16 -12
  8. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  9. package/dist/cjs/lib/v3/agent/utils/validateExperimentalFeatures.js +0 -4
  10. package/dist/cjs/lib/v3/agent/utils/validateExperimentalFeatures.js.map +1 -1
  11. package/dist/cjs/lib/v3/api.d.ts +1 -0
  12. package/dist/cjs/lib/v3/api.js +15 -3
  13. package/dist/cjs/lib/v3/api.js.map +1 -1
  14. package/dist/cjs/lib/v3/dom/build/a11yScripts.generated.js +12 -12
  15. package/dist/cjs/lib/v3/dom/build/a11yScripts.generated.js.map +1 -1
  16. package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.js +48 -48
  17. package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.js.map +1 -1
  18. package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.d.ts +1 -1
  19. package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.js +1 -1
  20. package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.js.map +1 -1
  21. package/dist/cjs/lib/v3/dom/build/screenshotScripts.generated.js +2 -2
  22. package/dist/cjs/lib/v3/dom/build/screenshotScripts.generated.js.map +1 -1
  23. package/dist/cjs/lib/v3/dom/build/scriptV3Content.d.ts +1 -1
  24. package/dist/cjs/lib/v3/dom/build/scriptV3Content.js +1 -1
  25. package/dist/cjs/lib/v3/dom/build/scriptV3Content.js.map +1 -1
  26. package/dist/cjs/lib/v3/handlers/extractHandler.js +3 -1
  27. package/dist/cjs/lib/v3/handlers/extractHandler.js.map +1 -1
  28. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +3 -5
  29. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  30. package/dist/cjs/lib/v3/index.d.ts +1 -1
  31. package/dist/cjs/lib/v3/llm/CerebrasClient.js +1 -1
  32. package/dist/cjs/lib/v3/llm/CerebrasClient.js.map +1 -1
  33. package/dist/cjs/lib/v3/llm/GroqClient.js +1 -1
  34. package/dist/cjs/lib/v3/llm/GroqClient.js.map +1 -1
  35. package/dist/cjs/lib/v3/types/private/agent.d.ts +5 -0
  36. package/dist/cjs/lib/v3/types/private/agent.js +11 -0
  37. package/dist/cjs/lib/v3/types/private/agent.js.map +1 -1
  38. package/dist/cjs/lib/v3/types/private/handlers.d.ts +1 -0
  39. package/dist/cjs/lib/v3/types/private/handlers.js.map +1 -1
  40. package/dist/cjs/lib/v3/types/private/snapshot.d.ts +8 -0
  41. package/dist/cjs/lib/v3/types/private/snapshot.js.map +1 -1
  42. package/dist/cjs/lib/v3/types/public/agent.d.ts +2 -3
  43. package/dist/cjs/lib/v3/types/public/agent.js +3 -0
  44. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  45. package/dist/cjs/lib/v3/types/public/api.d.ts +5 -1
  46. package/dist/cjs/lib/v3/types/public/api.js +15 -2
  47. package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
  48. package/dist/cjs/lib/v3/types/public/methods.d.ts +1 -0
  49. package/dist/cjs/lib/v3/types/public/methods.js.map +1 -1
  50. package/dist/cjs/lib/v3/understudy/a11y/snapshot/a11yTree.js +21 -12
  51. package/dist/cjs/lib/v3/understudy/a11y/snapshot/a11yTree.js.map +1 -1
  52. package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.d.ts +11 -2
  53. package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.js +268 -21
  54. package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.js.map +1 -1
  55. package/dist/cjs/lib/v3/understudy/a11y/snapshot/domTree.js +60 -7
  56. package/dist/cjs/lib/v3/understudy/a11y/snapshot/domTree.js.map +1 -1
  57. package/dist/cjs/lib/v3/understudy/frameRegistry.js +16 -5
  58. package/dist/cjs/lib/v3/understudy/frameRegistry.js.map +1 -1
  59. package/dist/cjs/lib/v3/v3.d.ts +1 -0
  60. package/dist/cjs/lib/v3/v3.js +15 -14
  61. package/dist/cjs/lib/v3/v3.js.map +1 -1
  62. package/dist/cjs/lib/version.d.ts +1 -1
  63. package/dist/cjs/lib/version.js +1 -1
  64. package/dist/cjs/lib/version.js.map +1 -1
  65. package/dist/cjs/tests/integration/observe-element-id-format.spec.js +130 -0
  66. package/dist/cjs/tests/integration/observe-element-id-format.spec.js.map +1 -0
  67. package/dist/cjs/tests/unit/agent-mode-routing.test.js +88 -0
  68. package/dist/cjs/tests/unit/agent-mode-routing.test.js.map +1 -0
  69. package/dist/cjs/tests/unit/agent-temperature.test.d.ts +1 -0
  70. package/dist/cjs/tests/unit/agent-temperature.test.js +191 -0
  71. package/dist/cjs/tests/unit/agent-temperature.test.js.map +1 -0
  72. package/dist/cjs/tests/unit/agent-variables-validation.test.d.ts +1 -0
  73. package/dist/cjs/tests/unit/agent-variables-validation.test.js +43 -0
  74. package/dist/cjs/tests/unit/agent-variables-validation.test.js.map +1 -0
  75. package/dist/cjs/tests/unit/api-client-observe-variables.test.js +47 -0
  76. package/dist/cjs/tests/unit/api-client-observe-variables.test.js.map +1 -1
  77. package/dist/cjs/tests/unit/api-optional-model-api-key.test.js +60 -0
  78. package/dist/cjs/tests/unit/api-optional-model-api-key.test.js.map +1 -1
  79. package/dist/cjs/tests/unit/api-variables-schema.test.js +25 -0
  80. package/dist/cjs/tests/unit/api-variables-schema.test.js.map +1 -1
  81. package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.d.ts +1 -0
  82. package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.js +60 -0
  83. package/dist/cjs/tests/unit/frame-registry-oopif-adoption.test.js.map +1 -0
  84. package/dist/cjs/tests/unit/inference-temperature.test.d.ts +1 -0
  85. package/dist/cjs/tests/unit/inference-temperature.test.js +65 -0
  86. package/dist/cjs/tests/unit/inference-temperature.test.js.map +1 -0
  87. package/dist/cjs/tests/unit/openai-compatible-temperature.test.d.ts +1 -0
  88. package/dist/cjs/tests/unit/openai-compatible-temperature.test.js +84 -0
  89. package/dist/cjs/tests/unit/openai-compatible-temperature.test.js.map +1 -0
  90. package/dist/cjs/tests/unit/prompt-observe-variables.test.js +6 -0
  91. package/dist/cjs/tests/unit/prompt-observe-variables.test.js.map +1 -1
  92. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js +3 -0
  93. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  94. package/dist/cjs/tests/unit/public-api/public-types.test.js.map +1 -1
  95. package/dist/cjs/tests/unit/snapshot-a11y-resolvers.test.js +106 -5
  96. package/dist/cjs/tests/unit/snapshot-a11y-resolvers.test.js.map +1 -1
  97. package/dist/cjs/tests/unit/snapshot-a11y-tree-utils.test.js +20 -0
  98. package/dist/cjs/tests/unit/snapshot-a11y-tree-utils.test.js.map +1 -1
  99. package/dist/cjs/tests/unit/snapshot-capture-orchestration.test.js +119 -9
  100. package/dist/cjs/tests/unit/snapshot-capture-orchestration.test.js.map +1 -1
  101. package/dist/esm/lib/inference.js +1 -8
  102. package/dist/esm/lib/inference.js.map +1 -1
  103. package/dist/esm/lib/prompt.js +3 -1
  104. package/dist/esm/lib/prompt.js.map +1 -1
  105. package/dist/esm/lib/v3/agent/AgentProvider.js +3 -0
  106. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  107. package/dist/esm/lib/v3/agent/tools/fillFormVision.js +16 -12
  108. package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  109. package/dist/esm/lib/v3/agent/utils/validateExperimentalFeatures.js +0 -4
  110. package/dist/esm/lib/v3/agent/utils/validateExperimentalFeatures.js.map +1 -1
  111. package/dist/esm/lib/v3/api.d.ts +1 -0
  112. package/dist/esm/lib/v3/api.js +15 -3
  113. package/dist/esm/lib/v3/api.js.map +1 -1
  114. package/dist/esm/lib/v3/dom/build/a11yScripts.generated.js +12 -12
  115. package/dist/esm/lib/v3/dom/build/a11yScripts.generated.js.map +1 -1
  116. package/dist/esm/lib/v3/dom/build/locatorScripts.generated.js +48 -48
  117. package/dist/esm/lib/v3/dom/build/locatorScripts.generated.js.map +1 -1
  118. package/dist/esm/lib/v3/dom/build/reRenderScriptContent.d.ts +1 -1
  119. package/dist/esm/lib/v3/dom/build/reRenderScriptContent.js +1 -1
  120. package/dist/esm/lib/v3/dom/build/reRenderScriptContent.js.map +1 -1
  121. package/dist/esm/lib/v3/dom/build/screenshotScripts.generated.js +2 -2
  122. package/dist/esm/lib/v3/dom/build/screenshotScripts.generated.js.map +1 -1
  123. package/dist/esm/lib/v3/dom/build/scriptV3Content.d.ts +1 -1
  124. package/dist/esm/lib/v3/dom/build/scriptV3Content.js +1 -1
  125. package/dist/esm/lib/v3/dom/build/scriptV3Content.js.map +1 -1
  126. package/dist/esm/lib/v3/handlers/extractHandler.js +3 -1
  127. package/dist/esm/lib/v3/handlers/extractHandler.js.map +1 -1
  128. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +3 -5
  129. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  130. package/dist/esm/lib/v3/index.d.ts +1 -1
  131. package/dist/esm/lib/v3/llm/CerebrasClient.js +1 -1
  132. package/dist/esm/lib/v3/llm/CerebrasClient.js.map +1 -1
  133. package/dist/esm/lib/v3/llm/GroqClient.js +1 -1
  134. package/dist/esm/lib/v3/llm/GroqClient.js.map +1 -1
  135. package/dist/esm/lib/v3/types/private/agent.d.ts +5 -0
  136. package/dist/esm/lib/v3/types/private/agent.js +10 -1
  137. package/dist/esm/lib/v3/types/private/agent.js.map +1 -1
  138. package/dist/esm/lib/v3/types/private/handlers.d.ts +1 -0
  139. package/dist/esm/lib/v3/types/private/handlers.js.map +1 -1
  140. package/dist/esm/lib/v3/types/private/snapshot.d.ts +8 -0
  141. package/dist/esm/lib/v3/types/private/snapshot.js.map +1 -1
  142. package/dist/esm/lib/v3/types/public/agent.d.ts +2 -3
  143. package/dist/esm/lib/v3/types/public/agent.js +3 -0
  144. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  145. package/dist/esm/lib/v3/types/public/api.d.ts +5 -1
  146. package/dist/esm/lib/v3/types/public/api.js +15 -2
  147. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  148. package/dist/esm/lib/v3/types/public/methods.d.ts +1 -0
  149. package/dist/esm/lib/v3/types/public/methods.js.map +1 -1
  150. package/dist/esm/lib/v3/understudy/a11y/snapshot/a11yTree.js +21 -12
  151. package/dist/esm/lib/v3/understudy/a11y/snapshot/a11yTree.js.map +1 -1
  152. package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.d.ts +11 -2
  153. package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.js +267 -22
  154. package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.js.map +1 -1
  155. package/dist/esm/lib/v3/understudy/a11y/snapshot/domTree.js +60 -7
  156. package/dist/esm/lib/v3/understudy/a11y/snapshot/domTree.js.map +1 -1
  157. package/dist/esm/lib/v3/understudy/frameRegistry.js +16 -5
  158. package/dist/esm/lib/v3/understudy/frameRegistry.js.map +1 -1
  159. package/dist/esm/lib/v3/v3.d.ts +1 -0
  160. package/dist/esm/lib/v3/v3.js +15 -14
  161. package/dist/esm/lib/v3/v3.js.map +1 -1
  162. package/dist/esm/lib/version.d.ts +1 -1
  163. package/dist/esm/lib/version.js +1 -1
  164. package/dist/esm/lib/version.js.map +1 -1
  165. package/dist/esm/tests/integration/observe-element-id-format.spec.d.ts +1 -0
  166. package/dist/esm/tests/integration/observe-element-id-format.spec.js +128 -0
  167. package/dist/esm/tests/integration/observe-element-id-format.spec.js.map +1 -0
  168. package/dist/esm/tests/unit/agent-mode-routing.test.d.ts +1 -0
  169. package/dist/esm/tests/unit/agent-mode-routing.test.js +86 -0
  170. package/dist/esm/tests/unit/agent-mode-routing.test.js.map +1 -0
  171. package/dist/esm/tests/unit/agent-temperature.test.d.ts +1 -0
  172. package/dist/esm/tests/unit/agent-temperature.test.js +189 -0
  173. package/dist/esm/tests/unit/agent-temperature.test.js.map +1 -0
  174. package/dist/esm/tests/unit/agent-variables-validation.test.d.ts +1 -0
  175. package/dist/esm/tests/unit/agent-variables-validation.test.js +41 -0
  176. package/dist/esm/tests/unit/agent-variables-validation.test.js.map +1 -0
  177. package/dist/esm/tests/unit/api-client-observe-variables.test.js +47 -0
  178. package/dist/esm/tests/unit/api-client-observe-variables.test.js.map +1 -1
  179. package/dist/esm/tests/unit/api-optional-model-api-key.test.js +60 -0
  180. package/dist/esm/tests/unit/api-optional-model-api-key.test.js.map +1 -1
  181. package/dist/esm/tests/unit/api-variables-schema.test.js +25 -0
  182. package/dist/esm/tests/unit/api-variables-schema.test.js.map +1 -1
  183. package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.d.ts +1 -0
  184. package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.js +58 -0
  185. package/dist/esm/tests/unit/frame-registry-oopif-adoption.test.js.map +1 -0
  186. package/dist/esm/tests/unit/inference-temperature.test.d.ts +1 -0
  187. package/dist/esm/tests/unit/inference-temperature.test.js +63 -0
  188. package/dist/esm/tests/unit/inference-temperature.test.js.map +1 -0
  189. package/dist/esm/tests/unit/openai-compatible-temperature.test.d.ts +1 -0
  190. package/dist/esm/tests/unit/openai-compatible-temperature.test.js +82 -0
  191. package/dist/esm/tests/unit/openai-compatible-temperature.test.js.map +1 -0
  192. package/dist/esm/tests/unit/prompt-observe-variables.test.js +6 -0
  193. package/dist/esm/tests/unit/prompt-observe-variables.test.js.map +1 -1
  194. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js +3 -0
  195. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  196. package/dist/esm/tests/unit/public-api/public-types.test.js.map +1 -1
  197. package/dist/esm/tests/unit/snapshot-a11y-resolvers.test.js +106 -5
  198. package/dist/esm/tests/unit/snapshot-a11y-resolvers.test.js.map +1 -1
  199. package/dist/esm/tests/unit/snapshot-a11y-tree-utils.test.js +20 -0
  200. package/dist/esm/tests/unit/snapshot-a11y-tree-utils.test.js.map +1 -1
  201. package/dist/esm/tests/unit/snapshot-capture-orchestration.test.js +119 -9
  202. package/dist/esm/tests/unit/snapshot-capture-orchestration.test.js.map +1 -1
  203. package/package.json +1 -1
  204. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js +0 -56
  205. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js.map +0 -1
  206. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js +0 -54
  207. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js.map +0 -1
  208. /package/dist/cjs/tests/integration/{agent-captcha-autosolve.spec.d.ts → observe-element-id-format.spec.d.ts} +0 -0
  209. /package/dist/{esm/tests/integration/agent-captcha-autosolve.spec.d.ts → cjs/tests/unit/agent-mode-routing.test.d.ts} +0 -0
@@ -21,7 +21,6 @@ async function extract({ instruction, domElements, schema, llmClient, logger, us
21
21
  .describe("true if the goal is now accomplished. Use this conservatively, only when sure that the goal has been completed."),
22
22
  });
23
23
  const isUsingAnthropic = llmClient.type === "anthropic";
24
- const isGPT5 = llmClient.modelName.includes("gpt-5"); // TODO: remove this as we update support for gpt-5 configuration options
25
24
  const extractCallMessages = [
26
25
  (0, prompt_js_1.buildExtractSystemPrompt)(isUsingAnthropic, userProvidedInstructions),
27
26
  (0, prompt_js_1.buildExtractUserPrompt)(instruction, domElements, isUsingAnthropic),
@@ -44,7 +43,6 @@ async function extract({ instruction, domElements, schema, llmClient, logger, us
44
43
  schema,
45
44
  name: "Extraction",
46
45
  },
47
- temperature: isGPT5 ? 1 : 0.1,
48
46
  top_p: 1,
49
47
  frequency_penalty: 0,
50
48
  presence_penalty: 0,
@@ -94,7 +92,6 @@ async function extract({ instruction, domElements, schema, llmClient, logger, us
94
92
  name: "Metadata",
95
93
  schema: metadataSchema,
96
94
  },
97
- temperature: isGPT5 ? 1 : 0.1,
98
95
  top_p: 1,
99
96
  frequency_penalty: 0,
100
97
  presence_penalty: 0,
@@ -146,14 +143,13 @@ async function extract({ instruction, domElements, schema, llmClient, logger, us
146
143
  };
147
144
  }
148
145
  async function observe({ instruction, domElements, llmClient, userProvidedInstructions, logger, logInferenceToFile = false, supportedActions, variables, }) {
149
- const isGPT5 = llmClient.modelName.includes("gpt-5"); // TODO: remove this as we update support for gpt-5 configuration options
150
146
  const observeSchema = zod_1.z.object({
151
147
  elements: zod_1.z
152
148
  .array(zod_1.z.object({
153
149
  elementId: zod_1.z
154
150
  .string()
155
151
  .regex(/^\d+-\d+$/)
156
- .describe("the ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'."),
152
+ .describe("the exact ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'. For example, if the accessibility tree shows [0-18372], return '0-18372', not '18372'."),
157
153
  description: zod_1.z
158
154
  .string()
159
155
  .describe("a description of the accessible element and its purpose"),
@@ -190,7 +186,6 @@ async function observe({ instruction, domElements, llmClient, userProvidedInstru
190
186
  schema: observeSchema,
191
187
  name: "Observation",
192
188
  },
193
- temperature: isGPT5 ? 1 : 0.1,
194
189
  top_p: 1,
195
190
  frequency_penalty: 0,
196
191
  presence_penalty: 0,
@@ -242,7 +237,6 @@ async function observe({ instruction, domElements, llmClient, userProvidedInstru
242
237
  };
243
238
  }
244
239
  async function act({ instruction, domElements, llmClient, userProvidedInstructions, logger, logInferenceToFile = false, }) {
245
- const isGPT5 = llmClient.modelName.includes("gpt-5"); // TODO: remove this as we update support for gpt-5 configuration options
246
240
  const actSchema = zod_1.z.object({
247
241
  action: zod_1.z
248
242
  .object({
@@ -288,7 +282,6 @@ async function act({ instruction, domElements, llmClient, userProvidedInstructio
288
282
  schema: actSchema,
289
283
  name: "act",
290
284
  },
291
- temperature: isGPT5 ? 1 : 0.1,
292
285
  top_p: 1,
293
286
  frequency_penalty: 0,
294
287
  presence_penalty: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"inference.js","sourceRoot":"","sources":["../../../lib/inference.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { LogLine } from \"./v3/types/public/logs.js\";\nimport { ChatMessage, LLMClient } from \"./v3/llm/LLMClient.js\";\nimport { getEnvTimeoutMs, withTimeout } from \"./v3/timeoutConfig.js\";\nimport {\n buildActSystemPrompt,\n buildExtractSystemPrompt,\n buildExtractUserPrompt,\n buildMetadataPrompt,\n buildMetadataSystemPrompt,\n buildObserveSystemPrompt,\n buildObserveUserMessage,\n} from \"./prompt.js\";\nimport { appendSummary, writeTimestampedTxtFile } from \"./inferenceLogUtils.js\";\nimport type {\n InferStagehandSchema,\n StagehandZodObject,\n} from \"./v3/zodCompat.js\";\nimport { SupportedUnderstudyAction } from \"./v3/types/private/handlers.js\";\nimport type { Variables } from \"./v3/types/public/agent.js\";\n\n// Re-export for backward compatibility\nexport type { LLMParsedResponse, LLMUsage } from \"./v3/llm/LLMClient.js\";\n\nfunction withLlmTimeout<T>(promise: Promise<T>, operation: string): Promise<T> {\n return withTimeout(\n promise,\n getEnvTimeoutMs(\"LLM_MAX_MS\"),\n `LLM ${operation}`,\n );\n}\n\nexport async function extract<T extends StagehandZodObject>({\n instruction,\n domElements,\n schema,\n llmClient,\n logger,\n userProvidedInstructions,\n logInferenceToFile = false,\n}: {\n instruction: string;\n domElements: string;\n schema: T;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n}) {\n const metadataSchema = z.object({\n progress: z\n .string()\n .describe(\n \"progress of what has been extracted so far, as concise as possible\",\n ),\n completed: z\n .boolean()\n .describe(\n \"true if the goal is now accomplished. Use this conservatively, only when sure that the goal has been completed.\",\n ),\n });\n\n type ExtractionResponse = InferStagehandSchema<T>;\n type MetadataResponse = z.infer<typeof metadataSchema>;\n\n const isUsingAnthropic = llmClient.type === \"anthropic\";\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const extractCallMessages: ChatMessage[] = [\n buildExtractSystemPrompt(isUsingAnthropic, userProvidedInstructions),\n buildExtractUserPrompt(instruction, domElements, isUsingAnthropic),\n ];\n\n let extractCallFile = \"\";\n let extractCallTimestamp = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"extract_call\",\n {\n modelCall: \"extract\",\n messages: extractCallMessages,\n },\n );\n extractCallFile = fileName;\n extractCallTimestamp = timestamp;\n }\n\n const extractStartTime = Date.now();\n const extractionResponse = await withLlmTimeout(\n llmClient.createChatCompletion<ExtractionResponse>({\n options: {\n messages: extractCallMessages,\n response_model: {\n schema,\n name: \"Extraction\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n }),\n \"extract\",\n );\n const extractEndTime = Date.now();\n\n const { data: extractedData, usage: extractUsage } = extractionResponse;\n\n let extractResponseFile: string;\n if (logInferenceToFile) {\n const { fileName } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"extract_response\",\n {\n modelResponse: \"extract\",\n rawResponse: extractedData,\n },\n );\n extractResponseFile = fileName;\n\n appendSummary(\"extract\", {\n extract_inference_type: \"extract\",\n timestamp: extractCallTimestamp,\n LLM_input_file: extractCallFile,\n LLM_output_file: extractResponseFile,\n prompt_tokens: extractUsage?.prompt_tokens ?? 0,\n completion_tokens: extractUsage?.completion_tokens ?? 0,\n reasoning_tokens: extractUsage?.reasoning_tokens ?? 0,\n cached_input_tokens: extractUsage?.cached_input_tokens ?? 0,\n inference_time_ms: extractEndTime - extractStartTime,\n });\n }\n\n const metadataCallMessages: ChatMessage[] = [\n buildMetadataSystemPrompt(),\n buildMetadataPrompt(instruction, extractedData),\n ];\n\n let metadataCallFile = \"\";\n let metadataCallTimestamp = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"metadata_call\",\n {\n modelCall: \"metadata\",\n messages: metadataCallMessages,\n },\n );\n metadataCallFile = fileName;\n metadataCallTimestamp = timestamp;\n }\n\n const metadataStartTime = Date.now();\n const metadataResponse = await withLlmTimeout(\n llmClient.createChatCompletion<MetadataResponse>({\n options: {\n messages: metadataCallMessages,\n response_model: {\n name: \"Metadata\",\n schema: metadataSchema,\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n }),\n \"extract metadata\",\n );\n const metadataEndTime = Date.now();\n\n const {\n data: {\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n usage: metadataResponseUsage,\n } = metadataResponse;\n\n let metadataResponseFile: string;\n if (logInferenceToFile) {\n const { fileName } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"metadata_response\",\n {\n modelResponse: \"metadata\",\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n );\n metadataResponseFile = fileName;\n\n appendSummary(\"extract\", {\n extract_inference_type: \"metadata\",\n timestamp: metadataCallTimestamp,\n LLM_input_file: metadataCallFile,\n LLM_output_file: metadataResponseFile,\n prompt_tokens: metadataResponseUsage?.prompt_tokens ?? 0,\n completion_tokens: metadataResponseUsage?.completion_tokens ?? 0,\n reasoning_tokens: metadataResponseUsage?.reasoning_tokens ?? 0,\n cached_input_tokens: metadataResponseUsage?.cached_input_tokens ?? 0,\n inference_time_ms: metadataEndTime - metadataStartTime,\n });\n }\n\n const totalPromptTokens =\n (extractUsage?.prompt_tokens ?? 0) +\n (metadataResponseUsage?.prompt_tokens ?? 0);\n\n const totalCompletionTokens =\n (extractUsage?.completion_tokens ?? 0) +\n (metadataResponseUsage?.completion_tokens ?? 0);\n\n const totalInferenceTimeMs =\n extractEndTime - extractStartTime + (metadataEndTime - metadataStartTime);\n const totalReasoningTokens =\n (extractUsage?.reasoning_tokens ?? 0) +\n (metadataResponseUsage?.reasoning_tokens ?? 0);\n const totalCachedInputTokens =\n (extractUsage?.cached_input_tokens ?? 0) +\n (metadataResponseUsage?.cached_input_tokens ?? 0);\n\n return {\n ...extractedData,\n metadata: {\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n prompt_tokens: totalPromptTokens,\n completion_tokens: totalCompletionTokens,\n reasoning_tokens: totalReasoningTokens,\n cached_input_tokens: totalCachedInputTokens,\n inference_time_ms: totalInferenceTimeMs,\n };\n}\n\nexport async function observe({\n instruction,\n domElements,\n llmClient,\n userProvidedInstructions,\n logger,\n logInferenceToFile = false,\n supportedActions,\n variables,\n}: {\n instruction: string;\n domElements: string;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n supportedActions?: string[];\n variables?: Variables;\n}) {\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const observeSchema = z.object({\n elements: z\n .array(\n z.object({\n elementId: z\n .string()\n .regex(/^\\d+-\\d+$/)\n .describe(\n \"the ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'.\",\n ),\n description: z\n .string()\n .describe(\n \"a description of the accessible element and its purpose\",\n ),\n method: z\n .enum(\n // Use Object.values() for Zod v3 compatibility - z.enum() in v3 doesn't accept TypeScript enums directly\n Object.values(SupportedUnderstudyAction) as unknown as readonly [\n string,\n ...string[],\n ],\n )\n .describe(\n `the candidate method/action to interact with the element. Select one of the available Understudy interaction methods.`,\n ),\n arguments: z.array(\n z\n .string()\n .describe(\n \"the arguments to pass to the method. For example, for a click, the arguments are empty, but for a fill, the arguments are the value to fill in.\",\n ),\n ),\n }),\n )\n .describe(\"an array of accessible elements that match the instruction\"),\n });\n\n type ObserveResponse = z.infer<typeof observeSchema>;\n\n const messages: ChatMessage[] = [\n buildObserveSystemPrompt(\n userProvidedInstructions,\n supportedActions,\n variables,\n ),\n buildObserveUserMessage(instruction, domElements),\n ];\n\n let callTimestamp = \"\";\n let callFile = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n `observe_summary`,\n `observe_call`,\n {\n modelCall: \"observe\",\n messages,\n },\n );\n callFile = fileName;\n callTimestamp = timestamp;\n }\n\n const start = Date.now();\n const rawResponse = await llmClient.createChatCompletion<ObserveResponse>({\n options: {\n messages,\n response_model: {\n schema: observeSchema,\n name: \"Observation\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n });\n const end = Date.now();\n const usageTimeMs = end - start;\n\n const { data: observeData, usage: observeUsage } = rawResponse;\n const promptTokens = observeUsage?.prompt_tokens ?? 0;\n const completionTokens = observeUsage?.completion_tokens ?? 0;\n const reasoningTokens = observeUsage?.reasoning_tokens ?? 0;\n const cachedInputTokens = observeUsage?.cached_input_tokens ?? 0;\n\n let responseFile: string;\n if (logInferenceToFile) {\n const { fileName: responseFileName } = writeTimestampedTxtFile(\n `observe_summary`,\n `observe_response`,\n {\n modelResponse: \"observe\",\n rawResponse: observeData,\n },\n );\n responseFile = responseFileName;\n\n appendSummary(\"observe\", {\n [`observe_inference_type`]: \"observe\",\n timestamp: callTimestamp,\n LLM_input_file: callFile,\n LLM_output_file: responseFile,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n });\n }\n\n const parsedElements =\n observeData.elements?.map((el) => {\n const base = {\n elementId: el.elementId,\n description: String(el.description),\n method: String(el.method),\n arguments: el.arguments,\n };\n return base;\n }) ?? [];\n\n return {\n elements: parsedElements,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n };\n}\n\nexport async function act({\n instruction,\n domElements,\n llmClient,\n userProvidedInstructions,\n logger,\n logInferenceToFile = false,\n}: {\n instruction: string;\n domElements: string;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n}) {\n const isGPT5 = llmClient.modelName.includes(\"gpt-5\"); // TODO: remove this as we update support for gpt-5 configuration options\n\n const actSchema = z.object({\n action: z\n .object({\n elementId: z\n .string()\n .regex(/^\\d+-\\d+$/)\n .describe(\n \"the ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'. for example, '0-76' or '16-21'\",\n ),\n description: z\n .string()\n .describe(\"a description of the accessible element and its purpose\"),\n method: z\n .enum(\n // Use Object.values() for Zod v3 compatibility - z.enum() in v3 doesn't accept TypeScript enums directly\n Object.values(SupportedUnderstudyAction) as unknown as readonly [\n string,\n ...string[],\n ],\n )\n .describe(\n \"the candidate method/action to interact with the element. Select one of the available Understudy interaction methods.\",\n ),\n arguments: z.array(\n z\n .string()\n .describe(\n \"the arguments to pass to the method. For example, for a click, the arguments are empty, but for a fill, the arguments are the value to fill in.\",\n ),\n ),\n })\n .nullable()\n .describe(\n \"The element to act on. Return null if no element on the page matches the instruction — do NOT fabricate or guess an element, and never emit empty strings or placeholder values.\",\n ),\n twoStep: z.boolean(),\n });\n\n type ActResponse = z.infer<typeof actSchema>;\n\n const messages: ChatMessage[] = [\n buildActSystemPrompt(userProvidedInstructions),\n buildObserveUserMessage(instruction, domElements),\n ];\n\n let callTimestamp = \"\";\n let callFile = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n `act_summary`,\n `act_call`,\n {\n modelCall: \"act\",\n messages,\n },\n );\n callFile = fileName;\n callTimestamp = timestamp;\n }\n\n const start = Date.now();\n const rawResponse = await llmClient.createChatCompletion<ActResponse>({\n options: {\n messages,\n response_model: {\n schema: actSchema,\n name: \"act\",\n },\n temperature: isGPT5 ? 1 : 0.1,\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n });\n const end = Date.now();\n const usageTimeMs = end - start;\n\n const { data: actData, usage: actUsage } = rawResponse;\n const promptTokens = actUsage?.prompt_tokens ?? 0;\n const completionTokens = actUsage?.completion_tokens ?? 0;\n const reasoningTokens = actUsage?.reasoning_tokens ?? 0;\n const cachedInputTokens = actUsage?.cached_input_tokens ?? 0;\n\n let responseFile: string;\n if (logInferenceToFile) {\n const { fileName: responseFileName } = writeTimestampedTxtFile(\n `act_summary`,\n `act_response`,\n {\n modelResponse: \"act\",\n rawResponse: actData,\n },\n );\n responseFile = responseFileName;\n\n appendSummary(\"act\", {\n [`act_inference_type`]: \"act\",\n timestamp: callTimestamp,\n LLM_input_file: callFile,\n LLM_output_file: responseFile,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n });\n }\n\n const parsedElement = actData.action\n ? {\n elementId: actData.action.elementId,\n description: String(actData.action.description),\n method: String(actData.action.method),\n arguments: actData.action.arguments,\n }\n : undefined;\n\n return {\n element: parsedElement,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n twoStep: actData.twoStep,\n };\n}\n"]}
1
+ {"version":3,"file":"inference.js","sourceRoot":"","sources":["../../../lib/inference.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { LogLine } from \"./v3/types/public/logs.js\";\nimport { ChatMessage, LLMClient } from \"./v3/llm/LLMClient.js\";\nimport { getEnvTimeoutMs, withTimeout } from \"./v3/timeoutConfig.js\";\nimport {\n buildActSystemPrompt,\n buildExtractSystemPrompt,\n buildExtractUserPrompt,\n buildMetadataPrompt,\n buildMetadataSystemPrompt,\n buildObserveSystemPrompt,\n buildObserveUserMessage,\n} from \"./prompt.js\";\nimport { appendSummary, writeTimestampedTxtFile } from \"./inferenceLogUtils.js\";\nimport type {\n InferStagehandSchema,\n StagehandZodObject,\n} from \"./v3/zodCompat.js\";\nimport { SupportedUnderstudyAction } from \"./v3/types/private/handlers.js\";\nimport type { Variables } from \"./v3/types/public/agent.js\";\n\n// Re-export for backward compatibility\nexport type { LLMParsedResponse, LLMUsage } from \"./v3/llm/LLMClient.js\";\n\nfunction withLlmTimeout<T>(promise: Promise<T>, operation: string): Promise<T> {\n return withTimeout(\n promise,\n getEnvTimeoutMs(\"LLM_MAX_MS\"),\n `LLM ${operation}`,\n );\n}\n\nexport async function extract<T extends StagehandZodObject>({\n instruction,\n domElements,\n schema,\n llmClient,\n logger,\n userProvidedInstructions,\n logInferenceToFile = false,\n}: {\n instruction: string;\n domElements: string;\n schema: T;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n}) {\n const metadataSchema = z.object({\n progress: z\n .string()\n .describe(\n \"progress of what has been extracted so far, as concise as possible\",\n ),\n completed: z\n .boolean()\n .describe(\n \"true if the goal is now accomplished. Use this conservatively, only when sure that the goal has been completed.\",\n ),\n });\n\n type ExtractionResponse = InferStagehandSchema<T>;\n type MetadataResponse = z.infer<typeof metadataSchema>;\n\n const isUsingAnthropic = llmClient.type === \"anthropic\";\n\n const extractCallMessages: ChatMessage[] = [\n buildExtractSystemPrompt(isUsingAnthropic, userProvidedInstructions),\n buildExtractUserPrompt(instruction, domElements, isUsingAnthropic),\n ];\n\n let extractCallFile = \"\";\n let extractCallTimestamp = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"extract_call\",\n {\n modelCall: \"extract\",\n messages: extractCallMessages,\n },\n );\n extractCallFile = fileName;\n extractCallTimestamp = timestamp;\n }\n\n const extractStartTime = Date.now();\n const extractionResponse = await withLlmTimeout(\n llmClient.createChatCompletion<ExtractionResponse>({\n options: {\n messages: extractCallMessages,\n response_model: {\n schema,\n name: \"Extraction\",\n },\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n }),\n \"extract\",\n );\n const extractEndTime = Date.now();\n\n const { data: extractedData, usage: extractUsage } = extractionResponse;\n\n let extractResponseFile: string;\n if (logInferenceToFile) {\n const { fileName } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"extract_response\",\n {\n modelResponse: \"extract\",\n rawResponse: extractedData,\n },\n );\n extractResponseFile = fileName;\n\n appendSummary(\"extract\", {\n extract_inference_type: \"extract\",\n timestamp: extractCallTimestamp,\n LLM_input_file: extractCallFile,\n LLM_output_file: extractResponseFile,\n prompt_tokens: extractUsage?.prompt_tokens ?? 0,\n completion_tokens: extractUsage?.completion_tokens ?? 0,\n reasoning_tokens: extractUsage?.reasoning_tokens ?? 0,\n cached_input_tokens: extractUsage?.cached_input_tokens ?? 0,\n inference_time_ms: extractEndTime - extractStartTime,\n });\n }\n\n const metadataCallMessages: ChatMessage[] = [\n buildMetadataSystemPrompt(),\n buildMetadataPrompt(instruction, extractedData),\n ];\n\n let metadataCallFile = \"\";\n let metadataCallTimestamp = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"metadata_call\",\n {\n modelCall: \"metadata\",\n messages: metadataCallMessages,\n },\n );\n metadataCallFile = fileName;\n metadataCallTimestamp = timestamp;\n }\n\n const metadataStartTime = Date.now();\n const metadataResponse = await withLlmTimeout(\n llmClient.createChatCompletion<MetadataResponse>({\n options: {\n messages: metadataCallMessages,\n response_model: {\n name: \"Metadata\",\n schema: metadataSchema,\n },\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n }),\n \"extract metadata\",\n );\n const metadataEndTime = Date.now();\n\n const {\n data: {\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n usage: metadataResponseUsage,\n } = metadataResponse;\n\n let metadataResponseFile: string;\n if (logInferenceToFile) {\n const { fileName } = writeTimestampedTxtFile(\n \"extract_summary\",\n \"metadata_response\",\n {\n modelResponse: \"metadata\",\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n );\n metadataResponseFile = fileName;\n\n appendSummary(\"extract\", {\n extract_inference_type: \"metadata\",\n timestamp: metadataCallTimestamp,\n LLM_input_file: metadataCallFile,\n LLM_output_file: metadataResponseFile,\n prompt_tokens: metadataResponseUsage?.prompt_tokens ?? 0,\n completion_tokens: metadataResponseUsage?.completion_tokens ?? 0,\n reasoning_tokens: metadataResponseUsage?.reasoning_tokens ?? 0,\n cached_input_tokens: metadataResponseUsage?.cached_input_tokens ?? 0,\n inference_time_ms: metadataEndTime - metadataStartTime,\n });\n }\n\n const totalPromptTokens =\n (extractUsage?.prompt_tokens ?? 0) +\n (metadataResponseUsage?.prompt_tokens ?? 0);\n\n const totalCompletionTokens =\n (extractUsage?.completion_tokens ?? 0) +\n (metadataResponseUsage?.completion_tokens ?? 0);\n\n const totalInferenceTimeMs =\n extractEndTime - extractStartTime + (metadataEndTime - metadataStartTime);\n const totalReasoningTokens =\n (extractUsage?.reasoning_tokens ?? 0) +\n (metadataResponseUsage?.reasoning_tokens ?? 0);\n const totalCachedInputTokens =\n (extractUsage?.cached_input_tokens ?? 0) +\n (metadataResponseUsage?.cached_input_tokens ?? 0);\n\n return {\n ...extractedData,\n metadata: {\n completed: metadataResponseCompleted,\n progress: metadataResponseProgress,\n },\n prompt_tokens: totalPromptTokens,\n completion_tokens: totalCompletionTokens,\n reasoning_tokens: totalReasoningTokens,\n cached_input_tokens: totalCachedInputTokens,\n inference_time_ms: totalInferenceTimeMs,\n };\n}\n\nexport async function observe({\n instruction,\n domElements,\n llmClient,\n userProvidedInstructions,\n logger,\n logInferenceToFile = false,\n supportedActions,\n variables,\n}: {\n instruction: string;\n domElements: string;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n supportedActions?: string[];\n variables?: Variables;\n}) {\n const observeSchema = z.object({\n elements: z\n .array(\n z.object({\n elementId: z\n .string()\n .regex(/^\\d+-\\d+$/)\n .describe(\n \"the exact ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'. For example, if the accessibility tree shows [0-18372], return '0-18372', not '18372'.\",\n ),\n description: z\n .string()\n .describe(\n \"a description of the accessible element and its purpose\",\n ),\n method: z\n .enum(\n // Use Object.values() for Zod v3 compatibility - z.enum() in v3 doesn't accept TypeScript enums directly\n Object.values(SupportedUnderstudyAction) as unknown as readonly [\n string,\n ...string[],\n ],\n )\n .describe(\n `the candidate method/action to interact with the element. Select one of the available Understudy interaction methods.`,\n ),\n arguments: z.array(\n z\n .string()\n .describe(\n \"the arguments to pass to the method. For example, for a click, the arguments are empty, but for a fill, the arguments are the value to fill in.\",\n ),\n ),\n }),\n )\n .describe(\"an array of accessible elements that match the instruction\"),\n });\n\n type ObserveResponse = z.infer<typeof observeSchema>;\n\n const messages: ChatMessage[] = [\n buildObserveSystemPrompt(\n userProvidedInstructions,\n supportedActions,\n variables,\n ),\n buildObserveUserMessage(instruction, domElements),\n ];\n\n let callTimestamp = \"\";\n let callFile = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n `observe_summary`,\n `observe_call`,\n {\n modelCall: \"observe\",\n messages,\n },\n );\n callFile = fileName;\n callTimestamp = timestamp;\n }\n\n const start = Date.now();\n const rawResponse = await llmClient.createChatCompletion<ObserveResponse>({\n options: {\n messages,\n response_model: {\n schema: observeSchema,\n name: \"Observation\",\n },\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n });\n const end = Date.now();\n const usageTimeMs = end - start;\n\n const { data: observeData, usage: observeUsage } = rawResponse;\n const promptTokens = observeUsage?.prompt_tokens ?? 0;\n const completionTokens = observeUsage?.completion_tokens ?? 0;\n const reasoningTokens = observeUsage?.reasoning_tokens ?? 0;\n const cachedInputTokens = observeUsage?.cached_input_tokens ?? 0;\n\n let responseFile: string;\n if (logInferenceToFile) {\n const { fileName: responseFileName } = writeTimestampedTxtFile(\n `observe_summary`,\n `observe_response`,\n {\n modelResponse: \"observe\",\n rawResponse: observeData,\n },\n );\n responseFile = responseFileName;\n\n appendSummary(\"observe\", {\n [`observe_inference_type`]: \"observe\",\n timestamp: callTimestamp,\n LLM_input_file: callFile,\n LLM_output_file: responseFile,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n });\n }\n\n const parsedElements =\n observeData.elements?.map((el) => {\n const base = {\n elementId: el.elementId,\n description: String(el.description),\n method: String(el.method),\n arguments: el.arguments,\n };\n return base;\n }) ?? [];\n\n return {\n elements: parsedElements,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n };\n}\n\nexport async function act({\n instruction,\n domElements,\n llmClient,\n userProvidedInstructions,\n logger,\n logInferenceToFile = false,\n}: {\n instruction: string;\n domElements: string;\n llmClient: LLMClient;\n userProvidedInstructions?: string;\n logger: (message: LogLine) => void;\n logInferenceToFile?: boolean;\n}) {\n const actSchema = z.object({\n action: z\n .object({\n elementId: z\n .string()\n .regex(/^\\d+-\\d+$/)\n .describe(\n \"the ID string associated with the element. Never include surrounding square brackets. This field must follow the format of 'number-number'. for example, '0-76' or '16-21'\",\n ),\n description: z\n .string()\n .describe(\"a description of the accessible element and its purpose\"),\n method: z\n .enum(\n // Use Object.values() for Zod v3 compatibility - z.enum() in v3 doesn't accept TypeScript enums directly\n Object.values(SupportedUnderstudyAction) as unknown as readonly [\n string,\n ...string[],\n ],\n )\n .describe(\n \"the candidate method/action to interact with the element. Select one of the available Understudy interaction methods.\",\n ),\n arguments: z.array(\n z\n .string()\n .describe(\n \"the arguments to pass to the method. For example, for a click, the arguments are empty, but for a fill, the arguments are the value to fill in.\",\n ),\n ),\n })\n .nullable()\n .describe(\n \"The element to act on. Return null if no element on the page matches the instruction — do NOT fabricate or guess an element, and never emit empty strings or placeholder values.\",\n ),\n twoStep: z.boolean(),\n });\n\n type ActResponse = z.infer<typeof actSchema>;\n\n const messages: ChatMessage[] = [\n buildActSystemPrompt(userProvidedInstructions),\n buildObserveUserMessage(instruction, domElements),\n ];\n\n let callTimestamp = \"\";\n let callFile = \"\";\n if (logInferenceToFile) {\n const { fileName, timestamp } = writeTimestampedTxtFile(\n `act_summary`,\n `act_call`,\n {\n modelCall: \"act\",\n messages,\n },\n );\n callFile = fileName;\n callTimestamp = timestamp;\n }\n\n const start = Date.now();\n const rawResponse = await llmClient.createChatCompletion<ActResponse>({\n options: {\n messages,\n response_model: {\n schema: actSchema,\n name: \"act\",\n },\n top_p: 1,\n frequency_penalty: 0,\n presence_penalty: 0,\n },\n logger,\n });\n const end = Date.now();\n const usageTimeMs = end - start;\n\n const { data: actData, usage: actUsage } = rawResponse;\n const promptTokens = actUsage?.prompt_tokens ?? 0;\n const completionTokens = actUsage?.completion_tokens ?? 0;\n const reasoningTokens = actUsage?.reasoning_tokens ?? 0;\n const cachedInputTokens = actUsage?.cached_input_tokens ?? 0;\n\n let responseFile: string;\n if (logInferenceToFile) {\n const { fileName: responseFileName } = writeTimestampedTxtFile(\n `act_summary`,\n `act_response`,\n {\n modelResponse: \"act\",\n rawResponse: actData,\n },\n );\n responseFile = responseFileName;\n\n appendSummary(\"act\", {\n [`act_inference_type`]: \"act\",\n timestamp: callTimestamp,\n LLM_input_file: callFile,\n LLM_output_file: responseFile,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n });\n }\n\n const parsedElement = actData.action\n ? {\n elementId: actData.action.elementId,\n description: String(actData.action.description),\n method: String(actData.action.method),\n arguments: actData.action.arguments,\n }\n : undefined;\n\n return {\n element: parsedElement,\n prompt_tokens: promptTokens,\n completion_tokens: completionTokens,\n reasoning_tokens: reasoningTokens,\n cached_input_tokens: cachedInputTokens,\n inference_time_ms: usageTimeMs,\n twoStep: actData.twoStep,\n };\n}\n"]}
@@ -108,7 +108,9 @@ You will be given:
108
108
  2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.
109
109
 
110
110
  Return an array of elements that match the instruction if they exist, otherwise return an empty array.
111
- When returning elements, include the appropriate method from the supported actions list.${actionsString}${variablesString}. When choosing non-left click actions, provide right or middle as the argument.`;
111
+ When returning elements, include the appropriate method from the supported actions list.${actionsString}${variablesString}. When choosing non-left click actions, provide right or middle as the argument.
112
+
113
+ Each element in the accessibility tree has an ID in square brackets, like [0-18372]. The ID has two parts: frame ordinal and backend node ID. Always copy the complete ID exactly as shown inside the brackets into elementId, including the frame ordinal and hyphen. For example, if the tree shows [0-18372], return elementId "0-18372"; never return only "18372".`;
112
114
  const content = observeSystemPrompt.replace(/\s+/g, " ");
113
115
  return {
114
116
  role: "system",
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../lib/prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChatMessage } from \"./v3/llm/LLMClient.js\";\nimport type { Variables } from \"./v3/types/public/agent.js\";\nimport { getVariablePromptEntries } from \"./v3/agent/utils/variables.js\";\n\nexport function buildUserInstructionsString(\n userProvidedInstructions?: string,\n): string {\n if (!userProvidedInstructions) {\n return \"\";\n }\n\n return `\\n\\n# Custom Instructions Provided by the User\n \nPlease keep the user's instructions in mind when performing actions. If the user's instructions are not relevant to the current task, ignore them.\n\nUser Instructions:\n${userProvidedInstructions}`;\n}\n\n// extract\nexport function buildExtractSystemPrompt(\n isUsingPrintExtractedDataTool: boolean = false,\n userProvidedInstructions?: string,\n): ChatMessage {\n const baseContent = `You are extracting content on behalf of a user.\n If a user asks you to extract a 'list' of information, or 'all' information, \n YOU MUST EXTRACT ALL OF THE INFORMATION THAT THE USER REQUESTS.\n \n You will be given:\n1. An instruction\n2. `;\n\n const contentDetail = `A list of DOM elements to extract from.`;\n\n const instructions = `\nPrint the exact text from the DOM elements with all symbols, characters, and endlines as is.\nPrint null or an empty string if no new information is found.\n `.trim();\n\n const toolInstructions = isUsingPrintExtractedDataTool\n ? `\nONLY print the content using the print_extracted_data tool provided.\nONLY print the content using the print_extracted_data tool provided.\n `.trim()\n : \"\";\n\n const additionalInstructions =\n \"If a user is attempting to extract links or URLs, you MUST respond with ONLY the IDs of the link elements. \\n\" +\n \"Do not attempt to extract links directly from the text unless absolutely necessary. \";\n\n const userInstructions = buildUserInstructionsString(\n userProvidedInstructions,\n );\n\n const content =\n `${baseContent}${contentDetail}\\n\\n${instructions}\\n${toolInstructions}${\n additionalInstructions ? `\\n\\n${additionalInstructions}` : \"\"\n }${userInstructions ? `\\n\\n${userInstructions}` : \"\"}`.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content,\n };\n}\n\nexport function buildExtractUserPrompt(\n instruction: string,\n domElements: string,\n isUsingPrintExtractedDataTool: boolean = false,\n): ChatMessage {\n let content = `Instruction: ${instruction}\nDOM: ${domElements}`;\n\n if (isUsingPrintExtractedDataTool) {\n content += `\nONLY print the content using the print_extracted_data tool provided.\nONLY print the content using the print_extracted_data tool provided.`;\n }\n\n return {\n role: \"user\",\n content,\n };\n}\n\nconst metadataSystemPrompt = `You are an AI assistant tasked with evaluating the progress and completion status of an extraction task.\nAnalyze the extraction response and determine if the task is completed or if more information is needed.\nStrictly abide by the following criteria:\n1. Once the instruction has been satisfied by the current extraction response, ALWAYS set completion status to true and stop processing, regardless of remaining chunks.\n2. Only set completion status to false if BOTH of these conditions are true:\n - The instruction has not been satisfied yet\n - There are still chunks left to process (chunksTotal > chunksSeen)`;\n\nexport function buildMetadataSystemPrompt(): ChatMessage {\n return {\n role: \"system\",\n content: metadataSystemPrompt,\n };\n}\n\nexport function buildMetadataPrompt(\n instruction: string,\n extractionResponse: object,\n): ChatMessage {\n return {\n role: \"user\",\n content: `Instruction: ${instruction}\nExtracted content: ${JSON.stringify(extractionResponse, null, 2)}`,\n };\n}\n\n// observe\nexport function buildObserveSystemPrompt(\n userProvidedInstructions?: string,\n supportedActions?: string[],\n variables?: Variables,\n): ChatMessage {\n const actionsString = supportedActions?.length\n ? `\\n\\nSupported actions: ${supportedActions.join(\", \")}`\n : \"\";\n const variableEntries = getVariablePromptEntries(variables);\n const variablesString = variableEntries.length\n ? `\\n\\nAvailable variables: ${variableEntries\n .map(({ name, description }) => {\n return description ? `%${name}% (${description})` : `%${name}%`;\n })\n .join(\n \", \",\n )}. When an action needs a dynamic or sensitive value, return the matching %variableName% placeholder in the action arguments instead of a literal value`\n : \"\";\n\n const observeSystemPrompt = `\nYou are helping the user automate the browser by finding elements based on what the user wants to observe in the page.\n\nYou will be given:\n1. a instruction of elements to observe\n2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.\n\nReturn an array of elements that match the instruction if they exist, otherwise return an empty array.\nWhen returning elements, include the appropriate method from the supported actions list.${actionsString}${variablesString}. When choosing non-left click actions, provide right or middle as the argument.`;\n const content = observeSystemPrompt.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content: [content, buildUserInstructionsString(userProvidedInstructions)]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n };\n}\n\nexport function buildObserveUserMessage(\n instruction: string,\n domElements: string,\n): ChatMessage {\n return {\n role: \"user\",\n content: `instruction: ${instruction}\nAccessibility Tree: \\n${domElements}\\n`,\n };\n}\n\nexport function buildActSystemPrompt(\n userProvidedInstructions?: string,\n): ChatMessage {\n const actSystemPrompt = `\nYou are helping the user automate the browser by finding elements based on what action the user wants to take on the page\n\nYou will be given:\n1. a user defined instruction about what action to take\n2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.\n\nReturn the element that matches the instruction if it exists. If no element on the page matches the instruction, set \\`action\\` to null. Do not fabricate or guess an element — empty strings or placeholder values for elementId/description/method are not acceptable.`;\n const content = actSystemPrompt.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content: [content, buildUserInstructionsString(userProvidedInstructions)]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n };\n}\n\nfunction buildActVariablesPrompt(variables?: Variables): string {\n if (!variables || Object.keys(variables).length === 0) {\n return \"\";\n }\n\n const variableNames = Object.keys(variables)\n .map((key) => `%${key}%`)\n .join(\", \");\n\n return ` The user has provided the following variables to be used in the action: ${variableNames} \\n\n Note that these are the variable names/keys, and not the actual variable values. \\n\n To use the variables in the action, you must respond with the variable name inside the 'arguments' array. The variable name must be wrapped in percentage signs (eg, %variableNameHere%) so that it can be replaced with the actual variable value before the action is taken. \\n`;\n}\n\nexport function buildActPrompt(\n action: string,\n supportedActions: string[],\n variables?: Variables,\n): string {\n // Base instruction\n let instruction = `Find the most relevant element to perform an action on given the following action: ${action}. \n IF AND ONLY IF the action EXPLICITLY includes the word 'dropdown' and implies choosing/selecting an option from a dropdown, ignore the 'General Instructions' section, and follow the 'Dropdown Specific Instructions' section carefully.\n \n General Instructions: \n Provide an action for this element such as ${supportedActions.join(\", \")}. Remember that to users, buttons and links look the same in most cases.\n When choosing non-left click actions, provide right or middle as the argument\n If the action is completely unrelated to a potential action to be taken on the page, or no matching element exists, set \\`action\\` to null. Do not fabricate or guess an element.\n ONLY return one action. If multiple actions are relevant, return the most relevant one.\n If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.\n If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.\n If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys. \n \n Dropdown Specific Instructions:\n For interacting with dropdowns, there are two specific cases that you need to handle. \n \n CASE 1: the element is a 'select' element. \n - choose the selectOptionFromDropdown method,\n - set the argument to the exact text of the option that should be selected,\n - set twoStep to false.\n CASE 2: the element is NOT a 'select' element:\n - do not attempt to directly choose the element from the dropdown. You will need to click to expand the dropdown first. You will achieve this by following these instructions:\n - choose the node that most closely corresponds to the given instruction EVEN if it is a 'StaticText' element, or otherwise does not appear to be interactable. \n - choose the 'click' method\n - set twoStep to true.\n `;\n\n instruction += buildActVariablesPrompt(variables);\n\n return instruction;\n}\n\nexport function buildStepTwoPrompt(\n originalUserAction: string,\n previousAction: string,\n supportedActions: string[],\n variables?: Variables,\n): string {\n // Base instruction\n let instruction = `\n The original user action was: ${originalUserAction}.\n You have just taken the following action which completed step 1 of 2: ${previousAction}.\n \n Now, you must find the most relevant element to perform an action on in order to complete step 2 of 2. \n \n General Instructions: \n Provide an action for this element such as ${supportedActions.join(\", \")}. Remember that to users, buttons and links look the same in most cases.\n If the action is completely unrelated to a potential action to be taken on the page, or no matching element exists, set \\`action\\` to null. Do not fabricate or guess an element.\n ONLY return one action. If multiple actions are relevant, return the most relevant one.\n If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.\n If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.\n If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys. \n `;\n\n instruction += buildActVariablesPrompt(variables);\n\n return instruction;\n}\n\nexport function buildOperatorSystemPrompt(goal: string): ChatMessage {\n return {\n role: \"system\",\n content: `You are a general-purpose agent whose job is to accomplish the user's goal across multiple model calls by running actions on the page.\n\nYou will be given a goal and a list of steps that have been taken so far. Your job is to determine if either the user's goal has been completed or if there are still steps that need to be taken.\n\n# Your current goal\n${goal}\n\n# CRITICAL: You MUST use the provided tools to take actions. Do not just describe what you want to do - actually call the appropriate tools.\n\n# Available tools and when to use them:\n- \\`act\\`: Use this to interact with the page (click, type, navigate, etc.)\n- \\`extract\\`: Use this to get information from the page\n- \\`goto\\`: Use this to navigate to a specific URL\n- \\`wait\\`: Use this to wait for a period of time\n- \\`navback\\`: Use this to go back to the previous page\n- \\`refresh\\`: Use this to refresh the current page\n- \\`close\\`: Use this ONLY when the task is complete or cannot be achieved\n- External tools: Use any additional tools (like search tools) as needed for your goal\n\n# Important guidelines\n1. ALWAYS use tools - never just provide text responses about what you plan to do\n2. Break down complex actions into individual atomic steps\n3. For \\`act\\` commands, use only one action at a time, such as:\n - Single click on a specific element\n - Type into a single input field\n - Select a single option\n4. Avoid combining multiple actions in one instruction\n5. If multiple actions are needed, they should be separate steps\n6. Only use \\`close\\` when the task is genuinely complete or impossible to achieve`,\n };\n}\n\nexport function buildCuaDefaultSystemPrompt(): string {\n return `You are a helpful assistant that can use a web browser.\\nDo not ask follow up questions, the user will trust your judgement. Today's date is ${new Date().toISOString().split(\"T\")[0]}.`;\n}\n\nexport function buildGoogleCUASystemPrompt(): ChatMessage {\n return {\n role: \"system\",\n content: `You are a general-purpose browser agent whose job is to accomplish the user's goal.\nToday's date is ${new Date().toISOString().split(\"T\")[0]}.\nYou have access to a search tool; however, in most cases you should operate within the page/url the user has provided. ONLY use the search tool if you're stuck or the task is impossible to complete within the current page.\nYou will be given a goal and a list of steps that have been taken so far. Avoid requesting the user for input as much as possible. Good luck!\n`,\n };\n}\n"]}
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../lib/prompt.ts"],"names":[],"mappings":";;AAIA,kEAaC;AAGD,4DA2CC;AAED,wDAkBC;AAUD,8DAKC;AAED,kDASC;AAGD,4DAsCC;AAED,0DASC;AAED,oDAmBC;AAgBD,wCAmCC;AAED,gDAyBC;AAED,8DAiCC;AAED,kEAEC;AAED,gEASC;AApTD,gEAAyE;AAEzE,SAAgB,2BAA2B,CACzC,wBAAiC;IAEjC,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO;;;;;EAKP,wBAAwB,EAAE,CAAC;AAC7B,CAAC;AAED,UAAU;AACV,SAAgB,wBAAwB,CACtC,gCAAyC,KAAK,EAC9C,wBAAiC;IAEjC,MAAM,WAAW,GAAG;;;;;;IAMlB,CAAC;IAEH,MAAM,aAAa,GAAG,yCAAyC,CAAC;IAEhE,MAAM,YAAY,GAAG;;;GAGpB,CAAC,IAAI,EAAE,CAAC;IAET,MAAM,gBAAgB,GAAG,6BAA6B;QACpD,CAAC,CAAC;;;GAGH,CAAC,IAAI,EAAE;QACN,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,sBAAsB,GAC1B,+GAA+G;QAC/G,sFAAsF,CAAC;IAEzF,MAAM,gBAAgB,GAAG,2BAA2B,CAClD,wBAAwB,CACzB,CAAC;IAEF,MAAM,OAAO,GACX,GAAG,WAAW,GAAG,aAAa,OAAO,YAAY,KAAK,gBAAgB,GACpE,sBAAsB,CAAC,CAAC,CAAC,OAAO,sBAAsB,EAAE,CAAC,CAAC,CAAC,EAC7D,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE9E,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO;KACR,CAAC;AACJ,CAAC;AAED,SAAgB,sBAAsB,CACpC,WAAmB,EACnB,WAAmB,EACnB,gCAAyC,KAAK;IAE9C,IAAI,OAAO,GAAG,gBAAgB,WAAW;OACpC,WAAW,EAAE,CAAC;IAEnB,IAAI,6BAA6B,EAAE,CAAC;QAClC,OAAO,IAAI;;qEAEsD,CAAC;IACpE,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,oBAAoB,GAAG;;;;;;uEAM0C,CAAC;AAExE,SAAgB,yBAAyB;IACvC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,oBAAoB;KAC9B,CAAC;AACJ,CAAC;AAED,SAAgB,mBAAmB,CACjC,WAAmB,EACnB,kBAA0B;IAE1B,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,gBAAgB,WAAW;qBACnB,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;KAC/D,CAAC;AACJ,CAAC;AAED,UAAU;AACV,SAAgB,wBAAwB,CACtC,wBAAiC,EACjC,gBAA2B,EAC3B,SAAqB;IAErB,MAAM,aAAa,GAAG,gBAAgB,EAAE,MAAM;QAC5C,CAAC,CAAC,0BAA0B,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACzD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,eAAe,GAAG,IAAA,uCAAwB,EAAC,SAAS,CAAC,CAAC;IAC5D,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM;QAC5C,CAAC,CAAC,4BAA4B,eAAe;aACxC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;YAC7B,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;QAClE,CAAC,CAAC;aACD,IAAI,CACH,IAAI,CACL,wJAAwJ;QAC7J,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,mBAAmB,GAAG;;;;;;;;0FAQ4D,aAAa,GAAG,eAAe;;wWAE+O,CAAC;IACvW,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEzD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC,OAAO,EAAE,2BAA2B,CAAC,wBAAwB,CAAC,CAAC;aACtE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,MAAM,CAAC;KAChB,CAAC;AACJ,CAAC;AAED,SAAgB,uBAAuB,CACrC,WAAmB,EACnB,WAAmB;IAEnB,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,gBAAgB,WAAW;wBAChB,WAAW,IAAI;KACpC,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB,CAClC,wBAAiC;IAEjC,MAAM,eAAe,GAAG;;;;;;;yQAO+O,CAAC;IACxQ,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAErD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC,OAAO,EAAE,2BAA2B,CAAC,wBAAwB,CAAC,CAAC;aACtE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,MAAM,CAAC;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,SAAqB;IACpD,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;SACzC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO,4EAA4E,aAAa;;sRAEoL,CAAC;AACvR,CAAC;AAED,SAAgB,cAAc,CAC5B,MAAc,EACd,gBAA0B,EAC1B,SAAqB;IAErB,mBAAmB;IACnB,IAAI,WAAW,GAAG,sFAAsF,MAAM;;;;iDAI/D,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;GAoBzE,CAAC;IAEF,WAAW,IAAI,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAElD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAgB,kBAAkB,CAChC,kBAA0B,EAC1B,cAAsB,EACtB,gBAA0B,EAC1B,SAAqB;IAErB,mBAAmB;IACnB,IAAI,WAAW,GAAG;kCACc,kBAAkB;0EACsB,cAAc;;;;;+CAKzC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;GAMvE,CAAC;IAEF,WAAW,IAAI,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAElD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAgB,yBAAyB,CAAC,IAAY;IACpD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;;;;;EAKX,IAAI;;;;;;;;;;;;;;;;;;;;;;;mFAuB6E;KAChF,CAAC;AACJ,CAAC;AAED,SAAgB,2BAA2B;IACzC,OAAO,gJAAgJ,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACnM,CAAC;AAED,SAAgB,0BAA0B;IACxC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;kBACK,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;;;CAGvD;KACE,CAAC;AACJ,CAAC","sourcesContent":["import { ChatMessage } from \"./v3/llm/LLMClient.js\";\nimport type { Variables } from \"./v3/types/public/agent.js\";\nimport { getVariablePromptEntries } from \"./v3/agent/utils/variables.js\";\n\nexport function buildUserInstructionsString(\n userProvidedInstructions?: string,\n): string {\n if (!userProvidedInstructions) {\n return \"\";\n }\n\n return `\\n\\n# Custom Instructions Provided by the User\n \nPlease keep the user's instructions in mind when performing actions. If the user's instructions are not relevant to the current task, ignore them.\n\nUser Instructions:\n${userProvidedInstructions}`;\n}\n\n// extract\nexport function buildExtractSystemPrompt(\n isUsingPrintExtractedDataTool: boolean = false,\n userProvidedInstructions?: string,\n): ChatMessage {\n const baseContent = `You are extracting content on behalf of a user.\n If a user asks you to extract a 'list' of information, or 'all' information, \n YOU MUST EXTRACT ALL OF THE INFORMATION THAT THE USER REQUESTS.\n \n You will be given:\n1. An instruction\n2. `;\n\n const contentDetail = `A list of DOM elements to extract from.`;\n\n const instructions = `\nPrint the exact text from the DOM elements with all symbols, characters, and endlines as is.\nPrint null or an empty string if no new information is found.\n `.trim();\n\n const toolInstructions = isUsingPrintExtractedDataTool\n ? `\nONLY print the content using the print_extracted_data tool provided.\nONLY print the content using the print_extracted_data tool provided.\n `.trim()\n : \"\";\n\n const additionalInstructions =\n \"If a user is attempting to extract links or URLs, you MUST respond with ONLY the IDs of the link elements. \\n\" +\n \"Do not attempt to extract links directly from the text unless absolutely necessary. \";\n\n const userInstructions = buildUserInstructionsString(\n userProvidedInstructions,\n );\n\n const content =\n `${baseContent}${contentDetail}\\n\\n${instructions}\\n${toolInstructions}${\n additionalInstructions ? `\\n\\n${additionalInstructions}` : \"\"\n }${userInstructions ? `\\n\\n${userInstructions}` : \"\"}`.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content,\n };\n}\n\nexport function buildExtractUserPrompt(\n instruction: string,\n domElements: string,\n isUsingPrintExtractedDataTool: boolean = false,\n): ChatMessage {\n let content = `Instruction: ${instruction}\nDOM: ${domElements}`;\n\n if (isUsingPrintExtractedDataTool) {\n content += `\nONLY print the content using the print_extracted_data tool provided.\nONLY print the content using the print_extracted_data tool provided.`;\n }\n\n return {\n role: \"user\",\n content,\n };\n}\n\nconst metadataSystemPrompt = `You are an AI assistant tasked with evaluating the progress and completion status of an extraction task.\nAnalyze the extraction response and determine if the task is completed or if more information is needed.\nStrictly abide by the following criteria:\n1. Once the instruction has been satisfied by the current extraction response, ALWAYS set completion status to true and stop processing, regardless of remaining chunks.\n2. Only set completion status to false if BOTH of these conditions are true:\n - The instruction has not been satisfied yet\n - There are still chunks left to process (chunksTotal > chunksSeen)`;\n\nexport function buildMetadataSystemPrompt(): ChatMessage {\n return {\n role: \"system\",\n content: metadataSystemPrompt,\n };\n}\n\nexport function buildMetadataPrompt(\n instruction: string,\n extractionResponse: object,\n): ChatMessage {\n return {\n role: \"user\",\n content: `Instruction: ${instruction}\nExtracted content: ${JSON.stringify(extractionResponse, null, 2)}`,\n };\n}\n\n// observe\nexport function buildObserveSystemPrompt(\n userProvidedInstructions?: string,\n supportedActions?: string[],\n variables?: Variables,\n): ChatMessage {\n const actionsString = supportedActions?.length\n ? `\\n\\nSupported actions: ${supportedActions.join(\", \")}`\n : \"\";\n const variableEntries = getVariablePromptEntries(variables);\n const variablesString = variableEntries.length\n ? `\\n\\nAvailable variables: ${variableEntries\n .map(({ name, description }) => {\n return description ? `%${name}% (${description})` : `%${name}%`;\n })\n .join(\n \", \",\n )}. When an action needs a dynamic or sensitive value, return the matching %variableName% placeholder in the action arguments instead of a literal value`\n : \"\";\n\n const observeSystemPrompt = `\nYou are helping the user automate the browser by finding elements based on what the user wants to observe in the page.\n\nYou will be given:\n1. a instruction of elements to observe\n2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.\n\nReturn an array of elements that match the instruction if they exist, otherwise return an empty array.\nWhen returning elements, include the appropriate method from the supported actions list.${actionsString}${variablesString}. When choosing non-left click actions, provide right or middle as the argument.\n\nEach element in the accessibility tree has an ID in square brackets, like [0-18372]. The ID has two parts: frame ordinal and backend node ID. Always copy the complete ID exactly as shown inside the brackets into elementId, including the frame ordinal and hyphen. For example, if the tree shows [0-18372], return elementId \"0-18372\"; never return only \"18372\".`;\n const content = observeSystemPrompt.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content: [content, buildUserInstructionsString(userProvidedInstructions)]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n };\n}\n\nexport function buildObserveUserMessage(\n instruction: string,\n domElements: string,\n): ChatMessage {\n return {\n role: \"user\",\n content: `instruction: ${instruction}\nAccessibility Tree: \\n${domElements}\\n`,\n };\n}\n\nexport function buildActSystemPrompt(\n userProvidedInstructions?: string,\n): ChatMessage {\n const actSystemPrompt = `\nYou are helping the user automate the browser by finding elements based on what action the user wants to take on the page\n\nYou will be given:\n1. a user defined instruction about what action to take\n2. a hierarchical accessibility tree showing the semantic structure of the page. The tree is a hybrid of the DOM and the accessibility tree.\n\nReturn the element that matches the instruction if it exists. If no element on the page matches the instruction, set \\`action\\` to null. Do not fabricate or guess an element — empty strings or placeholder values for elementId/description/method are not acceptable.`;\n const content = actSystemPrompt.replace(/\\s+/g, \" \");\n\n return {\n role: \"system\",\n content: [content, buildUserInstructionsString(userProvidedInstructions)]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n };\n}\n\nfunction buildActVariablesPrompt(variables?: Variables): string {\n if (!variables || Object.keys(variables).length === 0) {\n return \"\";\n }\n\n const variableNames = Object.keys(variables)\n .map((key) => `%${key}%`)\n .join(\", \");\n\n return ` The user has provided the following variables to be used in the action: ${variableNames} \\n\n Note that these are the variable names/keys, and not the actual variable values. \\n\n To use the variables in the action, you must respond with the variable name inside the 'arguments' array. The variable name must be wrapped in percentage signs (eg, %variableNameHere%) so that it can be replaced with the actual variable value before the action is taken. \\n`;\n}\n\nexport function buildActPrompt(\n action: string,\n supportedActions: string[],\n variables?: Variables,\n): string {\n // Base instruction\n let instruction = `Find the most relevant element to perform an action on given the following action: ${action}. \n IF AND ONLY IF the action EXPLICITLY includes the word 'dropdown' and implies choosing/selecting an option from a dropdown, ignore the 'General Instructions' section, and follow the 'Dropdown Specific Instructions' section carefully.\n \n General Instructions: \n Provide an action for this element such as ${supportedActions.join(\", \")}. Remember that to users, buttons and links look the same in most cases.\n When choosing non-left click actions, provide right or middle as the argument\n If the action is completely unrelated to a potential action to be taken on the page, or no matching element exists, set \\`action\\` to null. Do not fabricate or guess an element.\n ONLY return one action. If multiple actions are relevant, return the most relevant one.\n If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.\n If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.\n If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys. \n \n Dropdown Specific Instructions:\n For interacting with dropdowns, there are two specific cases that you need to handle. \n \n CASE 1: the element is a 'select' element. \n - choose the selectOptionFromDropdown method,\n - set the argument to the exact text of the option that should be selected,\n - set twoStep to false.\n CASE 2: the element is NOT a 'select' element:\n - do not attempt to directly choose the element from the dropdown. You will need to click to expand the dropdown first. You will achieve this by following these instructions:\n - choose the node that most closely corresponds to the given instruction EVEN if it is a 'StaticText' element, or otherwise does not appear to be interactable. \n - choose the 'click' method\n - set twoStep to true.\n `;\n\n instruction += buildActVariablesPrompt(variables);\n\n return instruction;\n}\n\nexport function buildStepTwoPrompt(\n originalUserAction: string,\n previousAction: string,\n supportedActions: string[],\n variables?: Variables,\n): string {\n // Base instruction\n let instruction = `\n The original user action was: ${originalUserAction}.\n You have just taken the following action which completed step 1 of 2: ${previousAction}.\n \n Now, you must find the most relevant element to perform an action on in order to complete step 2 of 2. \n \n General Instructions: \n Provide an action for this element such as ${supportedActions.join(\", \")}. Remember that to users, buttons and links look the same in most cases.\n If the action is completely unrelated to a potential action to be taken on the page, or no matching element exists, set \\`action\\` to null. Do not fabricate or guess an element.\n ONLY return one action. If multiple actions are relevant, return the most relevant one.\n If the user is asking to scroll to a position on the page, e.g., 'halfway' or 0.75, etc, you must return the argument formatted as the correct percentage, e.g., '50%' or '75%', etc.\n If the user is asking to scroll to the next chunk/previous chunk, choose the nextChunk/prevChunk method. No arguments are required here.\n If the action implies a key press, e.g., 'press enter', 'press a', 'press space', etc., always choose the press method with the appropriate key as argument — e.g. 'a', 'Enter', 'Space'. Do not choose a click action on an on-screen keyboard. Capitalize the first character like 'Enter', 'Tab', 'Escape' only for special keys. \n `;\n\n instruction += buildActVariablesPrompt(variables);\n\n return instruction;\n}\n\nexport function buildOperatorSystemPrompt(goal: string): ChatMessage {\n return {\n role: \"system\",\n content: `You are a general-purpose agent whose job is to accomplish the user's goal across multiple model calls by running actions on the page.\n\nYou will be given a goal and a list of steps that have been taken so far. Your job is to determine if either the user's goal has been completed or if there are still steps that need to be taken.\n\n# Your current goal\n${goal}\n\n# CRITICAL: You MUST use the provided tools to take actions. Do not just describe what you want to do - actually call the appropriate tools.\n\n# Available tools and when to use them:\n- \\`act\\`: Use this to interact with the page (click, type, navigate, etc.)\n- \\`extract\\`: Use this to get information from the page\n- \\`goto\\`: Use this to navigate to a specific URL\n- \\`wait\\`: Use this to wait for a period of time\n- \\`navback\\`: Use this to go back to the previous page\n- \\`refresh\\`: Use this to refresh the current page\n- \\`close\\`: Use this ONLY when the task is complete or cannot be achieved\n- External tools: Use any additional tools (like search tools) as needed for your goal\n\n# Important guidelines\n1. ALWAYS use tools - never just provide text responses about what you plan to do\n2. Break down complex actions into individual atomic steps\n3. For \\`act\\` commands, use only one action at a time, such as:\n - Single click on a specific element\n - Type into a single input field\n - Select a single option\n4. Avoid combining multiple actions in one instruction\n5. If multiple actions are needed, they should be separate steps\n6. Only use \\`close\\` when the task is genuinely complete or impossible to achieve`,\n };\n}\n\nexport function buildCuaDefaultSystemPrompt(): string {\n return `You are a helpful assistant that can use a web browser.\\nDo not ask follow up questions, the user will trust your judgement. Today's date is ${new Date().toISOString().split(\"T\")[0]}.`;\n}\n\nexport function buildGoogleCUASystemPrompt(): ChatMessage {\n return {\n role: \"system\",\n content: `You are a general-purpose browser agent whose job is to accomplish the user's goal.\nToday's date is ${new Date().toISOString().split(\"T\")[0]}.\nYou have access to a search tool; however, in most cases you should operate within the page/url the user has provided. ONLY use the search tool if you're stuck or the task is impossible to complete within the current page.\nYou will be given a goal and a list of steps that have been taken so far. Avoid requesting the user for input as much as possible. Good luck!\n`,\n };\n}\n"]}
@@ -9,6 +9,8 @@ const MicrosoftCUAClient_js_1 = require("./MicrosoftCUAClient.js");
9
9
  // Map model names to their provider types
10
10
  exports.modelToAgentProviderMap = {
11
11
  "gpt-5.4": "openai",
12
+ "gpt-5.4-mini": "openai",
13
+ "gpt-5.5": "openai",
12
14
  "computer-use-preview": "openai",
13
15
  "computer-use-preview-2025-03-11": "openai",
14
16
  "claude-sonnet-4-20250514": "anthropic",
@@ -16,6 +18,7 @@ exports.modelToAgentProviderMap = {
16
18
  "claude-opus-4-5-20251101": "anthropic",
17
19
  "claude-opus-4-6": "anthropic",
18
20
  "claude-sonnet-4-6": "anthropic",
21
+ "claude-haiku-4-5": "anthropic",
19
22
  "claude-haiku-4-5-20251001": "anthropic",
20
23
  "gemini-2.5-computer-use-preview-10-2025": "google",
21
24
  "gemini-3-flash-preview": "google",
@@ -1 +1 @@
1
- {"version":3,"file":"AgentProvider.js","sourceRoot":"","sources":["../../../../../lib/v3/agent/AgentProvider.ts"],"names":[],"mappings":";;;AAIA,+DAGsC;AAEtC,mEAA6D;AAC7D,6DAAuD;AACvD,6DAAuD;AACvD,mEAA6D;AAE7D,0CAA0C;AAC7B,QAAA,uBAAuB,GAAsC;IACxE,SAAS,EAAE,QAAQ;IACnB,sBAAsB,EAAE,QAAQ;IAChC,iCAAiC,EAAE,QAAQ;IAC3C,0BAA0B,EAAE,WAAW;IACvC,4BAA4B,EAAE,WAAW;IACzC,0BAA0B,EAAE,WAAW;IACvC,iBAAiB,EAAE,WAAW;IAC9B,mBAAmB,EAAE,WAAW;IAChC,2BAA2B,EAAE,WAAW;IACxC,yCAAyC,EAAE,QAAQ;IACnD,wBAAwB,EAAE,QAAQ;IAClC,sBAAsB,EAAE,QAAQ;IAChC,SAAS,EAAE,WAAW;CACvB,CAAC;AAEF;;;;GAIG;AACH,MAAa,aAAa;IAChB,MAAM,CAA6B;IAE3C;;OAEG;IACH,YAAY,MAAkC;QAC5C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,SAAS,CACP,SAAiB,EACjB,aAA6B,EAC7B,wBAAiC,EACjC,KAAe;QAEf,uDAAuD;QACvD,MAAM,gBAAgB,GAAG,aAAa,EAAE,QAE3B,CAAC;QACd,MAAM,IAAI,GAAG,gBAAgB,IAAI,aAAa,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAE3E,IAAI,CAAC,MAAM,CAAC;YACV,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,kCAAkC,IAAI,YAAY,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,EAAE;YACvH,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,QAAQ,IAAI,EAAE,CAAC;gBACb,KAAK,QAAQ;oBACX,OAAO,IAAI,oCAAe,CACxB,IAAI,EACJ,SAAS,EACT,wBAAwB,EACxB,aAAa,EACb,KAAK,CACN,CAAC;gBACJ,KAAK,WAAW;oBACd,OAAO,IAAI,0CAAkB,CAC3B,IAAI,EACJ,SAAS,EACT,wBAAwB,EACxB,aAAa,EACb,KAAK,CACN,CAAC;gBACJ,KAAK,QAAQ;oBACX,OAAO,IAAI,oCAAe,CACxB,IAAI,EACJ,SAAS,EACT,wBAAwB,EACxB,aAAa,EACb,KAAK,CACN,CAAC;gBACJ,KAAK,WAAW;oBACd,OAAO,IAAI,0CAAkB,CAC3B,IAAI,EACJ,SAAS,EACT,wBAAwB,EACxB,aAAa,CACd,CAAC;gBACJ;oBACE,MAAM,IAAI,4CAA6B,CACrC,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,EAC9C,oBAAoB,CACrB,CAAC;YACN,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC;gBACV,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,gCAAgC,YAAY,EAAE;gBACvD,KAAK,EAAE,CAAC;aACT,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,SAAiB;QACvC,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;YACxC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC,CAAC,SAAS,CAAC;QAEd,IAAI,UAAU,IAAI,+BAAuB,EAAE,CAAC;YAC1C,OAAO,+BAAuB,CAAC,UAAU,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,IAAI,oCAAqB,CAC7B,MAAM,CAAC,IAAI,CAAC,+BAAuB,CAAC,EACpC,oBAAoB,CACrB,CAAC;IACJ,CAAC;CACF;AA7FD,sCA6FC","sourcesContent":["import { ToolSet } from \"ai/dist\";\nimport { AgentProviderType } from \"../types/public/agent.js\";\nimport { LogLine } from \"../types/public/logs.js\";\nimport { ClientOptions } from \"../types/public/model.js\";\nimport {\n UnsupportedModelError,\n UnsupportedModelProviderError,\n} from \"../types/public/sdkErrors.js\";\nimport { AgentClient } from \"./AgentClient.js\";\nimport { AnthropicCUAClient } from \"./AnthropicCUAClient.js\";\nimport { OpenAICUAClient } from \"./OpenAICUAClient.js\";\nimport { GoogleCUAClient } from \"./GoogleCUAClient.js\";\nimport { MicrosoftCUAClient } from \"./MicrosoftCUAClient.js\";\n\n// Map model names to their provider types\nexport const modelToAgentProviderMap: Record<string, AgentProviderType> = {\n \"gpt-5.4\": \"openai\",\n \"computer-use-preview\": \"openai\",\n \"computer-use-preview-2025-03-11\": \"openai\",\n \"claude-sonnet-4-20250514\": \"anthropic\",\n \"claude-sonnet-4-5-20250929\": \"anthropic\",\n \"claude-opus-4-5-20251101\": \"anthropic\",\n \"claude-opus-4-6\": \"anthropic\",\n \"claude-sonnet-4-6\": \"anthropic\",\n \"claude-haiku-4-5-20251001\": \"anthropic\",\n \"gemini-2.5-computer-use-preview-10-2025\": \"google\",\n \"gemini-3-flash-preview\": \"google\",\n \"gemini-3-pro-preview\": \"google\",\n \"fara-7b\": \"microsoft\",\n};\n\n/**\n * Provider for agent clients\n * This class is responsible for creating the appropriate agent client\n * based on the provider type\n */\nexport class AgentProvider {\n private logger: (message: LogLine) => void;\n\n /**\n * Create a new agent provider\n */\n constructor(logger: (message: LogLine) => void) {\n this.logger = logger;\n }\n\n getClient(\n modelName: string,\n clientOptions?: ClientOptions,\n userProvidedInstructions?: string,\n tools?: ToolSet,\n ): AgentClient {\n // Check if provider is explicitly set in clientOptions\n const explicitProvider = clientOptions?.provider as\n | AgentProviderType\n | undefined;\n const type = explicitProvider || AgentProvider.getAgentProvider(modelName);\n\n this.logger({\n category: \"agent\",\n message: `Getting agent client for type: ${type}, model: ${modelName}${explicitProvider ? \" (explicit provider)\" : \"\"}`,\n level: 2,\n });\n\n try {\n switch (type) {\n case \"openai\":\n return new OpenAICUAClient(\n type,\n modelName,\n userProvidedInstructions,\n clientOptions,\n tools,\n );\n case \"anthropic\":\n return new AnthropicCUAClient(\n type,\n modelName,\n userProvidedInstructions,\n clientOptions,\n tools,\n );\n case \"google\":\n return new GoogleCUAClient(\n type,\n modelName,\n userProvidedInstructions,\n clientOptions,\n tools,\n );\n case \"microsoft\":\n return new MicrosoftCUAClient(\n type,\n modelName,\n userProvidedInstructions,\n clientOptions,\n );\n default:\n throw new UnsupportedModelProviderError(\n [\"openai\", \"anthropic\", \"google\", \"microsoft\"],\n \"Computer Use Agent\",\n );\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n this.logger({\n category: \"agent\",\n message: `Error creating agent client: ${errorMessage}`,\n level: 0,\n });\n throw error;\n }\n }\n\n static getAgentProvider(modelName: string): AgentProviderType {\n const normalized = modelName.includes(\"/\")\n ? modelName.split(\"/\")[1]\n : modelName;\n\n if (normalized in modelToAgentProviderMap) {\n return modelToAgentProviderMap[normalized];\n }\n\n throw new UnsupportedModelError(\n Object.keys(modelToAgentProviderMap),\n \"Computer Use Agent\",\n );\n }\n}\n"]}
1
+ {"version":3,"file":"AgentProvider.js","sourceRoot":"","sources":["../../../../../lib/v3/agent/AgentProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { ToolSet } from \"ai/dist\";\nimport { AgentProviderType } from \"../types/public/agent.js\";\nimport { LogLine } from \"../types/public/logs.js\";\nimport { ClientOptions } from \"../types/public/model.js\";\nimport {\n UnsupportedModelError,\n UnsupportedModelProviderError,\n} from \"../types/public/sdkErrors.js\";\nimport { AgentClient } from \"./AgentClient.js\";\nimport { AnthropicCUAClient } from \"./AnthropicCUAClient.js\";\nimport { OpenAICUAClient } from \"./OpenAICUAClient.js\";\nimport { GoogleCUAClient } from \"./GoogleCUAClient.js\";\nimport { MicrosoftCUAClient } from \"./MicrosoftCUAClient.js\";\n\n// Map model names to their provider types\nexport const modelToAgentProviderMap: Record<string, AgentProviderType> = {\n \"gpt-5.4\": \"openai\",\n \"gpt-5.4-mini\": \"openai\",\n \"gpt-5.5\": \"openai\",\n \"computer-use-preview\": \"openai\",\n \"computer-use-preview-2025-03-11\": \"openai\",\n \"claude-sonnet-4-20250514\": \"anthropic\",\n \"claude-sonnet-4-5-20250929\": \"anthropic\",\n \"claude-opus-4-5-20251101\": \"anthropic\",\n \"claude-opus-4-6\": \"anthropic\",\n \"claude-sonnet-4-6\": \"anthropic\",\n \"claude-haiku-4-5\": \"anthropic\",\n \"claude-haiku-4-5-20251001\": \"anthropic\",\n \"gemini-2.5-computer-use-preview-10-2025\": \"google\",\n \"gemini-3-flash-preview\": \"google\",\n \"gemini-3-pro-preview\": \"google\",\n \"fara-7b\": \"microsoft\",\n};\n\n/**\n * Provider for agent clients\n * This class is responsible for creating the appropriate agent client\n * based on the provider type\n */\nexport class AgentProvider {\n private logger: (message: LogLine) => void;\n\n /**\n * Create a new agent provider\n */\n constructor(logger: (message: LogLine) => void) {\n this.logger = logger;\n }\n\n getClient(\n modelName: string,\n clientOptions?: ClientOptions,\n userProvidedInstructions?: string,\n tools?: ToolSet,\n ): AgentClient {\n // Check if provider is explicitly set in clientOptions\n const explicitProvider = clientOptions?.provider as\n | AgentProviderType\n | undefined;\n const type = explicitProvider || AgentProvider.getAgentProvider(modelName);\n\n this.logger({\n category: \"agent\",\n message: `Getting agent client for type: ${type}, model: ${modelName}${explicitProvider ? \" (explicit provider)\" : \"\"}`,\n level: 2,\n });\n\n try {\n switch (type) {\n case \"openai\":\n return new OpenAICUAClient(\n type,\n modelName,\n userProvidedInstructions,\n clientOptions,\n tools,\n );\n case \"anthropic\":\n return new AnthropicCUAClient(\n type,\n modelName,\n userProvidedInstructions,\n clientOptions,\n tools,\n );\n case \"google\":\n return new GoogleCUAClient(\n type,\n modelName,\n userProvidedInstructions,\n clientOptions,\n tools,\n );\n case \"microsoft\":\n return new MicrosoftCUAClient(\n type,\n modelName,\n userProvidedInstructions,\n clientOptions,\n );\n default:\n throw new UnsupportedModelProviderError(\n [\"openai\", \"anthropic\", \"google\", \"microsoft\"],\n \"Computer Use Agent\",\n );\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n this.logger({\n category: \"agent\",\n message: `Error creating agent client: ${errorMessage}`,\n level: 0,\n });\n throw error;\n }\n }\n\n static getAgentProvider(modelName: string): AgentProviderType {\n const normalized = modelName.includes(\"/\")\n ? modelName.split(\"/\")[1]\n : modelName;\n\n if (normalized in modelToAgentProviderMap) {\n return modelToAgentProviderMap[normalized];\n }\n\n throw new UnsupportedModelError(\n Object.keys(modelToAgentProviderMap),\n \"Computer Use Agent\",\n );\n }\n}\n"]}
@@ -49,14 +49,16 @@ MANDATORY USE CASES (always use fillFormVision for these):
49
49
  execute: async ({ fields }) => {
50
50
  try {
51
51
  const page = await v3.context.awaitActivePage();
52
- // Process coordinates and substitute variables for each field
53
- // Keep original values (with %tokens%) for logging/caching, substituted values for typing
54
- const processedFields = fields.map((field) => {
52
+ // Process coordinates per field. Keep the original `value` (with any
53
+ // `%variableName%` tokens) so substituted secrets never leak through
54
+ // the tool result, replay cache, returned AgentResult.actions, or
55
+ // anything that logs the action. Variables are substituted only at
56
+ // typing time below.
57
+ const safeFields = fields.map((field) => {
55
58
  const processed = (0, coordinateNormalization_js_1.processCoordinates)(field.coordinates.x, field.coordinates.y, provider, v3);
56
59
  return {
57
- ...field,
58
- originalValue: field.value, // Keep original with %tokens% for cache
59
- value: (0, variables_js_1.substituteVariables)(field.value, variables),
60
+ action: field.action,
61
+ value: field.value,
60
62
  coordinates: { x: processed.x, y: processed.y },
61
63
  };
62
64
  });
@@ -74,14 +76,16 @@ MANDATORY USE CASES (always use fillFormVision for these):
74
76
  // Only request XPath when caching is enabled to avoid unnecessary computation
75
77
  const shouldCollectXpath = v3.isAgentReplayActive();
76
78
  const actions = [];
77
- for (const field of processedFields) {
79
+ for (const field of safeFields) {
78
80
  // Click the field, only requesting XPath when caching is enabled
79
81
  const xpath = await page.click(field.coordinates.x, field.coordinates.y, {
80
82
  returnXpath: shouldCollectXpath,
81
83
  });
82
- await page.type(field.value);
83
- // Build Action with XPath for deterministic replay (only when caching)
84
- // Use originalValue (with %tokens%) so cache stores references, not sensitive values
84
+ // Substitute variables only at the moment of typing so the resolved
85
+ // value never leaves this scope.
86
+ await page.type((0, variables_js_1.substituteVariables)(field.value, variables));
87
+ // Build Action with XPath for deterministic replay (only when caching).
88
+ // Store the placeholder value so cache entries don't contain secrets.
85
89
  if (shouldCollectXpath) {
86
90
  const normalizedXpath = (0, xpath_js_1.ensureXPath)(xpath);
87
91
  if (normalizedXpath) {
@@ -89,7 +93,7 @@ MANDATORY USE CASES (always use fillFormVision for these):
89
93
  selector: normalizedXpath,
90
94
  description: field.action,
91
95
  method: "type",
92
- arguments: [field.originalValue],
96
+ arguments: [field.value],
93
97
  });
94
98
  }
95
99
  }
@@ -108,7 +112,7 @@ MANDATORY USE CASES (always use fillFormVision for these):
108
112
  }
109
113
  return {
110
114
  success: true,
111
- playwrightArguments: processedFields,
115
+ playwrightArguments: safeFields,
112
116
  screenshotBase64,
113
117
  };
114
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fillFormVision.js","sourceRoot":"","sources":["../../../../../../lib/v3/agent/tools/fillFormVision.ts"],"names":[],"mappings":"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","sourcesContent":["import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport type { V3 } from \"../../v3.js\";\nimport type { Action } from \"../../types/public/methods.js\";\nimport type {\n FillFormVisionToolResult,\n ModelOutputContentItem,\n Variables,\n} from \"../../types/public/agent.js\";\nimport { processCoordinates } from \"../utils/coordinateNormalization.js\";\nimport { ensureXPath } from \"../utils/xpath.js\";\nimport { waitAndCaptureScreenshot } from \"../utils/screenshotHandler.js\";\nimport { substituteVariables } from \"../utils/variables.js\";\n\nexport const fillFormVisionTool = (\n v3: V3,\n provider?: string,\n variables?: Variables,\n) => {\n const hasVariables = variables && Object.keys(variables).length > 0;\n const valueDescription = hasVariables\n ? `Text to type into the target field. Use %variableName% to substitute a variable value. Available: ${Object.keys(variables).join(\", \")}`\n : \"Text to type into the target field\";\n\n return tool({\n description: `FORM FILL - SPECIALIZED MULTI-FIELD INPUT TOOL\n\nCRITICAL: Use this for ANY form with 2+ input fields (text inputs, textareas, etc.)\nIMPORTANT: Ensure the fields are visible within the current viewport\n\nWHY THIS TOOL EXISTS:\n- Forms are the #1 use case for multi-field input\n- Optimized specifically for input/textarea elements\n- 4-6x faster than individual typing actions\n\nUse fillFormVision: Pure form filling (inputs, textareas only)\nMANDATORY USE CASES (always use fillFormVision for these):\n- Registration forms: name, email, password fields\n- Contact forms: name, email, message fields\n- Checkout forms: address, payment info fields\n- Profile updates: multiple user data fields\n- Search filters: multiple criteria inputs`,\n inputSchema: z.object({\n fields: z\n .array(\n z.object({\n action: z\n .string()\n .describe(\n \"Description of the typing action, e.g. 'type foo into the bar field'\",\n ),\n value: z.string().describe(valueDescription),\n coordinates: z\n .object({\n x: z.number(),\n y: z.number(),\n })\n .describe(\"Coordinates of the target field\"),\n }),\n )\n .min(2, \"Provide at least two fields to fill\"),\n }),\n execute: async ({ fields }): Promise<FillFormVisionToolResult> => {\n try {\n const page = await v3.context.awaitActivePage();\n\n // Process coordinates and substitute variables for each field\n // Keep original values (with %tokens%) for logging/caching, substituted values for typing\n const processedFields = fields.map((field) => {\n const processed = processCoordinates(\n field.coordinates.x,\n field.coordinates.y,\n provider,\n v3,\n );\n return {\n ...field,\n originalValue: field.value, // Keep original with %tokens% for cache\n value: substituteVariables(field.value, variables),\n coordinates: { x: processed.x, y: processed.y },\n };\n });\n\n v3.logger({\n category: \"agent\",\n message: `Agent calling tool: fillFormVision`,\n level: 1,\n auxiliary: {\n arguments: {\n value: JSON.stringify({ fields }), // Don't log substituted values\n type: \"object\",\n },\n },\n });\n\n // Only request XPath when caching is enabled to avoid unnecessary computation\n const shouldCollectXpath = v3.isAgentReplayActive();\n const actions: Action[] = [];\n\n for (const field of processedFields) {\n // Click the field, only requesting XPath when caching is enabled\n const xpath = await page.click(\n field.coordinates.x,\n field.coordinates.y,\n {\n returnXpath: shouldCollectXpath,\n },\n );\n await page.type(field.value);\n\n // Build Action with XPath for deterministic replay (only when caching)\n // Use originalValue (with %tokens%) so cache stores references, not sensitive values\n if (shouldCollectXpath) {\n const normalizedXpath = ensureXPath(xpath);\n if (normalizedXpath) {\n actions.push({\n selector: normalizedXpath,\n description: field.action,\n method: \"type\",\n arguments: [field.originalValue],\n });\n }\n }\n\n // Small delay between fields\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n const screenshotBase64 = await waitAndCaptureScreenshot(page, 100);\n\n // Record as \"act\" step with proper Actions for deterministic replay (only when caching)\n if (shouldCollectXpath && actions.length > 0) {\n v3.recordAgentReplayStep({\n type: \"act\",\n instruction: `Fill ${fields.length} form fields`,\n actions,\n actionDescription: `Fill ${fields.length} form fields`,\n });\n }\n\n return {\n success: true,\n playwrightArguments: processedFields,\n screenshotBase64,\n };\n } catch (error) {\n return {\n success: false,\n error: `Error filling form: ${error.message}`,\n };\n }\n },\n toModelOutput: (result) => {\n if (result.success === false || result.error !== undefined) {\n return {\n type: \"content\",\n value: [\n {\n type: \"text\",\n text: JSON.stringify({\n success: result.success,\n error: result.error,\n }),\n },\n ],\n };\n }\n\n const content: ModelOutputContentItem[] = [\n {\n type: \"text\",\n text: JSON.stringify({\n success: result.success,\n fieldsCount: result.playwrightArguments?.length ?? 0,\n }),\n },\n ];\n if (result.screenshotBase64) {\n content.push({\n type: \"media\",\n mediaType: \"image/png\",\n data: result.screenshotBase64,\n });\n }\n return { type: \"content\", value: content };\n },\n });\n};\n"]}
1
+ {"version":3,"file":"fillFormVision.js","sourceRoot":"","sources":["../../../../../../lib/v3/agent/tools/fillFormVision.ts"],"names":[],"mappings":"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","sourcesContent":["import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport type { V3 } from \"../../v3.js\";\nimport type { Action } from \"../../types/public/methods.js\";\nimport type {\n FillFormVisionToolResult,\n ModelOutputContentItem,\n Variables,\n} from \"../../types/public/agent.js\";\nimport { processCoordinates } from \"../utils/coordinateNormalization.js\";\nimport { ensureXPath } from \"../utils/xpath.js\";\nimport { waitAndCaptureScreenshot } from \"../utils/screenshotHandler.js\";\nimport { substituteVariables } from \"../utils/variables.js\";\n\nexport const fillFormVisionTool = (\n v3: V3,\n provider?: string,\n variables?: Variables,\n) => {\n const hasVariables = variables && Object.keys(variables).length > 0;\n const valueDescription = hasVariables\n ? `Text to type into the target field. Use %variableName% to substitute a variable value. Available: ${Object.keys(variables).join(\", \")}`\n : \"Text to type into the target field\";\n\n return tool({\n description: `FORM FILL - SPECIALIZED MULTI-FIELD INPUT TOOL\n\nCRITICAL: Use this for ANY form with 2+ input fields (text inputs, textareas, etc.)\nIMPORTANT: Ensure the fields are visible within the current viewport\n\nWHY THIS TOOL EXISTS:\n- Forms are the #1 use case for multi-field input\n- Optimized specifically for input/textarea elements\n- 4-6x faster than individual typing actions\n\nUse fillFormVision: Pure form filling (inputs, textareas only)\nMANDATORY USE CASES (always use fillFormVision for these):\n- Registration forms: name, email, password fields\n- Contact forms: name, email, message fields\n- Checkout forms: address, payment info fields\n- Profile updates: multiple user data fields\n- Search filters: multiple criteria inputs`,\n inputSchema: z.object({\n fields: z\n .array(\n z.object({\n action: z\n .string()\n .describe(\n \"Description of the typing action, e.g. 'type foo into the bar field'\",\n ),\n value: z.string().describe(valueDescription),\n coordinates: z\n .object({\n x: z.number(),\n y: z.number(),\n })\n .describe(\"Coordinates of the target field\"),\n }),\n )\n .min(2, \"Provide at least two fields to fill\"),\n }),\n execute: async ({ fields }): Promise<FillFormVisionToolResult> => {\n try {\n const page = await v3.context.awaitActivePage();\n\n // Process coordinates per field. Keep the original `value` (with any\n // `%variableName%` tokens) so substituted secrets never leak through\n // the tool result, replay cache, returned AgentResult.actions, or\n // anything that logs the action. Variables are substituted only at\n // typing time below.\n const safeFields = fields.map((field) => {\n const processed = processCoordinates(\n field.coordinates.x,\n field.coordinates.y,\n provider,\n v3,\n );\n return {\n action: field.action,\n value: field.value,\n coordinates: { x: processed.x, y: processed.y },\n };\n });\n\n v3.logger({\n category: \"agent\",\n message: `Agent calling tool: fillFormVision`,\n level: 1,\n auxiliary: {\n arguments: {\n value: JSON.stringify({ fields }), // Don't log substituted values\n type: \"object\",\n },\n },\n });\n\n // Only request XPath when caching is enabled to avoid unnecessary computation\n const shouldCollectXpath = v3.isAgentReplayActive();\n const actions: Action[] = [];\n\n for (const field of safeFields) {\n // Click the field, only requesting XPath when caching is enabled\n const xpath = await page.click(\n field.coordinates.x,\n field.coordinates.y,\n {\n returnXpath: shouldCollectXpath,\n },\n );\n // Substitute variables only at the moment of typing so the resolved\n // value never leaves this scope.\n await page.type(substituteVariables(field.value, variables));\n\n // Build Action with XPath for deterministic replay (only when caching).\n // Store the placeholder value so cache entries don't contain secrets.\n if (shouldCollectXpath) {\n const normalizedXpath = ensureXPath(xpath);\n if (normalizedXpath) {\n actions.push({\n selector: normalizedXpath,\n description: field.action,\n method: \"type\",\n arguments: [field.value],\n });\n }\n }\n\n // Small delay between fields\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n const screenshotBase64 = await waitAndCaptureScreenshot(page, 100);\n\n // Record as \"act\" step with proper Actions for deterministic replay (only when caching)\n if (shouldCollectXpath && actions.length > 0) {\n v3.recordAgentReplayStep({\n type: \"act\",\n instruction: `Fill ${fields.length} form fields`,\n actions,\n actionDescription: `Fill ${fields.length} form fields`,\n });\n }\n\n return {\n success: true,\n playwrightArguments: safeFields,\n screenshotBase64,\n };\n } catch (error) {\n return {\n success: false,\n error: `Error filling form: ${error.message}`,\n };\n }\n },\n toModelOutput: (result) => {\n if (result.success === false || result.error !== undefined) {\n return {\n type: \"content\",\n value: [\n {\n type: \"text\",\n text: JSON.stringify({\n success: result.success,\n error: result.error,\n }),\n },\n ],\n };\n }\n\n const content: ModelOutputContentItem[] = [\n {\n type: \"text\",\n text: JSON.stringify({\n success: result.success,\n fieldsCount: result.playwrightArguments?.length ?? 0,\n }),\n },\n ];\n if (result.screenshotBase64) {\n content.push({\n type: \"media\",\n mediaType: \"image/png\",\n data: result.screenshotBase64,\n });\n }\n return { type: \"content\", value: content };\n },\n });\n};\n"]}
@@ -78,10 +78,6 @@ function validateExperimentalFeatures(options) {
78
78
  if (executeOptions.output) {
79
79
  features.push("output schema");
80
80
  }
81
- if (executeOptions.variables &&
82
- Object.keys(executeOptions.variables).length > 0) {
83
- features.push("variables");
84
- }
85
81
  }
86
82
  if (features.length > 0) {
87
83
  throw new sdkErrors_js_1.ExperimentalNotConfiguredError(`Agent ${features.join(", ")}`);
@@ -1 +1 @@
1
- {"version":3,"file":"validateExperimentalFeatures.js","sourceRoot":"","sources":["../../../../../../lib/v3/agent/utils/validateExperimentalFeatures.ts"],"names":[],"mappings":";;AAkCA,oEA8FC;AAhID,kEAGyC;AAmBzC;;;;;;;;;;;GAWG;AACH,SAAgB,4BAA4B,CAC1C,OAA+B;IAE/B,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAE7E,yEAAyE;IACzE,MAAM,SAAS,GACb,WAAW,EAAE,IAAI,KAAK,SAAS;QAC7B,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,KAAK;QAC5B,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,CAAC;IAEhC,qEAAqE;IACrE,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,mBAAmB,GAAa,EAAE,CAAC;QAEzC,IAAI,WAAW,EAAE,MAAM,EAAE,CAAC;YACxB,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;YAC3B,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,cAAc,EAAE,QAAQ,EAAE,CAAC;YAC7B,mBAAmB,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnD,CAAC;QACD,IACE,cAAc,EAAE,YAAY;YAC5B,cAAc,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EACtC,CAAC;YACD,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;YAC3B,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5C,CAAC;QACD,IACE,cAAc,EAAE,SAAS;YACzB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,EAChD,CAAC;YACD,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,4CAA6B,CACrC,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,oDAAoD,CACzI,CAAC;QACJ,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,IAAI,cAAc;QAAE,OAAO;IAE3B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,6FAA6F;IAC7F,MAAM,eAAe,GACnB,WAAW,EAAE,YAAY,IAAI,WAAW,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IACnE,MAAM,QAAQ,GACZ,WAAW,EAAE,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAClE,IAAI,eAAe,IAAI,QAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IACrD,CAAC;IAED,mFAAmF;IACnF,IAAI,CAAC,SAAS,IAAI,CAAC,WAAW,IAAI,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC;IAED,oDAAoD;IACpD,IAAI,cAAc,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,IAAI,cAAc,CAAC,SAAS,EAAE,CAAC;YAC7B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,cAAc,CAAC,YAAY,IAAI,cAAc,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1E,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACjC,CAAC;QACD,IACE,cAAc,CAAC,SAAS;YACxB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,EAChD,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,6CAA8B,CAAC,SAAS,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC","sourcesContent":["import {\n ExperimentalNotConfiguredError,\n StagehandInvalidArgumentError,\n} from \"../../types/public/sdkErrors.js\";\nimport type {\n AgentConfig,\n AgentExecuteOptionsBase,\n} from \"../../types/public/index.js\";\n\nexport interface AgentValidationOptions {\n /** Whether experimental mode is enabled */\n isExperimental: boolean;\n /** Agent config options (integrations, tools, stream, cua, etc.) */\n agentConfig?: Partial<AgentConfig>;\n /** Execute options (callbacks, signal, messages, etc.) */\n executeOptions?:\n | (Partial<AgentExecuteOptionsBase> & { callbacks?: unknown })\n | null;\n /** Whether this is streaming mode (can be derived from agentConfig.stream) */\n isStreaming?: boolean;\n}\n\n/**\n * Validates agent configuration and experimental feature usage.\n *\n * This utility consolidates all validation checks for both CUA and non-CUA agent paths:\n * - Invalid argument errors for CUA (streaming, abort signal, message continuation, excludeTools, output schema are not supported)\n * - Experimental feature checks for integrations and tools (both CUA and non-CUA)\n * - Experimental feature checks for hybrid mode (requires experimental: true)\n * - Experimental feature checks for non-CUA only (callbacks, signal, messages, streaming, excludeTools, output schema)\n *\n * Throws StagehandInvalidArgumentError for invalid/unsupported configurations.\n * Throws ExperimentalNotConfiguredError if experimental features are used without experimental mode.\n */\nexport function validateExperimentalFeatures(\n options: AgentValidationOptions,\n): void {\n const { isExperimental, agentConfig, executeOptions, isStreaming } = options;\n\n // Check if CUA mode is enabled (via mode: \"cua\" or deprecated cua: true)\n const isCuaMode =\n agentConfig?.mode !== undefined\n ? agentConfig.mode === \"cua\"\n : agentConfig?.cua === true;\n\n // CUA-specific validation: certain features are not available at all\n if (isCuaMode) {\n const unsupportedFeatures: string[] = [];\n\n if (agentConfig?.stream) {\n unsupportedFeatures.push(\"streaming\");\n }\n if (executeOptions?.signal) {\n unsupportedFeatures.push(\"abort signal\");\n }\n if (executeOptions?.messages) {\n unsupportedFeatures.push(\"message continuation\");\n }\n if (\n executeOptions?.excludeTools &&\n executeOptions.excludeTools.length > 0\n ) {\n unsupportedFeatures.push(\"excludeTools\");\n }\n if (executeOptions?.output) {\n unsupportedFeatures.push(\"output schema\");\n }\n if (\n executeOptions?.variables &&\n Object.keys(executeOptions.variables).length > 0\n ) {\n unsupportedFeatures.push(\"variables\");\n }\n\n if (unsupportedFeatures.length > 0) {\n throw new StagehandInvalidArgumentError(\n `${unsupportedFeatures.join(\", \")} ${unsupportedFeatures.length === 1 ? \"is\" : \"are\"} not supported with CUA (Computer Use Agent) mode.`,\n );\n }\n }\n\n // Skip experimental checks if already in experimental mode\n if (isExperimental) return;\n\n const features: string[] = [];\n\n // Check agent config features (check array length to avoid false positives for empty arrays)\n const hasIntegrations =\n agentConfig?.integrations && agentConfig.integrations.length > 0;\n const hasTools =\n agentConfig?.tools && Object.keys(agentConfig.tools).length > 0;\n if (hasIntegrations || hasTools) {\n features.push(\"MCP integrations and custom tools\");\n }\n\n // Check streaming mode (either explicit or derived from config) - only for non-CUA\n if (!isCuaMode && (isStreaming || agentConfig?.stream)) {\n features.push(\"streaming\");\n }\n\n // Check execute options features - only for non-CUA\n if (executeOptions && !isCuaMode) {\n if (executeOptions.callbacks) {\n features.push(\"callbacks\");\n }\n if (executeOptions.signal) {\n features.push(\"abort signal\");\n }\n if (executeOptions.messages) {\n features.push(\"message continuation\");\n }\n if (executeOptions.excludeTools && executeOptions.excludeTools.length > 0) {\n features.push(\"excludeTools\");\n }\n if (executeOptions.output) {\n features.push(\"output schema\");\n }\n if (\n executeOptions.variables &&\n Object.keys(executeOptions.variables).length > 0\n ) {\n features.push(\"variables\");\n }\n }\n\n if (features.length > 0) {\n throw new ExperimentalNotConfiguredError(`Agent ${features.join(\", \")}`);\n }\n}\n"]}
1
+ {"version":3,"file":"validateExperimentalFeatures.js","sourceRoot":"","sources":["../../../../../../lib/v3/agent/utils/validateExperimentalFeatures.ts"],"names":[],"mappings":";;AAkCA,oEAwFC;AA1HD,kEAGyC;AAmBzC;;;;;;;;;;;GAWG;AACH,SAAgB,4BAA4B,CAC1C,OAA+B;IAE/B,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAE7E,yEAAyE;IACzE,MAAM,SAAS,GACb,WAAW,EAAE,IAAI,KAAK,SAAS;QAC7B,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,KAAK;QAC5B,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,CAAC;IAEhC,qEAAqE;IACrE,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,mBAAmB,GAAa,EAAE,CAAC;QAEzC,IAAI,WAAW,EAAE,MAAM,EAAE,CAAC;YACxB,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;YAC3B,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,cAAc,EAAE,QAAQ,EAAE,CAAC;YAC7B,mBAAmB,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnD,CAAC;QACD,IACE,cAAc,EAAE,YAAY;YAC5B,cAAc,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EACtC,CAAC;YACD,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;YAC3B,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5C,CAAC;QACD,IACE,cAAc,EAAE,SAAS;YACzB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,EAChD,CAAC;YACD,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,4CAA6B,CACrC,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,oDAAoD,CACzI,CAAC;QACJ,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,IAAI,cAAc;QAAE,OAAO;IAE3B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,6FAA6F;IAC7F,MAAM,eAAe,GACnB,WAAW,EAAE,YAAY,IAAI,WAAW,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IACnE,MAAM,QAAQ,GACZ,WAAW,EAAE,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAClE,IAAI,eAAe,IAAI,QAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IACrD,CAAC;IAED,mFAAmF;IACnF,IAAI,CAAC,SAAS,IAAI,CAAC,WAAW,IAAI,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC;QACvD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC;IAED,oDAAoD;IACpD,IAAI,cAAc,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,IAAI,cAAc,CAAC,SAAS,EAAE,CAAC;YAC7B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,cAAc,CAAC,YAAY,IAAI,cAAc,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1E,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,6CAA8B,CAAC,SAAS,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC","sourcesContent":["import {\n ExperimentalNotConfiguredError,\n StagehandInvalidArgumentError,\n} from \"../../types/public/sdkErrors.js\";\nimport type {\n AgentConfig,\n AgentExecuteOptionsBase,\n} from \"../../types/public/index.js\";\n\nexport interface AgentValidationOptions {\n /** Whether experimental mode is enabled */\n isExperimental: boolean;\n /** Agent config options (integrations, tools, stream, cua, etc.) */\n agentConfig?: Partial<AgentConfig>;\n /** Execute options (callbacks, signal, messages, etc.) */\n executeOptions?:\n | (Partial<AgentExecuteOptionsBase> & { callbacks?: unknown })\n | null;\n /** Whether this is streaming mode (can be derived from agentConfig.stream) */\n isStreaming?: boolean;\n}\n\n/**\n * Validates agent configuration and experimental feature usage.\n *\n * This utility consolidates all validation checks for both CUA and non-CUA agent paths:\n * - Invalid argument errors for CUA (streaming, abort signal, message continuation, excludeTools, output schema are not supported)\n * - Experimental feature checks for integrations and tools (both CUA and non-CUA)\n * - Experimental feature checks for hybrid mode (requires experimental: true)\n * - Experimental feature checks for non-CUA only (callbacks, signal, messages, streaming, excludeTools, output schema)\n *\n * Throws StagehandInvalidArgumentError for invalid/unsupported configurations.\n * Throws ExperimentalNotConfiguredError if experimental features are used without experimental mode.\n */\nexport function validateExperimentalFeatures(\n options: AgentValidationOptions,\n): void {\n const { isExperimental, agentConfig, executeOptions, isStreaming } = options;\n\n // Check if CUA mode is enabled (via mode: \"cua\" or deprecated cua: true)\n const isCuaMode =\n agentConfig?.mode !== undefined\n ? agentConfig.mode === \"cua\"\n : agentConfig?.cua === true;\n\n // CUA-specific validation: certain features are not available at all\n if (isCuaMode) {\n const unsupportedFeatures: string[] = [];\n\n if (agentConfig?.stream) {\n unsupportedFeatures.push(\"streaming\");\n }\n if (executeOptions?.signal) {\n unsupportedFeatures.push(\"abort signal\");\n }\n if (executeOptions?.messages) {\n unsupportedFeatures.push(\"message continuation\");\n }\n if (\n executeOptions?.excludeTools &&\n executeOptions.excludeTools.length > 0\n ) {\n unsupportedFeatures.push(\"excludeTools\");\n }\n if (executeOptions?.output) {\n unsupportedFeatures.push(\"output schema\");\n }\n if (\n executeOptions?.variables &&\n Object.keys(executeOptions.variables).length > 0\n ) {\n unsupportedFeatures.push(\"variables\");\n }\n\n if (unsupportedFeatures.length > 0) {\n throw new StagehandInvalidArgumentError(\n `${unsupportedFeatures.join(\", \")} ${unsupportedFeatures.length === 1 ? \"is\" : \"are\"} not supported with CUA (Computer Use Agent) mode.`,\n );\n }\n }\n\n // Skip experimental checks if already in experimental mode\n if (isExperimental) return;\n\n const features: string[] = [];\n\n // Check agent config features (check array length to avoid false positives for empty arrays)\n const hasIntegrations =\n agentConfig?.integrations && agentConfig.integrations.length > 0;\n const hasTools =\n agentConfig?.tools && Object.keys(agentConfig.tools).length > 0;\n if (hasIntegrations || hasTools) {\n features.push(\"MCP integrations and custom tools\");\n }\n\n // Check streaming mode (either explicit or derived from config) - only for non-CUA\n if (!isCuaMode && (isStreaming || agentConfig?.stream)) {\n features.push(\"streaming\");\n }\n\n // Check execute options features - only for non-CUA\n if (executeOptions && !isCuaMode) {\n if (executeOptions.callbacks) {\n features.push(\"callbacks\");\n }\n if (executeOptions.signal) {\n features.push(\"abort signal\");\n }\n if (executeOptions.messages) {\n features.push(\"message continuation\");\n }\n if (executeOptions.excludeTools && executeOptions.excludeTools.length > 0) {\n features.push(\"excludeTools\");\n }\n if (executeOptions.output) {\n features.push(\"output schema\");\n }\n }\n\n if (features.length > 0) {\n throw new ExperimentalNotConfiguredError(`Agent ${features.join(\", \")}`);\n }\n}\n"]}
@@ -85,6 +85,7 @@ export declare class StagehandAPIClient {
85
85
  private serverCache;
86
86
  private lastFinishedEventData;
87
87
  private latestAgentCacheEntry;
88
+ private warnedStagehandBaseUrl;
88
89
  constructor({ apiKey, projectId, logger, serverCache, }: StagehandAPIConstructorParams);
89
90
  init({ modelName, modelApiKey, domSettleTimeoutMs, verbose, systemPrompt, selfHeal, browserbaseSessionCreateParams, browserbaseSessionID, }: ClientSessionStartParams): Promise<Api.SessionStartResult>;
90
91
  act({ input, options, frameId, }: ClientActParameters): Promise<ActResult>;
@@ -48,6 +48,7 @@ class StagehandAPIClient {
48
48
  serverCache;
49
49
  lastFinishedEventData = null;
50
50
  latestAgentCacheEntry = null;
51
+ warnedStagehandBaseUrl = false;
51
52
  constructor({ apiKey, projectId, logger, serverCache, }) {
52
53
  this.apiKey = apiKey;
53
54
  this.projectId = projectId;
@@ -561,11 +562,22 @@ class StagehandAPIClient {
561
562
  if (options.method === "POST" && options.body) {
562
563
  defaultHeaders["Content-Type"] = "application/json";
563
564
  }
564
- // Use STAGEHAND_API_URL env var if set, otherwise use region-based URL
565
+ // Use STAGEHAND_API_URL when set. STAGEHAND_BASE_URL is a legacy alias.
565
566
  // Ensure /v1 suffix is present for consistency
567
+ const configuredBaseUrl = process.env.STAGEHAND_API_URL ?? process.env.STAGEHAND_BASE_URL;
568
+ if (!process.env.STAGEHAND_API_URL &&
569
+ process.env.STAGEHAND_BASE_URL &&
570
+ !this.warnedStagehandBaseUrl) {
571
+ this.logger({
572
+ category: "config",
573
+ message: "STAGEHAND_BASE_URL is deprecated. Use STAGEHAND_API_URL instead.",
574
+ level: 0,
575
+ });
576
+ this.warnedStagehandBaseUrl = true;
577
+ }
566
578
  let baseUrl;
567
- if (process.env.STAGEHAND_API_URL) {
568
- const envUrl = process.env.STAGEHAND_API_URL.replace(/\/+$/, "");
579
+ if (configuredBaseUrl) {
580
+ const envUrl = configuredBaseUrl.replace(/\/+$/, "");
569
581
  // Append /v1 if not already present
570
582
  baseUrl = envUrl.endsWith("/v1") ? envUrl : `${envUrl}/v1`;
571
583
  }