@browserbasehq/orca 3.2.0-preview.3 → 3.2.0-preview.5

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 (313) hide show
  1. package/dist/cjs/lib/inference.d.ts +3 -1
  2. package/dist/cjs/lib/inference.js +2 -2
  3. package/dist/cjs/lib/inference.js.map +1 -1
  4. package/dist/cjs/lib/prompt.d.ts +1 -1
  5. package/dist/cjs/lib/prompt.js +11 -2
  6. package/dist/cjs/lib/prompt.js.map +1 -1
  7. package/dist/cjs/lib/utils.d.ts +1 -0
  8. package/dist/cjs/lib/utils.js +4 -0
  9. package/dist/cjs/lib/utils.js.map +1 -1
  10. package/dist/cjs/lib/v3/agent/AgentClient.d.ts +8 -0
  11. package/dist/cjs/lib/v3/agent/AgentClient.js +13 -0
  12. package/dist/cjs/lib/v3/agent/AgentClient.js.map +1 -1
  13. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +6 -7
  14. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  15. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +6 -7
  16. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  17. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js +1 -0
  18. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  19. package/dist/cjs/lib/v3/agent/OpenAICUAClient.d.ts +4 -4
  20. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +67 -8
  21. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  22. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.d.ts +2 -2
  23. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.js +10 -11
  24. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.js.map +1 -1
  25. package/dist/cjs/lib/v3/agent/tools/act.js +1 -10
  26. package/dist/cjs/lib/v3/agent/tools/act.js.map +1 -1
  27. package/dist/cjs/lib/v3/agent/tools/ariaTree.js +1 -12
  28. package/dist/cjs/lib/v3/agent/tools/ariaTree.js.map +1 -1
  29. package/dist/cjs/lib/v3/agent/tools/braveSearch.js.map +1 -1
  30. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.js.map +1 -1
  31. package/dist/cjs/lib/v3/agent/tools/click.js.map +1 -1
  32. package/dist/cjs/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  33. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  34. package/dist/cjs/lib/v3/agent/tools/extract.js +1 -10
  35. package/dist/cjs/lib/v3/agent/tools/extract.js.map +1 -1
  36. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  37. package/dist/cjs/lib/v3/agent/tools/fillform.d.ts +0 -1
  38. package/dist/cjs/lib/v3/agent/tools/fillform.js +8 -20
  39. package/dist/cjs/lib/v3/agent/tools/fillform.js.map +1 -1
  40. package/dist/cjs/lib/v3/agent/tools/index.d.ts +2 -2
  41. package/dist/cjs/lib/v3/agent/tools/index.js +53 -5
  42. package/dist/cjs/lib/v3/agent/tools/index.js.map +1 -1
  43. package/dist/cjs/lib/v3/agent/tools/keys.d.ts +1 -1
  44. package/dist/cjs/lib/v3/agent/tools/keys.js.map +1 -1
  45. package/dist/cjs/lib/v3/agent/tools/type.js.map +1 -1
  46. package/dist/cjs/lib/v3/agent/utils/captchaSolver.d.ts +76 -0
  47. package/dist/cjs/lib/v3/agent/utils/captchaSolver.js +175 -0
  48. package/dist/cjs/lib/v3/agent/utils/captchaSolver.js.map +1 -0
  49. package/dist/cjs/lib/v3/agent/utils/variables.d.ts +5 -0
  50. package/dist/cjs/lib/v3/agent/utils/variables.js +9 -0
  51. package/dist/cjs/lib/v3/agent/utils/variables.js.map +1 -1
  52. package/dist/cjs/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  53. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js +30 -0
  54. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  55. package/dist/cjs/lib/v3/flowlogger/EventSink.d.ts +44 -0
  56. package/dist/cjs/lib/v3/flowlogger/EventSink.js +217 -0
  57. package/dist/cjs/lib/v3/flowlogger/EventSink.js.map +1 -0
  58. package/dist/cjs/lib/v3/flowlogger/EventStore.d.ts +26 -0
  59. package/dist/cjs/lib/v3/flowlogger/EventStore.js +135 -0
  60. package/dist/cjs/lib/v3/flowlogger/EventStore.js.map +1 -0
  61. package/dist/cjs/lib/v3/flowlogger/FlowLogger.d.ts +99 -0
  62. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js +591 -0
  63. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  64. package/dist/cjs/lib/v3/flowlogger/prettify.d.ts +6 -0
  65. package/dist/cjs/lib/v3/flowlogger/prettify.js +395 -0
  66. package/dist/cjs/lib/v3/flowlogger/prettify.js.map +1 -0
  67. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js +43 -57
  68. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  69. package/dist/cjs/lib/v3/handlers/observeHandler.js +2 -1
  70. package/dist/cjs/lib/v3/handlers/observeHandler.js.map +1 -1
  71. package/dist/cjs/lib/v3/handlers/v3AgentHandler.d.ts +2 -5
  72. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +112 -78
  73. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  74. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.d.ts +5 -0
  75. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +134 -14
  76. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  77. package/dist/cjs/lib/v3/llm/aisdk.js +11 -17
  78. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  79. package/dist/cjs/lib/v3/types/private/cache.d.ts +0 -1
  80. package/dist/cjs/lib/v3/types/private/cache.js.map +1 -1
  81. package/dist/cjs/lib/v3/types/private/handlers.d.ts +1 -0
  82. package/dist/cjs/lib/v3/types/private/handlers.js.map +1 -1
  83. package/dist/cjs/lib/v3/types/public/api.d.ts +24 -7
  84. package/dist/cjs/lib/v3/types/public/api.js +41 -14
  85. package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
  86. package/dist/cjs/lib/v3/types/public/methods.d.ts +1 -0
  87. package/dist/cjs/lib/v3/types/public/methods.js.map +1 -1
  88. package/dist/cjs/lib/v3/types/public/options.d.ts +7 -0
  89. package/dist/cjs/lib/v3/types/public/options.js.map +1 -1
  90. package/dist/cjs/lib/v3/types/public/variables.d.ts +7 -0
  91. package/dist/cjs/lib/v3/types/public/variables.js +22 -0
  92. package/dist/cjs/lib/v3/types/public/variables.js.map +1 -0
  93. package/dist/cjs/lib/v3/understudy/cdp.d.ts +3 -12
  94. package/dist/cjs/lib/v3/understudy/cdp.js +134 -21
  95. package/dist/cjs/lib/v3/understudy/cdp.js.map +1 -1
  96. package/dist/cjs/lib/v3/understudy/page.js +28 -18
  97. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  98. package/dist/cjs/lib/v3/v3.d.ts +12 -2
  99. package/dist/cjs/lib/v3/v3.js +194 -160
  100. package/dist/cjs/lib/v3/v3.js.map +1 -1
  101. package/dist/cjs/lib/version.d.ts +1 -1
  102. package/dist/cjs/lib/version.js +1 -1
  103. package/dist/cjs/lib/version.js.map +1 -1
  104. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.d.ts +1 -0
  105. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js +56 -0
  106. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js.map +1 -0
  107. package/dist/cjs/tests/integration/agent-hybrid-mode.spec.js +6 -6
  108. package/dist/cjs/tests/integration/agent-hybrid-mode.spec.js.map +1 -1
  109. package/dist/cjs/tests/integration/flowLogger.spec.d.ts +1 -0
  110. package/dist/cjs/tests/integration/flowLogger.spec.js +714 -0
  111. package/dist/cjs/tests/integration/flowLogger.spec.js.map +1 -0
  112. package/dist/cjs/tests/integration/testUtils.d.ts +33 -0
  113. package/dist/cjs/tests/integration/testUtils.js +144 -0
  114. package/dist/cjs/tests/integration/testUtils.js.map +1 -1
  115. package/dist/cjs/tests/integration/timeouts.spec.js +113 -3
  116. package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
  117. package/dist/cjs/tests/unit/agent-captcha-hooks.test.d.ts +1 -0
  118. package/dist/cjs/tests/unit/agent-captcha-hooks.test.js +285 -0
  119. package/dist/cjs/tests/unit/agent-captcha-hooks.test.js.map +1 -0
  120. package/dist/cjs/tests/unit/agent-execution-model.test.js +25 -3
  121. package/dist/cjs/tests/unit/agent-execution-model.test.js.map +1 -1
  122. package/dist/cjs/tests/unit/agent-system-prompt-variables.test.d.ts +1 -0
  123. package/dist/cjs/tests/unit/agent-system-prompt-variables.test.js +23 -0
  124. package/dist/cjs/tests/unit/agent-system-prompt-variables.test.js.map +1 -0
  125. package/dist/cjs/tests/unit/api-client-observe-variables.test.d.ts +1 -0
  126. package/dist/cjs/tests/unit/api-client-observe-variables.test.js +86 -0
  127. package/dist/cjs/tests/unit/api-client-observe-variables.test.js.map +1 -0
  128. package/dist/cjs/tests/unit/api-variables-schema.test.d.ts +1 -0
  129. package/dist/cjs/tests/unit/api-variables-schema.test.js +37 -0
  130. package/dist/cjs/tests/unit/api-variables-schema.test.js.map +1 -0
  131. package/dist/cjs/tests/unit/browserbase-session-accessors.test.js +20 -0
  132. package/dist/cjs/tests/unit/browserbase-session-accessors.test.js.map +1 -1
  133. package/dist/cjs/tests/unit/captcha-solver.test.d.ts +1 -0
  134. package/dist/cjs/tests/unit/captcha-solver.test.js +154 -0
  135. package/dist/cjs/tests/unit/captcha-solver.test.js.map +1 -0
  136. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  137. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js +95 -0
  138. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  139. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  140. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js +43 -0
  141. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  142. package/dist/cjs/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  143. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js +250 -0
  144. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  145. package/dist/cjs/tests/unit/openai-cua-client.test.d.ts +1 -0
  146. package/dist/cjs/tests/unit/openai-cua-client.test.js +71 -0
  147. package/dist/cjs/tests/unit/openai-cua-client.test.js.map +1 -0
  148. package/dist/cjs/tests/unit/prompt-observe-variables.test.d.ts +1 -0
  149. package/dist/cjs/tests/unit/prompt-observe-variables.test.js +19 -0
  150. package/dist/cjs/tests/unit/prompt-observe-variables.test.js.map +1 -0
  151. package/dist/cjs/tests/unit/public-api/public-types.test.js.map +1 -1
  152. package/dist/cjs/tests/unit/timeout-handlers.test.js +50 -0
  153. package/dist/cjs/tests/unit/timeout-handlers.test.js.map +1 -1
  154. package/dist/esm/lib/inference.d.ts +3 -1
  155. package/dist/esm/lib/inference.js +2 -2
  156. package/dist/esm/lib/inference.js.map +1 -1
  157. package/dist/esm/lib/prompt.d.ts +1 -1
  158. package/dist/esm/lib/prompt.js +11 -2
  159. package/dist/esm/lib/prompt.js.map +1 -1
  160. package/dist/esm/lib/utils.d.ts +1 -0
  161. package/dist/esm/lib/utils.js +3 -0
  162. package/dist/esm/lib/utils.js.map +1 -1
  163. package/dist/esm/lib/v3/agent/AgentClient.d.ts +8 -0
  164. package/dist/esm/lib/v3/agent/AgentClient.js +13 -0
  165. package/dist/esm/lib/v3/agent/AgentClient.js.map +1 -1
  166. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +6 -7
  167. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  168. package/dist/esm/lib/v3/agent/GoogleCUAClient.js +6 -7
  169. package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  170. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js +1 -0
  171. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  172. package/dist/esm/lib/v3/agent/OpenAICUAClient.d.ts +4 -4
  173. package/dist/esm/lib/v3/agent/OpenAICUAClient.js +67 -8
  174. package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  175. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.d.ts +2 -2
  176. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.js +10 -11
  177. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.js.map +1 -1
  178. package/dist/esm/lib/v3/agent/tools/act.js +1 -10
  179. package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
  180. package/dist/esm/lib/v3/agent/tools/ariaTree.js +1 -12
  181. package/dist/esm/lib/v3/agent/tools/ariaTree.js.map +1 -1
  182. package/dist/esm/lib/v3/agent/tools/braveSearch.js.map +1 -1
  183. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.js.map +1 -1
  184. package/dist/esm/lib/v3/agent/tools/click.js.map +1 -1
  185. package/dist/esm/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  186. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  187. package/dist/esm/lib/v3/agent/tools/extract.js +1 -10
  188. package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
  189. package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  190. package/dist/esm/lib/v3/agent/tools/fillform.d.ts +0 -1
  191. package/dist/esm/lib/v3/agent/tools/fillform.js +8 -20
  192. package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
  193. package/dist/esm/lib/v3/agent/tools/index.d.ts +2 -2
  194. package/dist/esm/lib/v3/agent/tools/index.js +53 -5
  195. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  196. package/dist/esm/lib/v3/agent/tools/keys.d.ts +1 -1
  197. package/dist/esm/lib/v3/agent/tools/keys.js.map +1 -1
  198. package/dist/esm/lib/v3/agent/tools/type.js.map +1 -1
  199. package/dist/esm/lib/v3/agent/utils/captchaSolver.d.ts +76 -0
  200. package/dist/esm/lib/v3/agent/utils/captchaSolver.js +171 -0
  201. package/dist/esm/lib/v3/agent/utils/captchaSolver.js.map +1 -0
  202. package/dist/esm/lib/v3/agent/utils/variables.d.ts +5 -0
  203. package/dist/esm/lib/v3/agent/utils/variables.js +8 -0
  204. package/dist/esm/lib/v3/agent/utils/variables.js.map +1 -1
  205. package/dist/esm/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  206. package/dist/esm/lib/v3/flowlogger/EventEmitter.js +26 -0
  207. package/dist/esm/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  208. package/dist/esm/lib/v3/flowlogger/EventSink.d.ts +44 -0
  209. package/dist/esm/lib/v3/flowlogger/EventSink.js +206 -0
  210. package/dist/esm/lib/v3/flowlogger/EventSink.js.map +1 -0
  211. package/dist/esm/lib/v3/flowlogger/EventStore.d.ts +26 -0
  212. package/dist/esm/lib/v3/flowlogger/EventStore.js +127 -0
  213. package/dist/esm/lib/v3/flowlogger/EventStore.js.map +1 -0
  214. package/dist/esm/lib/v3/flowlogger/FlowLogger.d.ts +99 -0
  215. package/dist/esm/lib/v3/flowlogger/FlowLogger.js +583 -0
  216. package/dist/esm/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  217. package/dist/esm/lib/v3/flowlogger/prettify.d.ts +6 -0
  218. package/dist/esm/lib/v3/flowlogger/prettify.js +389 -0
  219. package/dist/esm/lib/v3/flowlogger/prettify.js.map +1 -0
  220. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js +43 -57
  221. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  222. package/dist/esm/lib/v3/handlers/observeHandler.js +2 -1
  223. package/dist/esm/lib/v3/handlers/observeHandler.js.map +1 -1
  224. package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +2 -5
  225. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +112 -78
  226. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  227. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.d.ts +5 -0
  228. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +134 -14
  229. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  230. package/dist/esm/lib/v3/llm/aisdk.js +11 -17
  231. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  232. package/dist/esm/lib/v3/types/private/cache.d.ts +0 -1
  233. package/dist/esm/lib/v3/types/private/cache.js.map +1 -1
  234. package/dist/esm/lib/v3/types/private/handlers.d.ts +1 -0
  235. package/dist/esm/lib/v3/types/private/handlers.js.map +1 -1
  236. package/dist/esm/lib/v3/types/public/api.d.ts +24 -7
  237. package/dist/esm/lib/v3/types/public/api.js +36 -12
  238. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  239. package/dist/esm/lib/v3/types/public/methods.d.ts +1 -0
  240. package/dist/esm/lib/v3/types/public/methods.js.map +1 -1
  241. package/dist/esm/lib/v3/types/public/options.d.ts +7 -0
  242. package/dist/esm/lib/v3/types/public/options.js.map +1 -1
  243. package/dist/esm/lib/v3/types/public/variables.d.ts +7 -0
  244. package/dist/esm/lib/v3/types/public/variables.js +19 -0
  245. package/dist/esm/lib/v3/types/public/variables.js.map +1 -0
  246. package/dist/esm/lib/v3/understudy/cdp.d.ts +3 -12
  247. package/dist/esm/lib/v3/understudy/cdp.js +134 -21
  248. package/dist/esm/lib/v3/understudy/cdp.js.map +1 -1
  249. package/dist/esm/lib/v3/understudy/page.js +28 -18
  250. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  251. package/dist/esm/lib/v3/v3.d.ts +12 -2
  252. package/dist/esm/lib/v3/v3.js +194 -160
  253. package/dist/esm/lib/v3/v3.js.map +1 -1
  254. package/dist/esm/lib/version.d.ts +1 -1
  255. package/dist/esm/lib/version.js +1 -1
  256. package/dist/esm/lib/version.js.map +1 -1
  257. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.d.ts +1 -0
  258. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js +54 -0
  259. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js.map +1 -0
  260. package/dist/esm/tests/integration/agent-hybrid-mode.spec.js +6 -6
  261. package/dist/esm/tests/integration/agent-hybrid-mode.spec.js.map +1 -1
  262. package/dist/esm/tests/integration/flowLogger.spec.d.ts +1 -0
  263. package/dist/esm/tests/integration/flowLogger.spec.js +712 -0
  264. package/dist/esm/tests/integration/flowLogger.spec.js.map +1 -0
  265. package/dist/esm/tests/integration/testUtils.d.ts +33 -0
  266. package/dist/esm/tests/integration/testUtils.js +138 -0
  267. package/dist/esm/tests/integration/testUtils.js.map +1 -1
  268. package/dist/esm/tests/integration/timeouts.spec.js +113 -3
  269. package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
  270. package/dist/esm/tests/unit/agent-captcha-hooks.test.d.ts +1 -0
  271. package/dist/esm/tests/unit/agent-captcha-hooks.test.js +283 -0
  272. package/dist/esm/tests/unit/agent-captcha-hooks.test.js.map +1 -0
  273. package/dist/esm/tests/unit/agent-execution-model.test.js +25 -3
  274. package/dist/esm/tests/unit/agent-execution-model.test.js.map +1 -1
  275. package/dist/esm/tests/unit/agent-system-prompt-variables.test.d.ts +1 -0
  276. package/dist/esm/tests/unit/agent-system-prompt-variables.test.js +21 -0
  277. package/dist/esm/tests/unit/agent-system-prompt-variables.test.js.map +1 -0
  278. package/dist/esm/tests/unit/api-client-observe-variables.test.d.ts +1 -0
  279. package/dist/esm/tests/unit/api-client-observe-variables.test.js +84 -0
  280. package/dist/esm/tests/unit/api-client-observe-variables.test.js.map +1 -0
  281. package/dist/esm/tests/unit/api-variables-schema.test.d.ts +1 -0
  282. package/dist/esm/tests/unit/api-variables-schema.test.js +35 -0
  283. package/dist/esm/tests/unit/api-variables-schema.test.js.map +1 -0
  284. package/dist/esm/tests/unit/browserbase-session-accessors.test.js +20 -0
  285. package/dist/esm/tests/unit/browserbase-session-accessors.test.js.map +1 -1
  286. package/dist/esm/tests/unit/captcha-solver.test.d.ts +1 -0
  287. package/dist/esm/tests/unit/captcha-solver.test.js +152 -0
  288. package/dist/esm/tests/unit/captcha-solver.test.js.map +1 -0
  289. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  290. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js +93 -0
  291. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  292. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  293. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js +41 -0
  294. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  295. package/dist/esm/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  296. package/dist/esm/tests/unit/flowlogger-eventstore.test.js +248 -0
  297. package/dist/esm/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  298. package/dist/esm/tests/unit/openai-cua-client.test.d.ts +1 -0
  299. package/dist/esm/tests/unit/openai-cua-client.test.js +69 -0
  300. package/dist/esm/tests/unit/openai-cua-client.test.js.map +1 -0
  301. package/dist/esm/tests/unit/prompt-observe-variables.test.d.ts +1 -0
  302. package/dist/esm/tests/unit/prompt-observe-variables.test.js +17 -0
  303. package/dist/esm/tests/unit/prompt-observe-variables.test.js.map +1 -0
  304. package/dist/esm/tests/unit/public-api/public-types.test.js.map +1 -1
  305. package/dist/esm/tests/unit/timeout-handlers.test.js +50 -0
  306. package/dist/esm/tests/unit/timeout-handlers.test.js.map +1 -1
  307. package/package.json +4 -2
  308. package/dist/cjs/lib/v3/flowLogger.d.ts +0 -139
  309. package/dist/cjs/lib/v3/flowLogger.js +0 -881
  310. package/dist/cjs/lib/v3/flowLogger.js.map +0 -1
  311. package/dist/esm/lib/v3/flowLogger.d.ts +0 -139
  312. package/dist/esm/lib/v3/flowLogger.js +0 -868
  313. package/dist/esm/lib/v3/flowLogger.js.map +0 -1
