@bctrl/sdk 1.0.1 → 1.0.2

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 (279) hide show
  1. package/README.md +24 -29
  2. package/dist/bctrl.d.ts +22 -36
  3. package/dist/bctrl.js +40 -75
  4. package/dist/browsers.d.ts +24 -0
  5. package/dist/browsers.js +82 -0
  6. package/dist/errors.d.ts +49 -43
  7. package/dist/errors.js +83 -120
  8. package/dist/files.d.ts +31 -0
  9. package/dist/files.js +97 -0
  10. package/dist/http.d.ts +18 -0
  11. package/dist/http.js +135 -0
  12. package/dist/index.d.ts +9 -12
  13. package/dist/index.js +8 -23
  14. package/dist/invocations.d.ts +24 -0
  15. package/dist/invocations.js +66 -0
  16. package/dist/pagination.d.ts +2 -0
  17. package/dist/pagination.js +13 -0
  18. package/dist/runs.d.ts +38 -0
  19. package/dist/runs.js +99 -0
  20. package/dist/runtimes.d.ts +73 -0
  21. package/dist/runtimes.js +205 -0
  22. package/dist/spaces.d.ts +41 -0
  23. package/dist/spaces.js +96 -0
  24. package/dist/types.d.ts +386 -0
  25. package/dist/types.js +1 -0
  26. package/dist/utils.d.ts +4 -0
  27. package/dist/utils.js +27 -0
  28. package/dist/version.js +2 -2
  29. package/package.json +12 -31
  30. package/dist/agents/browser-use/index.d.ts +0 -1
  31. package/dist/agents/browser-use/index.js +0 -9
  32. package/dist/agents/browser-use/namespace.d.ts +0 -39
  33. package/dist/agents/browser-use/namespace.js +0 -93
  34. package/dist/agents/index.d.ts +0 -2
  35. package/dist/agents/index.js +0 -17
  36. package/dist/agents/stagehand/core.d.ts +0 -93
  37. package/dist/agents/stagehand/core.js +0 -144
  38. package/dist/agents/stagehand/index.d.ts +0 -3
  39. package/dist/agents/stagehand/index.js +0 -24
  40. package/dist/agents/stagehand/namespace.d.ts +0 -51
  41. package/dist/agents/stagehand/namespace.js +0 -65
  42. package/dist/ai-credentials/client.d.ts +0 -12
  43. package/dist/ai-credentials/client.js +0 -70
  44. package/dist/ai-credentials/index.d.ts +0 -1
  45. package/dist/ai-credentials/index.js +0 -1
  46. package/dist/base/event-binding.d.ts +0 -7
  47. package/dist/base/event-binding.js +0 -23
  48. package/dist/base/types.d.ts +0 -109
  49. package/dist/base/types.js +0 -4
  50. package/dist/browser-extensions/client.d.ts +0 -15
  51. package/dist/browser-extensions/client.js +0 -72
  52. package/dist/browser-extensions/index.d.ts +0 -2
  53. package/dist/browser-extensions/index.js +0 -1
  54. package/dist/browser-profiles/client.d.ts +0 -11
  55. package/dist/browser-profiles/client.js +0 -63
  56. package/dist/browser-profiles/index.d.ts +0 -1
  57. package/dist/browser-profiles/index.js +0 -1
  58. package/dist/captcha/index.d.ts +0 -1
  59. package/dist/captcha/index.js +0 -1
  60. package/dist/captcha/namespace.d.ts +0 -34
  61. package/dist/captcha/namespace.js +0 -41
  62. package/dist/client/index.d.ts +0 -1
  63. package/dist/client/index.js +0 -1
  64. package/dist/client/rpc.d.ts +0 -83
  65. package/dist/client/rpc.js +0 -354
  66. package/dist/config.d.ts +0 -5
  67. package/dist/config.js +0 -28
  68. package/dist/constants/browser.d.ts +0 -2
  69. package/dist/constants/browser.js +0 -1
  70. package/dist/contracts/agent-tools.d.ts +0 -45
  71. package/dist/contracts/agent-tools.js +0 -31
  72. package/dist/contracts/automation.d.ts +0 -265
  73. package/dist/contracts/automation.js +0 -109
  74. package/dist/contracts/browser-management.d.ts +0 -179
  75. package/dist/contracts/browser-management.js +0 -95
  76. package/dist/contracts/browser-use.d.ts +0 -136
  77. package/dist/contracts/browser-use.js +0 -93
  78. package/dist/contracts/captcha.d.ts +0 -114
  79. package/dist/contracts/captcha.js +0 -40
  80. package/dist/contracts/desktop.d.ts +0 -223
  81. package/dist/contracts/desktop.js +0 -121
  82. package/dist/contracts/drivers/playwright.d.ts +0 -2008
  83. package/dist/contracts/drivers/playwright.js +0 -2033
  84. package/dist/contracts/drivers/puppeteer.d.ts +0 -1221
  85. package/dist/contracts/drivers/puppeteer.js +0 -941
  86. package/dist/contracts/drivers/selenium.d.ts +0 -156
  87. package/dist/contracts/drivers/selenium.js +0 -61
  88. package/dist/contracts/drivers/stagehand.d.ts +0 -155
  89. package/dist/contracts/drivers/stagehand.js +0 -7
  90. package/dist/contracts/extensions.d.ts +0 -13
  91. package/dist/contracts/extensions.js +0 -9
  92. package/dist/contracts/index.d.ts +0 -13
  93. package/dist/contracts/index.js +0 -13
  94. package/dist/contracts/public-api.d.ts +0 -360
  95. package/dist/contracts/public-api.js +0 -17
  96. package/dist/contracts/runtime.d.ts +0 -81
  97. package/dist/contracts/runtime.js +0 -16
  98. package/dist/contracts/stagehand.d.ts +0 -253
  99. package/dist/contracts/stagehand.js +0 -145
  100. package/dist/contracts/storage.d.ts +0 -51
  101. package/dist/contracts/storage.js +0 -56
  102. package/dist/contracts/vault.d.ts +0 -119
  103. package/dist/contracts/vault.js +0 -112
  104. package/dist/contracts/version.d.ts +0 -3
  105. package/dist/contracts/version.js +0 -16
  106. package/dist/desktop.d.ts +0 -2
  107. package/dist/desktop.js +0 -3
  108. package/dist/drivers/desktop/index.d.ts +0 -65
  109. package/dist/drivers/desktop/index.js +0 -68
  110. package/dist/drivers/desktop/session.d.ts +0 -313
  111. package/dist/drivers/desktop/session.js +0 -432
  112. package/dist/drivers/playwright/event-emitter.d.ts +0 -160
  113. package/dist/drivers/playwright/event-emitter.js +0 -297
  114. package/dist/drivers/playwright/generated/api-request-context.d.ts +0 -137
  115. package/dist/drivers/playwright/generated/api-request-context.js +0 -154
  116. package/dist/drivers/playwright/generated/api-response.d.ts +0 -119
  117. package/dist/drivers/playwright/generated/api-response.js +0 -123
  118. package/dist/drivers/playwright/generated/browser-context.d.ts +0 -284
  119. package/dist/drivers/playwright/generated/browser-context.js +0 -458
  120. package/dist/drivers/playwright/generated/browser.d.ts +0 -120
  121. package/dist/drivers/playwright/generated/browser.js +0 -151
  122. package/dist/drivers/playwright/generated/clock.d.ts +0 -80
  123. package/dist/drivers/playwright/generated/clock.js +0 -94
  124. package/dist/drivers/playwright/generated/console-message.d.ts +0 -94
  125. package/dist/drivers/playwright/generated/console-message.js +0 -89
  126. package/dist/drivers/playwright/generated/coverage.d.ts +0 -57
  127. package/dist/drivers/playwright/generated/coverage.js +0 -66
  128. package/dist/drivers/playwright/generated/dialog.d.ts +0 -79
  129. package/dist/drivers/playwright/generated/dialog.js +0 -80
  130. package/dist/drivers/playwright/generated/element-handle.d.ts +0 -399
  131. package/dist/drivers/playwright/generated/element-handle.js +0 -501
  132. package/dist/drivers/playwright/generated/frame-locator.d.ts +0 -34
  133. package/dist/drivers/playwright/generated/frame-locator.js +0 -63
  134. package/dist/drivers/playwright/generated/frame.d.ts +0 -557
  135. package/dist/drivers/playwright/generated/frame.js +0 -634
  136. package/dist/drivers/playwright/generated/js-handle.d.ts +0 -72
  137. package/dist/drivers/playwright/generated/js-handle.js +0 -92
  138. package/dist/drivers/playwright/generated/keyboard.d.ts +0 -103
  139. package/dist/drivers/playwright/generated/keyboard.js +0 -113
  140. package/dist/drivers/playwright/generated/locator.d.ts +0 -795
  141. package/dist/drivers/playwright/generated/locator.js +0 -974
  142. package/dist/drivers/playwright/generated/mouse.d.ts +0 -97
  143. package/dist/drivers/playwright/generated/mouse.js +0 -109
  144. package/dist/drivers/playwright/generated/page.d.ts +0 -762
  145. package/dist/drivers/playwright/generated/page.js +0 -988
  146. package/dist/drivers/playwright/generated/touchscreen.d.ts +0 -34
  147. package/dist/drivers/playwright/generated/touchscreen.js +0 -37
  148. package/dist/drivers/playwright/generated/tracing.d.ts +0 -78
  149. package/dist/drivers/playwright/generated/tracing.js +0 -80
  150. package/dist/drivers/playwright/generated/worker.d.ts +0 -53
  151. package/dist/drivers/playwright/generated/worker.js +0 -59
  152. package/dist/drivers/playwright/index.d.ts +0 -19
  153. package/dist/drivers/playwright/index.js +0 -20
  154. package/dist/drivers/playwright/remote-base.d.ts +0 -62
  155. package/dist/drivers/playwright/remote-base.js +0 -86
  156. package/dist/drivers/playwright/types.d.ts +0 -148
  157. package/dist/drivers/playwright/types.js +0 -8
  158. package/dist/drivers/puppeteer/errors.d.ts +0 -50
  159. package/dist/drivers/puppeteer/errors.js +0 -71
  160. package/dist/drivers/puppeteer/event-emitter.d.ts +0 -145
  161. package/dist/drivers/puppeteer/event-emitter.js +0 -259
  162. package/dist/drivers/puppeteer/generated/accessibility.d.ts +0 -77
  163. package/dist/drivers/puppeteer/generated/accessibility.js +0 -74
  164. package/dist/drivers/puppeteer/generated/browser-context.d.ts +0 -116
  165. package/dist/drivers/puppeteer/generated/browser-context.js +0 -168
  166. package/dist/drivers/puppeteer/generated/browser.d.ts +0 -169
  167. package/dist/drivers/puppeteer/generated/browser.js +0 -246
  168. package/dist/drivers/puppeteer/generated/console-message.d.ts +0 -54
  169. package/dist/drivers/puppeteer/generated/console-message.js +0 -69
  170. package/dist/drivers/puppeteer/generated/coverage.d.ts +0 -49
  171. package/dist/drivers/puppeteer/generated/coverage.js +0 -57
  172. package/dist/drivers/puppeteer/generated/dialog.d.ts +0 -46
  173. package/dist/drivers/puppeteer/generated/dialog.js +0 -60
  174. package/dist/drivers/puppeteer/generated/element-handle.d.ts +0 -261
  175. package/dist/drivers/puppeteer/generated/element-handle.js +0 -341
  176. package/dist/drivers/puppeteer/generated/file-chooser.d.ts +0 -34
  177. package/dist/drivers/puppeteer/generated/file-chooser.js +0 -43
  178. package/dist/drivers/puppeteer/generated/frame.d.ts +0 -221
  179. package/dist/drivers/puppeteer/generated/frame.js +0 -302
  180. package/dist/drivers/puppeteer/generated/http-request.d.ts +0 -195
  181. package/dist/drivers/puppeteer/generated/http-request.js +0 -243
  182. package/dist/drivers/puppeteer/generated/http-response.d.ts +0 -142
  183. package/dist/drivers/puppeteer/generated/http-response.js +0 -169
  184. package/dist/drivers/puppeteer/generated/js-handle.d.ts +0 -104
  185. package/dist/drivers/puppeteer/generated/js-handle.js +0 -125
  186. package/dist/drivers/puppeteer/generated/keyboard.d.ts +0 -79
  187. package/dist/drivers/puppeteer/generated/keyboard.js +0 -89
  188. package/dist/drivers/puppeteer/generated/locator.d.ts +0 -141
  189. package/dist/drivers/puppeteer/generated/locator.js +0 -164
  190. package/dist/drivers/puppeteer/generated/mouse.d.ts +0 -74
  191. package/dist/drivers/puppeteer/generated/mouse.js +0 -94
  192. package/dist/drivers/puppeteer/generated/page.d.ts +0 -604
  193. package/dist/drivers/puppeteer/generated/page.js +0 -776
  194. package/dist/drivers/puppeteer/generated/target.d.ts +0 -105
  195. package/dist/drivers/puppeteer/generated/target.js +0 -123
  196. package/dist/drivers/puppeteer/generated/touchscreen.d.ts +0 -87
  197. package/dist/drivers/puppeteer/generated/touchscreen.js +0 -103
  198. package/dist/drivers/puppeteer/generated/tracing.d.ts +0 -38
  199. package/dist/drivers/puppeteer/generated/tracing.js +0 -43
  200. package/dist/drivers/puppeteer/generated/web-worker.d.ts +0 -63
  201. package/dist/drivers/puppeteer/generated/web-worker.js +0 -73
  202. package/dist/drivers/puppeteer/index.d.ts +0 -21
  203. package/dist/drivers/puppeteer/index.js +0 -23
  204. package/dist/drivers/puppeteer/remote-base.d.ts +0 -57
  205. package/dist/drivers/puppeteer/remote-base.js +0 -79
  206. package/dist/drivers/puppeteer/types.d.ts +0 -178
  207. package/dist/drivers/puppeteer/types.js +0 -8
  208. package/dist/drivers/selenium/driver.d.ts +0 -28
  209. package/dist/drivers/selenium/driver.js +0 -169
  210. package/dist/drivers/selenium/element.d.ts +0 -34
  211. package/dist/drivers/selenium/element.js +0 -73
  212. package/dist/drivers/selenium/index.d.ts +0 -3
  213. package/dist/drivers/selenium/index.js +0 -5
  214. package/dist/drivers/selenium/types.d.ts +0 -2
  215. package/dist/drivers/selenium/types.js +0 -12
  216. package/dist/drivers/stagehand/generated/context.d.ts +0 -127
  217. package/dist/drivers/stagehand/generated/context.js +0 -153
  218. package/dist/drivers/stagehand/generated/locator.d.ts +0 -324
  219. package/dist/drivers/stagehand/generated/locator.js +0 -368
  220. package/dist/drivers/stagehand/generated/page.d.ts +0 -377
  221. package/dist/drivers/stagehand/generated/page.js +0 -439
  222. package/dist/drivers/stagehand/generated/response.d.ts +0 -197
  223. package/dist/drivers/stagehand/generated/response.js +0 -232
  224. package/dist/drivers/stagehand/index.d.ts +0 -5
  225. package/dist/drivers/stagehand/index.js +0 -8
  226. package/dist/drivers/stagehand/types.d.ts +0 -1
  227. package/dist/drivers/stagehand/types.js +0 -7
  228. package/dist/extensions/client.d.ts +0 -47
  229. package/dist/extensions/client.js +0 -154
  230. package/dist/extensions/index.d.ts +0 -1
  231. package/dist/extensions/index.js +0 -1
  232. package/dist/internal/dev-client.d.ts +0 -5
  233. package/dist/internal/dev-client.js +0 -9
  234. package/dist/internal/rpc-targets.d.ts +0 -17
  235. package/dist/internal/rpc-targets.js +0 -58
  236. package/dist/internal/serialization.d.ts +0 -32
  237. package/dist/internal/serialization.js +0 -42
  238. package/dist/internal/transport.d.ts +0 -24
  239. package/dist/internal/transport.js +0 -29
  240. package/dist/playwright.d.ts +0 -1
  241. package/dist/playwright.js +0 -2
  242. package/dist/puppeteer.d.ts +0 -1
  243. package/dist/puppeteer.js +0 -2
  244. package/dist/selenium.d.ts +0 -1
  245. package/dist/selenium.js +0 -2
  246. package/dist/stagehand.d.ts +0 -1
  247. package/dist/stagehand.js +0 -2
  248. package/dist/storage/client.d.ts +0 -151
  249. package/dist/storage/client.js +0 -329
  250. package/dist/storage/index.d.ts +0 -2
  251. package/dist/storage/index.js +0 -4
  252. package/dist/telemetry.d.ts +0 -18
  253. package/dist/telemetry.js +0 -93
  254. package/dist/updates/client.d.ts +0 -8
  255. package/dist/updates/client.js +0 -128
  256. package/dist/updates/index.d.ts +0 -1
  257. package/dist/updates/index.js +0 -1
  258. package/dist/utils/http.d.ts +0 -39
  259. package/dist/utils/http.js +0 -88
  260. package/dist/utils/index.d.ts +0 -4
  261. package/dist/utils/index.js +0 -4
  262. package/dist/utils/logger.d.ts +0 -27
  263. package/dist/utils/logger.js +0 -74
  264. package/dist/utils/schema.d.ts +0 -17
  265. package/dist/utils/schema.js +0 -31
  266. package/dist/utils/url.d.ts +0 -5
  267. package/dist/utils/url.js +0 -7
  268. package/dist/vault/client.d.ts +0 -43
  269. package/dist/vault/client.js +0 -123
  270. package/dist/vault/index.d.ts +0 -1
  271. package/dist/vault/index.js +0 -1
  272. package/dist/workspaces/browser-runtime.d.ts +0 -251
  273. package/dist/workspaces/browser-runtime.js +0 -1025
  274. package/dist/workspaces/client.d.ts +0 -48
  275. package/dist/workspaces/client.js +0 -222
  276. package/dist/workspaces/index.d.ts +0 -2
  277. package/dist/workspaces/index.js +0 -2
  278. package/dist/workspaces/runtime-event-pump.d.ts +0 -65
  279. package/dist/workspaces/runtime-event-pump.js +0 -716
