@browserbasehq/orca 3.5.1-preview.0 → 3.7.0-preview.1

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 (242) hide show
  1. package/README.md +0 -12
  2. package/dist/cjs/lib/utils.d.ts +6 -0
  3. package/dist/cjs/lib/utils.js +11 -0
  4. package/dist/cjs/lib/utils.js.map +1 -1
  5. package/dist/cjs/lib/v3/agent/AgentClient.d.ts +2 -2
  6. package/dist/cjs/lib/v3/agent/AgentClient.js.map +1 -1
  7. package/dist/cjs/lib/v3/agent/AgentProvider.js +4 -3
  8. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  9. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.d.ts +4 -3
  10. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +21 -18
  11. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  12. package/dist/cjs/lib/v3/agent/GoogleCUAClient.d.ts +12 -3
  13. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +217 -36
  14. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  15. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.d.ts +2 -2
  16. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js +2 -2
  17. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  18. package/dist/cjs/lib/v3/agent/OpenAICUAClient.d.ts +6 -3
  19. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +13 -7
  20. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  21. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.d.ts +1 -0
  22. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js +50 -3
  23. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  24. package/dist/cjs/lib/v3/cache/ActCache.js +1 -1
  25. package/dist/cjs/lib/v3/cache/ActCache.js.map +1 -1
  26. package/dist/cjs/lib/v3/cache/utils.d.ts +7 -0
  27. package/dist/cjs/lib/v3/cache/utils.js +19 -0
  28. package/dist/cjs/lib/v3/cache/utils.js.map +1 -1
  29. package/dist/cjs/lib/v3/handlers/v3AgentHandler.d.ts +2 -1
  30. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +55 -16
  31. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  32. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +32 -18
  33. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  34. package/dist/cjs/lib/v3/index.d.ts +3 -2
  35. package/dist/cjs/lib/v3/index.js.map +1 -1
  36. package/dist/cjs/lib/v3/launch/local.js +1 -0
  37. package/dist/cjs/lib/v3/launch/local.js.map +1 -1
  38. package/dist/cjs/lib/v3/llm/LLMProvider.d.ts +2 -2
  39. package/dist/cjs/lib/v3/llm/LLMProvider.js +1 -0
  40. package/dist/cjs/lib/v3/llm/LLMProvider.js.map +1 -1
  41. package/dist/cjs/lib/v3/llm/aisdk.js +4 -0
  42. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  43. package/dist/cjs/lib/v3/llm/anthropicOptions.d.ts +57 -0
  44. package/dist/cjs/lib/v3/llm/anthropicOptions.js +115 -0
  45. package/dist/cjs/lib/v3/llm/anthropicOptions.js.map +1 -0
  46. package/dist/cjs/lib/v3/types/public/agent.d.ts +10 -1
  47. package/dist/cjs/lib/v3/types/public/agent.js +2 -0
  48. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  49. package/dist/cjs/lib/v3/types/public/context.d.ts +7 -0
  50. package/dist/cjs/lib/v3/types/public/context.js.map +1 -1
  51. package/dist/cjs/lib/v3/types/public/model.d.ts +3 -2
  52. package/dist/cjs/lib/v3/types/public/model.js.map +1 -1
  53. package/dist/cjs/lib/v3/types/public/sdkErrors.d.ts +4 -0
  54. package/dist/cjs/lib/v3/types/public/sdkErrors.js +9 -1
  55. package/dist/cjs/lib/v3/types/public/sdkErrors.js.map +1 -1
  56. package/dist/cjs/lib/v3/understudy/cdp.d.ts +2 -0
  57. package/dist/cjs/lib/v3/understudy/cdp.js +26 -12
  58. package/dist/cjs/lib/v3/understudy/cdp.js.map +1 -1
  59. package/dist/cjs/lib/v3/understudy/context.d.ts +13 -1
  60. package/dist/cjs/lib/v3/understudy/context.js +284 -1
  61. package/dist/cjs/lib/v3/understudy/context.js.map +1 -1
  62. package/dist/cjs/lib/v3/understudy/domainPolicy.d.ts +25 -0
  63. package/dist/cjs/lib/v3/understudy/domainPolicy.js +162 -0
  64. package/dist/cjs/lib/v3/understudy/domainPolicy.js.map +1 -0
  65. package/dist/cjs/lib/v3/understudy/page.js +1 -1
  66. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  67. package/dist/cjs/lib/v3/v3.js +8 -2
  68. package/dist/cjs/lib/v3/v3.js.map +1 -1
  69. package/dist/cjs/lib/v3/verifier/errorTaxonomy.d.ts +35 -0
  70. package/dist/cjs/lib/v3/verifier/errorTaxonomy.js +291 -0
  71. package/dist/cjs/lib/v3/verifier/errorTaxonomy.js.map +1 -0
  72. package/dist/cjs/lib/v3/verifier/evidence.d.ts +44 -0
  73. package/dist/cjs/lib/v3/verifier/evidence.js +432 -0
  74. package/dist/cjs/lib/v3/verifier/evidence.js.map +1 -0
  75. package/dist/cjs/lib/v3/verifier/index.d.ts +1 -1
  76. package/dist/cjs/lib/v3/verifier/index.js.map +1 -1
  77. package/dist/cjs/lib/v3/verifier/prompts/batchedRelevance.d.ts +21 -0
  78. package/dist/cjs/lib/v3/verifier/prompts/batchedRelevance.js +71 -0
  79. package/dist/cjs/lib/v3/verifier/prompts/batchedRelevance.js.map +1 -0
  80. package/dist/cjs/lib/v3/verifier/prompts/firstPointOfFailure.d.ts +3 -0
  81. package/dist/cjs/lib/v3/verifier/prompts/firstPointOfFailure.js +166 -0
  82. package/dist/cjs/lib/v3/verifier/prompts/firstPointOfFailure.js.map +1 -0
  83. package/dist/cjs/lib/v3/verifier/prompts/fusedJudgment.d.ts +35 -0
  84. package/dist/cjs/lib/v3/verifier/prompts/fusedJudgment.js +158 -0
  85. package/dist/cjs/lib/v3/verifier/prompts/fusedJudgment.js.map +1 -0
  86. package/dist/cjs/lib/v3/verifier/prompts/fusedOutcome.d.ts +26 -0
  87. package/dist/cjs/lib/v3/verifier/prompts/fusedOutcome.js +137 -0
  88. package/dist/cjs/lib/v3/verifier/prompts/fusedOutcome.js.map +1 -0
  89. package/dist/cjs/lib/v3/verifier/prompts/index.d.ts +8 -0
  90. package/dist/cjs/lib/v3/verifier/prompts/index.js +22 -0
  91. package/dist/cjs/lib/v3/verifier/prompts/index.js.map +1 -0
  92. package/dist/cjs/lib/v3/verifier/prompts/perCriterionScore.d.ts +23 -0
  93. package/dist/cjs/lib/v3/verifier/prompts/perCriterionScore.js +77 -0
  94. package/dist/cjs/lib/v3/verifier/prompts/perCriterionScore.js.map +1 -0
  95. package/dist/cjs/lib/v3/verifier/prompts/render.d.ts +23 -0
  96. package/dist/cjs/lib/v3/verifier/prompts/render.js +45 -0
  97. package/dist/cjs/lib/v3/verifier/prompts/render.js.map +1 -0
  98. package/dist/cjs/lib/v3/verifier/prompts/rubricGeneration.d.ts +16 -0
  99. package/dist/cjs/lib/v3/verifier/prompts/rubricGeneration.js +321 -0
  100. package/dist/cjs/lib/v3/verifier/prompts/rubricGeneration.js.map +1 -0
  101. package/dist/cjs/lib/v3/verifier/prompts/taskValidity.d.ts +1 -0
  102. package/dist/cjs/lib/v3/verifier/prompts/taskValidity.js +116 -0
  103. package/dist/cjs/lib/v3/verifier/prompts/taskValidity.js.map +1 -0
  104. package/dist/cjs/lib/v3/verifier/rubricVerifier.d.ts +91 -0
  105. package/dist/cjs/lib/v3/verifier/rubricVerifier.js +1645 -0
  106. package/dist/cjs/lib/v3/verifier/rubricVerifier.js.map +1 -0
  107. package/dist/cjs/lib/v3/verifier/trajectory.d.ts +3 -3
  108. package/dist/cjs/lib/v3/verifier/trajectory.js +26 -26
  109. package/dist/cjs/lib/v3/verifier/trajectory.js.map +1 -1
  110. package/dist/cjs/lib/v3/verifier/types.d.ts +163 -15
  111. package/dist/cjs/lib/v3/verifier/types.js +0 -7
  112. package/dist/cjs/lib/v3/verifier/types.js.map +1 -1
  113. package/dist/cjs/lib/v3Evaluator.d.ts +5 -0
  114. package/dist/cjs/lib/v3Evaluator.js +47 -7
  115. package/dist/cjs/lib/v3Evaluator.js.map +1 -1
  116. package/dist/cjs/lib/version.d.ts +1 -1
  117. package/dist/cjs/lib/version.js +1 -1
  118. package/dist/cjs/lib/version.js.map +1 -1
  119. package/dist/esm/lib/utils.d.ts +6 -0
  120. package/dist/esm/lib/utils.js +10 -0
  121. package/dist/esm/lib/utils.js.map +1 -1
  122. package/dist/esm/lib/v3/agent/AgentClient.d.ts +2 -2
  123. package/dist/esm/lib/v3/agent/AgentClient.js.map +1 -1
  124. package/dist/esm/lib/v3/agent/AgentProvider.js +4 -3
  125. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  126. package/dist/esm/lib/v3/agent/AnthropicCUAClient.d.ts +4 -3
  127. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +21 -18
  128. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  129. package/dist/esm/lib/v3/agent/GoogleCUAClient.d.ts +12 -3
  130. package/dist/esm/lib/v3/agent/GoogleCUAClient.js +217 -36
  131. package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  132. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.d.ts +2 -2
  133. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js +2 -2
  134. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  135. package/dist/esm/lib/v3/agent/OpenAICUAClient.d.ts +6 -3
  136. package/dist/esm/lib/v3/agent/OpenAICUAClient.js +13 -7
  137. package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  138. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.d.ts +1 -0
  139. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js +49 -3
  140. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  141. package/dist/esm/lib/v3/cache/ActCache.js +2 -2
  142. package/dist/esm/lib/v3/cache/ActCache.js.map +1 -1
  143. package/dist/esm/lib/v3/cache/utils.d.ts +7 -0
  144. package/dist/esm/lib/v3/cache/utils.js +18 -0
  145. package/dist/esm/lib/v3/cache/utils.js.map +1 -1
  146. package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +2 -1
  147. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +55 -16
  148. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  149. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +32 -18
  150. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  151. package/dist/esm/lib/v3/index.d.ts +3 -2
  152. package/dist/esm/lib/v3/index.js.map +1 -1
  153. package/dist/esm/lib/v3/launch/local.js +1 -0
  154. package/dist/esm/lib/v3/launch/local.js.map +1 -1
  155. package/dist/esm/lib/v3/llm/LLMProvider.d.ts +2 -2
  156. package/dist/esm/lib/v3/llm/LLMProvider.js +1 -0
  157. package/dist/esm/lib/v3/llm/LLMProvider.js.map +1 -1
  158. package/dist/esm/lib/v3/llm/aisdk.js +4 -0
  159. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  160. package/dist/esm/lib/v3/llm/anthropicOptions.d.ts +57 -0
  161. package/dist/esm/lib/v3/llm/anthropicOptions.js +106 -0
  162. package/dist/esm/lib/v3/llm/anthropicOptions.js.map +1 -0
  163. package/dist/esm/lib/v3/types/public/agent.d.ts +10 -1
  164. package/dist/esm/lib/v3/types/public/agent.js +2 -0
  165. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  166. package/dist/esm/lib/v3/types/public/context.d.ts +7 -0
  167. package/dist/esm/lib/v3/types/public/context.js.map +1 -1
  168. package/dist/esm/lib/v3/types/public/model.d.ts +3 -2
  169. package/dist/esm/lib/v3/types/public/model.js.map +1 -1
  170. package/dist/esm/lib/v3/types/public/sdkErrors.d.ts +4 -0
  171. package/dist/esm/lib/v3/types/public/sdkErrors.js +7 -0
  172. package/dist/esm/lib/v3/types/public/sdkErrors.js.map +1 -1
  173. package/dist/esm/lib/v3/understudy/cdp.d.ts +2 -0
  174. package/dist/esm/lib/v3/understudy/cdp.js +26 -12
  175. package/dist/esm/lib/v3/understudy/cdp.js.map +1 -1
  176. package/dist/esm/lib/v3/understudy/context.d.ts +13 -1
  177. package/dist/esm/lib/v3/understudy/context.js +285 -2
  178. package/dist/esm/lib/v3/understudy/context.js.map +1 -1
  179. package/dist/esm/lib/v3/understudy/domainPolicy.d.ts +25 -0
  180. package/dist/esm/lib/v3/understudy/domainPolicy.js +158 -0
  181. package/dist/esm/lib/v3/understudy/domainPolicy.js.map +1 -0
  182. package/dist/esm/lib/v3/understudy/page.js +1 -1
  183. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  184. package/dist/esm/lib/v3/v3.js +8 -2
  185. package/dist/esm/lib/v3/v3.js.map +1 -1
  186. package/dist/esm/lib/v3/verifier/errorTaxonomy.d.ts +35 -0
  187. package/dist/esm/lib/v3/verifier/errorTaxonomy.js +285 -0
  188. package/dist/esm/lib/v3/verifier/errorTaxonomy.js.map +1 -0
  189. package/dist/esm/lib/v3/verifier/evidence.d.ts +44 -0
  190. package/dist/esm/lib/v3/verifier/evidence.js +393 -0
  191. package/dist/esm/lib/v3/verifier/evidence.js.map +1 -0
  192. package/dist/esm/lib/v3/verifier/index.d.ts +1 -1
  193. package/dist/esm/lib/v3/verifier/index.js.map +1 -1
  194. package/dist/esm/lib/v3/verifier/prompts/batchedRelevance.d.ts +21 -0
  195. package/dist/esm/lib/v3/verifier/prompts/batchedRelevance.js +68 -0
  196. package/dist/esm/lib/v3/verifier/prompts/batchedRelevance.js.map +1 -0
  197. package/dist/esm/lib/v3/verifier/prompts/firstPointOfFailure.d.ts +3 -0
  198. package/dist/esm/lib/v3/verifier/prompts/firstPointOfFailure.js +162 -0
  199. package/dist/esm/lib/v3/verifier/prompts/firstPointOfFailure.js.map +1 -0
  200. package/dist/esm/lib/v3/verifier/prompts/fusedJudgment.d.ts +35 -0
  201. package/dist/esm/lib/v3/verifier/prompts/fusedJudgment.js +155 -0
  202. package/dist/esm/lib/v3/verifier/prompts/fusedJudgment.js.map +1 -0
  203. package/dist/esm/lib/v3/verifier/prompts/fusedOutcome.d.ts +26 -0
  204. package/dist/esm/lib/v3/verifier/prompts/fusedOutcome.js +134 -0
  205. package/dist/esm/lib/v3/verifier/prompts/fusedOutcome.js.map +1 -0
  206. package/dist/esm/lib/v3/verifier/prompts/index.d.ts +8 -0
  207. package/dist/esm/lib/v3/verifier/prompts/index.js +9 -0
  208. package/dist/esm/lib/v3/verifier/prompts/index.js.map +1 -0
  209. package/dist/esm/lib/v3/verifier/prompts/perCriterionScore.d.ts +23 -0
  210. package/dist/esm/lib/v3/verifier/prompts/perCriterionScore.js +74 -0
  211. package/dist/esm/lib/v3/verifier/prompts/perCriterionScore.js.map +1 -0
  212. package/dist/esm/lib/v3/verifier/prompts/render.d.ts +23 -0
  213. package/dist/esm/lib/v3/verifier/prompts/render.js +41 -0
  214. package/dist/esm/lib/v3/verifier/prompts/render.js.map +1 -0
  215. package/dist/esm/lib/v3/verifier/prompts/rubricGeneration.d.ts +16 -0
  216. package/dist/esm/lib/v3/verifier/prompts/rubricGeneration.js +318 -0
  217. package/dist/esm/lib/v3/verifier/prompts/rubricGeneration.js.map +1 -0
  218. package/dist/esm/lib/v3/verifier/prompts/taskValidity.d.ts +1 -0
  219. package/dist/esm/lib/v3/verifier/prompts/taskValidity.js +113 -0
  220. package/dist/esm/lib/v3/verifier/prompts/taskValidity.js.map +1 -0
  221. package/dist/esm/lib/v3/verifier/rubricVerifier.d.ts +91 -0
  222. package/dist/esm/lib/v3/verifier/rubricVerifier.js +1640 -0
  223. package/dist/esm/lib/v3/verifier/rubricVerifier.js.map +1 -0
  224. package/dist/esm/lib/v3/verifier/trajectory.d.ts +3 -3
  225. package/dist/esm/lib/v3/verifier/trajectory.js +26 -26
  226. package/dist/esm/lib/v3/verifier/trajectory.js.map +1 -1
  227. package/dist/esm/lib/v3/verifier/types.d.ts +163 -15
  228. package/dist/esm/lib/v3/verifier/types.js +0 -7
  229. package/dist/esm/lib/v3/verifier/types.js.map +1 -1
  230. package/dist/esm/lib/v3Evaluator.d.ts +5 -0
  231. package/dist/esm/lib/v3Evaluator.js +47 -7
  232. package/dist/esm/lib/v3Evaluator.js.map +1 -1
  233. package/dist/esm/lib/version.d.ts +1 -1
  234. package/dist/esm/lib/version.js +1 -1
  235. package/dist/esm/lib/version.js.map +1 -1
  236. package/package.json +10 -10
  237. package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.d.ts +0 -24
  238. package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.js +0 -31
  239. package/dist/cjs/lib/v3/dom/build/selectorRuntime.generated.js.map +0 -1
  240. package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.d.ts +0 -24
  241. package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.js +0 -28
  242. package/dist/esm/lib/v3/dom/build/selectorRuntime.generated.js.map +0 -1