@@ -0,0 +1,248 @@
1
+ import { afterEach, describe, expect, it } from "vitest";
2
+ import { EventStore } from "../../lib/v3/flowlogger/EventStore.js";
3
+ import { EventEmitterWithWildcardSupport } from "../../lib/v3/flowlogger/EventEmitter.js";
4
+ import { FlowEvent } from "../../lib/v3/flowlogger/FlowLogger.js";
5
+ function attachEventStoreToBus(store, bus) {
6
+ const onFlowEvent = (event) => {
7
+ if (event instanceof FlowEvent) {
8
+ void store.emit(event);
9
+ }
10
+ };
11
+ bus.on("*", onFlowEvent);
12
+ return () => {
13
+ bus.off("*", onFlowEvent);
14
+ };
15
+ }
16
+ function createVerboseStoreHarness() {
17
+ const writes = [];
18
+ process.stderr.write = ((chunk, cb) => {
19
+ writes.push(String(chunk));
20
+ cb?.(null);
21
+ return true;
22
+ });
23
+ const store = new EventStore("session-test");
24
+ const bus = new EventEmitterWithWildcardSupport();
25
+ const detachBus = attachEventStoreToBus(store, bus);
26
+ return { writes, store, bus, detachBus };
27
+ }
28
+ describe("flow logger event store", () => {
29
+ const stderrWrite = process.stderr.write.bind(process.stderr);
30
+ afterEach(() => {
31
+ process.stderr.write = stderrWrite;
32
+ });
33
+ it("queries recent events from the default in-memory sink", async () => {
34
+ const store = new EventStore("session-test");
35
+ await store.emit(new FlowEvent({
36
+ eventType: "StagehandExtractEvent",
37
+ sessionId: "session-test",
38
+ eventId: "stagehand-1234",
39
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
40
+ data: { params: ["grab title"] },
41
+ }));
42
+ const events = await store.query({});
43
+ expect(events).toHaveLength(1);
44
+ expect(events[0].eventType).toBe("StagehandExtractEvent");
45
+ await store.destroy();
46
+ });
47
+ it("drops payloads from the default in-memory sink", async () => {
48
+ const store = new EventStore("session-test");
49
+ await store.emit(new FlowEvent({
50
+ eventType: "LlmRequestEvent",
51
+ sessionId: "session-test",
52
+ eventId: "llm-1234",
53
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
54
+ data: {
55
+ prompt: [{ type: "image_url", image_url: { url: "huge" } }],
56
+ output: "huge",
57
+ },
58
+ }));
59
+ const [event] = await store.query({});
60
+ expect(event.eventType).toBe("LlmRequestEvent");
61
+ expect(event.eventId).toBe("llm-1234");
62
+ expect(event.data).toEqual({});
63
+ await store.destroy();
64
+ });
65
+ it("renders semantic hierarchy tags for non-cdp stderr events only", async () => {
66
+ // Intercept stderr so the pretty sink can be asserted without polluting the
67
+ // real test runner output.
68
+ const { writes, store, bus, detachBus } = createVerboseStoreHarness();
69
+ const stepEvent = new FlowEvent({
70
+ eventType: "StagehandExtractEvent",
71
+ sessionId: "session-test",
72
+ eventId: "stagehand-1234",
73
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
74
+ data: { params: ["grab title"] },
75
+ });
76
+ const cdpEvent = new FlowEvent({
77
+ eventType: "CdpCallEvent",
78
+ sessionId: "session-test",
79
+ eventId: "cdp-call-5678",
80
+ eventCreatedAt: "2026-03-16T21:45:00.100Z",
81
+ eventParentIds: [stepEvent.eventId],
82
+ data: {
83
+ method: "Runtime.evaluate",
84
+ params: { expression: "2 + 2" },
85
+ targetId: "1234567890ABCDEF1234567890ABCDEF",
86
+ },
87
+ });
88
+ // The stderr sink intentionally suppresses CDP noise even though the event
89
+ // still exists for in-memory and file-backed sinks.
90
+ bus.emit(stepEvent.eventType, stepEvent);
91
+ bus.emit(cdpEvent.eventType, cdpEvent);
92
+ await new Promise((resolve) => setTimeout(resolve, 0));
93
+ expect(writes).toHaveLength(1);
94
+ expect(writes[0]).toContain("[🆂 #1234 EXTRACT]");
95
+ expect(writes[0]).toContain("Stagehand.extract");
96
+ expect(writes[0]).not.toContain("Runtime.evaluate");
97
+ detachBus();
98
+ await store.destroy();
99
+ });
100
+ it("renders generic stagehand events without crashing the stderr sink", async () => {
101
+ const { writes, store, bus, detachBus } = createVerboseStoreHarness();
102
+ // `StagehandEvent` has no action suffix, so this guards the formatter path
103
+ // that cannot assume a method name exists.
104
+ bus.emit("StagehandEvent", new FlowEvent({
105
+ eventType: "StagehandEvent",
106
+ sessionId: "session-test",
107
+ eventId: "stagehand-0001",
108
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
109
+ data: { params: ["noop"] },
110
+ }));
111
+ await new Promise((resolve) => setTimeout(resolve, 0));
112
+ expect(writes).toHaveLength(1);
113
+ expect(writes[0]).toContain("[🆂 #0001");
114
+ expect(writes[0]).toContain("Stagehand(");
115
+ detachBus();
116
+ await store.destroy();
117
+ });
118
+ it("colorizes pretty stderr output with ansi escapes when enabled", async () => {
119
+ const previousForceColor = process.env.FORCE_COLOR;
120
+ const previousNoColor = process.env.NO_COLOR;
121
+ delete process.env.NO_COLOR;
122
+ process.env.FORCE_COLOR = "1";
123
+ const { writes, store, bus, detachBus } = createVerboseStoreHarness();
124
+ try {
125
+ bus.emit("StagehandActEvent", new FlowEvent({
126
+ eventType: "StagehandActEvent",
127
+ sessionId: "session-test",
128
+ eventId: "stagehand-0002",
129
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
130
+ data: { params: ["click submit"] },
131
+ }));
132
+ await new Promise((resolve) => setTimeout(resolve, 0));
133
+ expect(writes).toHaveLength(1);
134
+ expect(writes[0]).toContain("\u001B[");
135
+ }
136
+ finally {
137
+ if (previousNoColor === undefined) {
138
+ delete process.env.NO_COLOR;
139
+ }
140
+ else {
141
+ process.env.NO_COLOR = previousNoColor;
142
+ }
143
+ if (previousForceColor === undefined) {
144
+ delete process.env.FORCE_COLOR;
145
+ }
146
+ else {
147
+ process.env.FORCE_COLOR = previousForceColor;
148
+ }
149
+ detachBus();
150
+ await store.destroy();
151
+ }
152
+ });
153
+ it("keeps agent ancestry and start ids for completion events after many child events", async () => {
154
+ const { writes, store, bus, detachBus } = createVerboseStoreHarness();
155
+ const agentEvent = new FlowEvent({
156
+ eventType: "AgentExecuteEvent",
157
+ sessionId: "session-test",
158
+ eventId: "agent-1234",
159
+ eventCreatedAt: "2026-03-16T21:45:00.000Z",
160
+ data: { params: [{ instruction: "click the button" }] },
161
+ });
162
+ const actEvent = new FlowEvent({
163
+ eventType: "StagehandActEvent",
164
+ sessionId: "session-test",
165
+ eventId: "stagehand-2222",
166
+ eventCreatedAt: "2026-03-16T21:45:00.001Z",
167
+ eventParentIds: [agentEvent.eventId],
168
+ data: { params: ["click the button"] },
169
+ });
170
+ const clickEvent = new FlowEvent({
171
+ eventType: "UnderstudyClickEvent",
172
+ sessionId: "session-test",
173
+ eventId: "action-3333",
174
+ eventCreatedAt: "2026-03-16T21:45:00.002Z",
175
+ eventParentIds: [agentEvent.eventId, actEvent.eventId],
176
+ data: { target: "xpath=/button[1]" },
177
+ });
178
+ bus.emit(agentEvent.eventType, agentEvent);
179
+ bus.emit(actEvent.eventType, actEvent);
180
+ bus.emit(clickEvent.eventType, clickEvent);
181
+ // Flood the retained history with child events so the completion lines have
182
+ // to recover their displayed ancestry from the queryable sink.
183
+ for (let index = 0; index < 150; index += 1) {
184
+ bus.emit("CdpCallEvent", new FlowEvent({
185
+ eventType: "CdpCallEvent",
186
+ sessionId: "session-test",
187
+ eventId: `cdp-${String(index).padStart(4, "0")}`,
188
+ eventCreatedAt: `2026-03-16T21:45:00.${String(index + 10).padStart(3, "0")}Z`,
189
+ eventParentIds: [
190
+ agentEvent.eventId,
191
+ actEvent.eventId,
192
+ clickEvent.eventId,
193
+ ],
194
+ data: {
195
+ method: "Runtime.evaluate",
196
+ params: { expression: `${index}` },
197
+ targetId: "1234567890ABCDEF1234567890ABCDEF",
198
+ },
199
+ }));
200
+ }
201
+ bus.emit("UnderstudyClickCompletedEvent", new FlowEvent({
202
+ eventType: "UnderstudyClickCompletedEvent",
203
+ sessionId: "session-test",
204
+ eventId: "done-4444",
205
+ eventCreatedAt: "2026-03-16T21:45:01.000Z",
206
+ eventParentIds: [
207
+ agentEvent.eventId,
208
+ actEvent.eventId,
209
+ clickEvent.eventId,
210
+ ],
211
+ data: { durationMs: 250 },
212
+ }));
213
+ bus.emit("StagehandActCompletedEvent", new FlowEvent({
214
+ eventType: "StagehandActCompletedEvent",
215
+ sessionId: "session-test",
216
+ eventId: "done-5555",
217
+ eventCreatedAt: "2026-03-16T21:45:01.001Z",
218
+ eventParentIds: [agentEvent.eventId, actEvent.eventId],
219
+ data: { durationMs: 500 },
220
+ }));
221
+ bus.emit("AgentExecuteCompletedEvent", new FlowEvent({
222
+ eventType: "AgentExecuteCompletedEvent",
223
+ sessionId: "session-test",
224
+ eventId: "done-6666",
225
+ eventCreatedAt: "2026-03-16T21:45:01.002Z",
226
+ eventParentIds: [agentEvent.eventId],
227
+ data: { durationMs: 750 },
228
+ }));
229
+ await new Promise((resolve) => setTimeout(resolve, 0));
230
+ // Completion lines should reference the original started-event ids, not the
231
+ // synthetic completed-event ids emitted at the end of the lifecycle.
232
+ const clickCompletedLine = writes.find((line) => line.includes("CLICK completed"));
233
+ const actCompletedLine = writes.find((line) => line.includes("ACT completed"));
234
+ const agentCompletedLine = writes.find((line) => line.includes("Agent.execute() completed"));
235
+ expect(clickCompletedLine).toContain("[🅰 #1234]");
236
+ expect(clickCompletedLine).toContain("[🆂 #2222 ACT]");
237
+ expect(clickCompletedLine).toContain("[🆄 #3333 CLICK]");
238
+ expect(clickCompletedLine).not.toContain("#4444");
239
+ expect(actCompletedLine).toContain("[🅰 #1234]");
240
+ expect(actCompletedLine).toContain("[🆂 #2222 ACT]");
241
+ expect(actCompletedLine).not.toContain("#5555");
242
+ expect(agentCompletedLine).toContain("[🅰 #1234]");
243
+ expect(agentCompletedLine).not.toContain("#6666");
244
+ detachBus();
245
+ await store.destroy();
246
+ });
247
+ });
248
+ //# sourceMappingURL=flowlogger-eventstore.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flowlogger-eventstore.test.js","sourceRoot":"","sources":["../../../../tests/unit/flowlogger-eventstore.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, describe, expect, it } from \"vitest\";\nimport { EventStore } from \"../../lib/v3/flowlogger/EventStore.js\";\nimport { EventEmitterWithWildcardSupport } from \"../../lib/v3/flowlogger/EventEmitter.js\";\nimport { FlowEvent } from \"../../lib/v3/flowlogger/FlowLogger.js\";\n\nfunction attachEventStoreToBus(\n store: EventStore,\n bus: EventEmitterWithWildcardSupport,\n): () => void {\n const onFlowEvent = (event: unknown) => {\n if (event instanceof FlowEvent) {\n void store.emit(event);\n }\n };\n\n bus.on(\"*\", onFlowEvent);\n return () => {\n bus.off(\"*\", onFlowEvent);\n };\n}\n\nfunction createVerboseStoreHarness(): {\n writes: string[];\n store: EventStore;\n bus: EventEmitterWithWildcardSupport;\n detachBus: () => void;\n} {\n const writes: string[] = [];\n process.stderr.write = ((\n chunk: string,\n cb?: (error?: Error | null) => void,\n ) => {\n writes.push(String(chunk));\n cb?.(null);\n return true;\n }) as typeof process.stderr.write;\n\n const store = new EventStore(\"session-test\");\n const bus = new EventEmitterWithWildcardSupport();\n const detachBus = attachEventStoreToBus(store, bus);\n\n return { writes, store, bus, detachBus };\n}\n\ndescribe(\"flow logger event store\", () => {\n const stderrWrite = process.stderr.write.bind(process.stderr);\n\n afterEach(() => {\n process.stderr.write = stderrWrite;\n });\n\n it(\"queries recent events from the default in-memory sink\", async () => {\n const store = new EventStore(\"session-test\");\n\n await store.emit(\n new FlowEvent({\n eventType: \"StagehandExtractEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-1234\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [\"grab title\"] },\n }),\n );\n\n const events = await store.query({});\n expect(events).toHaveLength(1);\n expect(events[0].eventType).toBe(\"StagehandExtractEvent\");\n\n await store.destroy();\n });\n\n it(\"drops payloads from the default in-memory sink\", async () => {\n const store = new EventStore(\"session-test\");\n\n await store.emit(\n new FlowEvent({\n eventType: \"LlmRequestEvent\",\n sessionId: \"session-test\",\n eventId: \"llm-1234\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: {\n prompt: [{ type: \"image_url\", image_url: { url: \"huge\" } }],\n output: \"huge\",\n },\n }),\n );\n\n const [event] = await store.query({});\n expect(event.eventType).toBe(\"LlmRequestEvent\");\n expect(event.eventId).toBe(\"llm-1234\");\n expect(event.data).toEqual({});\n\n await store.destroy();\n });\n\n it(\"renders semantic hierarchy tags for non-cdp stderr events only\", async () => {\n // Intercept stderr so the pretty sink can be asserted without polluting the\n // real test runner output.\n const { writes, store, bus, detachBus } = createVerboseStoreHarness();\n\n const stepEvent = new FlowEvent({\n eventType: \"StagehandExtractEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-1234\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [\"grab title\"] },\n });\n const cdpEvent = new FlowEvent({\n eventType: \"CdpCallEvent\",\n sessionId: \"session-test\",\n eventId: \"cdp-call-5678\",\n eventCreatedAt: \"2026-03-16T21:45:00.100Z\",\n eventParentIds: [stepEvent.eventId],\n data: {\n method: \"Runtime.evaluate\",\n params: { expression: \"2 + 2\" },\n targetId: \"1234567890ABCDEF1234567890ABCDEF\",\n },\n });\n\n // The stderr sink intentionally suppresses CDP noise even though the event\n // still exists for in-memory and file-backed sinks.\n bus.emit(stepEvent.eventType, stepEvent);\n bus.emit(cdpEvent.eventType, cdpEvent);\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect(writes).toHaveLength(1);\n expect(writes[0]).toContain(\"[🆂 #1234 EXTRACT]\");\n expect(writes[0]).toContain(\"Stagehand.extract\");\n expect(writes[0]).not.toContain(\"Runtime.evaluate\");\n\n detachBus();\n await store.destroy();\n });\n\n it(\"renders generic stagehand events without crashing the stderr sink\", async () => {\n const { writes, store, bus, detachBus } = createVerboseStoreHarness();\n\n // `StagehandEvent` has no action suffix, so this guards the formatter path\n // that cannot assume a method name exists.\n bus.emit(\n \"StagehandEvent\",\n new FlowEvent({\n eventType: \"StagehandEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-0001\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [\"noop\"] },\n }),\n );\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect(writes).toHaveLength(1);\n expect(writes[0]).toContain(\"[🆂 #0001\");\n expect(writes[0]).toContain(\"Stagehand(\");\n\n detachBus();\n await store.destroy();\n });\n\n it(\"colorizes pretty stderr output with ansi escapes when enabled\", async () => {\n const previousForceColor = process.env.FORCE_COLOR;\n const previousNoColor = process.env.NO_COLOR;\n delete process.env.NO_COLOR;\n process.env.FORCE_COLOR = \"1\";\n\n const { writes, store, bus, detachBus } = createVerboseStoreHarness();\n\n try {\n bus.emit(\n \"StagehandActEvent\",\n new FlowEvent({\n eventType: \"StagehandActEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-0002\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [\"click submit\"] },\n }),\n );\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n expect(writes).toHaveLength(1);\n expect(writes[0]).toContain(\"\\u001B[\");\n } finally {\n if (previousNoColor === undefined) {\n delete process.env.NO_COLOR;\n } else {\n process.env.NO_COLOR = previousNoColor;\n }\n\n if (previousForceColor === undefined) {\n delete process.env.FORCE_COLOR;\n } else {\n process.env.FORCE_COLOR = previousForceColor;\n }\n\n detachBus();\n await store.destroy();\n }\n });\n\n it(\"keeps agent ancestry and start ids for completion events after many child events\", async () => {\n const { writes, store, bus, detachBus } = createVerboseStoreHarness();\n\n const agentEvent = new FlowEvent({\n eventType: \"AgentExecuteEvent\",\n sessionId: \"session-test\",\n eventId: \"agent-1234\",\n eventCreatedAt: \"2026-03-16T21:45:00.000Z\",\n data: { params: [{ instruction: \"click the button\" }] },\n });\n const actEvent = new FlowEvent({\n eventType: \"StagehandActEvent\",\n sessionId: \"session-test\",\n eventId: \"stagehand-2222\",\n eventCreatedAt: \"2026-03-16T21:45:00.001Z\",\n eventParentIds: [agentEvent.eventId],\n data: { params: [\"click the button\"] },\n });\n const clickEvent = new FlowEvent({\n eventType: \"UnderstudyClickEvent\",\n sessionId: \"session-test\",\n eventId: \"action-3333\",\n eventCreatedAt: \"2026-03-16T21:45:00.002Z\",\n eventParentIds: [agentEvent.eventId, actEvent.eventId],\n data: { target: \"xpath=/button[1]\" },\n });\n\n bus.emit(agentEvent.eventType, agentEvent);\n bus.emit(actEvent.eventType, actEvent);\n bus.emit(clickEvent.eventType, clickEvent);\n\n // Flood the retained history with child events so the completion lines have\n // to recover their displayed ancestry from the queryable sink.\n for (let index = 0; index < 150; index += 1) {\n bus.emit(\n \"CdpCallEvent\",\n new FlowEvent({\n eventType: \"CdpCallEvent\",\n sessionId: \"session-test\",\n eventId: `cdp-${String(index).padStart(4, \"0\")}`,\n eventCreatedAt: `2026-03-16T21:45:00.${String(index + 10).padStart(3, \"0\")}Z`,\n eventParentIds: [\n agentEvent.eventId,\n actEvent.eventId,\n clickEvent.eventId,\n ],\n data: {\n method: \"Runtime.evaluate\",\n params: { expression: `${index}` },\n targetId: \"1234567890ABCDEF1234567890ABCDEF\",\n },\n }),\n );\n }\n\n bus.emit(\n \"UnderstudyClickCompletedEvent\",\n new FlowEvent({\n eventType: \"UnderstudyClickCompletedEvent\",\n sessionId: \"session-test\",\n eventId: \"done-4444\",\n eventCreatedAt: \"2026-03-16T21:45:01.000Z\",\n eventParentIds: [\n agentEvent.eventId,\n actEvent.eventId,\n clickEvent.eventId,\n ],\n data: { durationMs: 250 },\n }),\n );\n bus.emit(\n \"StagehandActCompletedEvent\",\n new FlowEvent({\n eventType: \"StagehandActCompletedEvent\",\n sessionId: \"session-test\",\n eventId: \"done-5555\",\n eventCreatedAt: \"2026-03-16T21:45:01.001Z\",\n eventParentIds: [agentEvent.eventId, actEvent.eventId],\n data: { durationMs: 500 },\n }),\n );\n bus.emit(\n \"AgentExecuteCompletedEvent\",\n new FlowEvent({\n eventType: \"AgentExecuteCompletedEvent\",\n sessionId: \"session-test\",\n eventId: \"done-6666\",\n eventCreatedAt: \"2026-03-16T21:45:01.002Z\",\n eventParentIds: [agentEvent.eventId],\n data: { durationMs: 750 },\n }),\n );\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Completion lines should reference the original started-event ids, not the\n // synthetic completed-event ids emitted at the end of the lifecycle.\n const clickCompletedLine = writes.find((line) =>\n line.includes(\"CLICK completed\"),\n );\n const actCompletedLine = writes.find((line) =>\n line.includes(\"ACT completed\"),\n );\n const agentCompletedLine = writes.find((line) =>\n line.includes(\"Agent.execute() completed\"),\n );\n\n expect(clickCompletedLine).toContain(\"[🅰 #1234]\");\n expect(clickCompletedLine).toContain(\"[🆂 #2222 ACT]\");\n expect(clickCompletedLine).toContain(\"[🆄 #3333 CLICK]\");\n expect(clickCompletedLine).not.toContain(\"#4444\");\n\n expect(actCompletedLine).toContain(\"[🅰 #1234]\");\n expect(actCompletedLine).toContain(\"[🆂 #2222 ACT]\");\n expect(actCompletedLine).not.toContain(\"#5555\");\n\n expect(agentCompletedLine).toContain(\"[🅰 #1234]\");\n expect(agentCompletedLine).not.toContain(\"#6666\");\n\n detachBus();\n await store.destroy();\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { OpenAICUAClient } from "../../lib/v3/agent/OpenAICUAClient.js";
3
+ function createClient() {
4
+ return new OpenAICUAClient("openai", "computer-use-preview-2025-03-11", undefined, { apiKey: "test-key" });
5
+ }
6
+ describe("OpenAICUAClient", () => {
7
+ it("exposes captchaSolvedProceed tool after a captcha context note", () => {
8
+ const client = createClient();
9
+ // Before captcha note — tool should not be active
10
+ expect(client
11
+ .captchaSolvedToolActive).toBe(false);
12
+ // Simulate a captcha context note being added (as the CUA handler does)
13
+ client.addContextNote("A captcha was automatically detected and solved — no further interaction needed.");
14
+ expect(client
15
+ .captchaSolvedToolActive).toBe(true);
16
+ });
17
+ it("does NOT activate captcha tool for non-captcha context notes", () => {
18
+ const client = createClient();
19
+ client.addContextNote("The page has finished loading.");
20
+ expect(client
21
+ .captchaSolvedToolActive).toBe(false);
22
+ });
23
+ it("deactivates captcha tool after takeAction handles the function call", async () => {
24
+ const client = createClient();
25
+ client.addContextNote("A captcha was solved.");
26
+ expect(client
27
+ .captchaSolvedToolActive).toBe(true);
28
+ // Simulate the model calling the captchaSolvedProceed tool
29
+ const result = await client.takeAction([
30
+ {
31
+ type: "function_call",
32
+ name: "captchaSolvedProceed",
33
+ call_id: "call-1",
34
+ arguments: "{}",
35
+ },
36
+ ], vi.fn());
37
+ // Tool should be deactivated
38
+ expect(client
39
+ .captchaSolvedToolActive).toBe(false);
40
+ // Result should contain a function_call_output confirming proceed
41
+ expect(result).toEqual([
42
+ {
43
+ type: "function_call_output",
44
+ call_id: "call-1",
45
+ output: expect.stringContaining("Continue completing"),
46
+ },
47
+ ]);
48
+ });
49
+ it("does NOT auto-continue follow-up questions without a captcha context", async () => {
50
+ const client = createClient();
51
+ const executeStepSpy = vi.spyOn(client, "executeStep");
52
+ executeStepSpy.mockResolvedValueOnce({
53
+ actions: [],
54
+ message: "I've located the Submit button. Should I go ahead and submit it?",
55
+ completed: true,
56
+ nextInputItems: [],
57
+ responseId: "response-1",
58
+ usage: { input_tokens: 1, output_tokens: 1, inference_time_ms: 1 },
59
+ });
60
+ const result = await client.execute({
61
+ options: { instruction: "Submit the form.", maxSteps: 10 },
62
+ logger: vi.fn(),
63
+ });
64
+ // Should NOT have continued — the model's follow-up is treated as completion
65
+ expect(executeStepSpy).toHaveBeenCalledTimes(1);
66
+ expect(result.completed).toBe(true);
67
+ });
68
+ });
69
+ //# sourceMappingURL=openai-cua-client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-cua-client.test.js","sourceRoot":"","sources":["../../../../tests/unit/openai-cua-client.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { OpenAICUAClient } from \"../../lib/v3/agent/OpenAICUAClient.js\";\n\nfunction createClient() {\n return new OpenAICUAClient(\n \"openai\",\n \"computer-use-preview-2025-03-11\",\n undefined,\n { apiKey: \"test-key\" },\n );\n}\n\ndescribe(\"OpenAICUAClient\", () => {\n it(\"exposes captchaSolvedProceed tool after a captcha context note\", () => {\n const client = createClient();\n\n // Before captcha note — tool should not be active\n expect(\n (client as unknown as { captchaSolvedToolActive: boolean })\n .captchaSolvedToolActive,\n ).toBe(false);\n\n // Simulate a captcha context note being added (as the CUA handler does)\n client.addContextNote(\n \"A captcha was automatically detected and solved — no further interaction needed.\",\n );\n\n expect(\n (client as unknown as { captchaSolvedToolActive: boolean })\n .captchaSolvedToolActive,\n ).toBe(true);\n });\n\n it(\"does NOT activate captcha tool for non-captcha context notes\", () => {\n const client = createClient();\n\n client.addContextNote(\"The page has finished loading.\");\n\n expect(\n (client as unknown as { captchaSolvedToolActive: boolean })\n .captchaSolvedToolActive,\n ).toBe(false);\n });\n\n it(\"deactivates captcha tool after takeAction handles the function call\", async () => {\n const client = createClient();\n client.addContextNote(\"A captcha was solved.\");\n\n expect(\n (client as unknown as { captchaSolvedToolActive: boolean })\n .captchaSolvedToolActive,\n ).toBe(true);\n\n // Simulate the model calling the captchaSolvedProceed tool\n const result = await (\n client as unknown as {\n takeAction: (\n output: unknown[],\n logger: (msg: unknown) => void,\n ) => Promise<unknown[]>;\n }\n ).takeAction(\n [\n {\n type: \"function_call\",\n name: \"captchaSolvedProceed\",\n call_id: \"call-1\",\n arguments: \"{}\",\n },\n ],\n vi.fn(),\n );\n\n // Tool should be deactivated\n expect(\n (client as unknown as { captchaSolvedToolActive: boolean })\n .captchaSolvedToolActive,\n ).toBe(false);\n\n // Result should contain a function_call_output confirming proceed\n expect(result).toEqual([\n {\n type: \"function_call_output\",\n call_id: \"call-1\",\n output: expect.stringContaining(\"Continue completing\"),\n },\n ]);\n });\n\n it(\"does NOT auto-continue follow-up questions without a captcha context\", async () => {\n const client = createClient();\n // No captcha context note — no tool should be exposed\n\n type ExecuteStepResult = {\n actions: Array<{ type: string }>;\n message: string;\n completed: boolean;\n nextInputItems: unknown[];\n responseId: string;\n usage: {\n input_tokens: number;\n output_tokens: number;\n inference_time_ms: number;\n };\n };\n\n const executeStepSpy = vi.spyOn(\n client as unknown as {\n executeStep: (\n inputItems: unknown[],\n previousResponseId: string | undefined,\n logger: (message: { message: string }) => void,\n ) => Promise<ExecuteStepResult>;\n },\n \"executeStep\",\n );\n\n executeStepSpy.mockResolvedValueOnce({\n actions: [],\n message:\n \"I've located the Submit button. Should I go ahead and submit it?\",\n completed: true,\n nextInputItems: [],\n responseId: \"response-1\",\n usage: { input_tokens: 1, output_tokens: 1, inference_time_ms: 1 },\n });\n\n const result = await client.execute({\n options: { instruction: \"Submit the form.\", maxSteps: 10 } as never,\n logger: vi.fn(),\n });\n\n // Should NOT have continued — the model's follow-up is treated as completion\n expect(executeStepSpy).toHaveBeenCalledTimes(1);\n expect(result.completed).toBe(true);\n });\n});\n"]}
@@ -0,0 +1,17 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildObserveSystemPrompt } from "../../lib/prompt.js";
3
+ describe("buildObserveSystemPrompt", () => {
4
+ it("includes variable descriptions when present", () => {
5
+ const prompt = buildObserveSystemPrompt(undefined, ["click", "fill"], {
6
+ username: {
7
+ value: "john@example.com",
8
+ description: "The login email",
9
+ },
10
+ password: "secret123",
11
+ });
12
+ expect(prompt.content).toContain("Supported actions: click, fill");
13
+ expect(prompt.content).toContain("Available variables: %username% (The login email), %password%");
14
+ expect(prompt.content).toContain("return the matching %variableName% placeholder");
15
+ });
16
+ });
17
+ //# sourceMappingURL=prompt-observe-variables.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-observe-variables.test.js","sourceRoot":"","sources":["../../../../tests/unit/prompt-observe-variables.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE;YACpE,QAAQ,EAAE;gBACR,KAAK,EAAE,kBAAkB;gBACzB,WAAW,EAAE,iBAAiB;aAC/B;YACD,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;QACnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAC9B,+DAA+D,CAChE,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAC9B,gDAAgD,CACjD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { buildObserveSystemPrompt } from \"../../lib/prompt.js\";\n\ndescribe(\"buildObserveSystemPrompt\", () => {\n it(\"includes variable descriptions when present\", () => {\n const prompt = buildObserveSystemPrompt(undefined, [\"click\", \"fill\"], {\n username: {\n value: \"john@example.com\",\n description: \"The login email\",\n },\n password: \"secret123\",\n });\n\n expect(prompt.content).toContain(\"Supported actions: click, fill\");\n expect(prompt.content).toContain(\n \"Available variables: %username% (The login email), %password%\",\n );\n expect(prompt.content).toContain(\n \"return the matching %variableName% placeholder\",\n );\n });\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"public-types.test.js","sourceRoot":"","sources":["../../../../../tests/unit/public-api/public-types.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expectTypeOf, it } from \"vitest\";\nimport * as Stagehand from \"@browserbasehq/stagehand\";\n\n// Type-level manifest of all expected exported types\n// Since these types don't exist at runtime, we currently need to manually add new publicly exported types\n// to this list ourselves - it's not automatically going to catch changes like our export-surface.test.ts does.\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype ExpectedExportedTypes = {\n // Types from model.ts\n AvailableModel: Stagehand.AvailableModel;\n AvailableCuaModel: Stagehand.AvailableCuaModel;\n ModelProvider: Stagehand.ModelProvider;\n ClientOptions: Stagehand.ClientOptions;\n ModelConfiguration: Stagehand.ModelConfiguration;\n AnthropicJsonSchemaObject: Stagehand.AnthropicJsonSchemaObject;\n AISDKProvider: Stagehand.AISDKProvider;\n AISDKCustomProvider: Stagehand.AISDKCustomProvider;\n LLMTool: Stagehand.LLMTool;\n // Types from methods.ts\n ActOptions: Stagehand.ActOptions;\n ActResult: Stagehand.ActResult;\n ExtractResult: Stagehand.ExtractResult<Stagehand.StagehandZodSchema>;\n Action: Stagehand.Action;\n HistoryEntry: Stagehand.HistoryEntry;\n ExtractOptions: Stagehand.ExtractOptions;\n ObserveOptions: Stagehand.ObserveOptions;\n ObserveResult: Stagehand.ObserveResult;\n V3FunctionName: Stagehand.V3FunctionName;\n // Types from agent.ts\n Tool: Stagehand.Tool;\n AgentAction: Stagehand.AgentAction;\n AgentResult: Stagehand.AgentResult;\n AgentExecuteOptions: Stagehand.AgentExecuteOptions;\n AgentType: Stagehand.AgentType;\n AgentExecutionOptions: Stagehand.AgentExecutionOptions<Stagehand.AgentExecuteOptions>;\n AgentHandlerOptions: Stagehand.AgentHandlerOptions;\n ActionExecutionResult: Stagehand.ActionExecutionResult;\n ToolUseItem: Stagehand.ToolUseItem;\n AnthropicMessage: Stagehand.AnthropicMessage;\n AnthropicContentBlock: Stagehand.AnthropicContentBlock;\n AnthropicTextBlock: Stagehand.AnthropicTextBlock;\n AnthropicToolResult: Stagehand.AnthropicToolResult;\n ResponseItem: Stagehand.ResponseItem;\n ComputerCallItem: Stagehand.ComputerCallItem;\n FunctionCallItem: Stagehand.FunctionCallItem;\n ResponseInputItem: Stagehand.ResponseInputItem;\n AgentInstance: Stagehand.AgentInstance;\n AgentProviderType: Stagehand.AgentProviderType;\n AgentModelConfig: Stagehand.AgentModelConfig;\n AgentConfig: Stagehand.AgentConfig;\n AgentToolMode: Stagehand.AgentToolMode;\n VariableValue: Stagehand.VariableValue;\n Variables: Stagehand.Variables;\n AgentCallbacks: Stagehand.AgentCallbacks;\n AgentExecuteCallbacks: Stagehand.AgentExecuteCallbacks;\n AgentStreamCallbacks: Stagehand.AgentStreamCallbacks;\n AgentExecuteOptionsBase: Stagehand.AgentExecuteOptionsBase;\n AgentStreamExecuteOptions: Stagehand.AgentStreamExecuteOptions;\n ModelMessage: Stagehand.ModelMessage;\n // Types from agent/tools\n AgentTools: Stagehand.AgentTools;\n AgentToolTypesMap: Stagehand.AgentToolTypesMap;\n AgentUITools: Stagehand.AgentUITools;\n AgentToolCall: Stagehand.AgentToolCall;\n AgentToolResult: Stagehand.AgentToolResult;\n // Types from logs.ts\n LogLevel: Stagehand.LogLevel;\n LogLine: Stagehand.LogLine;\n Logger: Stagehand.Logger;\n // Types from metrics.ts\n StagehandMetrics: Stagehand.StagehandMetrics;\n // Types from options.ts\n V3Env: Stagehand.V3Env;\n LocalBrowserLaunchOptions: Stagehand.LocalBrowserLaunchOptions;\n V3Options: Stagehand.V3Options;\n // Types from page.ts\n AnyPage: Stagehand.AnyPage;\n Page: Stagehand.Page;\n PlaywrightPage: Stagehand.PlaywrightPage;\n PatchrightPage: Stagehand.PatchrightPage;\n PuppeteerPage: Stagehand.PuppeteerPage;\n ConsoleListener: Stagehand.ConsoleListener;\n LoadState: Stagehand.LoadState;\n // Types from LLMClient.ts\n ChatMessage: Stagehand.ChatMessage;\n ChatMessageContent: Stagehand.ChatMessageContent;\n ChatMessageImageContent: Stagehand.ChatMessageImageContent;\n ChatMessageTextContent: Stagehand.ChatMessageTextContent;\n ChatCompletionOptions: Stagehand.ChatCompletionOptions;\n LLMResponse: Stagehand.LLMResponse;\n CreateChatCompletionOptions: Stagehand.CreateChatCompletionOptions;\n LLMUsage: Stagehand.LLMUsage;\n LLMParsedResponse: Stagehand.LLMParsedResponse<Record<string, unknown>>;\n // Types from zodCompat.ts\n StagehandZodSchema: Stagehand.StagehandZodSchema;\n StagehandZodObject: Stagehand.StagehandZodObject;\n InferStagehandSchema: Stagehand.InferStagehandSchema<Stagehand.StagehandZodSchema>;\n JsonSchemaDocument: Stagehand.JsonSchemaDocument;\n // Types from utils.ts\n JsonSchema: Stagehand.JsonSchema;\n JsonSchemaProperty: Stagehand.JsonSchemaProperty;\n // Types from cookies.ts\n Cookie: Stagehand.Cookie;\n CookieParam: Stagehand.CookieParam;\n ClearCookieOptions: Stagehand.ClearCookieOptions;\n};\n\ndescribe(\"Stagehand public API types\", () => {\n describe(\"AnyPage\", () => {\n type ExpectedAnyPage =\n | Stagehand.PlaywrightPage\n | Stagehand.PuppeteerPage\n | Stagehand.PatchrightPage\n | Stagehand.Page;\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AnyPage>().toEqualTypeOf<ExpectedAnyPage>();\n });\n });\n\n describe(\"ActOptions\", () => {\n type ExpectedActOptions = {\n model?: Stagehand.ModelConfiguration;\n variables?: Stagehand.Variables;\n timeout?: number;\n page?: Stagehand.AnyPage;\n serverCache?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ActOptions>().toEqualTypeOf<ExpectedActOptions>();\n });\n });\n\n describe(\"ActResult\", () => {\n type ExpectedActResult = {\n success: boolean;\n message: string;\n actionDescription: string;\n actions: Stagehand.Action[];\n cacheStatus?: \"HIT\" | \"MISS\";\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ActResult>().toEqualTypeOf<ExpectedActResult>();\n });\n });\n\n describe(\"ExtractOptions\", () => {\n type ExpectedExtractOptions = {\n model?: Stagehand.ModelConfiguration;\n timeout?: number;\n selector?: string;\n page?: Stagehand.AnyPage;\n serverCache?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ExtractOptions>().toEqualTypeOf<ExpectedExtractOptions>();\n });\n });\n\n describe(\"ObserveOptions\", () => {\n type ExpectedObserveOptions = {\n model?: Stagehand.ModelConfiguration;\n timeout?: number;\n selector?: string;\n page?: Stagehand.AnyPage;\n serverCache?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ObserveOptions>().toEqualTypeOf<ExpectedObserveOptions>();\n });\n });\n\n describe(\"ObserveResult\", () => {\n it(\"is an Action array with optional cacheStatus\", () => {\n expectTypeOf<Stagehand.ObserveResult>().toExtend<Stagehand.Action[]>();\n expectTypeOf<Stagehand.ObserveResult[\"cacheStatus\"]>().toEqualTypeOf<\n \"HIT\" | \"MISS\" | undefined\n >();\n });\n });\n\n describe(\"Action\", () => {\n type ExpectedAction = {\n selector: string;\n description: string;\n method?: string;\n arguments?: string[];\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.Action>().toEqualTypeOf<ExpectedAction>();\n });\n });\n\n describe(\"AgentAction\", () => {\n // AgentAction is a separate type from Action, not an extension\n // It has additional fields like type, reasoning, taskCompleted, etc.\n it(\"has type field\", () => {\n type TestAction = { type: string } & Stagehand.AgentAction;\n expectTypeOf<TestAction[\"type\"]>().toEqualTypeOf<string>();\n });\n });\n\n describe(\"AgentExecuteOptions\", () => {\n type ExpectedAgentExecuteOptions = {\n instruction: string;\n maxSteps?: number;\n page?: Stagehand.AnyPage;\n highlightCursor?: boolean;\n messages?: Stagehand.ModelMessage[];\n signal?: AbortSignal;\n excludeTools?: string[];\n output?: Stagehand.StagehandZodObject;\n callbacks?: Stagehand.AgentExecuteCallbacks;\n variables?: Stagehand.Variables;\n toolTimeout?: number;\n useSearch?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentExecuteOptions>().toEqualTypeOf<ExpectedAgentExecuteOptions>();\n });\n });\n\n describe(\"AgentStreamExecuteOptions\", () => {\n type ExpectedAgentStreamExecuteOptions = {\n instruction: string;\n maxSteps?: number;\n page?: Stagehand.AnyPage;\n highlightCursor?: boolean;\n messages?: Stagehand.ModelMessage[];\n signal?: AbortSignal;\n excludeTools?: string[];\n output?: Stagehand.StagehandZodObject;\n callbacks?: Stagehand.AgentStreamCallbacks;\n variables?: Stagehand.Variables;\n toolTimeout?: number;\n useSearch?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentStreamExecuteOptions>().toEqualTypeOf<ExpectedAgentStreamExecuteOptions>();\n });\n });\n\n describe(\"AgentExecutionOptions\", () => {\n type ExpectedAgentExecutionOptions<T = Stagehand.AgentExecuteOptions> = {\n options: T;\n logger: (message: Stagehand.LogLine) => void;\n retries?: number;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<\n Stagehand.AgentExecutionOptions<Stagehand.AgentExecuteOptions>\n >().toEqualTypeOf<\n ExpectedAgentExecutionOptions<Stagehand.AgentExecuteOptions>\n >();\n });\n });\n\n describe(\"AgentResult\", () => {\n type ExpectedAgentResult = {\n success: boolean;\n message: string;\n actions: Stagehand.AgentAction[];\n completed: boolean;\n metadata?: Record<string, unknown>;\n usage?: {\n input_tokens: number;\n output_tokens: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n inference_time_ms: number;\n };\n messages?: Stagehand.ModelMessage[];\n output?: Record<string, unknown>;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentResult>().toEqualTypeOf<ExpectedAgentResult>();\n });\n });\n\n describe(\"AgentConfig\", () => {\n type ExpectedAgentConfig = {\n systemPrompt?: string;\n integrations?: (unknown | string)[];\n tools?: unknown;\n cua?: boolean;\n model?: string | Stagehand.AgentModelConfig<string>;\n executionModel?: string | Stagehand.AgentModelConfig<string>;\n stream?: boolean;\n mode?: Stagehand.AgentToolMode;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentConfig>().toExtend<ExpectedAgentConfig>();\n });\n });\n\n describe(\"AgentToolMode\", () => {\n type ExpectedAgentToolMode = \"dom\" | \"hybrid\" | \"cua\";\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentToolMode>().toEqualTypeOf<ExpectedAgentToolMode>();\n });\n });\n\n describe(\"HistoryEntry\", () => {\n type ExpectedHistoryEntry = {\n method: \"act\" | \"extract\" | \"observe\" | \"navigate\" | \"agent\";\n parameters: unknown;\n result: unknown;\n timestamp: string;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.HistoryEntry>().toEqualTypeOf<ExpectedHistoryEntry>();\n });\n });\n\n describe(\"Cookie\", () => {\n type ExpectedCookie = {\n name: string;\n value: string;\n domain: string;\n path: string;\n expires: number;\n httpOnly: boolean;\n secure: boolean;\n sameSite: \"Strict\" | \"Lax\" | \"None\";\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.Cookie>().toEqualTypeOf<ExpectedCookie>();\n });\n });\n\n describe(\"CookieParam\", () => {\n type ExpectedCookieParam = {\n name: string;\n value: string;\n url?: string;\n domain?: string;\n path?: string;\n expires?: number;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.CookieParam>().toEqualTypeOf<ExpectedCookieParam>();\n });\n });\n\n describe(\"ClearCookieOptions\", () => {\n type ExpectedClearCookieOptions = {\n name?: string | RegExp;\n domain?: string | RegExp;\n path?: string | RegExp;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ClearCookieOptions>().toEqualTypeOf<ExpectedClearCookieOptions>();\n });\n });\n});\n"]}
1
+ {"version":3,"file":"public-types.test.js","sourceRoot":"","sources":["../../../../../tests/unit/public-api/public-types.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expectTypeOf, it } from \"vitest\";\nimport * as Stagehand from \"@browserbasehq/stagehand\";\n\n// Type-level manifest of all expected exported types\n// Since these types don't exist at runtime, we currently need to manually add new publicly exported types\n// to this list ourselves - it's not automatically going to catch changes like our export-surface.test.ts does.\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype ExpectedExportedTypes = {\n // Types from model.ts\n AvailableModel: Stagehand.AvailableModel;\n AvailableCuaModel: Stagehand.AvailableCuaModel;\n ModelProvider: Stagehand.ModelProvider;\n ClientOptions: Stagehand.ClientOptions;\n ModelConfiguration: Stagehand.ModelConfiguration;\n AnthropicJsonSchemaObject: Stagehand.AnthropicJsonSchemaObject;\n AISDKProvider: Stagehand.AISDKProvider;\n AISDKCustomProvider: Stagehand.AISDKCustomProvider;\n LLMTool: Stagehand.LLMTool;\n // Types from methods.ts\n ActOptions: Stagehand.ActOptions;\n ActResult: Stagehand.ActResult;\n ExtractResult: Stagehand.ExtractResult<Stagehand.StagehandZodSchema>;\n Action: Stagehand.Action;\n HistoryEntry: Stagehand.HistoryEntry;\n ExtractOptions: Stagehand.ExtractOptions;\n ObserveOptions: Stagehand.ObserveOptions;\n ObserveResult: Stagehand.ObserveResult;\n V3FunctionName: Stagehand.V3FunctionName;\n // Types from agent.ts\n Tool: Stagehand.Tool;\n AgentAction: Stagehand.AgentAction;\n AgentResult: Stagehand.AgentResult;\n AgentExecuteOptions: Stagehand.AgentExecuteOptions;\n AgentType: Stagehand.AgentType;\n AgentExecutionOptions: Stagehand.AgentExecutionOptions<Stagehand.AgentExecuteOptions>;\n AgentHandlerOptions: Stagehand.AgentHandlerOptions;\n ActionExecutionResult: Stagehand.ActionExecutionResult;\n ToolUseItem: Stagehand.ToolUseItem;\n AnthropicMessage: Stagehand.AnthropicMessage;\n AnthropicContentBlock: Stagehand.AnthropicContentBlock;\n AnthropicTextBlock: Stagehand.AnthropicTextBlock;\n AnthropicToolResult: Stagehand.AnthropicToolResult;\n ResponseItem: Stagehand.ResponseItem;\n ComputerCallItem: Stagehand.ComputerCallItem;\n FunctionCallItem: Stagehand.FunctionCallItem;\n ResponseInputItem: Stagehand.ResponseInputItem;\n AgentInstance: Stagehand.AgentInstance;\n AgentProviderType: Stagehand.AgentProviderType;\n AgentModelConfig: Stagehand.AgentModelConfig;\n AgentConfig: Stagehand.AgentConfig;\n AgentToolMode: Stagehand.AgentToolMode;\n VariableValue: Stagehand.VariableValue;\n Variables: Stagehand.Variables;\n AgentCallbacks: Stagehand.AgentCallbacks;\n AgentExecuteCallbacks: Stagehand.AgentExecuteCallbacks;\n AgentStreamCallbacks: Stagehand.AgentStreamCallbacks;\n AgentExecuteOptionsBase: Stagehand.AgentExecuteOptionsBase;\n AgentStreamExecuteOptions: Stagehand.AgentStreamExecuteOptions;\n ModelMessage: Stagehand.ModelMessage;\n // Types from agent/tools\n AgentTools: Stagehand.AgentTools;\n AgentToolTypesMap: Stagehand.AgentToolTypesMap;\n AgentUITools: Stagehand.AgentUITools;\n AgentToolCall: Stagehand.AgentToolCall;\n AgentToolResult: Stagehand.AgentToolResult;\n // Types from logs.ts\n LogLevel: Stagehand.LogLevel;\n LogLine: Stagehand.LogLine;\n Logger: Stagehand.Logger;\n // Types from metrics.ts\n StagehandMetrics: Stagehand.StagehandMetrics;\n // Types from options.ts\n V3Env: Stagehand.V3Env;\n LocalBrowserLaunchOptions: Stagehand.LocalBrowserLaunchOptions;\n V3Options: Stagehand.V3Options;\n // Types from page.ts\n AnyPage: Stagehand.AnyPage;\n Page: Stagehand.Page;\n PlaywrightPage: Stagehand.PlaywrightPage;\n PatchrightPage: Stagehand.PatchrightPage;\n PuppeteerPage: Stagehand.PuppeteerPage;\n ConsoleListener: Stagehand.ConsoleListener;\n LoadState: Stagehand.LoadState;\n // Types from LLMClient.ts\n ChatMessage: Stagehand.ChatMessage;\n ChatMessageContent: Stagehand.ChatMessageContent;\n ChatMessageImageContent: Stagehand.ChatMessageImageContent;\n ChatMessageTextContent: Stagehand.ChatMessageTextContent;\n ChatCompletionOptions: Stagehand.ChatCompletionOptions;\n LLMResponse: Stagehand.LLMResponse;\n CreateChatCompletionOptions: Stagehand.CreateChatCompletionOptions;\n LLMUsage: Stagehand.LLMUsage;\n LLMParsedResponse: Stagehand.LLMParsedResponse<Record<string, unknown>>;\n // Types from zodCompat.ts\n StagehandZodSchema: Stagehand.StagehandZodSchema;\n StagehandZodObject: Stagehand.StagehandZodObject;\n InferStagehandSchema: Stagehand.InferStagehandSchema<Stagehand.StagehandZodSchema>;\n JsonSchemaDocument: Stagehand.JsonSchemaDocument;\n // Types from utils.ts\n JsonSchema: Stagehand.JsonSchema;\n JsonSchemaProperty: Stagehand.JsonSchemaProperty;\n // Types from cookies.ts\n Cookie: Stagehand.Cookie;\n CookieParam: Stagehand.CookieParam;\n ClearCookieOptions: Stagehand.ClearCookieOptions;\n};\n\ndescribe(\"Stagehand public API types\", () => {\n describe(\"AnyPage\", () => {\n type ExpectedAnyPage =\n | Stagehand.PlaywrightPage\n | Stagehand.PuppeteerPage\n | Stagehand.PatchrightPage\n | Stagehand.Page;\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AnyPage>().toEqualTypeOf<ExpectedAnyPage>();\n });\n });\n\n describe(\"ActOptions\", () => {\n type ExpectedActOptions = {\n model?: Stagehand.ModelConfiguration;\n variables?: Stagehand.Variables;\n timeout?: number;\n page?: Stagehand.AnyPage;\n serverCache?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ActOptions>().toEqualTypeOf<ExpectedActOptions>();\n });\n });\n\n describe(\"ActResult\", () => {\n type ExpectedActResult = {\n success: boolean;\n message: string;\n actionDescription: string;\n actions: Stagehand.Action[];\n cacheStatus?: \"HIT\" | \"MISS\";\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ActResult>().toEqualTypeOf<ExpectedActResult>();\n });\n });\n\n describe(\"ExtractOptions\", () => {\n type ExpectedExtractOptions = {\n model?: Stagehand.ModelConfiguration;\n timeout?: number;\n selector?: string;\n page?: Stagehand.AnyPage;\n serverCache?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ExtractOptions>().toEqualTypeOf<ExpectedExtractOptions>();\n });\n });\n\n describe(\"ObserveOptions\", () => {\n type ExpectedObserveOptions = {\n model?: Stagehand.ModelConfiguration;\n variables?: Stagehand.Variables;\n timeout?: number;\n selector?: string;\n page?: Stagehand.AnyPage;\n serverCache?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ObserveOptions>().toEqualTypeOf<ExpectedObserveOptions>();\n });\n });\n\n describe(\"ObserveResult\", () => {\n it(\"is an Action array with optional cacheStatus\", () => {\n expectTypeOf<Stagehand.ObserveResult>().toExtend<Stagehand.Action[]>();\n expectTypeOf<Stagehand.ObserveResult[\"cacheStatus\"]>().toEqualTypeOf<\n \"HIT\" | \"MISS\" | undefined\n >();\n });\n });\n\n describe(\"Action\", () => {\n type ExpectedAction = {\n selector: string;\n description: string;\n method?: string;\n arguments?: string[];\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.Action>().toEqualTypeOf<ExpectedAction>();\n });\n });\n\n describe(\"AgentAction\", () => {\n // AgentAction is a separate type from Action, not an extension\n // It has additional fields like type, reasoning, taskCompleted, etc.\n it(\"has type field\", () => {\n type TestAction = { type: string } & Stagehand.AgentAction;\n expectTypeOf<TestAction[\"type\"]>().toEqualTypeOf<string>();\n });\n });\n\n describe(\"AgentExecuteOptions\", () => {\n type ExpectedAgentExecuteOptions = {\n instruction: string;\n maxSteps?: number;\n page?: Stagehand.AnyPage;\n highlightCursor?: boolean;\n messages?: Stagehand.ModelMessage[];\n signal?: AbortSignal;\n excludeTools?: string[];\n output?: Stagehand.StagehandZodObject;\n callbacks?: Stagehand.AgentExecuteCallbacks;\n variables?: Stagehand.Variables;\n toolTimeout?: number;\n useSearch?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentExecuteOptions>().toEqualTypeOf<ExpectedAgentExecuteOptions>();\n });\n });\n\n describe(\"AgentStreamExecuteOptions\", () => {\n type ExpectedAgentStreamExecuteOptions = {\n instruction: string;\n maxSteps?: number;\n page?: Stagehand.AnyPage;\n highlightCursor?: boolean;\n messages?: Stagehand.ModelMessage[];\n signal?: AbortSignal;\n excludeTools?: string[];\n output?: Stagehand.StagehandZodObject;\n callbacks?: Stagehand.AgentStreamCallbacks;\n variables?: Stagehand.Variables;\n toolTimeout?: number;\n useSearch?: boolean;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentStreamExecuteOptions>().toEqualTypeOf<ExpectedAgentStreamExecuteOptions>();\n });\n });\n\n describe(\"AgentExecutionOptions\", () => {\n type ExpectedAgentExecutionOptions<T = Stagehand.AgentExecuteOptions> = {\n options: T;\n logger: (message: Stagehand.LogLine) => void;\n retries?: number;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<\n Stagehand.AgentExecutionOptions<Stagehand.AgentExecuteOptions>\n >().toEqualTypeOf<\n ExpectedAgentExecutionOptions<Stagehand.AgentExecuteOptions>\n >();\n });\n });\n\n describe(\"AgentResult\", () => {\n type ExpectedAgentResult = {\n success: boolean;\n message: string;\n actions: Stagehand.AgentAction[];\n completed: boolean;\n metadata?: Record<string, unknown>;\n usage?: {\n input_tokens: number;\n output_tokens: number;\n reasoning_tokens?: number;\n cached_input_tokens?: number;\n inference_time_ms: number;\n };\n messages?: Stagehand.ModelMessage[];\n output?: Record<string, unknown>;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentResult>().toEqualTypeOf<ExpectedAgentResult>();\n });\n });\n\n describe(\"AgentConfig\", () => {\n type ExpectedAgentConfig = {\n systemPrompt?: string;\n integrations?: (unknown | string)[];\n tools?: unknown;\n cua?: boolean;\n model?: string | Stagehand.AgentModelConfig<string>;\n executionModel?: string | Stagehand.AgentModelConfig<string>;\n stream?: boolean;\n mode?: Stagehand.AgentToolMode;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentConfig>().toExtend<ExpectedAgentConfig>();\n });\n });\n\n describe(\"AgentToolMode\", () => {\n type ExpectedAgentToolMode = \"dom\" | \"hybrid\" | \"cua\";\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.AgentToolMode>().toEqualTypeOf<ExpectedAgentToolMode>();\n });\n });\n\n describe(\"HistoryEntry\", () => {\n type ExpectedHistoryEntry = {\n method: \"act\" | \"extract\" | \"observe\" | \"navigate\" | \"agent\";\n parameters: unknown;\n result: unknown;\n timestamp: string;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.HistoryEntry>().toEqualTypeOf<ExpectedHistoryEntry>();\n });\n });\n\n describe(\"Cookie\", () => {\n type ExpectedCookie = {\n name: string;\n value: string;\n domain: string;\n path: string;\n expires: number;\n httpOnly: boolean;\n secure: boolean;\n sameSite: \"Strict\" | \"Lax\" | \"None\";\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.Cookie>().toEqualTypeOf<ExpectedCookie>();\n });\n });\n\n describe(\"CookieParam\", () => {\n type ExpectedCookieParam = {\n name: string;\n value: string;\n url?: string;\n domain?: string;\n path?: string;\n expires?: number;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.CookieParam>().toEqualTypeOf<ExpectedCookieParam>();\n });\n });\n\n describe(\"ClearCookieOptions\", () => {\n type ExpectedClearCookieOptions = {\n name?: string | RegExp;\n domain?: string | RegExp;\n path?: string | RegExp;\n };\n\n it(\"matches expected type shape\", () => {\n expectTypeOf<Stagehand.ClearCookieOptions>().toEqualTypeOf<ExpectedClearCookieOptions>();\n });\n });\n});\n"]}
@@ -685,6 +685,56 @@ describe("No-timeout success paths", () => {
685
685
  expect(result[0]).toHaveProperty("description", "Submit button");
686
686
  expect(metricsCallback).toHaveBeenCalledWith(V3FunctionName.OBSERVE, 150, 75, 15, 8, 600);
687
687
  });
