agents 0.27.0 → 0.28.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 (216) hide show
  1. package/dist/abortable-C1SpfVoi.js +21 -0
  2. package/dist/abortable-C1SpfVoi.js.map +1 -0
  3. package/dist/{agent-routing-Bhdbvf7s.d.ts → agent-routing-BMvWTFEp.d.ts} +21 -15
  4. package/dist/agent-routing.d.ts +1 -1
  5. package/dist/agent-tool-types.d.ts +1 -1
  6. package/dist/{agent-tools-bJZwBMfq.d.ts → agent-tools-ohoewW-B.d.ts} +2 -2
  7. package/dist/agent-tools.d.ts +1 -1
  8. package/dist/ai-ahruGw7e.d.ts +239 -0
  9. package/dist/{ai-sdk-OoGkFy3s.js → ai-sdk-C2iTAwUd.js} +44 -18
  10. package/dist/ai-sdk-C2iTAwUd.js.map +1 -0
  11. package/dist/browser/ai.d.ts +8 -227
  12. package/dist/browser/ai.js +259 -1
  13. package/dist/browser/ai.js.map +1 -0
  14. package/dist/browser/index.d.ts +56 -46
  15. package/dist/browser/index.js +4 -361
  16. package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
  17. package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +5 -4
  18. package/dist/browser/tools/ai-sdk.js.map +1 -0
  19. package/dist/browser/tools/pi.d.ts +111 -0
  20. package/dist/browser/tools/pi.js +119 -0
  21. package/dist/browser/tools/pi.js.map +1 -0
  22. package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
  23. package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
  24. package/dist/browser/tools/tanstack-ai.js.map +1 -0
  25. package/dist/browser-CEdNlsaD.js +481 -0
  26. package/dist/browser-CEdNlsaD.js.map +1 -0
  27. package/dist/{browser-tmkcAAI3.d.ts → browser-D30VlpcA.d.ts} +63 -37
  28. package/dist/{browser-tool-CBqs6hqa.js → browser-tool-4iomavs_.js} +145 -49
  29. package/dist/browser-tool-4iomavs_.js.map +1 -0
  30. package/dist/{browser-tool-Bn-nzJQI.d.ts → browser-tool-vtrPOV8e.d.ts} +24 -5
  31. package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
  32. package/dist/capability-DBAKc6UZ.js.map +1 -0
  33. package/dist/{capability-runner-O5VbQzqg.d.ts → capability-runner-BiVUtjqC.d.ts} +1 -7
  34. package/dist/chat/index.d.ts +4 -4
  35. package/dist/chat/index.js +1 -1
  36. package/dist/chat-sdk/index.d.ts +1 -1
  37. package/dist/chat-sdk/index.js +1 -1
  38. package/dist/{client-1tEQ1Oqz.js → client-BnYbNT3z.js} +3 -4
  39. package/dist/client-BnYbNT3z.js.map +1 -0
  40. package/dist/{client-DS3Dz9l0.d.ts → client-Bp-JwL3p.d.ts} +2 -2
  41. package/dist/client.d.ts +1 -1
  42. package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
  43. package/dist/connector-CtZylXdk.js.map +1 -0
  44. package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
  45. package/dist/{conversations-DH0ut_8n.d.ts → conversations-FjHDRZyD.d.ts} +4 -4
  46. package/dist/{current-agent-C07C5o5Y.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
  47. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  48. package/dist/{durable-object-lifecycle-DRqp475_.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
  49. package/dist/experimental/channels/index.d.ts +2 -2
  50. package/dist/experimental/channels/index.js +2 -2
  51. package/dist/experimental/channels/web/index.d.ts +2 -2
  52. package/dist/experimental/channels/web/index.js +1 -1
  53. package/dist/{gateway-BDC07gYO.d.ts → gateway-BFO6vRDn.d.ts} +2 -2
  54. package/dist/{handler-stateless-VvrWSAVA.js → handler-stateless-Bly_nSH3.js} +12 -3
  55. package/dist/handler-stateless-Bly_nSH3.js.map +1 -0
  56. package/dist/harness/ai-sdk/index.d.ts +2 -2
  57. package/dist/harness/ai-sdk/index.js +1 -1
  58. package/dist/harness/container/index.d.ts +2 -2
  59. package/dist/harness/container/index.js +3 -3
  60. package/dist/harness/opencode/index.d.ts +183 -7
  61. package/dist/harness/opencode/index.js +355 -24
  62. package/dist/harness/opencode/index.js.map +1 -1
  63. package/dist/harness/pi/index.d.ts +2 -2
  64. package/dist/harness/pi/index.js +3 -3
  65. package/dist/harness/store/index.d.ts +1 -1
  66. package/dist/harness/store/index.js +1 -1
  67. package/dist/harness/think/index.d.ts +2 -2
  68. package/dist/harness/think/index.js +363 -171
  69. package/dist/harness/think/index.js.map +1 -1
  70. package/dist/{images-Ce9SCu3X.js → images-C4hiIexM.js} +46 -4
  71. package/dist/images-C4hiIexM.js.map +1 -0
  72. package/dist/{index-D0A5tbWu.d.ts → index-BEL3ZV-s.d.ts} +2 -6
  73. package/dist/{index-Ib_4dwOo.d.ts → index-CBt8oRJt.d.ts} +3 -5
  74. package/dist/index.d.ts +4 -4
  75. package/dist/index.js +2 -2
  76. package/dist/input-schema-BQykTEp_.js +20 -0
  77. package/dist/input-schema-BQykTEp_.js.map +1 -0
  78. package/dist/{input-schema-DNrpTu49.js → input-schema-xBofjBKC.js} +3 -3
  79. package/dist/input-schema-xBofjBKC.js.map +1 -0
  80. package/dist/internal_context.d.ts +1 -1
  81. package/dist/lifecycle/index.d.ts +3 -3
  82. package/dist/lifecycle/index.js +2 -2
  83. package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
  84. package/dist/lifecycle-DGorpAmA.js.map +1 -0
  85. package/dist/mcp/client/index.d.ts +1 -1
  86. package/dist/mcp/client/index.js +1 -1
  87. package/dist/mcp/index.d.ts +1 -1
  88. package/dist/mcp/index.js +18 -4
  89. package/dist/mcp/index.js.map +1 -1
  90. package/dist/mcp/server/index.js +1 -1
  91. package/dist/models/ai-sdk/index.d.ts +45 -17
  92. package/dist/models/ai-sdk/index.js +1 -1
  93. package/dist/models/opencode/index.d.ts +2 -2
  94. package/dist/models/opencode/index.js +1 -1
  95. package/dist/models/pi-ai/index.d.ts +8 -3
  96. package/dist/models/pi-ai/index.js +6 -6
  97. package/dist/models/pi-ai/index.js.map +1 -1
  98. package/dist/{options-pwTNq9z6.d.ts → options-CiIsJHXR.d.ts} +2 -6
  99. package/dist/queue/index.d.ts +1 -1
  100. package/dist/queue/index.js +1 -1
  101. package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
  102. package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
  103. package/dist/react.d.ts +2 -2
  104. package/dist/routing/index.d.ts +2 -2
  105. package/dist/routing/index.js +1 -1
  106. package/dist/{scheduler-CrFCnv_J.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
  107. package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
  108. package/dist/scheduler-FIHv2-kJ.js.map +1 -0
  109. package/dist/schedules/index.d.ts +1 -1
  110. package/dist/schedules/index.js +1 -1
  111. package/dist/serializable.d.ts +1 -1
  112. package/dist/session-store-Do4xkDcf.js +606 -0
  113. package/dist/session-store-Do4xkDcf.js.map +1 -0
  114. package/dist/session-store-DoPY12xM.d.ts +383 -0
  115. package/dist/sessions/index.d.ts +1 -1
  116. package/dist/sessions/index.js +1 -1
  117. package/dist/{sessions-B9pNuxdT.js → sessions-_vN5BEZX.js} +2 -2
  118. package/dist/{sessions-B9pNuxdT.js.map → sessions-_vN5BEZX.js.map} +1 -1
  119. package/dist/{settings-C45hDliX.js → settings-BjAiPd6Z.js} +7 -4
  120. package/dist/settings-BjAiPd6Z.js.map +1 -0
  121. package/dist/{settings-NgGwF7Qt.d.ts → settings-DnD__xuE.d.ts} +22 -4
  122. package/dist/{src-DgCbZtIR.js → src-CQxJFv4l.js} +8 -8
  123. package/dist/src-CQxJFv4l.js.map +1 -0
  124. package/dist/state/index.d.ts +1 -1
  125. package/dist/state/index.js +1 -3
  126. package/dist/state/index.js.map +1 -1
  127. package/dist/{store-DLeqKuj3.d.ts → store-BKM4Xm9M.d.ts} +23 -1
  128. package/dist/{store-vgcPYo8K.js → store-CslVzfN7.js} +28 -2
  129. package/dist/store-CslVzfN7.js.map +1 -0
  130. package/dist/streams/index.d.ts +1 -1
  131. package/dist/streams/index.js +1 -1
  132. package/dist/{streams-CITClVer.js → streams-lsHMJhRW.js} +2 -2
  133. package/dist/{streams-CITClVer.js.map → streams-lsHMJhRW.js.map} +1 -1
  134. package/dist/{streams-fbG61qM8.d.ts → streams-vrCtbUIn.d.ts} +2 -2
  135. package/dist/sub-routing.d.ts +1 -1
  136. package/dist/tasks/index.d.ts +1 -1
  137. package/dist/tasks/index.js +1 -1
  138. package/dist/{tasks-CkTZNaV1.js → tasks-BN_5AWqI.js} +2 -2
  139. package/dist/{tasks-CkTZNaV1.js.map → tasks-BN_5AWqI.js.map} +1 -1
  140. package/dist/{tasks-PtlB4Uyn.d.ts → tasks-E89KdwkS.d.ts} +2 -2
  141. package/dist/{tool-BPJEbwaX.d.ts → tool-CTp72Jb_.d.ts} +4 -4
  142. package/dist/tool-CxKsvxjm.js +1126 -0
  143. package/dist/tool-CxKsvxjm.js.map +1 -0
  144. package/dist/tool-DoVberpN.d.ts +301 -0
  145. package/dist/{tool-3PA8xjB_.js → tool-VF0qiO7q.js} +7 -18
  146. package/dist/tool-VF0qiO7q.js.map +1 -0
  147. package/dist/tool-helpers-O5BDVEAY.js +58 -0
  148. package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
  149. package/dist/{transport-k2mFrtL8.d.ts → transport-DCyarnwm.d.ts} +2 -2
  150. package/dist/voice/index.d.ts +2 -2
  151. package/dist/web/fetch/index.d.ts +89 -0
  152. package/dist/web/fetch/index.js +20 -0
  153. package/dist/web/fetch/index.js.map +1 -0
  154. package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
  155. package/dist/web/fetch/tools/ai-sdk.js +47 -0
  156. package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
  157. package/dist/web/fetch/tools/pi.d.ts +84 -0
  158. package/dist/web/fetch/tools/pi.js +88 -0
  159. package/dist/web/fetch/tools/pi.js.map +1 -0
  160. package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
  161. package/dist/web/fetch/tools/tanstack-ai.js +45 -0
  162. package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
  163. package/dist/{websearch → web/search}/index.d.ts +1 -1
  164. package/dist/{websearch → web/search}/index.js +1 -1
  165. package/dist/{websearch → web/search}/tools/ai-sdk.d.ts +2 -2
  166. package/dist/{websearch → web/search}/tools/ai-sdk.js +3 -3
  167. package/dist/web/search/tools/ai-sdk.js.map +1 -0
  168. package/dist/{websearch → web/search}/tools/pi.d.ts +3 -3
  169. package/dist/{websearch → web/search}/tools/pi.js +2 -2
  170. package/dist/web/search/tools/pi.js.map +1 -0
  171. package/dist/{websearch → web/search}/tools/tanstack-ai.d.ts +2 -2
  172. package/dist/{websearch → web/search}/tools/tanstack-ai.js +3 -3
  173. package/dist/web/search/tools/tanstack-ai.js.map +1 -0
  174. package/dist/websockets/index.d.ts +2 -2
  175. package/dist/websockets/index.js +1 -1
  176. package/dist/{websockets-CmENGb-Z.js → websockets-C3zy8YR0.js} +3 -5
  177. package/dist/websockets-C3zy8YR0.js.map +1 -0
  178. package/dist/workflow-types.d.ts +1 -1
  179. package/dist/workflows.d.ts +1 -1
  180. package/dist/workflows.js +1 -1
  181. package/docs/browse-the-web.md +26 -1
  182. package/docs/fetch-the-web.md +276 -0
  183. package/docs/harnesses/pi.md +25 -0
  184. package/docs/index.md +99 -76
  185. package/docs/lifecycle.md +2 -3
  186. package/docs/mcp-client.md +1 -1
  187. package/docs/mcp-servers.md +1 -1
  188. package/docs/models-pi-ai.md +11 -0
  189. package/docs/models.md +45 -3
  190. package/docs/queue.md +2 -3
  191. package/docs/scheduling.md +2 -6
  192. package/docs/search-the-web.md +2 -0
  193. package/package.json +52 -27
  194. package/dist/ai-fm7xx1BK.js +0 -312
  195. package/dist/ai-fm7xx1BK.js.map +0 -1
  196. package/dist/ai-sdk-OoGkFy3s.js.map +0 -1
  197. package/dist/browser/ai-sdk.js.map +0 -1
  198. package/dist/browser/index.js.map +0 -1
  199. package/dist/browser/tanstack-ai.js.map +0 -1
  200. package/dist/browser-tool-CBqs6hqa.js.map +0 -1
  201. package/dist/capability-B4WbF81e.js.map +0 -1
  202. package/dist/client-1tEQ1Oqz.js.map +0 -1
  203. package/dist/connector-58XDGvc3.js.map +0 -1
  204. package/dist/handler-stateless-VvrWSAVA.js.map +0 -1
  205. package/dist/images-Ce9SCu3X.js.map +0 -1
  206. package/dist/input-schema-DNrpTu49.js.map +0 -1
  207. package/dist/lifecycle-CFu6OV03.js.map +0 -1
  208. package/dist/scheduler-DZ3xQfeK.js.map +0 -1
  209. package/dist/settings-C45hDliX.js.map +0 -1
  210. package/dist/src-DgCbZtIR.js.map +0 -1
  211. package/dist/store-vgcPYo8K.js.map +0 -1
  212. package/dist/tool-3PA8xjB_.js.map +0 -1
  213. package/dist/websearch/tools/ai-sdk.js.map +0 -1
  214. package/dist/websearch/tools/pi.js.map +0 -1
  215. package/dist/websearch/tools/tanstack-ai.js.map +0 -1
  216. package/dist/websockets-CmENGb-Z.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-tool-4iomavs_.js","names":[],"sources":["../src/browser/session-connector.ts","../src/browser/browser-tool.ts"],"sourcesContent":["import {\n CodemodeConnector,\n MAX_DURABLE_VALUE_BYTES,\n type ConnectorTool,\n type ConnectorTools,\n type ToolExecuteContext\n} from \"@cloudflare/codemode\";\nimport { validateConnectorArgs } from \"./connector-validation\";\nimport {\n CDP_METHOD_NOT_FOUND,\n CdpProtocolError,\n type CdpConnection\n} from \"./cdp-connection\";\nimport type { BrowserConnection, BrowserConnectOptions } from \"./browser\";\nimport type { SearchableCdpSpec } from \"./spec\";\n\n/**\n * Where a {@link BrowserSessionConnector} gets its browser. Usually a\n * `Browser` installed on the host's Lifecycle.\n */\nexport interface BrowserSource {\n /** The browser's name, for log messages. */\n readonly name: string;\n /**\n * Reattach to the browser (or replace it) and open a CDP connection for\n * a scope. A source that ignores `scope` shares one active tab between\n * every caller.\n */\n connect(options?: BrowserConnectOptions): Promise<BrowserConnection>;\n}\n\nexport interface BrowserSessionConnectorOptions {\n /** The persistent browser this connector drives. */\n browser: BrowserSource;\n /**\n * The scope this connector's executions work in: they share one active\n * tab, kept apart from other scopes'. Defaults to the browser's default\n * scope.\n */\n scope?: string;\n}\n\n/** A tab a page opened on its own during an execution. */\nexport interface BrowserNewTab {\n targetId: string;\n url?: string;\n title?: string;\n}\n\n/**\n * What happened to the browser during one execution, beyond the code's own\n * result — read by the tool after the run via\n * {@link BrowserSessionConnector.takeReport}.\n */\nexport interface BrowserExecutionReport {\n /** The browser was replaced before this run; earlier page state is gone. */\n restarted: boolean;\n /** Tabs the page opened itself (popups, `target=_blank`). */\n newTabs: BrowserNewTab[];\n /**\n * The tab this scope was working in was closed by someone else (another\n * scope, or a person in Live View), so `\"active\"` will be a new blank tab.\n */\n tabClosed: boolean;\n /** Another scope is working in this scope's active tab too. */\n tabShared: boolean;\n}\n\n/** `sessionId` value that addresses the tab the agent is working in. */\nexport const ACTIVE_PAGE_SESSION = \"active\";\n\n/**\n * `cdp.attachToTarget` returns `{ sessionId: \"target:<targetId>\" }` — a\n * stable handle rather than a connection-scoped CDP session id, so replayed\n * code computes identical arguments. `send` resolves it on the live socket.\n */\nconst ATTACH_HANDLE_PREFIX = \"target:\";\n\n/** Chrome's JSON-RPC code for a CDP session id it doesn't know. */\nconst CDP_SESSION_NOT_FOUND = -32001;\n\n/**\n * Codemode records every `send` result for replay and fails the run when one\n * is over {@link MAX_DURABLE_VALUE_BYTES}, telling the model to write to a\n * file, which this sandbox can't. A full-page screenshot is the usual\n * culprit, so say how to take a smaller one instead.\n */\nfunction assertScreenshotFits(result: unknown): void {\n // Measure the result as codemode stores it (JSON), not just the data, so a\n // screenshot just under the limit can't slip past with its JSON framing.\n const size = JSON.stringify(result ?? null).length;\n if (size <= MAX_DURABLE_VALUE_BYTES) return;\n const megabytes = (size / 1_000_000).toFixed(1);\n throw new Error(\n `The screenshot result is ${megabytes} MB, over the 1 MB limit on a ` +\n `cdp.send result. Capture just the viewport (no captureBeyondViewport ` +\n `or clip larger than the window), or pass format: \"jpeg\" with ` +\n `quality: 60.`\n );\n}\n\n/** {@link BrowserSessionConnector} `#liveParams`: nothing to detach. */\nconst DETACHED = Symbol(\"detached\");\n\n/** Reports awaiting their tool call; bounded in case a caller never reads. */\nconst MAX_PENDING_REPORTS = 100;\n\n/**\n * Commands that would end the browser. The host owns its lifetime, so the\n * model can't close it out from under the agent (and lose its logins).\n */\nconst BROWSER_LIFETIME_COMMANDS = new Set([\n \"Browser.close\",\n \"Browser.crash\",\n \"Browser.crashGpuProcess\"\n]);\n\n/** A CDP target id — for this connector, a tab. */\ntype TargetId = string & { readonly __brand: \"TargetId\" };\n\n/** A CDP session id from `Target.attachToTarget`, valid on one socket only. */\ntype LiveSessionId = string & { readonly __brand: \"LiveSessionId\" };\n\n/** The stable `sessionId` handle `cdp.attachToTarget` gives the model. */\ntype AttachHandle = `${typeof ATTACH_HANDLE_PREFIX}${string}`;\n\ninterface TargetInfo {\n targetId: TargetId;\n type: string;\n url?: string;\n title?: string;\n /** The tab that opened this one (popups, `target=_blank` links). */\n openerId?: TargetId;\n}\n\n/** Per-execution state for one pass. Dropped when the pass ends. */\ninterface ExecutionState {\n executionId: string;\n connected: BrowserConnection;\n /** Live CDP session per target, valid on this socket only. */\n attached: Map<TargetId, LiveSessionId>;\n /**\n * Tabs this pass attached to, through the connector or a raw\n * `Target.attachToTarget`. Their popups are this pass's new tabs.\n */\n workedIn: Set<TargetId>;\n /** Page targets open when the pass connected. */\n initialPages: Set<TargetId>;\n /** The tab `\"active\"` resolves to — decided lazily on first use. */\n activeTargetId?: TargetId;\n /** Whether {@link activeTargetId} was decided (vs. never needed). */\n activeResolved: boolean;\n /** Tabs this pass closed with `Target.closeTarget`. */\n closed: Set<TargetId>;\n}\n\n/**\n * How to use the `cdp` connector, one rule per line. `codemode.describe(\"cdp\")`\n * returns these, and `browserTool` puts them in its description. Each rule\n * fixes a mistake models make with CDP, or states something about this\n * browser they can't know; leave out what a model knows already.\n */\nexport const BROWSER_INSTRUCTIONS = [\n \"The browser persists between runs: tabs, cookies, and logins are still there next time. You never start or close it.\",\n \"If the browser was replaced (idle timeout, crash), the result says restarted: true and earlier tabs and logins are gone. Before an action that matters (submitting a form, a purchase), check you're on the page you expect.\",\n 'Page-scoped commands (Page.*, Runtime.*, DOM.*, Input.*, Network.*, Emulation.*) need sessionId: \"active\", your tab, which is remembered between runs. Browser.* and Target.* commands take no sessionId.',\n \"Other open tabs (Target.getTargets) may belong to other conversations using this browser: don't close, navigate, or attach to a tab you didn't open unless the user asks.\",\n \"Target.createTarget opens a tab and makes it active. To switch to another open tab, call cdp.attachToTarget({ targetId }); the sessionId it returns keeps working in later runs, while one from a raw Target.attachToTarget only works in the current run.\",\n \"Tabs a page opens itself (popups, target=_blank links) don't become active; the result lists them as newTabs.\",\n \"Runtime.evaluate: pass returnByValue: true, or objects come back as a remote reference with no value, and awaitPromise: true for async expressions. The value is at result.value. A thrown error doesn't reject: check exceptionDetails.\",\n \"Page.navigate returns before the page loads and doesn't throw when it fails: check errorText, then poll document.readyState with Runtime.evaluate until it is 'complete'.\",\n \"Pick out what you need inside Runtime.evaluate and return only that. Results over about 24,000 characters are cut short, and a single cdp.send result over 1 MB (a full-page screenshot, say) fails the run.\"\n].join(\"\\n\");\n\n/**\n * Codemode connector exposing one host-named, persistent browser over the\n * Chrome DevTools Protocol as the `cdp` global.\n *\n * The model never manages sessions: every execution reattaches to the\n * browser (or gets a replacement, reported as `restarted`), and\n * `sessionId: \"active\"` addresses the tab it last worked in. The active tab\n * is stored per scope (see {@link BrowserSessionConnectorOptions.scope}), so\n * it survives between executions for as long as the tab does, and one\n * scope's executions never land in another scope's tab unless the model\n * attaches to it.\n *\n * The CDP socket is per pass: opened on the first call, closed when the pass\n * ends. The browser itself outlives the execution.\n */\nexport class BrowserSessionConnector extends CodemodeConnector {\n readonly #browser: BrowserSource;\n readonly #scope: string | undefined;\n #states = new Map<string, ExecutionState>();\n #connecting = new Map<string, Promise<ExecutionState>>();\n /**\n * In memory, on this instance. An execution resumed after an approval\n * pause may run on a fresh connector, whose report starts over. Nothing\n * pauses today — the browser tool wires no approval tools — so reporting\n * across a resume is left for when approvals are added.\n *\n * The same goes for raw CDP session ids from `Target.attachToTarget` sent\n * through `send`: they belong to one pass's socket, so a replay after a\n * pause would reuse a dead id. The stable handles from `attachToTarget`\n * are the replay-safe path.\n */\n #reports = new Map<string, BrowserExecutionReport>();\n\n constructor(\n ctx: DurableObjectState | ExecutionContext,\n options: BrowserSessionConnectorOptions\n ) {\n super(ctx, {});\n this.#browser = options.browser;\n this.#scope = options.scope;\n }\n\n name(): string {\n return \"cdp\";\n }\n\n protected instructions(): string {\n return BROWSER_INSTRUCTIONS;\n }\n\n protected override tool(name: string, tool: ConnectorTool): ConnectorTool {\n return validateConnectorArgs(this.name(), name, tool);\n }\n\n protected tools(): ConnectorTools {\n return {\n send: {\n description:\n 'Send a CDP command and return its method result directly. Pass sessionId: \"active\" for page-scoped commands; omit it for Browser/Target commands.',\n inputSchema: {\n type: \"object\",\n properties: {\n method: {\n type: \"string\",\n description: 'CDP method, e.g. \"Page.navigate\"'\n },\n params: {\n type: \"object\",\n description: \"CDP command parameters\"\n },\n sessionId: {\n type: \"string\",\n description:\n '\"active\" for the current tab, or a handle from attachToTarget. Omit for Browser/Target commands.'\n },\n timeoutMs: {\n type: \"number\",\n description: \"Per-command timeout override in milliseconds\"\n }\n },\n required: [\"method\"]\n },\n execute: async (args, ctx) => {\n const { method, params, sessionId, timeoutMs } = args as {\n method: string;\n params?: Record<string, unknown>;\n sessionId?: string;\n timeoutMs?: number;\n };\n if (BROWSER_LIFETIME_COMMANDS.has(method)) {\n throw new Error(\n `${method} is not available: this browser is managed for you ` +\n `and persists between runs. To close a tab, send ` +\n `Target.closeTarget with its targetId.`\n );\n }\n const state = await this.#state(this.#executionId(ctx));\n const live = await this.#resolveSessionId(state, sessionId);\n const liveParams = this.#liveParams(state, method, params);\n if (liveParams === DETACHED) return {};\n let result: unknown;\n try {\n result = await state.connected.cdp.send(method, liveParams, {\n sessionId: live,\n timeoutMs\n });\n } catch (error) {\n throw await this.#teach(state, error, method, sessionId);\n }\n this.#observe(state, method, liveParams, result);\n if (method === \"Page.captureScreenshot\") {\n assertScreenshotFits(result);\n }\n return result;\n }\n },\n\n attachToTarget: {\n description:\n \"Switch to an open tab: make it the active tab and return { sessionId } — a handle you can pass to page-scoped send calls for that tab.\",\n inputSchema: {\n type: \"object\",\n properties: {\n targetId: {\n type: \"string\",\n description: \"Target id from Target.getTargets/createTarget\"\n },\n timeoutMs: { type: \"number\" }\n },\n required: [\"targetId\"]\n },\n outputSchema: {\n type: \"object\",\n properties: {\n sessionId: {\n type: \"string\",\n description: \"Session handle for page-scoped send calls\"\n }\n },\n required: [\"sessionId\"]\n },\n execute: async (args, ctx) => {\n const { targetId, timeoutMs } = args as {\n targetId: TargetId;\n timeoutMs?: number;\n };\n const state = await this.#state(this.#executionId(ctx));\n await this.#attach(state, targetId, timeoutMs);\n this.#setActive(state, targetId);\n return { sessionId: attachHandle(targetId) };\n }\n },\n\n spec: {\n description:\n \"Return the searchable Chrome DevTools Protocol spec: domains with their commands, events, and types.\",\n replay: \"reexecute\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (_args, ctx): Promise<SearchableCdpSpec> => {\n const state = await this.#state(this.#executionId(ctx));\n return state.connected.spec();\n }\n },\n\n getDebugLog: {\n description:\n \"Return recent CDP protocol traffic (sends, receives, warnings) for this execution — useful to diagnose failures and timeouts.\",\n replay: \"reexecute\",\n inputSchema: {\n type: \"object\",\n properties: {\n limit: {\n type: \"number\",\n minimum: 1,\n description:\n \"Max entries to return, newest last (default 50; only the last 400 are kept)\"\n }\n }\n },\n execute: async (args, ctx) => {\n const { limit } = (args ?? {}) as { limit?: number };\n const state = await this.#state(this.#executionId(ctx));\n return state.connected.cdp.getDebugLog(limit);\n }\n },\n\n clearDebugLog: {\n description: \"Clear the CDP debug log for this execution.\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (_args, ctx) => {\n const state = await this.#state(this.#executionId(ctx));\n state.connected.cdp.clearDebugLog();\n return null;\n }\n }\n };\n }\n\n // ── Codemode execution hooks ─────────────────────────────────────────────\n\n /**\n * The pass is over: note tabs the page opened, save the scope's active\n * tab, note whether another scope shares it, and drop the socket. The\n * browser stays alive.\n */\n override async onPassEnd(executionId: string): Promise<void> {\n const state = this.#states.get(executionId);\n if (!state) return;\n this.#states.delete(executionId);\n try {\n const open = await this.#recordNewTabs(executionId, state);\n const active = await this.#saveActiveTarget(state, open);\n if (active && state.activeResolved) {\n await this.#recordSharedTab(state, active);\n }\n } finally {\n state.connected.cdp.disconnect();\n }\n }\n\n /** Nothing per execution outlives the pass; the named browser persists. */\n override async disposeExecution(executionId: string): Promise<void> {\n const state = this.#states.get(executionId);\n if (!state) return;\n this.#states.delete(executionId);\n state.connected.cdp.disconnect();\n }\n\n /**\n * Take (and forget) what happened to the browser during an execution.\n * `undefined` when the execution never touched the browser. Covers the\n * passes this instance ran; see the note on `#reports`.\n */\n takeReport(executionId: string): BrowserExecutionReport | undefined {\n const report = this.#reports.get(executionId);\n this.#reports.delete(executionId);\n return report;\n }\n\n // ── Internals ────────────────────────────────────────────────────────────\n\n #executionId(ctx: ToolExecuteContext | undefined): string {\n if (!ctx?.executionId) {\n throw new Error(\"Browser tools must run inside a codemode execution\");\n }\n return ctx.executionId;\n }\n\n /**\n * Connect once per pass. Concurrent first calls (model code that uses\n * Promise.all despite the instructions) share one connect.\n */\n #state(executionId: string): Promise<ExecutionState> {\n const existing = this.#states.get(executionId);\n if (existing) return Promise.resolve(existing);\n const inFlight = this.#connecting.get(executionId);\n if (inFlight) return inFlight;\n const promise = this.#connect(executionId).finally(() => {\n this.#connecting.delete(executionId);\n });\n this.#connecting.set(executionId, promise);\n return promise;\n }\n\n async #connect(executionId: string): Promise<ExecutionState> {\n const connected = await this.#browser.connect(\n this.#scope === undefined ? undefined : { scope: this.#scope }\n );\n let initialPages: TargetInfo[];\n try {\n initialPages = await this.#pages(connected.cdp);\n } catch (error) {\n connected.cdp.disconnect();\n throw error;\n }\n const state: ExecutionState = {\n executionId,\n connected,\n attached: new Map(),\n workedIn: new Set(),\n initialPages: new Set(initialPages.map((page) => page.targetId)),\n activeResolved: false,\n closed: new Set()\n };\n this.#states.set(executionId, state);\n this.#report(executionId, connected.restarted);\n return state;\n }\n\n #report(executionId: string, restarted: boolean): BrowserExecutionReport {\n let report = this.#reports.get(executionId);\n if (!report) {\n report = { restarted, newTabs: [], tabClosed: false, tabShared: false };\n this.#reports.set(executionId, report);\n if (this.#reports.size > MAX_PENDING_REPORTS) {\n const oldest = this.#reports.keys().next().value;\n if (oldest !== undefined) this.#reports.delete(oldest);\n }\n }\n // A replacement on any pass means earlier page state is gone.\n report.restarted ||= restarted;\n return report;\n }\n\n /**\n * Add tabs the page opened this pass to the execution's report, and drop\n * earlier ones that have since closed: `newTabs` lists page-opened tabs\n * still open when the execution ends, across every pass. Returns the open\n * tabs, or `undefined` when the browser couldn't be asked.\n */\n async #recordNewTabs(\n executionId: string,\n state: ExecutionState\n ): Promise<Set<TargetId> | undefined> {\n let pages: TargetInfo[];\n try {\n pages = await this.#pages(state.connected.cdp);\n } catch (error) {\n this.#warn(\"list the open tabs\", error);\n return undefined;\n }\n const report = this.#report(executionId, state.connected.restarted);\n const opened = new Set<string>(report.newTabs.map((tab) => tab.targetId));\n // A new tab is this execution's when its opener is a tab this pass\n // worked in, or another of its new tabs (a popup's popup). Chrome sets\n // openerId only on tabs a page opened, never on Target.createTarget\n // tabs, and a popup another scope's page opened meanwhile has that\n // scope's tab as its opener.\n let grew = true;\n while (grew) {\n grew = false;\n for (const page of pages) {\n const opener = page.openerId;\n if (\n !opener ||\n opened.has(page.targetId) ||\n state.initialPages.has(page.targetId)\n ) {\n continue;\n }\n if (state.workedIn.has(opener) || opened.has(opener)) {\n opened.add(page.targetId);\n grew = true;\n }\n }\n }\n report.newTabs = pages\n .filter((page) => opened.has(page.targetId))\n .map(({ targetId, url, title }) => ({ targetId, url, title }));\n return new Set(pages.map((page) => page.targetId));\n }\n\n /**\n * Save the tab this pass settled on, forgetting one that has since closed,\n * and return it. Without the list of open tabs, save the choice\n * unchecked: the next execution checks the stored tab is still open\n * before using it.\n */\n async #saveActiveTarget(\n state: ExecutionState,\n open: Set<TargetId> | undefined\n ): Promise<TargetId | undefined> {\n const stored = state.connected.activeTargetId as TargetId | undefined;\n // A pass that never used \"active\" still sees the stored tab is gone;\n // say so now, since the next pass won't know there was one.\n if (\n !state.activeResolved &&\n stored &&\n open &&\n !open.has(stored) &&\n !state.closed.has(stored)\n ) {\n this.#report(state.executionId, state.connected.restarted).tabClosed =\n true;\n }\n const candidate = state.activeResolved ? state.activeTargetId : stored;\n const active =\n candidate && (!open || open.has(candidate)) ? candidate : undefined;\n if (active === stored) return active;\n try {\n await state.connected.setActiveTarget(active);\n } catch (error) {\n this.#warn(\"save the active tab\", error);\n }\n return active;\n }\n\n /** Report when another scope is working in this pass's tab too. */\n async #recordSharedTab(\n state: ExecutionState,\n active: TargetId\n ): Promise<void> {\n try {\n const others = await state.connected.targetsInOtherScopes();\n if (others.has(active)) {\n this.#report(state.executionId, state.connected.restarted).tabShared =\n true;\n }\n } catch (error) {\n this.#warn(\"check whether the active tab is shared\", error);\n }\n }\n\n #warn(action: string, error: unknown): void {\n console.warn(\n `[agents/browser] Failed to ${action} for browser \"${this.#browser.name}\"`,\n error\n );\n }\n\n async #pages(cdp: CdpConnection): Promise<TargetInfo[]> {\n const result = (await cdp.send(\"Target.getTargets\")) as {\n targetInfos?: TargetInfo[];\n };\n return (result?.targetInfos ?? []).filter((info) => info.type === \"page\");\n }\n\n async #resolveSessionId(\n state: ExecutionState,\n sessionId: string | undefined\n ): Promise<LiveSessionId | undefined> {\n if (sessionId === ACTIVE_PAGE_SESSION) {\n return this.#attach(state, await this.#activeTarget(state));\n }\n if (isAttachHandle(sessionId)) {\n return this.#attach(state, targetOfHandle(sessionId));\n }\n // Omitted, or a raw CDP session id the model got from send().\n return sessionId as LiveSessionId | undefined;\n }\n\n /**\n * Decide which tab `\"active\"` means, once per pass: the scope's stored tab\n * if it is still open, else a new blank tab. Never a tab the scope didn't\n * open, even a blank one: it may be another scope's, or a popup.\n */\n async #activeTarget(state: ExecutionState): Promise<TargetId> {\n if (state.activeTargetId) return state.activeTargetId;\n const { connected } = state;\n const pages = await this.#pages(connected.cdp);\n const stored = connected.activeTargetId as TargetId | undefined;\n let targetId = pages.find((page) => page.targetId === stored)?.targetId;\n if (!targetId && stored && !state.closed.has(stored)) {\n this.#report(state.executionId, connected.restarted).tabClosed = true;\n }\n if (!targetId) {\n const created = (await connected.cdp.send(\"Target.createTarget\", {\n url: \"about:blank\"\n })) as { targetId: TargetId };\n targetId = created.targetId;\n }\n this.#setActive(state, targetId);\n return targetId;\n }\n\n #setActive(state: ExecutionState, targetId: TargetId | undefined): void {\n state.activeTargetId = targetId;\n state.activeResolved = true;\n }\n\n async #attach(\n state: ExecutionState,\n targetId: TargetId,\n timeoutMs?: number\n ): Promise<LiveSessionId> {\n const existing = state.attached.get(targetId);\n if (existing) return existing;\n const live = (await state.connected.cdp.attachToTarget(targetId, {\n timeoutMs\n })) as LiveSessionId;\n state.attached.set(targetId, live);\n state.workedIn.add(targetId);\n return live;\n }\n\n /** Track tab changes the model makes through raw Target commands. */\n #observe(\n state: ExecutionState,\n method: string,\n params: Record<string, unknown> | undefined,\n result: unknown\n ): void {\n const targetId =\n typeof params?.targetId === \"string\"\n ? (params.targetId as TargetId)\n : undefined;\n if (method === \"Target.createTarget\") {\n const created = (result as { targetId?: unknown } | undefined)?.targetId;\n if (typeof created === \"string\") {\n this.#setActive(state, created as TargetId);\n }\n } else if (method === \"Target.attachToTarget\" && targetId) {\n this.#setActive(state, targetId);\n state.workedIn.add(targetId);\n } else if (method === \"Target.closeTarget\" && targetId) {\n state.attached.delete(targetId);\n state.closed.add(targetId);\n // The next \"active\" use picks a tab afresh.\n if (state.activeTargetId === targetId) state.activeTargetId = undefined;\n } else if (method === \"Target.detachFromTarget\") {\n // Forget a session the model detached, so the next use reattaches.\n for (const [target, live] of state.attached) {\n if (target === targetId || live === params?.sessionId) {\n state.attached.delete(target);\n }\n }\n }\n }\n\n /**\n * Swap a handle in `Target.detachFromTarget`'s `sessionId` param for the\n * live CDP session id. Returns {@link DETACHED} when the handle's tab isn't\n * attached on this socket, so there is nothing to detach.\n */\n #liveParams(\n state: ExecutionState,\n method: string,\n params: Record<string, unknown> | undefined\n ): Record<string, unknown> | undefined | typeof DETACHED {\n const handle = params?.sessionId;\n if (method !== \"Target.detachFromTarget\" || typeof handle !== \"string\") {\n return params;\n }\n if (!isAttachHandle(handle)) return params;\n const live = state.attached.get(targetOfHandle(handle));\n return live ? { ...params, sessionId: live } : DETACHED;\n }\n\n /**\n * Turn the common protocol mistakes into instructions: sending an\n * event as a command, and a page-scoped command without a session.\n */\n async #teach(\n state: ExecutionState,\n error: unknown,\n method: string,\n sessionId: string | undefined\n ): Promise<unknown> {\n if (!(error instanceof CdpProtocolError)) return error;\n if (\n error.code === CDP_SESSION_NOT_FOUND &&\n sessionId &&\n sessionId !== ACTIVE_PAGE_SESSION &&\n !isAttachHandle(sessionId)\n ) {\n return new Error(\n `${error.message}. CDP session ids don't carry over between runs. ` +\n `Use sessionId: \"active\" for the current tab, or the handle from ` +\n `cdp.attachToTarget({ targetId }) for another tab.`\n );\n }\n if (error.code !== CDP_METHOD_NOT_FOUND) return error;\n if (await this.#isEvent(state, method)) {\n return new Error(\n `${error.message}. '${method}' is a CDP *event*, not a command — it ` +\n `cannot be sent. To wait for page state, poll instead (e.g. ` +\n `Runtime.evaluate of document.readyState until \"complete\").`\n );\n }\n if (!sessionId) {\n return new Error(\n `${error.message}. '${method}' is page-scoped: pass sessionId: ` +\n `\"active\" to run it in the current tab — ` +\n `cdp.send({ method: \"${method}\", params, sessionId: \"active\" }).`\n );\n }\n return error;\n }\n\n async #isEvent(state: ExecutionState, method: string): Promise<boolean> {\n try {\n const spec = await state.connected.spec();\n const domain = method.split(\".\")[0];\n return spec.domains.some(\n (d) => d.name === domain && d.events.some((e) => e.event === method)\n );\n } catch {\n return false;\n }\n }\n}\n\nfunction attachHandle(targetId: TargetId): AttachHandle {\n return `${ATTACH_HANDLE_PREFIX}${targetId}`;\n}\n\nfunction isAttachHandle(\n sessionId: string | undefined\n): sessionId is AttachHandle {\n return sessionId?.startsWith(ATTACH_HANDLE_PREFIX) ?? false;\n}\n\nfunction targetOfHandle(handle: AttachHandle): TargetId {\n return handle.slice(ATTACH_HANDLE_PREFIX.length) as TargetId;\n}\n","/**\n * The harness-neutral core of `browserTool`, shared by the adapters in\n * `tools/` (`agents/browser/ai-sdk`, `agents/browser/tanstack-ai`,\n * `agents/browser/pi`).\n * Internal — not an entry point.\n */\nimport {\n createCodemodeRuntime,\n DynamicWorkerExecutor,\n type ProxyToolOutput\n} from \"@cloudflare/codemode\";\nimport { DEFAULT_BROWSER_SCOPE } from \"./browser\";\nimport {\n BROWSER_INSTRUCTIONS,\n BrowserSessionConnector,\n type BrowserExecutionReport,\n type BrowserNewTab,\n type BrowserSource\n} from \"./session-connector\";\nimport { resolveCtx, transformBrowserResult } from \"./tool-helpers\";\n\nexport interface BrowserToolOptions {\n /**\n * The browser the tool drives — usually a `Browser` installed on the\n * host's Lifecycle. Tools built from the same `Browser` share it.\n */\n browser: BrowserSource;\n\n /**\n * WorkerLoader binding for sandboxed code execution.\n *\n * Requires `\"worker_loaders\": [{ \"binding\": \"LOADER\" }]` in wrangler.jsonc.\n */\n loader: WorkerLoader;\n\n /** Sandbox execution timeout in milliseconds. Defaults to 60000 (60s). */\n timeoutMs?: number;\n\n /**\n * Who is driving, when several chats or users share one `Browser`: runs\n * with the same scope share an active tab, and each scope keeps its own.\n * Cookies and logins are shared by every scope. Defaults to `\"shared\"`,\n * one active tab for every tool that leaves it out.\n */\n scope?: string;\n\n /**\n * Durable Object state for the codemode runtime facet. Optional inside an\n * Agent (resolved via `getCurrentAgent()`); pass it explicitly elsewhere.\n *\n * The worker must export the `CodemodeRuntime` class (the\n * `@cloudflare/codemode/vite` plugin does this automatically, or add\n * `export { CodemodeRuntime } from \"@cloudflare/codemode\"` to your entry).\n */\n ctx?: DurableObjectState;\n}\n\n/** The model's input to `browserTool`: JavaScript to run. */\nexport interface BrowserToolInput {\n code: string;\n}\n\n/**\n * The result of one `browserTool` run: the codemode execution result,\n * plus what happened to the browser.\n */\nexport type BrowserToolOutput = ProxyToolOutput & {\n /** The browser was replaced before this run; earlier tabs are gone. */\n restarted?: true;\n /**\n * Sentences telling the model what happened to its browser: it was\n * restarted, its tab was closed by someone else, or another scope is\n * working in its tab too.\n */\n notice?: string;\n /** Tabs the page opened itself (popups, `target=_blank` links). */\n newTabs?: BrowserNewTab[];\n};\n\nconst DEFAULT_TIMEOUT_MS = 60_000;\n\nconst RESTARTED_NOTICE =\n \"The browser was restarted before this run (it expired or was closed): earlier tabs, logins, and page state are gone. Your code ran in a fresh browser — navigate again before relying on page state.\";\n\nconst TAB_CLOSED_NOTICE =\n 'The tab you were working in was closed (by another conversation using this browser, or a person). `sessionId: \"active\"` now opens a blank tab — navigate again before relying on page state.';\n\nconst TAB_SHARED_NOTICE =\n \"Another conversation using this browser is also working in your tab, so its page may change between your runs. Open a tab of your own with Target.createTarget if you need one.\";\n\n/** Scopes whose runtime and connector stay built; older ones are rebuilt. */\nconst MAX_CACHED_SCOPES = 32;\n\n/**\n * A codemode runtime name per browser. Browser names are host-chosen and\n * unrestricted; runtime names allow only `[a-zA-Z0-9_.-]`, so anything else\n * (including `.`, the escape) is hex-escaped.\n */\nfunction browserRuntimeName(name: string): string {\n const escaped = name.replace(\n /[^a-zA-Z0-9_-]/g,\n (char) => `.${char.codePointAt(0)?.toString(16)}.`\n );\n return `browser-tool_${escaped}`;\n}\n\n/**\n * The latest run queued per browser and scope, so runs in one scope go one\n * at a time, even from tools built separately (one per turn, say). Per\n * isolate, which is per Durable Object.\n */\nconst runQueues = new WeakMap<BrowserSource, Map<string, Promise<unknown>>>();\n\nfunction queued<T>(\n browser: BrowserSource,\n scope: string,\n run: () => Promise<T>\n): Promise<T> {\n let queues = runQueues.get(browser);\n if (!queues) runQueues.set(browser, (queues = new Map()));\n const previous = queues.get(scope) ?? Promise.resolve();\n const next = previous.then(run, run);\n const settled = next.catch(() => undefined);\n queues.set(scope, settled);\n void settled.then(() => {\n if (queues.get(scope) === settled) queues.delete(scope);\n });\n return next;\n}\n\n/** Add what happened to the browser to the codemode result. */\nfunction withBrowserReport(\n output: ProxyToolOutput,\n report: BrowserExecutionReport | undefined\n): BrowserToolOutput {\n if (!report) return output;\n const notices = [\n report.restarted && RESTARTED_NOTICE,\n report.tabClosed && !report.restarted && TAB_CLOSED_NOTICE,\n report.tabShared && TAB_SHARED_NOTICE\n ].filter((notice) => typeof notice === \"string\");\n return {\n ...output,\n ...(report.restarted ? { restarted: true as const } : {}),\n ...(notices.length > 0 ? { notice: notices.join(\" \") } : {}),\n ...(report.newTabs.length > 0 ? { newTabs: report.newTabs } : {})\n };\n}\n\n/** Report sentences that must survive a screenshot's text summary. */\nexport function browserReportNotes(output: BrowserToolOutput): string[] {\n const notes: string[] = [];\n if (output.notice) notes.push(output.notice);\n if (output.newTabs?.length) {\n notes.push(\n `New tabs opened by the page: ${JSON.stringify(output.newTabs)}`\n );\n }\n return notes;\n}\n\n/**\n * Build the codemode runtime and connector for one `browserTool`, and wrap\n * `execute` so each result carries the browser report.\n *\n * Each scope gets its own connector (which knows its scope) on the same\n * codemode runtime, built on first use. Runs in one scope wait for each\n * other, since they drive one tab; runs in different scopes go in parallel.\n */\nexport function createBrowserToolCore(\n options: BrowserToolOptions,\n adapter: {\n /** What the adapter does with screenshots, told to the model. */\n screenshotHint: string;\n }\n) {\n const ctx = resolveCtx(options);\n if (!ctx) {\n throw new Error(\n \"browserTool requires a Durable Object 'ctx' — pass it explicitly, or call from within an Agent so it can be resolved via getCurrentAgent()\"\n );\n }\n\n const timeout = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const executor = new DynamicWorkerExecutor({\n loader: options.loader,\n timeout\n });\n\n // Our own description, not codemode's generic one: that one tells the\n // model to search before every new connector (search doesn't cover CDP\n // commands), and describes approvals, snippets, and replay, which this\n // tool doesn't use.\n const rules = [\n BROWSER_INSTRUCTIONS,\n `Each run times out after ${Math.round(timeout / 1000)}s, so split long jobs (crawling a site, say) across runs.`,\n adapter.screenshotHint\n ]\n .join(\"\\n\")\n .split(\"\\n\")\n .map((rule) => `- ${rule}`)\n .join(\"\\n\");\n const description = [\n \"Run JavaScript that drives a persistent Chrome browser over the Chrome DevTools Protocol (CDP).\",\n \"\",\n \"Write an async arrow function, `async () => { ... }`, and return a small JSON value. Use the `cdp` global to reach the browser. `fetch` is blocked and there is no file system or Node.js API.\",\n \"\",\n \"## cdp\",\n \"\",\n \"- `cdp.send({ method, params?, sessionId?, timeoutMs? })` sends a CDP command and returns its result without the JSON-RPC envelope: `Page.navigate` returns `{ frameId, errorText? }`, `Runtime.evaluate` returns `{ result: { value }, exceptionDetails? }`.\",\n \"- `cdp.attachToTarget({ targetId })` makes an open tab active and returns `{ sessionId }`.\",\n '- `cdp.spec()` returns the whole protocol (about 650 KB) as `{ domains: [{ name, commands, events, types }] }`. Filter it in code, for example `spec.domains.find((d) => d.name === \"Page\").commands.find((c) => c.name === \"navigate\")`.',\n \"- `cdp.getDebugLog()` returns recent protocol traffic, for when a command fails or times out.\",\n \"\",\n \"## Rules\",\n \"\",\n rules,\n '- A `SyntaxError` from \"Failed to start Worker\" means your code didn\\'t parse; its line number points into wrapper code, not yours. Check regex literals and escapes.'\n ].join(\"\\n\");\n type CodemodeTool = ReturnType<\n ReturnType<typeof createCodemodeRuntime>[\"tool\"]\n >;\n interface ScopedTool {\n connector: BrowserSessionConnector;\n tool: CodemodeTool;\n }\n const durableCtx: DurableObjectState = ctx;\n const scopes = new Map<string, ScopedTool>();\n function scoped(scope: string): ScopedTool {\n const cached = scopes.get(scope);\n if (cached) {\n // Most recently used last, so the first entry is the one to drop.\n scopes.delete(scope);\n scopes.set(scope, cached);\n return cached;\n }\n const connector = new BrowserSessionConnector(durableCtx, {\n browser: options.browser,\n scope\n });\n const runtime = createCodemodeRuntime({\n ctx: durableCtx,\n executor,\n connectors: [connector],\n name: browserRuntimeName(options.browser.name),\n transformResult: transformBrowserResult\n });\n const built = { connector, tool: runtime.tool({ description }) };\n scopes.set(scope, built);\n if (scopes.size > MAX_CACHED_SCOPES) {\n const oldest = scopes.keys().next().value;\n if (oldest !== undefined) scopes.delete(oldest);\n }\n return built;\n }\n\n const defaultScope = options.scope ?? DEFAULT_BROWSER_SCOPE;\n const { inputSchema } = scoped(defaultScope).tool;\n\n return {\n description,\n inputSchema,\n /** Run `input` in `scope`, which defaults to the tool's `scope`. */\n execute: (\n input: BrowserToolInput,\n scope: string = defaultScope\n ): Promise<BrowserToolOutput> =>\n queued(options.browser, scope, async () => {\n const { connector, tool } = scoped(scope);\n const output = await tool.execute(input, undefined);\n return withBrowserReport(\n output,\n connector.takeReport(output.executionId)\n );\n })\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,7 @@
1
- import { n as BrowserConnection } from "./browser-tmkcAAI3.js";
1
+ import {
2
+ n as BrowserConnectOptions,
3
+ r as BrowserConnection
4
+ } from "./browser-D30VlpcA.js";
2
5
  import {
3
6
  CodemodeConnector,
4
7
  ConnectorTool,
@@ -14,8 +17,12 @@ import {
14
17
  interface BrowserSource {
15
18
  /** The browser's name, for log messages. */
16
19
  readonly name: string;
17
- /** Reattach to the browser (or replace it) and open a CDP connection. */
18
- connect(): Promise<BrowserConnection>;
20
+ /**
21
+ * Reattach to the browser (or replace it) and open a CDP connection for
22
+ * a scope. A source that ignores `scope` shares one active tab between
23
+ * every caller.
24
+ */
25
+ connect(options?: BrowserConnectOptions): Promise<BrowserConnection>;
19
26
  }
20
27
  /** A tab a page opened on its own during an execution. */
21
28
  interface BrowserNewTab {
@@ -39,6 +46,13 @@ interface BrowserToolOptions {
39
46
  loader: WorkerLoader;
40
47
  /** Sandbox execution timeout in milliseconds. Defaults to 60000 (60s). */
41
48
  timeoutMs?: number;
49
+ /**
50
+ * Who is driving, when several chats or users share one `Browser`: runs
51
+ * with the same scope share an active tab, and each scope keeps its own.
52
+ * Cookies and logins are shared by every scope. Defaults to `"shared"`,
53
+ * one active tab for every tool that leaves it out.
54
+ */
55
+ scope?: string;
42
56
  /**
43
57
  * Durable Object state for the codemode runtime facet. Optional inside an
44
58
  * Agent (resolved via `getCurrentAgent()`); pass it explicitly elsewhere.
@@ -58,7 +72,12 @@ interface BrowserToolInput {
58
72
  * plus what happened to the browser.
59
73
  */
60
74
  type BrowserToolOutput = ProxyToolOutput & {
61
- /** The browser was replaced before this run; earlier tabs are gone. */ restarted?: true /** A sentence telling the model what `restarted` means for it. */;
75
+ /** The browser was replaced before this run; earlier tabs are gone. */ restarted?: true;
76
+ /**
77
+ * Sentences telling the model what happened to its browser: it was
78
+ * restarted, its tab was closed by someone else, or another scope is
79
+ * working in its tab too.
80
+ */
62
81
  notice?: string /** Tabs the page opened itself (popups, `target=_blank` links). */;
63
82
  newTabs?: BrowserNewTab[];
64
83
  };
@@ -70,4 +89,4 @@ export {
70
89
  BrowserToolOutput as r,
71
90
  BrowserToolInput as t
72
91
  };
73
- //# sourceMappingURL=browser-tool-Bn-nzJQI.d.ts.map
92
+ //# sourceMappingURL=browser-tool-vtrPOV8e.d.ts.map
@@ -2,8 +2,6 @@
2
2
  const installedServices = /* @__PURE__ */ new WeakMap();
3
3
  /**
4
4
  * Base class for capabilities that consume standard Lifecycle services.
5
- *
6
- * @experimental The API surface may change before stabilizing.
7
5
  */
8
6
  var LifecycleCapability = class {
9
7
  constructor(capabilityId) {
@@ -40,4 +38,4 @@ function lifecycleCapabilityId(capability) {
40
38
  //#endregion
41
39
  export { bindLifecycleCapability as n, lifecycleCapabilityId as r, LifecycleCapability as t };
42
40
 
43
- //# sourceMappingURL=capability-B4WbF81e.js.map
41
+ //# sourceMappingURL=capability-DBAKc6UZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-DBAKc6UZ.js","names":[],"sources":["../src/lifecycle/capability.ts"],"sourcesContent":["import type {\n CapabilityStartContext,\n DurableObjectCapability\n} from \"./capability-runner\";\nimport type { Connection } from \"./types\";\nimport type { LifecycleJobs } from \"./job-queue\";\n\n/** Opaque address understood by a Lifecycle routing transport. */\nexport type LifecycleRouteAddress = {\n /** Stable equality and storage key. */\n readonly key: string;\n /** Transport-owned serialized address. */\n readonly data: string;\n};\n\n/** Context supplied with a routed capability message. */\nexport type LifecycleRouteContext = {\n /** Address of the sending Lifecycle, or undefined for an unrouted root. */\n readonly source: LifecycleRouteAddress | undefined;\n /** Capability-owned message payload. */\n readonly payload: unknown;\n};\n\n/** Startup state of a Lifecycle. */\nexport type LifecycleStatus = \"zero\" | \"starting\" | \"started\";\n\n/** Best-effort telemetry available to every Lifecycle capability. */\nexport type LifecycleEvents = {\n /** Publish an event under this capability's stable identity. */\n readonly emit: (type: string, payload: unknown) => void;\n};\n\n/** Routing available to every Lifecycle capability. */\nexport type LifecycleRoutes = {\n /** This Lifecycle's transport address, or undefined at the route root. */\n readonly source: LifecycleRouteAddress | undefined;\n /** Route a capability-owned message to the root Lifecycle. */\n readonly toRoot: (payload: unknown) => Promise<unknown>;\n /** Route a capability-owned message to another Lifecycle. */\n readonly to: (\n target: LifecycleRouteAddress,\n payload: unknown\n ) => Promise<unknown>;\n};\n\n/**\n * Ambient scope a capability supplies when entering host context on\n * behalf of a live connection or request.\n */\nexport type LifecycleHostContextScope = {\n /** The connection the callback runs on behalf of, when there is one. */\n readonly connection?: Connection;\n /** The request the callback runs on behalf of, when there is one. */\n readonly request?: Request;\n};\n\n/**\n * The platform's hibernatable-socket surface, exposed narrowly so a\n * capability that owns connections (e.g. WebSockets) can accept and\n * enumerate them without holding the whole `DurableObjectState`.\n * These are workerd API names, not Lifecycle modeling sockets.\n */\nexport type LifecycleSockets = {\n /** Accept a socket into hibernation under the given tags. */\n readonly accept: (ws: WebSocket, tags: string[]) => void;\n /** Every hibernated socket on the object, optionally by tag. */\n readonly get: (tag?: string) => WebSocket[];\n};\n\n/**\n * Standard services granted to every installed Lifecycle capability.\n */\nexport type LifecycleServices = {\n /** The host's Durable Object name; see `Lifecycle.name`. */\n readonly name: string;\n /** The host class name, as exported from the Worker. */\n readonly className: string;\n readonly storage: DurableObjectStorage;\n readonly sockets: LifecycleSockets;\n /**\n * Resolve once Lifecycle startup has finished, starting it if needed, and\n * reject if that startup fails. Calls made from inside startup resolve\n * immediately.\n *\n * Await it first in any operation that can run before startup and starts\n * work `onStart` also awaits, such as lazily opening a store. Native RPC\n * bypasses the automatic startup on fetch, alarm and WebSocket events, so\n * such an operation can begin that work outside startup. `onStart` then\n * awaits it while startup holds the input gate (`blockConcurrencyWhile`),\n * which holds back the work's timers and I/O, and startup times out after\n * 30 seconds and resets the object.\n */\n readonly ready: () => Promise<void>;\n /**\n * Startup state: `\"zero\"` before startup, `\"starting\"` while capability\n * and host startup hooks run, `\"started\"` once `ready()` resolves without\n * waiting.\n */\n readonly status: () => LifecycleStatus;\n /**\n * This capability's scoped access to the Lifecycle-owned work queue.\n * Pushed items are dispatched to `onJob` when due; every queue mutation\n * re-arms the physical alarm automatically.\n */\n readonly jobs: LifecycleJobs;\n /**\n * Keep work this capability hands off at a bounded `onJob` return inside\n * the current alarm's memory-limit breaker domain (#1825). Returns false,\n * tracking nothing, outside an alarm invocation.\n */\n readonly trackAlarmWork: (work: Promise<unknown>) => boolean;\n /**\n * Run a capability-held user callback inside the host invocation context.\n * Capability hooks run outside host context; this is the one boundary for\n * entering it, and a host composition root may substitute its own wrapper\n * (Agent adds tracing span scope). Pass `scope` to make a live\n * connection or request ambient for the callback.\n */\n readonly runInHostContext: (\n fn: () => unknown,\n scope?: LifecycleHostContextScope\n ) => Promise<unknown>;\n readonly events: LifecycleEvents;\n readonly routes: LifecycleRoutes;\n};\n\nconst installedServices = new WeakMap<object, LifecycleServices>();\n\n/**\n * Base class for capabilities that consume standard Lifecycle services.\n */\nexport abstract class LifecycleCapability<Props extends object = object> {\n readonly capabilityId: string;\n\n /** How this capability claims traffic; see {@link DurableObjectCapability.claims}. */\n readonly claims: \"selective\" | \"catch-all\" = \"selective\";\n\n protected constructor(capabilityId: string) {\n if (capabilityId.trim() === \"\") {\n throw new Error(\"Lifecycle capability IDs must be non-empty\");\n }\n this.capabilityId = capabilityId;\n }\n\n /** Default startup hook; capabilities override when they own startup work. */\n onStart(_context: CapabilityStartContext<Props>): void {}\n\n /** Standard services when installed, or undefined in isolated unit tests. */\n protected get lifecycleServices(): LifecycleServices | undefined {\n return installedServices.get(this);\n }\n\n /** Standard services supplied when Lifecycle installs this capability. */\n protected get lifecycle(): LifecycleServices {\n const services = this.lifecycleServices;\n if (!services) {\n throw new Error(\n `${this.constructor.name} must be installed with Lifecycle.use() before use`\n );\n }\n return services;\n }\n}\n\n/**\n * @internal Bind the standard service surface to one capability instance.\n * `Lifecycle.use()` calls this during installation. Test a capability by\n * installing it on a minimal Durable Object with a real Lifecycle rather\n * than binding fake services.\n */\nexport function bindLifecycleCapability(\n capability: LifecycleCapability,\n services: LifecycleServices\n): void {\n installedServices.set(capability, services);\n}\n\n/** @internal Read a capability ID without exposing installation internals. */\nexport function lifecycleCapabilityId(\n capability: DurableObjectCapability\n): string | undefined {\n return capability instanceof LifecycleCapability\n ? capability.capabilityId\n : undefined;\n}\n"],"mappings":";AA8HA,MAAM,oCAAoB,IAAI,QAAmC;;;;AAKjE,IAAsB,sBAAtB,MAAyE;CAMvE,YAAsB,cAAsB;EAF5C,KAAS,SAAoC;EAG3C,IAAI,aAAa,KAAK,MAAM,IAC1B,MAAM,IAAI,MAAM,4CAA4C;EAE9D,KAAK,eAAe;CACtB;;CAGA,QAAQ,UAA+C,CAAC;;CAGxD,IAAc,oBAAmD;EAC/D,OAAO,kBAAkB,IAAI,IAAI;CACnC;;CAGA,IAAc,YAA+B;EAC3C,MAAM,WAAW,KAAK;EACtB,IAAI,CAAC,UACH,MAAM,IAAI,MACR,GAAG,KAAK,YAAY,KAAK,mDAC3B;EAEF,OAAO;CACT;AACF;;;;;;;AAQA,SAAgB,wBACd,YACA,UACM;CACN,kBAAkB,IAAI,YAAY,QAAQ;AAC5C;;AAGA,SAAgB,sBACd,YACoB;CACpB,OAAO,sBAAsB,sBACzB,WAAW,eACX,KAAA;AACN"}
@@ -219,8 +219,6 @@ type LifecycleSockets = {
219
219
  };
220
220
  /**
221
221
  * Standard services granted to every installed Lifecycle capability.
222
- *
223
- * @experimental The API surface may change before stabilizing.
224
222
  */
225
223
  type LifecycleServices = {
226
224
  /** The host's Durable Object name; see `Lifecycle.name`. */ readonly name: string /** The host class name, as exported from the Worker. */;
@@ -275,8 +273,6 @@ type LifecycleServices = {
275
273
  };
276
274
  /**
277
275
  * Base class for capabilities that consume standard Lifecycle services.
278
- *
279
- * @experimental The API surface may change before stabilizing.
280
276
  */
281
277
  declare abstract class LifecycleCapability<Props extends object = object> {
282
278
  readonly capabilityId: string;
@@ -369,8 +365,6 @@ type MemoryLimitContext = {
369
365
  * - `onRoute` is addressed to one capability by its id; `onJob` is
370
366
  * addressed by the due job's owning capability, with Lifecycle owning
371
367
  * the queue and the one physical alarm.
372
- *
373
- * @experimental The API surface may change before stabilizing.
374
368
  */
375
369
  interface DurableObjectCapability<Props extends object = object> {
376
370
  /**
@@ -494,4 +488,4 @@ export {
494
488
  Connection as x,
495
489
  LifecycleJobPushOptions as y
496
490
  };
497
- //# sourceMappingURL=capability-runner-O5VbQzqg.d.ts.map
491
+ //# sourceMappingURL=capability-runner-BiVUtjqC.d.ts.map
@@ -9,14 +9,14 @@ import {
9
9
  _ as FiberRecoveryContext$1,
10
10
  at as isPositionlessAgentToolChunk,
11
11
  z as AgentToolEventState
12
- } from "../agent-routing-Bhdbvf7s.js";
13
- import { _ as TaskStep, m as TaskRunOptions } from "../tasks-PtlB4Uyn.js";
12
+ } from "../agent-routing-BMvWTFEp.js";
13
+ import { _ as TaskStep, m as TaskRunOptions } from "../tasks-E89KdwkS.js";
14
14
  import {
15
15
  n as ClientToolSchema,
16
16
  r as createToolsFromClientSchemas,
17
17
  t as ClientToolExecutor
18
18
  } from "../client-tools-aIBO0Fk7.js";
19
- import { n as Streams } from "../streams-fbG61qM8.js";
19
+ import { n as Streams } from "../streams-vrCtbUIn.js";
20
20
  import {
21
21
  a as CHAT_MESSAGE_TYPES,
22
22
  i as OutgoingMessage,
@@ -34,7 +34,7 @@ import {
34
34
  r as AgentToolProgressEmitResult,
35
35
  s as interceptAgentToolBroadcast,
36
36
  t as AgentToolBroadcastHooks
37
- } from "../agent-tools-bJZwBMfq.js";
37
+ } from "../agent-tools-ohoewW-B.js";
38
38
  import { l as SessionMessage } from "../types-B7LojTe4.js";
39
39
  import { ModelMessage, UIMessage } from "ai";
40
40
  import { Connection, FiberRecoveryContext } from "agents";
@@ -6,7 +6,7 @@ import { n as sanitizeMessage, t as byteLength } from "../sanitize-D9TujEK8.js";
6
6
  import { n as STREAM_RESUME_NONE_REASONS, r as StreamAccumulator, t as CHAT_MESSAGE_TYPES } from "../protocol-eXeJxhgu.js";
7
7
  import { t as TextSegmentJoiner } from "../text-segment-joiner-BtAFQSA_.js";
8
8
  import { n as transition } from "../broadcast-state-CEyI4uAK.js";
9
- import { n as Streams } from "../streams-CITClVer.js";
9
+ import { n as Streams } from "../streams-lsHMJhRW.js";
10
10
  import { i as createToolsFromClientSchemas, n as iterateWithStallWatchdog, r as parseProtocolMessage, t as ChatStreamStalledError } from "../stall-watchdog-BpRF2uwG.js";
11
11
  import { t as MessageType } from "../wire-types-CnMt6_HR.js";
12
12
  import { nanoid } from "nanoid";
@@ -2,7 +2,7 @@ import {
2
2
  bn as DynamicAgentClass,
3
3
  c as Agent,
4
4
  xn as DynamicAgentStub
5
- } from "../agent-routing-Bhdbvf7s.js";
5
+ } from "../agent-routing-BMvWTFEp.js";
6
6
  import { Lock, QueueEntry, StateAdapter } from "chat";
7
7
 
8
8
  //#region src/chat-sdk/agent.d.ts
@@ -1,4 +1,4 @@
1
- import { i as getCurrentAgent, t as Agent } from "../src-DgCbZtIR.js";
1
+ import { i as getCurrentAgent, t as Agent } from "../src-CQxJFv4l.js";
2
2
  //#region src/chat-sdk/agent.ts
3
3
  const NEXT_CLEANUP_AT_KEY = "next_cleanup_at";
4
4
  const CLEANUP_SCHEDULE_ID_KEY = "cleanup_schedule_id";
@@ -1,5 +1,5 @@
1
1
  import { getAgentByName } from "./agent-routing.js";
2
- import { t as LifecycleCapability } from "./capability-B4WbF81e.js";
2
+ import { t as LifecycleCapability } from "./capability-DBAKc6UZ.js";
3
3
  import { tryN } from "./retries.js";
4
4
  import { n as callV2Tool } from "./invoker-CHMnoxIA.js";
5
5
  import { DurableObjectOAuthClientProvider } from "./mcp/client/do-oauth-client-provider.js";
@@ -1271,8 +1271,7 @@ const MCP_SCHEMA_VERSION_KEY = "cf_agents:mcp_schema_version";
1271
1271
  const CURRENT_MCP_SCHEMA_VERSION = 1;
1272
1272
  /**
1273
1273
  * A Durable Object capability that persists and aggregates MCP client
1274
- * connections. Installing it directly on a Lifecycle (outside `agent.mcp`)
1275
- * is experimental: that capability surface may change before stabilizing.
1274
+ * connections. Install it on any Lifecycle, or use `agent.mcp` on an Agent.
1276
1275
  */
1277
1276
  var MCPClientManager = class extends LifecycleCapability {
1278
1277
  /**
@@ -2499,4 +2498,4 @@ function getNamespacedData(mcpClients, type) {
2499
2498
  //#endregion
2500
2499
  export { ensureMcpServerTable as a, RPCServerTransport as c, DisposableStore as d, normalizeServerId as i, RPC_DO_PREFIX as l, MCP_SERVER_ID_MAX_LENGTH as n, MCPConnectionState as o, getNamespacedData as r, RPCClientTransport as s, MCPClientManager as t, isDurableObjectNamespace as u };
2501
2500
 
2502
- //# sourceMappingURL=client-1tEQ1Oqz.js.map
2501
+ //# sourceMappingURL=client-BnYbNT3z.js.map