@@ -12,6 +12,11 @@ const clipboard_js_1 = require("./clipboard.js");
12
12
  const sdkErrors_js_1 = require("../types/public/sdkErrors.js");
13
13
  const timeoutConfig_js_1 = require("../timeoutConfig.js");
14
14
  const cookies_js_1 = require("./cookies.js");
15
+ const domainPolicy_js_1 = require("./domainPolicy.js");
16
+ function isMissingTargetError(error) {
17
+ const message = error instanceof Error ? error.message : String(error);
18
+ return /No target with given id found/i.test(message);
19
+ }
15
20
  /**
16
21
  * Returns true when the target's URL points to a document with a real,
17
22
  * pierceable HTML DOM. We allowlist the small set of schemes that carry
@@ -82,6 +87,7 @@ class V3Context {
82
87
  // Timestamp for most recent popup/open signal
83
88
  _lastPopupSignalAt = 0;
84
89
  _targetSessionListeners = new Set();
90
+ _domainPolicySessionListeners = new Map();
85
91
  _sessionInit = new Set();
86
92
  pagesByTarget = new Map();
87
93
  mainFrameToTarget = new Map();
@@ -92,8 +98,17 @@ class V3Context {
92
98
  typeByTarget = new Map();
93
99
  _pageOrder = [];
94
100
  pendingCreatedTargetUrl = new Map();
101
+ pageCreationFailures = new Map();
102
+ // Popup close attempts can race targetCreated, targetInfoChanged, and attached.
103
+ // In-flight promises let attach wait for a close result before deciding whether
104
+ // to skip normal setup. Successful closes stay deduped for the context lifetime
105
+ // because Chrome can emit late targetInfoChanged events after targetDestroyed.
106
+ // Failed closes are not retained so attach can continue and future events may retry.
107
+ domainPolicyClosingTargets = new Set();
108
+ domainPolicyClosePromises = new Map();
95
109
  initScripts = [];
96
110
  extraHttpHeaders = null;
111
+ domainPolicy = null;
97
112
  _clipboard;
98
113
  installTargetSessionListeners(session) {
99
114
  const sessionId = session.id;
@@ -332,6 +347,120 @@ class V3Context {
332
347
  throw new sdkErrors_js_1.StagehandSetExtraHTTPHeadersError(failures);
333
348
  }
334
349
  }
350
+ getDomainPolicy() {
351
+ if (!this.domainPolicy)
352
+ return null;
353
+ return {
354
+ ...(this.domainPolicy.allowedDomains.length
355
+ ? { allowedDomains: [...this.domainPolicy.allowedDomains] }
356
+ : {}),
357
+ ...(this.domainPolicy.blockedDomains.length
358
+ ? { blockedDomains: [...this.domainPolicy.blockedDomains] }
359
+ : {}),
360
+ };
361
+ }
362
+ async setDomainPolicy(policy) {
363
+ const nextPolicy = (0, domainPolicy_js_1.normalizeDomainPolicy)(policy);
364
+ this.domainPolicy = nextPolicy;
365
+ const sessions = [];
366
+ for (const sessionId of this._sessionInit) {
367
+ const session = this.conn.getSession(sessionId);
368
+ if (session)
369
+ sessions.push(session);
370
+ }
371
+ if (!sessions.length)
372
+ return;
373
+ const results = await Promise.allSettled(sessions.map(async (session) => {
374
+ if (!nextPolicy) {
375
+ try {
376
+ await session.send("Fetch.disable");
377
+ this.uninstallDomainPolicyHandler(session);
378
+ }
379
+ catch (error) {
380
+ throw { action: "disable", error };
381
+ }
382
+ return;
383
+ }
384
+ this.installDomainPolicyHandler(session);
385
+ try {
386
+ await session.send("Fetch.enable", {
387
+ patterns: nextPolicy.fetchPatterns,
388
+ });
389
+ }
390
+ catch (error) {
391
+ throw { action: "enable", error };
392
+ }
393
+ }));
394
+ const failures = results
395
+ .map((result, index) => ({ result, session: sessions[index] }))
396
+ .filter((entry) => entry.result.status === "rejected")
397
+ .map((entry) => {
398
+ const failure = entry.result.reason;
399
+ if (failure?.action === "enable") {
400
+ this.uninstallDomainPolicyHandler(entry.session);
401
+ }
402
+ const reason = failure?.error ?? entry.result.reason;
403
+ const sid = entry.session.id ?? "unknown";
404
+ const message = reason instanceof Error ? reason.message : String(reason);
405
+ return `session=${sid} error=${message}`;
406
+ });
407
+ if (failures.length) {
408
+ throw new sdkErrors_js_1.StagehandSetDomainPolicyError(failures);
409
+ }
410
+ }
411
+ installDomainPolicyHandler(session) {
412
+ const sessionId = session.id;
413
+ if (!sessionId)
414
+ return;
415
+ if (this._domainPolicySessionListeners.has(sessionId))
416
+ return;
417
+ const handler = (evt) => {
418
+ void this.handleDomainPolicyRequestPaused(session, evt);
419
+ };
420
+ this._domainPolicySessionListeners.set(sessionId, handler);
421
+ session.on("Fetch.requestPaused", handler);
422
+ }
423
+ uninstallDomainPolicyHandler(session) {
424
+ const sessionId = session.id;
425
+ if (!sessionId)
426
+ return;
427
+ const handler = this._domainPolicySessionListeners.get(sessionId);
428
+ if (!handler)
429
+ return;
430
+ session.off("Fetch.requestPaused", handler);
431
+ this._domainPolicySessionListeners.delete(sessionId);
432
+ }
433
+ async handleDomainPolicyRequestPaused(session, evt) {
434
+ const decision = (0, domainPolicy_js_1.getDomainPolicyDecision)(evt.request.url, this.domainPolicy);
435
+ if (decision.action === "continue") {
436
+ await session
437
+ .send("Fetch.continueRequest", { requestId: evt.requestId })
438
+ .catch(() => { });
439
+ return;
440
+ }
441
+ let hostname = "";
442
+ try {
443
+ hostname = new URL(evt.request.url).hostname.toLowerCase();
444
+ }
445
+ catch {
446
+ // ignore malformed URLs for logging
447
+ }
448
+ (0, logger_js_1.v3Logger)({
449
+ category: "network",
450
+ message: "Blocked request by domain policy",
451
+ level: 2,
452
+ auxiliary: {
453
+ hostname: { value: hostname, type: "string" },
454
+ ruleType: { value: decision.reason, type: "string" },
455
+ },
456
+ });
457
+ await session
458
+ .send("Fetch.failRequest", {
459
+ requestId: evt.requestId,
460
+ errorReason: "BlockedByClient",
461
+ })
462
+ .catch(() => { });
463
+ }
335
464
  get clipboard() {
336
465
  return (this._clipboard ??= new clipboard_js_1.ContextClipboard({
337
466
  context: this,
@@ -400,6 +529,12 @@ class V3Context {
400
529
  await this.conn.send("Target.activateTarget", { targetId }).catch(() => { });
401
530
  const deadline = Date.now() + 5000;
402
531
  while (Date.now() < deadline) {
532
+ const failure = this.pageCreationFailures.get(targetId);
533
+ if (failure) {
534
+ this.pageCreationFailures.delete(targetId);
535
+ this.pendingCreatedTargetUrl.delete(targetId);
536
+ throw failure;
537
+ }
403
538
  const page = this.pagesByTarget.get(targetId);
404
539
  if (page) {
405
540
  // we created at about:blank; navigate only after attach so init scripts run
@@ -415,6 +550,7 @@ class V3Context {
415
550
  }
416
551
  await new Promise((r) => setTimeout(r, 25));
417
552
  }
553
+ this.pendingCreatedTargetUrl.delete(targetId);
418
554
  throw new sdkErrors_js_1.TimeoutError(`newPage: target not attached (${targetId})`, 5000);
419
555
  }
420
556
  /**
@@ -430,6 +566,9 @@ class V3Context {
430
566
  this.createdAtByTarget.clear();
431
567
  this.typeByTarget.clear();
432
568
  this.pendingCreatedTargetUrl.clear();
569
+ this.pageCreationFailures.clear();
570
+ this.domainPolicyClosingTargets.clear();
571
+ this.domainPolicyClosePromises.clear();
433
572
  }
434
573
  /**
435
574
  * Bootstrap target lifecycle:
@@ -456,8 +595,12 @@ class V3Context {
456
595
  const ti = info;
457
596
  if (info.type === "page" && (ti?.openerId || ti?.openerFrameId)) {
458
597
  this._notePopupSignal();
598
+ void this.closePopupIfBlockedByDomainPolicy(info, "targetCreated");
459
599
  }
460
600
  });
601
+ this.conn.on("Target.targetInfoChanged", (evt) => {
602
+ void this.closePopupIfBlockedByDomainPolicy(evt.targetInfo, "targetInfoChanged");
603
+ });
461
604
  // Only enable auto-attach after listeners are ready so replayed targets are captured.
462
605
  await this.conn.enableAutoAttach();
463
606
  const targets = await this.conn.getTargets();
@@ -485,6 +628,9 @@ class V3Context {
485
628
  * - Resume the target only after listeners are wired.
486
629
  */