688
+ it("observe() forwards variables to inference and preserves placeholders", async () => {
689
+ const captureHybridSnapshotMock = vi.mocked(captureHybridSnapshot);
690
+ captureHybridSnapshotMock.mockResolvedValue({
691
+ combinedTree: "tree content",
692
+ combinedXpathMap: { "1-0": "/html/body/input" },
693
+ combinedUrlMap: {},
694
+ });
695
+ const observeInferenceMock = vi.mocked(observeInference);
696
+ observeInferenceMock.mockResolvedValue({
697
+ elements: [
698
+ {
699
+ elementId: "1-0",
700
+ description: "Email field",
701
+ method: "fill",
702
+ arguments: ["%username%"],
703
+ },
704
+ ],
705
+ prompt_tokens: 150,
706
+ completion_tokens: 75,
707
+ reasoning_tokens: 15,
708
+ cached_input_tokens: 8,
709
+ inference_time_ms: 600,
710
+ });
711
+ vi.mocked(createTimeoutGuard).mockImplementation(() => {
712
+ return vi.fn(() => {
713
+ // No-op - never throws
714
+ });
715
+ });
716
+ const handler = buildObserveHandler();
717
+ const fakePage = {
718
+ mainFrame: vi.fn().mockReturnValue({}),
719
+ };
720
+ const variables = {
721
+ username: {
722
+ value: "john@example.com",
723
+ description: "The login email",
724
+ },
725
+ };
726
+ const result = await handler.observe({
727
+ instruction: "find the field where %username% should be entered",
728
+ variables,
729
+ page: fakePage,
730
+ });
731
+ expect(observeInferenceMock).toHaveBeenCalledWith(expect.objectContaining({
732
+ variables,
733
+ }));
734
+ expect(result).toHaveLength(1);
735
+ expect(result[0]).toHaveProperty("arguments");
736
+ expect(result[0]?.arguments).toEqual(["%username%"]);
737
+ });
688
738
  it("act() with zero timeout behaves as no timeout", async () => {
689
739
  const waitForDomNetworkQuietMock = vi.mocked(waitForDomNetworkQuiet);
690
740
  waitForDomNetworkQuietMock.mockResolvedValue(undefined);