@@ -1,1025 +0,0 @@
1
- import { getRemoteListenerBinding } from '../base/event-binding.js';
2
- import { CaptchaNamespace } from '../captcha/namespace.js';
3
- import { fromErrorResponse } from '../errors.js';
4
- import { CONTEXT_REF_TARGETS, HANDLE_TARGETS, PAGE_REF_TARGETS } from '../internal/rpc-targets.js';
5
- import { fetchWithTimeout, parseErrorDetails, parseJsonResponse } from '../utils/http.js';
6
- import { SDK_VERSION } from '../version.js';
7
- import { StagehandCore } from '../agents/stagehand/core.js';
8
- import { RemotePlaywrightBrowser } from '../drivers/playwright/generated/browser.js';
9
- import { RemotePlaywrightBrowserContext } from '../drivers/playwright/generated/browser-context.js';
10
- import { RemotePlaywrightElementHandle } from '../drivers/playwright/generated/element-handle.js';
11
- import { RemotePlaywrightFrame } from '../drivers/playwright/generated/frame.js';
12
- import { RemotePlaywrightFrameLocator } from '../drivers/playwright/generated/frame-locator.js';
13
- import { RemotePlaywrightJSHandle } from '../drivers/playwright/generated/js-handle.js';
14
- import { RemotePlaywrightLocator } from '../drivers/playwright/generated/locator.js';
15
- import { RemotePlaywrightPage } from '../drivers/playwright/generated/page.js';
16
- import { RemotePuppeteerBrowser } from '../drivers/puppeteer/generated/browser.js';
17
- import { RemotePuppeteerBrowserContext } from '../drivers/puppeteer/generated/browser-context.js';
18
- import { RemotePuppeteerElementHandle } from '../drivers/puppeteer/generated/element-handle.js';
19
- import { RemotePuppeteerFrame } from '../drivers/puppeteer/generated/frame.js';
20
- import { RemotePuppeteerJSHandle } from '../drivers/puppeteer/generated/js-handle.js';
21
- import { RemotePuppeteerLocator } from '../drivers/puppeteer/generated/locator.js';
22
- import { RemotePuppeteerPage } from '../drivers/puppeteer/generated/page.js';
23
- import { RemoteStagehandLocator } from '../drivers/stagehand/generated/locator.js';
24
- import { RemoteStagehandPage } from '../drivers/stagehand/generated/page.js';
25
- import { RemoteStagehandResponse } from '../drivers/stagehand/generated/response.js';
26
- import { RemoteWebDriver } from '../drivers/selenium/driver.js';
27
- import { RuntimeEventPump, } from './runtime-event-pump.js';
28
- const PLAYWRIGHT_PAGE_EVENT_MAP = {
29
- console: 'console',
30
- crash: 'page.crash',
31
- dialog: 'page.dialog',
32
- domcontentloaded: 'page.domcontentloaded',
33
- download: 'page.download',
34
- filechooser: 'page.filechooser',
35
- frameattached: 'page.frame_attached',
36
- framedetached: 'page.frame_detached',
37
- framenavigated: 'page.navigated',
38
- load: 'page.load',
39
- popup: 'page.popup',
40
- request: 'page.request',
41
- pageerror: 'page.error',
42
- requestfinished: 'page.request_finished',
43
- requestfailed: 'page.request_failed',
44
- response: 'page.response',
45
- websocket: 'page.websocket',
46
- worker: 'page.worker',
47
- close: 'page.closed',
48
- };
49
- const PLAYWRIGHT_CONTEXT_EVENT_MAP = {
50
- page: 'context.page_created',
51
- close: 'context.closed',
52
- };
53
- const PUPPETEER_PAGE_EVENT_MAP = {
54
- close: 'page.closed',
55
- console: 'console',
56
- dialog: 'page.dialog',
57
- domcontentloaded: 'page.domcontentloaded',
58
- error: 'page.crash',
59
- frameattached: 'page.frame_attached',
60
- framedetached: 'page.frame_detached',
61
- framenavigated: 'page.navigated',
62
- load: 'page.load',
63
- pageerror: 'page.error',
64
- popup: 'page.popup',
65
- request: 'page.request',
66
- requestfailed: 'page.request_failed',
67
- requestfinished: 'page.request_finished',
68
- response: 'page.response',
69
- workercreated: 'page.worker',
70
- };
71
- const STAGEHAND_PAGE_EVENT_MAP = {
72
- ...PLAYWRIGHT_PAGE_EVENT_MAP,
73
- };
74
- function getTimeoutMs(timeoutRaw, fallbackMs) {
75
- return typeof timeoutRaw === 'number' && Number.isFinite(timeoutRaw)
76
- ? Math.max(0, Math.floor(timeoutRaw))
77
- : fallbackMs;
78
- }
79
- function patchLocalWaitForEvent(target, options) {
80
- if (target[options.patchedFlag])
81
- return;
82
- target[options.patchedFlag] = true;
83
- const originalWaitForEvent = typeof target.waitForEvent === 'function' ? target.waitForEvent.bind(target) : null;
84
- target.waitForEvent = async (event, optionsOrPredicate) => {
85
- const eventName = String(event);
86
- if (originalWaitForEvent &&
87
- options.supportedEvents &&
88
- !options.supportedEvents.has(eventName)) {
89
- return originalWaitForEvent(eventName, optionsOrPredicate);
90
- }
91
- const predicate = typeof optionsOrPredicate === 'function'
92
- ? optionsOrPredicate
93
- : typeof optionsOrPredicate?.predicate === 'function'
94
- ? optionsOrPredicate.predicate
95
- : undefined;
96
- const timeoutRaw = typeof optionsOrPredicate === 'object' && optionsOrPredicate
97
- ? optionsOrPredicate.timeout
98
- : undefined;
99
- const timeoutMs = getTimeoutMs(timeoutRaw, options.defaultTimeoutMs());
100
- return new Promise((resolve, reject) => {
101
- let done = false;
102
- let timeoutId = null;
103
- const cleanup = () => {
104
- target.off(eventName, handler);
105
- if (timeoutId) {
106
- clearTimeout(timeoutId);
107
- timeoutId = null;
108
- }
109
- };
110
- const handler = (value) => {
111
- if (done)
112
- return;
113
- void (async () => {
114
- try {
115
- if (predicate) {
116
- const matched = await predicate(value);
117
- if (!matched)
118
- return;
119
- }
120
- done = true;
121
- cleanup();
122
- resolve(value);
123
- }
124
- catch (error) {
125
- done = true;
126
- cleanup();
127
- reject(error);
128
- }
129
- })();
130
- };
131
- target.on(eventName, handler);
132
- if (timeoutMs > 0) {
133
- timeoutId = setTimeout(() => {
134
- if (done)
135
- return;
136
- done = true;
137
- cleanup();
138
- reject(new Error(`waitForEvent('${eventName}') timed out after ${timeoutMs}ms`));
139
- }, timeoutMs);
140
- }
141
- });
142
- };
143
- }
144
- function patchStagehandEventBridge(page) {
145
- const target = page;
146
- const record = page;
147
- const getListeners = () => {
148
- const value = record['_eventListeners'];
149
- return value instanceof Map
150
- ? value
151
- : new Map();
152
- };
153
- if (!record['__bctrlEventBridgePatched']) {
154
- record['__bctrlEventBridgePatched'] = true;
155
- const originalOn = target.on.bind(page);
156
- const originalOff = target.off.bind(page);
157
- target.listenerCount = (event) => {
158
- return getListeners().get(event)?.size ?? 0;
159
- };
160
- target.emit = (event, payload) => {
161
- const listeners = Array.from(getListeners().get(event) ?? []);
162
- if (listeners.length === 0)
163
- return false;
164
- for (const handler of listeners) {
165
- try {
166
- handler(payload);
167
- }
168
- catch (error) {
169
- console.error(`Error in Stagehand event handler for "${event}":`, error);
170
- }
171
- }
172
- return true;
173
- };
174
- target.on = ((event, handler) => {
175
- const hadListeners = target.listenerCount?.(event) ?? 0;
176
- const result = originalOn(event, handler);
177
- const hasListeners = (target.listenerCount?.(event) ?? 0) > 0;
178
- if (hadListeners === 0 && hasListeners) {
179
- getRemoteListenerBinding(page)?.onFirstListener(event);
180
- }
181
- return result;
182
- });
183
- target.off = ((event, handler) => {
184
- const hadListeners = (target.listenerCount?.(event) ?? 0) > 0;
185
- const result = originalOff(event, handler);
186
- const hasListeners = (target.listenerCount?.(event) ?? 0) > 0;
187
- if (hadListeners && !hasListeners) {
188
- getRemoteListenerBinding(page)?.onNoListeners(event);
189
- }
190
- return result;
191
- });
192
- }
193
- patchLocalWaitForEvent(record, {
194
- patchedFlag: '__bctrlWaitForEventPatched',
195
- defaultTimeoutMs: () => 30_000,
196
- });
197
- return target;
198
- }
199
- function buildHeaders(apiKey, withJsonBody = false) {
200
- const headers = {
201
- 'x-sdk-version': SDK_VERSION,
202
- Authorization: `Bearer ${apiKey}`,
203
- };
204
- if (withJsonBody) {
205
- headers['Content-Type'] = 'application/json';
206
- }
207
- return headers;
208
- }
209
- async function expectJson(response, context) {
210
- if (!response.ok) {
211
- const details = parseErrorDetails(await response.text());
212
- throw new Error(`${context}: ${details.message}`);
213
- }
214
- return parseJsonResponse(response, context);
215
- }
216
- class RuntimeExecutionTransport {
217
- workspaceClient;
218
- runtimeAlias;
219
- contextId;
220
- activePageId;
221
- constructor(workspaceClient, runtimeAlias, runtime) {
222
- this.workspaceClient = workspaceClient;
223
- this.runtimeAlias = runtimeAlias;
224
- this.contextId = runtime?.summary?.defaultContextId ?? undefined;
225
- this.activePageId = runtime?.summary?.defaultPageId ?? undefined;
226
- }
227
- getContextId() {
228
- return this.contextId;
229
- }
230
- getActivePageId() {
231
- return this.activePageId;
232
- }
233
- noteContext(contextId) {
234
- if (contextId) {
235
- this.contextId = contextId;
236
- }
237
- }
238
- notePage(pageId, contextId) {
239
- if (contextId) {
240
- this.contextId = contextId;
241
- }
242
- if (pageId) {
243
- this.activePageId = pageId;
244
- }
245
- }
246
- buildRef(target, ids) {
247
- if (HANDLE_TARGETS.has(target)) {
248
- return ids?.handleId;
249
- }
250
- if (CONTEXT_REF_TARGETS.has(target)) {
251
- return ids?.contextId;
252
- }
253
- if (PAGE_REF_TARGETS.has(target)) {
254
- return ids?.pageId;
255
- }
256
- return undefined;
257
- }
258
- rememberCallResult(call, step) {
259
- if (step.resolved.contextId) {
260
- this.contextId = step.resolved.contextId;
261
- }
262
- if (step.resolved.pageId) {
263
- this.activePageId = step.resolved.pageId;
264
- }
265
- if (step.binding?.type === 'context') {
266
- this.contextId = step.binding.id;
267
- }
268
- if (step.binding?.type === 'page') {
269
- this.activePageId = step.binding.id;
270
- }
271
- if (typeof step.result === 'string') {
272
- if (call === 'browser.newContext') {
273
- this.contextId = step.result;
274
- }
275
- if (call === 'browser.newPage' || call === 'context.newPage' || call === 'stagehand.context.newPage') {
276
- this.activePageId = step.result;
277
- }
278
- }
279
- }
280
- async executeSingleStep(step) {
281
- return this.workspaceClient.execute({
282
- runtime: this.runtimeAlias,
283
- steps: [step],
284
- });
285
- }
286
- async executeImmediate(call, args = [], ids, options) {
287
- const target = call.slice(0, call.indexOf('.'));
288
- const ref = this.buildRef(target, ids);
289
- const response = await this.executeSingleStep({
290
- call,
291
- ...(ref ? { ref } : {}),
292
- ...(args.length > 0 ? { args } : {}),
293
- ...(options ? { options } : {}),
294
- });
295
- if (response.kind === 'operation') {
296
- throw new Error(`Call '${call}' started a long-running operation; use runtime.run() or the agent APIs for operation-aware execution.`);
297
- }
298
- const step = response.result.steps[0];
299
- if (!step.ok) {
300
- throw fromErrorResponse(step.error.message, step.error.code, {
301
- ...(step.error.hint ? { hint: step.error.hint } : {}),
302
- ...(step.error.diagnostic ? { diagnostic: step.error.diagnostic } : {}),
303
- });
304
- }
305
- this.rememberCallResult(call, step);
306
- return step.result;
307
- }
308
- async executeOperationAware(call, args = [], ids, options) {
309
- const target = call.slice(0, call.indexOf('.'));
310
- const ref = this.buildRef(target, ids);
311
- const response = await this.executeSingleStep({
312
- call,
313
- ...(ref ? { ref } : {}),
314
- ...(args.length > 0 ? { args } : {}),
315
- ...(options ? { options } : {}),
316
- });
317
- if (response.kind === 'result') {
318
- const step = response.result.steps[0];
319
- if (!step.ok) {
320
- throw fromErrorResponse(step.error.message, step.error.code, {
321
- ...(step.error.hint ? { hint: step.error.hint } : {}),
322
- ...(step.error.diagnostic ? { diagnostic: step.error.diagnostic } : {}),
323
- });
324
- }
325
- this.rememberCallResult(call, step);
326
- }
327
- return response;
328
- }
329
- createRpcSender() {
330
- return (target, method, args, ids) => {
331
- return this.executeImmediate(`${target}.${method}`, args, ids);
332
- };
333
- }
334
- createPageSender(pageId, contextId) {
335
- return async (method, args) => {
336
- this.notePage(pageId, contextId);
337
- return this.executeImmediate('page.' + method, args, { pageId, contextId });
338
- };
339
- }
340
- createContextSender(contextId) {
341
- return async (method, args) => {
342
- this.noteContext(contextId);
343
- return this.executeImmediate('context.' + method, args, { contextId });
344
- };
345
- }
346
- createBrowserSender() {
347
- return async (method, args) => {
348
- return this.executeImmediate('browser.' + method, args);
349
- };
350
- }
351
- createHandleSender(target, handleId) {
352
- return async (method, args) => {
353
- return this.executeImmediate(`${target}.${method}`, args, { handleId });
354
- };
355
- }
356
- createLocatorSender(selector, pageId, contextId) {
357
- return async (method, args) => {
358
- const cleanMethod = method.startsWith('locator:') ? method.slice(8) : method;
359
- this.notePage(pageId, contextId);
360
- return this.executeImmediate('locator.' + cleanMethod, [selector, ...args], { pageId, contextId });
361
- };
362
- }
363
- }
364
- class BrowserRuntimeEventsClient {
365
- workspaceClient;
366
- runtimeAlias;
367
- constructor(workspaceClient, runtimeAlias) {
368
- this.workspaceClient = workspaceClient;
369
- this.runtimeAlias = runtimeAlias;
370
- }
371
- async list(query = {}) {
372
- const params = new URLSearchParams();
373
- if (query.after)
374
- params.set('after', query.after);
375
- if (query.limit !== undefined)
376
- params.set('limit', String(query.limit));
377
- if (query.pageId)
378
- params.set('pageId', query.pageId);
379
- if (query.contextId)
380
- params.set('contextId', query.contextId);
381
- if (Array.isArray(query.eventTypes)) {
382
- for (const eventType of query.eventTypes)
383
- params.append('eventTypes', eventType);
384
- }
385
- else if (typeof query.eventTypes === 'string') {
386
- params.set('eventTypes', query.eventTypes);
387
- }
388
- const suffix = params.toString() ? `?${params.toString()}` : '';
389
- const response = await fetchWithTimeout(`${this.workspaceClient.baseUrl}/workspaces/${encodeURIComponent(this.workspaceClient.id)}/runtimes/${encodeURIComponent(this.runtimeAlias)}/events${suffix}`, { headers: buildHeaders(this.workspaceClient.apiKey) });
390
- return expectJson(response, 'List runtime events');
391
- }
392
- async wait(request = {}, options = {}) {
393
- const controller = new AbortController();
394
- const timeoutMs = (request.timeoutMs ?? 30_000) + 5_000;
395
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
396
- const onAbort = () => controller.abort();
397
- if (options.signal) {
398
- if (options.signal.aborted) {
399
- controller.abort();
400
- }
401
- else {
402
- options.signal.addEventListener('abort', onAbort, { once: true });
403
- }
404
- }
405
- let response;
406
- try {
407
- response = await fetch(`${this.workspaceClient.baseUrl}/workspaces/${encodeURIComponent(this.workspaceClient.id)}/runtimes/${encodeURIComponent(this.runtimeAlias)}/events/wait`, {
408
- method: 'POST',
409
- headers: buildHeaders(this.workspaceClient.apiKey, true),
410
- body: JSON.stringify(request),
411
- signal: controller.signal,
412
- });
413
- }
414
- finally {
415
- clearTimeout(timeoutId);
416
- options.signal?.removeEventListener('abort', onAbort);
417
- }
418
- return expectJson(response, 'Wait for runtime event');
419
- }
420
- }
421
- export class BrowserRuntimeAccessor {
422
- workspaceClient;
423
- runtimeAlias;
424
- events;
425
- constructor(workspaceClient, runtimeAlias) {
426
- this.workspaceClient = workspaceClient;
427
- this.runtimeAlias = runtimeAlias;
428
- this.events = new BrowserRuntimeEventsClient(workspaceClient, runtimeAlias);
429
- }
430
- async run(input) {
431
- return this.workspaceClient.execute({
432
- runtime: this.runtimeAlias,
433
- ...(input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : {}),
434
- mode: input.mode,
435
- steps: input.steps,
436
- });
437
- }
438
- async state() {
439
- return this.workspaceClient.state({ runtime: this.runtimeAlias });
440
- }
441
- async help(topic) {
442
- return this.workspaceClient.help({
443
- runtime: this.runtimeAlias,
444
- ...(topic ? { topic } : {}),
445
- });
446
- }
447
- async live(options = {}) {
448
- return this.workspaceClient.embedRuntimeLive(this.runtimeAlias, options);
449
- }
450
- async recording() {
451
- return this.workspaceClient.embedRuntimeRecording(this.runtimeAlias);
452
- }
453
- async stop() {
454
- return this.workspaceClient.stopRuntime(this.runtimeAlias);
455
- }
456
- }
457
- export class BrowserRuntimeClient extends BrowserRuntimeAccessor {
458
- runtimeValue;
459
- transport;
460
- eventPump = null;
461
- _captcha = null;
462
- constructor(workspaceClient, runtimeValue) {
463
- super(workspaceClient, runtimeValue.alias);
464
- this.runtimeValue = runtimeValue;
465
- this.transport = new RuntimeExecutionTransport(workspaceClient, runtimeValue.alias, runtimeValue);
466
- }
467
- get id() {
468
- return this.runtimeValue.id;
469
- }
470
- get alias() {
471
- return this.runtimeValue.alias;
472
- }
473
- get driverName() {
474
- return this.runtimeValue.driver;
475
- }
476
- get status() {
477
- return this.runtimeValue.status;
478
- }
479
- get captcha() {
480
- if (!this._captcha) {
481
- this._captcha = new CaptchaNamespace(this.transport.createRpcSender(), () => this.transport.getActivePageId());
482
- }
483
- return this._captcha;
484
- }
485
- getEventPump() {
486
- if (!this.eventPump) {
487
- this.eventPump = new RuntimeEventPump(this.events);
488
- }
489
- return this.eventPump;
490
- }
491
- registerPageEventEmitter(registration) {
492
- this.getEventPump().registerPageEmitter(registration);
493
- }
494
- registerContextEventEmitter(registration) {
495
- this.getEventPump().registerContextEmitter(registration);
496
- }
497
- async stop() {
498
- if (this.eventPump) {
499
- await this.eventPump.close();
500
- this.eventPump = null;
501
- }
502
- const runtime = await super.stop();
503
- this.runtimeValue = runtime;
504
- return runtime;
505
- }
506
- }
507
- class RuntimeStagehandAgent {
508
- transport;
509
- getContextId;
510
- resolvePageId;
511
- config;
512
- constructor(transport, getContextId, resolvePageId, config) {
513
- this.transport = transport;
514
- this.getContextId = getContextId;
515
- this.resolvePageId = resolvePageId;
516
- this.config = config;
517
- }
518
- execute(instructionOrOptions, options) {
519
- const isString = typeof instructionOrOptions === 'string';
520
- const page = isString ? options?.page : instructionOrOptions.page;
521
- let cleanOptions;
522
- if (isString) {
523
- const { page: _page, ...rest } = options ?? {};
524
- cleanOptions = {
525
- instruction: instructionOrOptions,
526
- ...rest,
527
- };
528
- }
529
- else {
530
- const { page: _page, ...rest } = instructionOrOptions;
531
- cleanOptions = rest;
532
- }
533
- return this.transport.executeOperationAware('stagehand.agent.execute', [this.config, cleanOptions], {
534
- contextId: this.getContextId(),
535
- pageId: this.resolvePageId(page),
536
- });
537
- }
538
- }
539
- class RuntimeStagehandNamespace {
540
- transport;
541
- getContextId;
542
- getActivePageId;
543
- resolvePage;
544
- core;
545
- constructor(transport, getContextId, getActivePageId, resolvePage) {
546
- this.transport = transport;
547
- this.getContextId = getContextId;
548
- this.getActivePageId = getActivePageId;
549
- this.resolvePage = resolvePage;
550
- this.core = new StagehandCore(transport.createRpcSender(), getContextId, getActivePageId, resolvePage);
551
- }
552
- act(instruction, options) {
553
- return this.core.act(instruction, options);
554
- }
555
- extract(instructionOrOptions, schema, options) {
556
- return this.core.extract(instructionOrOptions, schema, options);
557
- }
558
- observe(instructionOrOptions, options) {
559
- return this.core.observe(instructionOrOptions, options);
560
- }
561
- agent(config) {
562
- return new RuntimeStagehandAgent(this.transport, this.getContextId, (page) => {
563
- if (page) {
564
- const resolved = this.resolvePage(page);
565
- if (resolved)
566
- return resolved;
567
- }
568
- return this.getActivePageId();
569
- }, config);
570
- }
571
- getMetrics() {
572
- return this.core.getMetrics();
573
- }
574
- getHistory() {
575
- return this.core.getHistory();
576
- }
577
- }
578
- class RuntimeBrowserUseNamespace {
579
- transport;
580
- getActivePageId;
581
- constructor(transport, getActivePageId) {
582
- this.transport = transport;
583
- this.getActivePageId = getActivePageId;
584
- }
585
- agent(config = {}) {
586
- return {
587
- execute: async (task, options) => {
588
- const pageId = config.pageId || this.getActivePageId();
589
- const executeOptions = {
590
- task,
591
- ...(options?.maxSteps !== undefined ? { maxSteps: options.maxSteps } : {}),
592
- ...(options?.tools !== undefined ? { tools: options.tools } : {}),
593
- };
594
- return this.transport.executeOperationAware('browserUse.agent.execute', [config, executeOptions], { pageId });
595
- },
596
- };
597
- }
598
- codeAgent(config = {}) {
599
- return {
600
- execute: async (task, options) => {
601
- const pageId = config.pageId || this.getActivePageId();
602
- const executeOptions = {
603
- task,
604
- ...(options?.maxSteps !== undefined ? { maxSteps: options.maxSteps } : {}),
605
- ...(options?.tools !== undefined ? { tools: options.tools } : {}),
606
- };
607
- return this.transport.executeOperationAware('browserUse.codeAgent.execute', [config, executeOptions], { pageId });
608
- },
609
- };
610
- }
611
- }
612
- class AgentBrowserRuntimeClient extends BrowserRuntimeClient {
613
- _stagehand = null;
614
- _browserUse = null;
615
- get stagehand() {
616
- if (!this._stagehand) {
617
- this._stagehand = new RuntimeStagehandNamespace(this.transport, () => this.transport.getContextId(), () => this.transport.getActivePageId(), (page) => this.resolvePage(page));
618
- }
619
- return this._stagehand;
620
- }
621
- get browserUse() {
622
- if (!this._browserUse) {
623
- this._browserUse = new RuntimeBrowserUseNamespace(this.transport, () => this.transport.getActivePageId());
624
- }
625
- return this._browserUse;
626
- }
627
- }
628
- export class PlaywrightBrowserRuntimeClient extends AgentBrowserRuntimeClient {
629
- _browser = null;
630
- _defaultPage = null;
631
- contextCache = new Map();
632
- pageCache = new Map();
633
- pageContextIds = new Map();
634
- resolvePage(page) {
635
- return page instanceof RemotePlaywrightPage ? page.id : undefined;
636
- }
637
- get browser() {
638
- if (!this._browser) {
639
- this._browser = new RemotePlaywrightBrowser('default', this.transport.createBrowserSender(), (contextId) => this.getOrCreateBrowserContext(contextId), (pageId) => this.createPlaywrightPage(pageId, this.transport.getContextId()));
640
- }
641
- return this._browser;
642
- }
643
- get browserContext() {
644
- const contextId = this.transport.getContextId();
645
- if (!contextId) {
646
- throw new Error('No default browser context available');
647
- }
648
- return this.getOrCreateBrowserContext(contextId);
649
- }
650
- get page() {
651
- if (!this._defaultPage) {
652
- const pageId = this.transport.getActivePageId();
653
- if (!pageId) {
654
- throw new Error('No default page available');
655
- }
656
- this._defaultPage = this.createPlaywrightPage(pageId, this.transport.getContextId());
657
- }
658
- return this._defaultPage;
659
- }
660
- async getPages() {
661
- return this.browserContext.pages();
662
- }
663
- resolvePageContextId(pageId, contextId) {
664
- if (contextId) {
665
- this.pageContextIds.set(pageId, contextId);
666
- return contextId;
667
- }
668
- return this.pageContextIds.get(pageId) ?? this.transport.getContextId();
669
- }
670
- getOrCreateBrowserContext(contextId) {
671
- const cached = this.contextCache.get(contextId);
672
- if (cached)
673
- return cached;
674
- this.transport.noteContext(contextId);
675
- const context = new RemotePlaywrightBrowserContext(contextId, this.transport.createContextSender(contextId), (pageId) => this.createPlaywrightPage(pageId, contextId), this._browser);
676
- patchLocalWaitForEvent(context, {
677
- patchedFlag: '__bctrlWaitForContextEventPatched',
678
- supportedEvents: new Set(Object.keys(PLAYWRIGHT_CONTEXT_EVENT_MAP)),
679
- defaultTimeoutMs: () => getTimeoutMs(context._defaultTimeout, 30_000),
680
- });
681
- this.registerContextEventEmitter({
682
- contextId,
683
- emitter: context,
684
- eventMap: PLAYWRIGHT_CONTEXT_EVENT_MAP,
685
- createPage: (pageId) => this.createPlaywrightPage(pageId, contextId),
686
- });
687
- this.contextCache.set(contextId, context);
688
- return context;
689
- }
690
- createPlaywrightPage(pageId, contextId) {
691
- this.transport.notePage(pageId, contextId);
692
- this.resolvePageContextId(pageId, contextId);
693
- const cached = this.pageCache.get(pageId);
694
- if (cached)
695
- return cached;
696
- let page;
697
- const frameCache = new Map();
698
- const contextIdForPage = () => this.resolvePageContextId(pageId, contextId);
699
- const pageRpcSender = this.transport.createPageSender(pageId, contextIdForPage());
700
- const createFrameRpcSender = (handleId) => this.transport.createHandleSender('frame', handleId);
701
- const createJSHandleRpcSender = (handleId) => this.transport.createHandleSender('jsHandle', handleId);
702
- const createElementRpcSender = (handleId) => this.transport.createHandleSender('element', handleId);
703
- const createLocatorRpcSender = (selector) => this.transport.createLocatorSender(selector, pageId, contextIdForPage());
704
- const createJSHandle = (handleId) => new RemotePlaywrightJSHandle(handleId, createJSHandleRpcSender(handleId), createJSHandle);
705
- const createElementHandle = (handleId) => new RemotePlaywrightElementHandle(handleId, createElementRpcSender(handleId), createElementHandle, createFrame, createJSHandle);
706
- const createFrameLocator = (selector) => new RemotePlaywrightFrameLocator(pageRpcSender, selector, createLocator);
707
- const createLocator = (selector) => new RemotePlaywrightLocator(selector, createLocatorRpcSender(selector), createElementHandle, createLocator, createFrameLocator, page);
708
- const createFrame = (frameId) => {
709
- let frame = frameCache.get(frameId);
710
- if (!frame) {
711
- frame = new RemotePlaywrightFrame(frameId, createFrameRpcSender(frameId), createElementHandle, createFrame, createLocator, createFrameLocator, createJSHandle, () => page);
712
- frameCache.set(frameId, frame);
713
- }
714
- return frame;
715
- };
716
- page = new RemotePlaywrightPage(pageRpcSender, pageId, createElementHandle, createFrame, createLocator, createJSHandle);
717
- patchLocalWaitForEvent(page, {
718
- patchedFlag: '__bctrlWaitForEventPatched',
719
- supportedEvents: new Set(Object.keys(PLAYWRIGHT_PAGE_EVENT_MAP)),
720
- defaultTimeoutMs: () => getTimeoutMs(page._defaultTimeout, 30_000),
721
- });
722
- this.registerPageEventEmitter({
723
- pageId,
724
- emitter: page,
725
- eventMap: PLAYWRIGHT_PAGE_EVENT_MAP,
726
- createPage: (nextPageId) => this.createPlaywrightPage(nextPageId, contextIdForPage()),
727
- });
728
- this.pageCache.set(pageId, page);
729
- return page;
730
- }
731
- }
732
- export class PuppeteerBrowserRuntimeClient extends AgentBrowserRuntimeClient {
733
- _browser = null;
734
- _defaultPage = null;
735
- contextCache = new Map();
736
- pageCache = new Map();
737
- resolvePage(page) {
738
- return page instanceof RemotePuppeteerPage ? page.id : undefined;
739
- }
740
- get browser() {
741
- if (!this._browser) {
742
- const createContext = (contextId, isDefault) => {
743
- return this.getOrCreateBrowserContext(contextId, isDefault);
744
- };
745
- this._browser = new RemotePuppeteerBrowser(this.transport.createBrowserSender(), (pageId) => this.createPuppeteerPage(pageId), createContext);
746
- }
747
- return this._browser;
748
- }
749
- get page() {
750
- if (!this._defaultPage) {
751
- const pageId = this.transport.getActivePageId();
752
- if (!pageId) {
753
- throw new Error('No default page available');
754
- }
755
- this._defaultPage = this.createPuppeteerPage(pageId);
756
- }
757
- return this._defaultPage;
758
- }
759
- getOrCreateBrowserContext(contextId, isDefault) {
760
- const cached = this.contextCache.get(contextId);
761
- if (cached)
762
- return cached;
763
- const contextRpcSender = async (method, args) => {
764
- this.transport.noteContext(contextId);
765
- return this.transport.executeImmediate('context.' + method, args, { contextId });
766
- };
767
- const context = new RemotePuppeteerBrowserContext(contextRpcSender, { contextId, isDefault }, (pageId) => this.createPuppeteerPage(pageId));
768
- this.contextCache.set(contextId, context);
769
- return context;
770
- }
771
- createPuppeteerPage(pageId) {
772
- this.transport.notePage(pageId, this.transport.getContextId());
773
- const cached = this.pageCache.get(pageId);
774
- if (cached)
775
- return cached;
776
- let page;
777
- const frameCache = new Map();
778
- const contextId = this.transport.getContextId();
779
- const pageTimeoutIds = { contextId, pageId };
780
- let pageDefaultsInitPromise = null;
781
- const ensurePageDefaults = async () => {
782
- if (!pageDefaultsInitPromise) {
783
- pageDefaultsInitPromise = (async () => {
784
- const defaultTimeoutMs = 120_000;
785
- try {
786
- await this.transport.executeImmediate('page.setDefaultTimeout', [defaultTimeoutMs], pageTimeoutIds);
787
- await this.transport.executeImmediate('page.setDefaultNavigationTimeout', [defaultTimeoutMs], pageTimeoutIds);
788
- }
789
- catch {
790
- // Fall back to upstream defaults.
791
- }
792
- })();
793
- }
794
- await pageDefaultsInitPromise;
795
- };
796
- const pageRpcSender = async (method, args) => {
797
- if (method !== 'setDefaultTimeout' && method !== 'setDefaultNavigationTimeout') {
798
- await ensurePageDefaults();
799
- }
800
- this.transport.notePage(pageId, contextId);
801
- return this.transport.executeImmediate('page.' + method, args, pageTimeoutIds);
802
- };
803
- const createFrameRpcSender = (frameId) => async (method, args) => {
804
- await ensurePageDefaults();
805
- return this.transport.executeImmediate('frame.' + method, args, {
806
- contextId,
807
- pageId,
808
- handleId: frameId,
809
- });
810
- };
811
- const createElementRpcSender = (handleId) => async (method, args) => {
812
- await ensurePageDefaults();
813
- return this.transport.executeImmediate('element.' + method, args, {
814
- contextId,
815
- pageId,
816
- handleId,
817
- });
818
- };
819
- const createJSHandleRpcSender = (handleId) => async (method, args) => {
820
- await ensurePageDefaults();
821
- return this.transport.executeImmediate('jsHandle.' + method, args, {
822
- contextId,
823
- pageId,
824
- handleId,
825
- });
826
- };
827
- const createLocatorRpcSender = (selector) => async (method, args) => {
828
- await ensurePageDefaults();
829
- const cleanMethod = method.startsWith('locator:') ? method.slice(8) : method;
830
- return this.transport.executeImmediate('locator.' + cleanMethod, [selector, ...args], {
831
- contextId,
832
- pageId,
833
- });
834
- };
835
- const createTouchHandle = (touchId) => ({
836
- move: async (x, y) => {
837
- await pageRpcSender('touchscreen.touchMove', [touchId, x, y]);
838
- },
839
- end: async () => {
840
- await pageRpcSender('touchscreen.touchEnd', [touchId]);
841
- },
842
- });
843
- const createLocator = (selector) => new RemotePuppeteerLocator(selector, createLocatorRpcSender(selector), createElementHandle, createLocator);
844
- const createFrame = (frameId) => {
845
- let frame = frameCache.get(frameId);
846
- if (!frame) {
847
- frame = new RemotePuppeteerFrame(frameId, createFrameRpcSender(frameId), createElementHandle, createFrame, createLocator, createJSHandle, () => page);
848
- frameCache.set(frameId, frame);
849
- }
850
- return frame;
851
- };
852
- const createElementHandle = (handleId) => new RemotePuppeteerElementHandle(handleId, createElementRpcSender(handleId), createElementHandle, createFrame, createLocator, createTouchHandle);
853
- const createJSHandle = (handleId) => new RemotePuppeteerJSHandle(handleId, createJSHandleRpcSender(handleId), createJSHandle, createElementHandle);
854
- page = new RemotePuppeteerPage(pageRpcSender, pageId, createElementHandle, createFrame, createLocator, createJSHandle);
855
- patchLocalWaitForEvent(page, {
856
- patchedFlag: '__bctrlWaitForEventPatched',
857
- supportedEvents: new Set(Object.keys(PUPPETEER_PAGE_EVENT_MAP)),
858
- defaultTimeoutMs: () => getTimeoutMs(page.getDefaultTimeout?.(), 30_000),
859
- });
860
- this.registerPageEventEmitter({
861
- pageId,
862
- emitter: page,
863
- eventMap: PUPPETEER_PAGE_EVENT_MAP,
864
- callDialogAction: async (dialogId, action, promptText) => {
865
- if (action === 'accept') {
866
- await this.transport.executeImmediate('dialog.accept', [promptText], {
867
- contextId,
868
- pageId,
869
- handleId: dialogId,
870
- });
871
- return;
872
- }
873
- await this.transport.executeImmediate('dialog.dismiss', [], {
874
- contextId,
875
- pageId,
876
- handleId: dialogId,
877
- });
878
- },
879
- });
880
- this.pageCache.set(pageId, page);
881
- return page;
882
- }
883
- }
884
- export class StagehandBrowserRuntimeClient extends AgentBrowserRuntimeClient {
885
- _page = null;
886
- pageCache = new Map();
887
- resolvePage(page) {
888
- return page instanceof RemoteStagehandPage ? page.id : undefined;
889
- }
890
- get page() {
891
- if (!this._page) {
892
- const pageId = this.transport.getActivePageId();
893
- if (!pageId) {
894
- throw new Error('No page available');
895
- }
896
- this._page = this.createStagehandPage(pageId);
897
- }
898
- return this._page;
899
- }
900
- createStagehandPage(pageId) {
901
- this.transport.notePage(pageId, this.transport.getContextId());
902
- const cached = this.pageCache.get(pageId);
903
- if (cached)
904
- return cached;
905
- const pageRpcSender = this.transport.createPageSender(pageId, this.transport.getContextId());
906
- const createLocator = (selector) => new RemoteStagehandLocator(selector, async (method, args) => {
907
- return this.transport.executeImmediate('locator.' + method, [selector, ...args], {
908
- pageId,
909
- contextId: this.transport.getContextId(),
910
- });
911
- });
912
- const createResponse = (data) => new RemoteStagehandResponse(pageRpcSender, data);
913
- const page = patchStagehandEventBridge(new RemoteStagehandPage(pageId, pageRpcSender, createLocator, createLocator, createResponse));
914
- this.registerPageEventEmitter({
915
- pageId,
916
- emitter: page,
917
- eventMap: STAGEHAND_PAGE_EVENT_MAP,
918
- createPage: (nextPageId) => this.createStagehandPage(nextPageId),
919
- });
920
- this.pageCache.set(pageId, page);
921
- return page;
922
- }
923
- }
924
- export class SeleniumBrowserRuntimeClient extends AgentBrowserRuntimeClient {
925
- _webDriver = null;
926
- resolvePage() {
927
- return undefined;
928
- }
929
- get webDriver() {
930
- if (!this._webDriver) {
931
- const pageId = this.transport.getActivePageId();
932
- if (!pageId) {
933
- throw new Error('No page available - runtime may not be initialized');
934
- }
935
- this._webDriver = new RemoteWebDriver(pageId, this.transport.createRpcSender());
936
- }
937
- return this._webDriver;
938
- }
939
- get driver() {
940
- return this.webDriver;
941
- }
942
- }
943
- export function createBrowserRuntimeClient(workspaceClient, runtime) {
944
- switch (runtime.driver) {
945
- case 'playwright':
946
- return new PlaywrightBrowserRuntimeClient(workspaceClient, runtime);
947
- case 'puppeteer':
948
- return new PuppeteerBrowserRuntimeClient(workspaceClient, runtime);
949
- case 'stagehand':
950
- return new StagehandBrowserRuntimeClient(workspaceClient, runtime);
951
- case 'selenium':
952
- return new SeleniumBrowserRuntimeClient(workspaceClient, runtime);
953
- default:
954
- return new BrowserRuntimeClient(workspaceClient, runtime);
955
- }
956
- }
957
- function createBrowserRuntimeClientForDriver(workspaceClient, runtime, driver) {
958
- if (runtime.driver !== driver) {
959
- throw new Error(`Expected runtime driver '${driver}', received '${runtime.driver}'`);
960
- }
961
- switch (driver) {
962
- case 'playwright':
963
- return new PlaywrightBrowserRuntimeClient(workspaceClient, runtime);
964
- case 'puppeteer':
965
- return new PuppeteerBrowserRuntimeClient(workspaceClient, runtime);
966
- case 'stagehand':
967
- return new StagehandBrowserRuntimeClient(workspaceClient, runtime);
968
- case 'selenium':
969
- return new SeleniumBrowserRuntimeClient(workspaceClient, runtime);
970
- }
971
- }
972
- export class BrowserRuntimeBuilder extends BrowserRuntimeAccessor {
973
- alias;
974
- constructor(workspaceClient, alias) {
975
- super(workspaceClient, alias);
976
- this.alias = alias;
977
- }
978
- async createRuntimeRecord(driver, launch) {
979
- return this.workspaceClient.createBrowserRuntime({
980
- alias: this.alias,
981
- kind: 'browser',
982
- driver,
983
- ...(launch ? { launch } : {}),
984
- });
985
- }
986
- async playwright(launch) {
987
- const runtime = await this.createRuntimeRecord('playwright', launch);
988
- return createBrowserRuntimeClientForDriver(this.workspaceClient, runtime, 'playwright');
989
- }
990
- async puppeteer(launch) {
991
- const runtime = await this.createRuntimeRecord('puppeteer', launch);
992
- return createBrowserRuntimeClientForDriver(this.workspaceClient, runtime, 'puppeteer');
993
- }
994
- async stagehand(launch) {
995
- const runtime = await this.createRuntimeRecord('stagehand', launch);
996
- return createBrowserRuntimeClientForDriver(this.workspaceClient, runtime, 'stagehand');
997
- }
998
- async selenium(launch) {
999
- const runtime = await this.createRuntimeRecord('selenium', launch);
1000
- return createBrowserRuntimeClientForDriver(this.workspaceClient, runtime, 'selenium');
1001
- }
1002
- async get() {
1003
- const runtime = await this.workspaceClient.getRuntime(this.alias);
1004
- if (!runtime) {
1005
- throw new Error(`Runtime '${this.alias}' not found in workspace '${this.workspaceClient.id}'`);
1006
- }
1007
- return createBrowserRuntimeClient(this.workspaceClient, runtime);
1008
- }
1009
- }
1010
- export class RuntimeNamespace {
1011
- workspaceClient;
1012
- constructor(workspaceClient) {
1013
- this.workspaceClient = workspaceClient;
1014
- }
1015
- async list() {
1016
- const response = await fetchWithTimeout(`${this.workspaceClient.baseUrl}/workspaces/${encodeURIComponent(this.workspaceClient.id)}/runtimes`, {
1017
- headers: buildHeaders(this.workspaceClient.apiKey),
1018
- });
1019
- const data = await expectJson(response, 'List runtimes');
1020
- return data.runtimes;
1021
- }
1022
- browser(alias) {
1023
- return new BrowserRuntimeBuilder(this.workspaceClient, alias);
1024
- }
1025
- }