487
630
  async onAttachedToTarget(info, sessionId) {
631
+ if (await this.closePopupIfBlockedByDomainPolicy(info, "attached")) {
632
+ return;
633
+ }
488
634
  // Skip non-web targets (workers, chrome extensions, background pages, etc.).
489
635
  // They still need to be resumed so we don't leave them paused by
490
636
  // waitForDebuggerOnStart, but injecting the piercer into these targets
@@ -536,6 +682,24 @@ class V3Context {
536
682
  .catch(() => false);
537
683
  return { dispatched, response };
538
684
  };
685
+ const queueFetchEnablePreResume = (params) => {
686
+ let error;
687
+ const dispatched = this.conn
688
+ .waitForSessionDispatch(sessionId, "Fetch.enable")
689
+ .then(() => true)
690
+ .catch((err) => {
691
+ error = err;
692
+ return false;
693
+ });
694
+ const response = session
695
+ .send("Fetch.enable", params)
696
+ .then(() => true)
697
+ .catch((err) => {
698
+ error = err;
699
+ return false;
700
+ });
701
+ return { dispatched, response, getError: () => error };
702
+ };
539
703
  const initScriptOps = [];
540
704
  // Pre-resume ordering matters:
541
705
  // - enable domains;
@@ -557,6 +721,13 @@ class V3Context {
557
721
  headerPreResumeOps.push(queuePreResume("Network.enable"));
558
722
  headerPreResumeOps.push(queuePreResume("Network.setExtraHTTPHeaders", { headers }));
559
723
  }
724
+ const fetchPreResumeOps = [];
725
+ if (this.domainPolicy) {
726
+ this.installDomainPolicyHandler(session);
727
+ fetchPreResumeOps.push(queueFetchEnablePreResume({
728
+ patterns: this.domainPolicy.fetchPatterns,
729
+ }));
730
+ }
560
731
  // Send init scripts only after auto-attach has been queued.
561
732
  if (this.initScripts.length) {
562
733
  for (const source of this.initScripts) {
@@ -575,6 +746,7 @@ class V3Context {
575
746
  const preResumeDispatched = (await Promise.all([
576
747
  ...corePreResumeOps.map((op) => op.dispatched),
577
748
  ...headerPreResumeOps.map((op) => op.dispatched),
749
+ ...fetchPreResumeOps.map((op) => op.dispatched),
578
750
  ...initScriptOps.map((op) => op.dispatched),
579
751
  piercerPreloadOp.dispatched,
580
752
  ])).every(Boolean);
@@ -584,9 +756,10 @@ class V3Context {
584
756
  resumeOp.dispatched,
585
757
  resumeOp.response,
586
758
  ]);
587
- const [coreResults, headerResults, initScriptResults, piercerPreRegistered,] = await Promise.all([
759
+ const [coreResults, headerResults, fetchResults, initScriptResults, piercerPreRegistered,] = await Promise.all([
588
760
  Promise.all(corePreResumeOps.map((op) => op.response)),
589
761
  Promise.all(headerPreResumeOps.map((op) => op.response)),
762
+ Promise.all(fetchPreResumeOps.map((op) => op.response)),
590
763
  Promise.all(initScriptOps.map((op) => op.response)),
591
764
  piercerPreloadOp.response,
592
765
  ]);
@@ -619,6 +792,40 @@ class V3Context {
619
792
  return;
620
793
  }
621
794
  resumed = true;
795
+ if (fetchPreResumeOps.length > 0 && !fetchResults.every(Boolean)) {
796
+ this.uninstallDomainPolicyHandler(session);
797
+ const fetchError = fetchPreResumeOps
798
+ .map((op) => op.getError())
799
+ .find((error) => error !== undefined);
800
+ const fetchErrorMessage = fetchError
801
+ ? fetchError instanceof Error
802
+ ? fetchError.message
803
+ : String(fetchError)
804
+ : "Fetch.enable failed during target attach";
805
+ const policyFailureMessage = "Fetch.enable failed during target attach; closing target because " +
806
+ "Stagehand cannot guarantee domain policy enforcement";
807
+ if (this.pendingCreatedTargetUrl.has(info.targetId)) {
808
+ this.pageCreationFailures.set(info.targetId, new sdkErrors_js_1.StagehandSetDomainPolicyError([
809
+ `session=${sessionId} target=${info.targetId} error=${policyFailureMessage} cdpError=${fetchErrorMessage}`,
810
+ ]));
811
+ }
812
+ (0, logger_js_1.v3Logger)({
813
+ category: "ctx",
814
+ message: "Closing target because domain policy could not be guaranteed",
815
+ level: 0,
816
+ auxiliary: {
817
+ targetId: { value: String(info.targetId), type: "string" },
818
+ targetType: { value: String(info.type), type: "string" },
819
+ targetUrl: { value: String(info.url ?? ""), type: "string" },
820
+ sessionId: { value: sessionId, type: "string" },
821
+ cdpError: { value: fetchErrorMessage, type: "string" },
822
+ },
823
+ });
824
+ await this.conn
825
+ .send("Target.closeTarget", { targetId: info.targetId })
826
+ .catch(() => { });
827
+ return;
828
+ }
622
829
  const scriptsInstalled = coreResults.every(Boolean) && initScriptResults.every(Boolean);
623
830
  try {
624
831
  // Best-effort lifecycle events; do not block top-level page registration
@@ -734,6 +941,74 @@ class V3Context {
734
941
  await resume();
735
942
  }
736
943
  }
944
+ async closePopupIfBlockedByDomainPolicy(info, source) {
945
+ if (!this.domainPolicy || !isTopLevelPage(info))
946
+ return false;
947
+ if (!info.openerId && !info.openerFrameId)
948
+ return false;
949
+ if (this.domainPolicyClosingTargets.has(info.targetId))
950
+ return true;
951
+ const existingClose = this.domainPolicyClosePromises.get(info.targetId);
952
+ if (existingClose) {
953
+ return source === "attached" ? await existingClose : true;
954
+ }
955
+ const decision = (0, domainPolicy_js_1.getDomainPolicyDecision)(info.url ?? "", this.domainPolicy);
956
+ if (decision.action === "continue")
957
+ return false;
958
+ (0, logger_js_1.v3Logger)({
959
+ category: "network",
960
+ message: "Popup reached a disallowed domain before it could be intercepted; closing it",
961
+ level: 2,
962
+ auxiliary: {
963
+ targetId: { value: String(info.targetId), type: "string" },
964
+ targetUrl: { value: String(info.url ?? ""), type: "string" },
965
+ openerId: { value: String(info.openerId ?? ""), type: "string" },
966
+ openerFrameId: {
967
+ value: String(info.openerFrameId ?? ""),
968
+ type: "string",
969
+ },
970
+ ruleType: { value: decision.reason, type: "string" },
971
+ source: { value: source, type: "string" },
972
+ },
973
+ });
974
+ const closePromise = this.closeTargetAfterDomainPolicyViolation(info, {
975
+ failureMessage: "Failed to close popup after it reached a disallowed domain",
976
+ }).then((closed) => {
977
+ this.domainPolicyClosePromises.delete(info.targetId);
978
+ if (closed) {
979
+ this.domainPolicyClosingTargets.add(info.targetId);
980
+ }
981
+ return closed;
982
+ });
983
+ this.domainPolicyClosePromises.set(info.targetId, closePromise);
984
+ return await closePromise;
985
+ }
986
+ async closeTargetAfterDomainPolicyViolation(info, opts) {
987
+ try {
988
+ await this.conn.send("Target.closeTarget", { targetId: info.targetId });
989
+ return true;
990
+ }
991
+ catch (error) {
992
+ if (isMissingTargetError(error)) {
993
+ return true;
994
+ }
995
+ (0, logger_js_1.v3Logger)({
996
+ category: "network",
997
+ message: opts.failureMessage,
998
+ level: 0,
999
+ auxiliary: {
1000
+ targetId: { value: String(info.targetId), type: "string" },
1001
+ targetType: { value: String(info.type), type: "string" },
1002
+ targetUrl: { value: String(info.url ?? ""), type: "string" },
1003
+ error: {
1004
+ value: error instanceof Error ? error.message : String(error),
1005
+ type: "string",
1006
+ },
1007
+ },
1008
+ });
1009
+ return false;
1010
+ }
1011
+ }
737
1012
  /**
738
1013
  * Detach handler:
739
1014
  * - Remove child session ownership and prune its subtree.
@@ -754,6 +1029,13 @@ class V3Context {
754
1029
  this.pendingOopifByMainFrame.delete(fid);
755
1030
  }
756
1031
  this._targetSessionListeners.delete(sessionId);
1032
+ const session = this.conn.getSession(sessionId);
1033
+ if (session) {
1034
+ this.uninstallDomainPolicyHandler(session);
1035
+ }
1036
+ else {
1037
+ this._domainPolicySessionListeners.delete(sessionId);
1038
+ }
757
1039
  this._sessionInit.delete(sessionId);
758
1040
  this._piercerInstalled.delete(sessionId);
759
1041
  }
@@ -764,6 +1046,7 @@ class V3Context {
764
1046
  const page = this.pagesByTarget.get(targetId);
765
1047
  if (!page)
766
1048
  return;
1049
+ this.pageCreationFailures.delete(targetId);
767
1050
  const mainId = page.mainFrameId();
768
1051
  this.mainFrameToTarget.delete(mainId);
769
1052
  this.frameOwnerPage.delete(mainId);