agents 0.23.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/dist/{agent-routing-DE5zmCQ8.d.ts → agent-routing-0DR0Tk2v.d.ts} +270 -190
  2. package/dist/agent-routing.d.ts +1 -1
  3. package/dist/agent-routing.js.map +1 -1
  4. package/dist/agent-tool-types.d.ts +13 -7
  5. package/dist/agent-tool-types.js +23 -1
  6. package/dist/agent-tool-types.js.map +1 -1
  7. package/dist/{agent-tools-y7zLfw4Q.js → agent-tools-CdJC-8Dc.js} +72 -9
  8. package/dist/agent-tools-CdJC-8Dc.js.map +1 -0
  9. package/dist/{agent-tools-DtXMTDGM.d.ts → agent-tools-YrATZJu2.d.ts} +29 -15
  10. package/dist/agent-tools.d.ts +6 -4
  11. package/dist/agent-tools.js.map +1 -1
  12. package/dist/ai-fm7xx1BK.js +312 -0
  13. package/dist/ai-fm7xx1BK.js.map +1 -0
  14. package/dist/base64-redaction-C1Uu29t5.js +59 -0
  15. package/dist/base64-redaction-C1Uu29t5.js.map +1 -0
  16. package/dist/browser/ai-sdk.d.ts +90 -0
  17. package/dist/browser/ai-sdk.js +51 -0
  18. package/dist/browser/ai-sdk.js.map +1 -0
  19. package/dist/browser/ai.d.ts +4 -4
  20. package/dist/browser/ai.js +1 -347
  21. package/dist/browser/index.d.ts +81 -79
  22. package/dist/browser/index.js +361 -2
  23. package/dist/browser/index.js.map +1 -0
  24. package/dist/browser/tanstack-ai.d.ts +96 -1
  25. package/dist/browser/tanstack-ai.js +62 -2
  26. package/dist/browser/tanstack-ai.js.map +1 -1
  27. package/dist/browser-DE3d-RLk.d.ts +275 -0
  28. package/dist/browser-tool-CQ10e6Kj.js +480 -0
  29. package/dist/browser-tool-CQ10e6Kj.js.map +1 -0
  30. package/dist/browser-tool-DuNdlwZ9.d.ts +73 -0
  31. package/dist/{capability-BjSKYpzg.js → capability-B4WbF81e.js} +2 -1
  32. package/dist/capability-B4WbF81e.js.map +1 -0
  33. package/dist/{capability-runner-Be_-PLR1.d.ts → capability-runner-DBAnGr6L.d.ts} +45 -15
  34. package/dist/chat/index.d.ts +341 -232
  35. package/dist/chat/index.js +602 -72
  36. package/dist/chat/index.js.map +1 -1
  37. package/dist/chat/react.d.ts +42 -2
  38. package/dist/chat/react.js +191 -35
  39. package/dist/chat/react.js.map +1 -1
  40. package/dist/chat/transport.d.ts +1 -1
  41. package/dist/chat/transport.js +1 -1
  42. package/dist/chat-sdk/index.d.ts +17 -3
  43. package/dist/chat-sdk/index.js +28 -2
  44. package/dist/chat-sdk/index.js.map +1 -1
  45. package/dist/client-4OlMIJx-.js +591 -0
  46. package/dist/client-4OlMIJx-.js.map +1 -0
  47. package/dist/{client-jagG8a9_.js → client-fyQrLGkD.js} +2 -2
  48. package/dist/{client-jagG8a9_.js.map → client-fyQrLGkD.js.map} +1 -1
  49. package/dist/client-je3koD9Z.d.ts +446 -0
  50. package/dist/client.d.ts +29 -283
  51. package/dist/client.js +2 -274
  52. package/dist/{connector-CptFKzRh.js → connector-58XDGvc3.js} +251 -120
  53. package/dist/connector-58XDGvc3.js.map +1 -0
  54. package/dist/{connector-CkQD4MK3.d.ts → connector-Cl-VqPmA.d.ts} +244 -146
  55. package/dist/context/index.d.ts +29 -0
  56. package/dist/context/index.js +64 -17
  57. package/dist/context/index.js.map +1 -1
  58. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  59. package/dist/current-agent-vAk_5JMt.d.ts +93 -0
  60. package/dist/{current-agent-Da_C9a3b.d.ts → durable-object-lifecycle-HhgOMWq9.d.ts} +26 -127
  61. package/dist/harnesses/pi/index.d.ts +348 -0
  62. package/dist/harnesses/pi/index.js +754 -0
  63. package/dist/harnesses/pi/index.js.map +1 -0
  64. package/dist/images-iiTDSyRu.js +1631 -0
  65. package/dist/images-iiTDSyRu.js.map +1 -0
  66. package/dist/index-BreL0YrQ.d.ts +78 -0
  67. package/dist/index-kbSUIer3.d.ts +343 -0
  68. package/dist/index.d.ts +43 -41
  69. package/dist/index.js +2 -2
  70. package/dist/internal_context.d.ts +1 -1
  71. package/dist/lifecycle/index.d.ts +19 -17
  72. package/dist/lifecycle/index.js +2 -2
  73. package/dist/{lifecycle-CMRGjZdw.js → lifecycle-CFu6OV03.js} +73 -29
  74. package/dist/lifecycle-CFu6OV03.js.map +1 -0
  75. package/dist/mcp/client/index.d.ts +20 -20
  76. package/dist/mcp/client/index.js +1 -1
  77. package/dist/mcp/client/x402.js +21 -19
  78. package/dist/mcp/client/x402.js.map +1 -1
  79. package/dist/mcp/index.d.ts +35 -35
  80. package/dist/mcp/index.js +2 -2
  81. package/dist/{message-builder-BymO4N_D.js → message-builder-DAl9AhHH.js} +89 -4
  82. package/dist/message-builder-DAl9AhHH.js.map +1 -0
  83. package/dist/models/ai-sdk/index.d.ts +353 -0
  84. package/dist/models/ai-sdk/index.js +2443 -0
  85. package/dist/models/ai-sdk/index.js.map +1 -0
  86. package/dist/models/pi-ai/index.d.ts +313 -0
  87. package/dist/models/pi-ai/index.js +1795 -0
  88. package/dist/models/pi-ai/index.js.map +1 -0
  89. package/dist/observability/ai/index.js +20 -4
  90. package/dist/observability/ai/index.js.map +1 -1
  91. package/dist/{protocol-B0nh6KNf.js → protocol-kHsr-f0X.js} +26 -12
  92. package/dist/{protocol-B0nh6KNf.js.map → protocol-kHsr-f0X.js.map} +1 -1
  93. package/dist/queue/index.d.ts +123 -0
  94. package/dist/queue/index.js +2 -0
  95. package/dist/queue-BB-zfIYF.js +406 -0
  96. package/dist/queue-BB-zfIYF.js.map +1 -0
  97. package/dist/react.d.ts +31 -13
  98. package/dist/react.js +190 -71
  99. package/dist/react.js.map +1 -1
  100. package/dist/{retries-D9Ds-1lz.d.ts → retries-CV6AkXmQ.d.ts} +23 -8
  101. package/dist/retries.d.ts +12 -8
  102. package/dist/retries.js +19 -1
  103. package/dist/retries.js.map +1 -1
  104. package/dist/routing/index.d.ts +2 -2
  105. package/dist/routing/index.js +1 -1
  106. package/dist/{scheduler-DD9NdYbF.js → scheduler-DZ3xQfeK.js} +4 -11
  107. package/dist/scheduler-DZ3xQfeK.js.map +1 -0
  108. package/dist/{scheduler-Dwh85ZGl.d.ts → scheduler-RdACNXDP.d.ts} +6 -6
  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/sessions/index.d.ts +70 -3
  113. package/dist/sessions/index.js +276 -67
  114. package/dist/sessions/index.js.map +1 -1
  115. package/dist/skills/index.d.ts +29 -314
  116. package/dist/socket-address.d.ts +16 -0
  117. package/dist/socket-address.js +19 -0
  118. package/dist/socket-address.js.map +1 -0
  119. package/dist/{src-DlSHshb2.js → src-BZeu-SCD.js} +541 -500
  120. package/dist/src-BZeu-SCD.js.map +1 -0
  121. package/dist/state/index.d.ts +6 -0
  122. package/dist/state/index.js +137 -0
  123. package/dist/state/index.js.map +1 -0
  124. package/dist/streams/index.d.ts +1 -1
  125. package/dist/streams/index.js +1 -1
  126. package/dist/{streams-D6tJ0NN9.d.ts → streams-Cmkj9QfW.d.ts} +4 -2
  127. package/dist/{streams-DZKgAj9b.js → streams-DW-UCOUc.js} +9 -2
  128. package/dist/streams-DW-UCOUc.js.map +1 -0
  129. package/dist/sub-routing.d.ts +12 -12
  130. package/dist/tasks/index.d.ts +1 -1
  131. package/dist/tasks/index.js +1 -1
  132. package/dist/{tasks-ylZgBjhj.js → tasks-68DESxf0.js} +3 -3
  133. package/dist/{tasks-ylZgBjhj.js.map → tasks-68DESxf0.js.map} +1 -1
  134. package/dist/{tasks-BRJ5zgya.d.ts → tasks-9YxYtByh.d.ts} +5 -5
  135. package/dist/transport-PfFnt-Ld.d.ts +525 -0
  136. package/dist/transport-protocol-BxyngQ_R.js +25 -0
  137. package/dist/transport-protocol-BxyngQ_R.js.map +1 -0
  138. package/dist/transport-protocol-ZTew5Wso.d.ts +27 -0
  139. package/dist/types-BA4anrjI.d.ts +70 -0
  140. package/dist/voice/index.d.ts +2 -2
  141. package/dist/websockets/index.d.ts +195 -69
  142. package/dist/websockets/index.js +3 -2
  143. package/dist/websockets-Ci-LZFHH.js +1030 -0
  144. package/dist/websockets-Ci-LZFHH.js.map +1 -0
  145. package/dist/wire-types-CnMt6_HR.js.map +1 -1
  146. package/dist/wire-types-CrjKvDyi.d.ts +300 -0
  147. package/dist/workflow-types.d.ts +25 -25
  148. package/dist/workflows.d.ts +21 -21
  149. package/dist/workflows.js +1 -1
  150. package/dist/{ws-chat-transport-UNRIS2xl.d.ts → ws-chat-transport-BbT1A5Lc.d.ts} +51 -2
  151. package/dist/{ws-chat-transport-rWwta645.js → ws-chat-transport-cqMKq3IY.js} +143 -16
  152. package/dist/ws-chat-transport-cqMKq3IY.js.map +1 -0
  153. package/docs/agent-class.md +2 -2
  154. package/docs/agent-tools.md +29 -4
  155. package/docs/browse-the-web.md +87 -5
  156. package/docs/chat-agents.md +124 -16
  157. package/docs/client-sdk.md +30 -0
  158. package/docs/context.md +27 -0
  159. package/docs/durable-execution.md +2 -0
  160. package/docs/harnesses/pi.md +91 -0
  161. package/docs/human-in-the-loop.md +4 -0
  162. package/docs/index.md +4 -1
  163. package/docs/lifecycle.md +114 -23
  164. package/docs/models-pi-ai.md +325 -0
  165. package/docs/models.md +504 -0
  166. package/docs/queue.md +135 -241
  167. package/docs/resumable-streaming.md +2 -0
  168. package/docs/retries.md +1 -1
  169. package/docs/routing.md +13 -13
  170. package/docs/sessions.md +36 -1
  171. package/docs/state.md +1 -0
  172. package/docs/sub-agents.md +12 -3
  173. package/package.json +51 -3
  174. package/dist/agent-tools-y7zLfw4Q.js.map +0 -1
  175. package/dist/browser/ai.js.map +0 -1
  176. package/dist/capability-BjSKYpzg.js.map +0 -1
  177. package/dist/client-tools-aIBO0Fk7.d.ts +0 -53
  178. package/dist/client.js.map +0 -1
  179. package/dist/connector-CptFKzRh.js.map +0 -1
  180. package/dist/lifecycle-CMRGjZdw.js.map +0 -1
  181. package/dist/message-builder-BymO4N_D.js.map +0 -1
  182. package/dist/scheduler-DD9NdYbF.js.map +0 -1
  183. package/dist/src-DlSHshb2.js.map +0 -1
  184. package/dist/streams-DZKgAj9b.js.map +0 -1
  185. package/dist/websockets-DUfRHPRq.js +0 -502
  186. package/dist/websockets-DUfRHPRq.js.map +0 -1
  187. package/dist/ws-chat-transport-rWwta645.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"connector-CptFKzRh.js","names":[],"sources":["../src/browser/cdp-session.ts","../src/browser/browser-run.ts","../src/browser/quick-actions.ts","../src/browser/spec.ts","../src/browser/session-manager.ts","../src/browser/connector.ts"],"sourcesContent":["interface PendingCommand {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n method: string;\n sessionId?: string;\n startedAt: number;\n}\n\ninterface DebugEntry {\n at: string;\n type: string;\n [key: string]: unknown;\n}\n\nexport interface CdpSendOptions {\n timeoutMs?: number;\n sessionId?: string;\n}\n\nexport interface CdpAttachOptions {\n timeoutMs?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_DEBUG_ENTRIES = 400;\n\n/**\n * A CDP session over an open WebSocket. Manages command correlation,\n * timeouts, target sessions, and a debug event ring buffer.\n *\n * Used host-side (not in the sandbox) — the sandbox calls into this\n * via DynamicWorkerExecutor's ToolDispatcher RPC.\n */\nexport class CdpSession {\n #socket: WebSocket;\n #nextId = 1;\n #pending = new Map<number, PendingCommand>();\n #debugLog: DebugEntry[] = [];\n #defaultTimeoutMs: number;\n #dispose?: () => void;\n readonly sessionId?: string;\n\n constructor(\n socket: WebSocket,\n defaultTimeoutMs = DEFAULT_TIMEOUT_MS,\n dispose?: () => void,\n sessionId?: string\n ) {\n this.#socket = socket;\n this.#defaultTimeoutMs = defaultTimeoutMs;\n this.#dispose = dispose;\n this.sessionId = sessionId;\n\n socket.addEventListener(\"message\", (event) => this.#handleMessage(event));\n socket.addEventListener(\"error\", () => {\n this.#rejectAll(new Error(\"CDP socket error\"));\n });\n socket.addEventListener(\"close\", () => {\n this.#rejectAll(new Error(\"CDP connection closed\"));\n });\n }\n\n send(\n method: string,\n params?: unknown,\n options: CdpSendOptions = {}\n ): Promise<unknown> {\n const id = this.#nextId++;\n const timeoutMs = options.timeoutMs ?? this.#defaultTimeoutMs;\n const sessionId =\n typeof options.sessionId === \"string\" && options.sessionId.length > 0\n ? options.sessionId\n : undefined;\n\n const domain = typeof method === \"string\" ? method.split(\".\")[0] : \"\";\n if (!sessionId && domain && ![\"Browser\", \"Target\"].includes(domain)) {\n this.#recordDebug(\"warning\", {\n id,\n method,\n reason: \"target-scoped method sent without sessionId\"\n });\n }\n\n const result = new Promise<unknown>((resolve, reject) => {\n const startedAt = performance.now();\n const timeoutId = setTimeout(() => {\n this.#pending.delete(id);\n reject(\n new Error(`CDP command timed out after ${timeoutMs}ms: ${method}`)\n );\n }, timeoutMs);\n this.#pending.set(id, {\n resolve,\n reject,\n timeoutId,\n method,\n sessionId,\n startedAt\n });\n });\n\n this.#recordDebug(\"send\", { id, method, sessionId, timeoutMs });\n this.#socket.send(JSON.stringify({ id, method, params, sessionId }));\n return result;\n }\n\n async attachToTarget(\n targetId: string,\n options: CdpAttachOptions = {}\n ): Promise<string> {\n if (typeof targetId !== \"string\" || !targetId) {\n throw new Error(\n \"attachToTarget requires a targetId — list open tabs with \" +\n \"send('Target.getTargets') or create one with \" +\n \"send('Target.createTarget', { url })\"\n );\n }\n\n const result = (await this.send(\n \"Target.attachToTarget\",\n {\n targetId,\n flatten: true\n },\n { timeoutMs: options.timeoutMs }\n )) as { sessionId?: string };\n\n const sessionId = result?.sessionId ?? \"\";\n if (!sessionId) {\n throw new Error(\n `Target.attachToTarget did not return a sessionId for target ${targetId}`\n );\n }\n\n this.#recordDebug(\"attach\", { targetId, sessionId });\n return sessionId;\n }\n\n getDebugLog(limit = 50): DebugEntry[] {\n const normalized = Number.isFinite(limit)\n ? Math.max(1, Math.floor(limit))\n : 50;\n return this.#debugLog.slice(-normalized);\n }\n\n clearDebugLog(): void {\n this.#debugLog = [];\n }\n\n disconnect(): void {\n this.#rejectAll(new Error(\"CDP session disconnected\"));\n try {\n this.#socket.close(1000, \"Done\");\n } catch {\n // socket may already be closed\n }\n }\n\n close(): void {\n this.disconnect();\n this.#dispose?.();\n }\n\n #rejectAll(error: Error): void {\n for (const [id, pending] of this.#pending.entries()) {\n clearTimeout(pending.timeoutId);\n this.#pending.delete(id);\n pending.reject(error);\n }\n }\n\n #handleMessage(event: MessageEvent): void {\n if (typeof event.data !== \"string\") {\n return;\n }\n\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(event.data) as Record<string, unknown>;\n } catch {\n return;\n }\n\n this.#recordDebug(\"receive\", {\n id: payload.id,\n method: payload.method,\n sessionId: payload.sessionId,\n hasError: !!payload.error\n });\n\n if (typeof payload.id !== \"number\") {\n return;\n }\n\n const pending = this.#pending.get(payload.id);\n if (!pending) {\n return;\n }\n\n clearTimeout(pending.timeoutId);\n this.#pending.delete(payload.id);\n\n if (payload.error) {\n const err = payload.error as { code?: unknown; message?: string };\n const code = err.code ?? \"unknown\";\n const message = err.message ?? \"CDP error\";\n pending.reject(\n new Error(`CDP error ${code}: ${message} for ${pending.method}`)\n );\n return;\n }\n\n pending.resolve(payload.result);\n }\n\n #recordDebug(type: string, data: Record<string, unknown>): void {\n this.#debugLog.push({\n at: new Date().toISOString(),\n type,\n ...data\n });\n if (this.#debugLog.length > MAX_DEBUG_ENTRIES) {\n this.#debugLog.splice(0, this.#debugLog.length - MAX_DEBUG_ENTRIES);\n }\n }\n}\n\nconst LOCALHOST_HOSTS = new Set([\n \"localhost\",\n \"127.0.0.1\",\n \"0.0.0.0\",\n \"::1\",\n \"[::1]\"\n]);\n\n/**\n * Connect to a browser via a CDP base URL (e.g. http://localhost:9222).\n * Discovers the WebSocket debugger URL via /json/version,\n * rewrites localhost URLs to the base URL host, and opens the WebSocket.\n *\n * Useful for local development with `chrome --remote-debugging-port=9222`\n * or when connecting through a tunnel.\n */\nexport async function connectUrl(\n baseUrl: string,\n options?: { timeoutMs?: number; headers?: Record<string, string> }\n): Promise<CdpSession> {\n const endpoint = new URL(\"/json/version\", baseUrl).toString();\n const response = await fetch(endpoint, {\n headers: options?.headers\n });\n if (!response.ok) {\n throw new Error(\n `Failed to discover CDP endpoint at ${endpoint}: ${response.status}`\n );\n }\n\n const payload = (await response.json()) as {\n webSocketDebuggerUrl?: string;\n };\n if (!payload.webSocketDebuggerUrl) {\n throw new Error(\"CDP /json/version did not include webSocketDebuggerUrl\");\n }\n\n let wsUrl = payload.webSocketDebuggerUrl;\n const parsed = new URL(wsUrl);\n if (LOCALHOST_HOSTS.has(parsed.hostname)) {\n const base = new URL(baseUrl);\n parsed.hostname = base.hostname;\n parsed.port = base.port;\n parsed.protocol = base.protocol;\n } else {\n // Workers runtime requires fetch + Upgrade header for outbound WebSockets\n parsed.protocol = parsed.protocol === \"wss:\" ? \"https:\" : \"http:\";\n }\n const fetchUrl = parsed.toString();\n\n const wsResponse = await fetch(fetchUrl, {\n headers: { ...options?.headers, Upgrade: \"websocket\" }\n });\n const ws = wsResponse.webSocket;\n if (!ws) {\n throw new Error(\n `Failed to establish CDP WebSocket at ${fetchUrl} (status ${wsResponse.status})`\n );\n }\n ws.accept();\n\n return new CdpSession(ws, options?.timeoutMs);\n}\n","import { CdpSession } from \"./cdp-session\";\n\n/**\n * A Browser Rendering binding. Structural so it accepts both the classic\n * `Fetcher`-typed binding and the newer `BrowserRun` type generated by\n * `wrangler types` — we only ever use its `fetch` surface.\n */\nexport interface BrowserBinding {\n fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;\n}\n\nexport interface BrowserTargetInfo {\n id: string;\n type?: string;\n url?: string;\n title?: string;\n description?: string;\n devtoolsFrontendUrl?: string;\n webSocketDebuggerUrl?: string;\n}\n\nexport interface BrowserSessionInfo {\n sessionId: string;\n targets?: BrowserTargetInfo[];\n webSocketDebuggerUrl?: string;\n}\n\nexport interface ConnectBrowserOptions {\n timeoutMs?: number;\n keepAliveMs?: number;\n includeTargets?: boolean;\n /**\n * Opt into Browser Run [session recording](https://developers.cloudflare.com/browser-run/features/session-recording/):\n * an rrweb capture of DOM changes, input, and navigation, finalized when the\n * session closes. Set at session-launch time. Retrieve later with\n * {@link getBrowserRecording}.\n */\n recording?: boolean;\n /**\n * Select the browser engine. Defaults to Chromium. Use `\"kitesurf\"` for\n * Cloudflare's connection-scoped, agent-first browser engine.\n */\n browser?: \"kitesurf\";\n}\n\n/** An rrweb session recording for a closed Browser Run session. */\nexport interface BrowserRecording {\n sessionId: string;\n /** Recording length in milliseconds. */\n duration: number;\n /**\n * rrweb event arrays keyed by CDP target id (one per tab). Each value can be\n * passed directly to `rrweb-player` to replay that tab.\n */\n events: Record<string, unknown[]>;\n}\n\nexport class BrowserRenderingError extends Error {\n constructor(\n message: string,\n readonly status: number\n ) {\n super(message);\n this.name = \"BrowserRenderingError\";\n }\n}\n\nfunction browserSessionEndpoint(\n sessionId?: string,\n options?: {\n keepAliveMs?: number;\n includeTargets?: boolean;\n recording?: boolean;\n browser?: \"kitesurf\";\n }\n): string {\n const path = sessionId\n ? `/v1/devtools/browser/${sessionId}`\n : \"/v1/devtools/browser\";\n const url = new URL(`https://localhost${path}`);\n\n if (options?.keepAliveMs !== undefined) {\n url.searchParams.set(\"keep_alive\", String(options.keepAliveMs));\n }\n if (options?.includeTargets) {\n url.searchParams.set(\"targets\", \"true\");\n }\n if (options?.recording) {\n url.searchParams.set(\"recording\", \"true\");\n }\n if (options?.browser) {\n url.searchParams.set(\"browser\", options.browser);\n }\n\n return url.toString();\n}\n\nasync function parseBrowserSessionInfo(\n response: Response\n): Promise<BrowserSessionInfo> {\n const payload = (await response.json()) as {\n sessionId?: unknown;\n targets?: unknown;\n webSocketDebuggerUrl?: unknown;\n };\n const sessionId =\n typeof payload.sessionId === \"string\" ? payload.sessionId : \"\";\n\n if (!sessionId) {\n throw new Error(\"Browser Rendering response did not include a sessionId\");\n }\n\n return {\n sessionId,\n targets: Array.isArray(payload.targets)\n ? (payload.targets as BrowserTargetInfo[])\n : undefined,\n webSocketDebuggerUrl:\n typeof payload.webSocketDebuggerUrl === \"string\"\n ? payload.webSocketDebuggerUrl\n : undefined\n };\n}\n\nexport async function createBrowserSession(\n browser: BrowserBinding,\n options?: {\n keepAliveMs?: number;\n includeTargets?: boolean;\n recording?: boolean;\n }\n): Promise<BrowserSessionInfo> {\n const response = await browser.fetch(\n browserSessionEndpoint(undefined, options),\n { method: \"POST\" }\n );\n\n if (!response.ok) {\n throw new BrowserRenderingError(\n `Failed to create Browser Rendering session: ${response.status}`,\n response.status\n );\n }\n\n return parseBrowserSessionInfo(response);\n}\n\nexport async function listBrowserTargets(\n browser: BrowserBinding,\n sessionId: string\n): Promise<BrowserTargetInfo[]> {\n const response = await browser.fetch(\n `https://localhost/v1/devtools/browser/${sessionId}/json/list`\n );\n\n if (!response.ok) {\n throw new BrowserRenderingError(\n `Failed to list Browser Rendering targets for ${sessionId}: ${response.status}`,\n response.status\n );\n }\n\n const payload = (await response.json()) as unknown;\n return Array.isArray(payload) ? (payload as BrowserTargetInfo[]) : [];\n}\n\nexport async function deleteBrowserSession(\n browser: BrowserBinding,\n sessionId: string\n): Promise<void> {\n const response = await browser.fetch(\n `https://localhost/v1/devtools/browser/${sessionId}`,\n { method: \"DELETE\" }\n );\n\n if (!response.ok && response.status !== 404) {\n throw new BrowserRenderingError(\n `Failed to delete Browser Rendering session ${sessionId}: ${response.status}`,\n response.status\n );\n }\n}\n\n/**\n * Connect to a Browser Rendering session and delete it when closed.\n */\nexport async function connectBrowser(\n browser: BrowserBinding,\n options?: number | ConnectBrowserOptions\n): Promise<CdpSession> {\n const normalizedOptions =\n typeof options === \"number\" ? { timeoutMs: options } : (options ?? {});\n const isKitesurf = normalizedOptions.browser === \"kitesurf\";\n if (\n isKitesurf &&\n (normalizedOptions.keepAliveMs ||\n normalizedOptions.includeTargets ||\n normalizedOptions.recording)\n ) {\n throw new Error(\n \"Kitesurf does not support keepAliveMs, includeTargets, or recording\"\n );\n }\n\n const response = await browser.fetch(\n browserSessionEndpoint(undefined, {\n // Explicitly disabled Chromium-only options are accepted but never sent:\n // `keep_alive=0` is not a valid Kitesurf query parameter.\n keepAliveMs: isKitesurf ? undefined : normalizedOptions.keepAliveMs,\n includeTargets: normalizedOptions.includeTargets,\n recording: normalizedOptions.recording,\n browser: normalizedOptions.browser\n }),\n { headers: { Upgrade: \"websocket\" } }\n );\n\n const ws = response.webSocket;\n if (!ws) {\n throw new Error(\n \"Browser Rendering binding did not return a WebSocket. \" +\n \"Ensure the 'browser' binding is configured in wrangler.jsonc.\"\n );\n }\n\n if (normalizedOptions.browser === \"kitesurf\") {\n // A Kitesurf browser is scoped to this WebSocket. Browser Run may return\n // an ID for analytics correlation, but it cannot be used with the\n // session-scoped reconnect or delete endpoints.\n ws.accept();\n return new CdpSession(ws, normalizedOptions.timeoutMs);\n }\n\n const sessionId = response.headers.get(\"cf-browser-session-id\");\n if (!sessionId) {\n throw new Error(\n \"Browser Rendering binding did not include a session ID when opening the CDP WebSocket\"\n );\n }\n\n ws.accept();\n return new CdpSession(\n ws,\n normalizedOptions.timeoutMs,\n () => {\n deleteBrowserSession(browser, sessionId).catch((error: unknown) => {\n console.warn(\n `[agents/browser] Failed to delete one-shot Browser Run session ${sessionId}`,\n error\n );\n });\n },\n sessionId\n );\n}\n\n/**\n * Fetch a Browser Run [session recording](https://developers.cloudflare.com/browser-run/features/session-recording/)\n * by session id, via the Browser Rendering REST API.\n *\n * A recording is only available **after** the session closes (explicit\n * `closeSession()`, idle `keep_alive` expiry, or sweep) and is retained for 30\n * days. Capture the session id while the session is alive — e.g. from\n * `connector.liveView()`/`sessionInfo()` — then call this once it has ended.\n *\n * Unlike the binding-based helpers, this hits `api.cloudflare.com` directly, so\n * it needs an account id and an API token with `Browser Rendering` read access\n * (the Workers Browser Run binding cannot read recordings).\n */\nexport async function getBrowserRecording(options: {\n accountId: string;\n apiToken: string;\n sessionId: string;\n /** Override for testing; defaults to the global `fetch`. */\n fetchImpl?: typeof fetch;\n}): Promise<BrowserRecording> {\n const { accountId, apiToken, sessionId } = options;\n const fetchImpl = options.fetchImpl ?? fetch;\n const endpoint = `https://api.cloudflare.com/client/v4/accounts/${accountId}/browser-rendering/recording/${sessionId}`;\n\n const response = await fetchImpl(endpoint, {\n headers: { Authorization: `Bearer ${apiToken}` }\n });\n\n if (!response.ok) {\n throw new BrowserRenderingError(\n `Failed to fetch Browser Run recording for ${sessionId}: ${response.status}`,\n response.status\n );\n }\n\n // The recording endpoint returns the recording object directly; tolerate a\n // standard v4 `{ result }` envelope in case that changes.\n const payload = (await response.json()) as\n | BrowserRecording\n | { result?: BrowserRecording };\n const recording =\n \"result\" in payload && payload.result ? payload.result : payload;\n\n return recording as BrowserRecording;\n}\n\n/**\n * Connect to an existing Browser Rendering session without deleting it on close.\n */\nexport async function connectBrowserSession(\n browser: BrowserBinding,\n sessionId: string,\n timeoutMs?: number\n): Promise<CdpSession> {\n const response = await browser.fetch(browserSessionEndpoint(sessionId), {\n headers: { Upgrade: \"websocket\" }\n });\n\n const ws = response.webSocket;\n if (!ws) {\n throw new Error(\n `Browser Rendering binding did not return a WebSocket for session ${sessionId}`\n );\n }\n\n ws.accept();\n return new CdpSession(ws, timeoutMs, undefined, sessionId);\n}\n","import { BrowserRenderingError } from \"./browser-run\";\n\n/**\n * A Browser Run binding that supports [Quick Actions](https://developers.cloudflare.com/browser-run/quick-actions/).\n *\n * This is the `quickAction()` surface of the `BrowserRun` binding generated by\n * `wrangler types`. Quick Actions are stateless one-shot tasks (screenshot,\n * PDF, markdown, structured extraction, …) — no session, no token, just the\n * binding.\n *\n * Requires a Worker `compatibility_date` of `2026-03-24` or later, and\n * `remote: true` on the browser binding for local `wrangler dev`.\n */\nexport interface QuickActionBinding {\n // `options: unknown` (declared as a method, so parameters are checked\n // bivariantly) lets the real `BrowserRun` binding — whose `quickAction` is a\n // set of per-action typed overloads — satisfy this structural type.\n quickAction(action: string, options: unknown): Promise<Response>;\n}\n\n/** The Quick Action endpoints exposed by Browser Run. */\nexport type QuickAction =\n | \"content\"\n | \"screenshot\"\n | \"pdf\"\n | \"markdown\"\n | \"snapshot\"\n | \"scrape\"\n | \"json\"\n | \"links\"\n | \"crawl\";\n\ntype GotoOptions = {\n waitUntil?: \"load\" | \"domcontentloaded\" | \"networkidle0\" | \"networkidle2\";\n timeout?: number;\n};\n\n/** Options accepted by every Quick Action endpoint. */\nexport interface QuickActionCommonOptions {\n gotoOptions?: GotoOptions;\n viewport?: { width: number; height: number; deviceScaleFactor?: number };\n cookies?: unknown[];\n authenticate?: { username: string; password: string };\n setExtraHTTPHeaders?: Record<string, string>;\n userAgent?: string;\n /** Regex strings for requests to drop before render (e.g. `[\"/\\\\.css$/\"]`). */\n rejectRequestPattern?: string[];\n}\n\n/**\n * The page a Quick Action operates on: a `url` to load, or raw `html` to\n * render. Exactly one is required.\n */\nexport type QuickActionPage =\n | ({ url: string; html?: never } & QuickActionCommonOptions)\n | ({ html: string; url?: never } & QuickActionCommonOptions);\n\n/** Input for the AI-powered `/json` extraction endpoint. */\nexport type QuickActionExtractInput = QuickActionPage & {\n /** Natural-language instruction for what to extract. */\n prompt?: string;\n /** A JSON Schema describing the desired output shape. */\n response_format?: { type: \"json_schema\"; json_schema: unknown };\n /** Bring-your-own model(s), tried in order, for extraction. */\n custom_ai?: { model: string; authorization: string }[];\n};\n\n/** Input for the `/scrape` endpoint. */\nexport type QuickActionScrapeInput = QuickActionPage & {\n elements: { selector: string }[];\n};\n\n/** Input for the `/screenshot` endpoint. */\nexport type QuickActionScreenshotInput = QuickActionPage & {\n screenshotOptions?: Record<string, unknown>;\n selector?: string;\n};\n\n/** Binary output (screenshot or PDF) with its reported content type. */\nexport interface QuickActionBinary {\n data: Uint8Array;\n contentType: string;\n}\n\n/** Any Quick Action input accepted by the typed helpers. */\nexport type QuickActionInput =\n | QuickActionPage\n | QuickActionExtractInput\n | QuickActionScrapeInput\n | QuickActionScreenshotInput;\n\n/** Elements matched by one selector via `/scrape`. */\nexport interface QuickActionScrapeResult {\n selector: string;\n results: {\n html: string;\n text: string;\n width: number;\n height: number;\n top: number;\n left: number;\n attributes: { name: string; value: string }[];\n }[];\n}\n\n/** Result of a `/snapshot` request: rendered HTML plus a base64 screenshot. */\nexport interface QuickActionSnapshot {\n /** HTML content of the page. */\n content: string;\n /** Base64-encoded screenshot image. */\n screenshot: string;\n}\n\n/**\n * Run a Quick Action and return the raw {@link Response} from the binding.\n *\n * Most callers want a typed helper ({@link browserMarkdown},\n * {@link browserExtract}, …) instead; reach for this only when you need an\n * endpoint or option not yet wrapped. The per-action overloads type `params`\n * against the action when it is a string literal (e.g. `\"json\"` requires a\n * {@link QuickActionExtractInput}); any {@link QuickActionInput} is accepted\n * otherwise.\n */\nexport function runQuickAction(\n browser: QuickActionBinding,\n action: \"json\",\n params: QuickActionExtractInput\n): Promise<Response>;\nexport function runQuickAction(\n browser: QuickActionBinding,\n action: \"scrape\",\n params: QuickActionScrapeInput\n): Promise<Response>;\nexport function runQuickAction(\n browser: QuickActionBinding,\n action: \"screenshot\",\n params: QuickActionScreenshotInput\n): Promise<Response>;\nexport function runQuickAction(\n browser: QuickActionBinding,\n action: QuickAction,\n params: QuickActionInput\n): Promise<Response>;\nexport function runQuickAction(\n browser: QuickActionBinding,\n action: QuickAction,\n params: QuickActionInput\n): Promise<Response> {\n return browser.quickAction(action, params);\n}\n\n/** Build an error that includes the service's explanation, if the body has one. */\nasync function quickActionError(\n action: QuickAction,\n response: Response\n): Promise<BrowserRenderingError> {\n let detail = \"\";\n try {\n const text = await response.text();\n try {\n const body = JSON.parse(text) as {\n errors?: { message?: string }[];\n rawAiResponse?: string;\n };\n const messages = (body.errors ?? [])\n .map((e) => e.message)\n .filter((m): m is string => Boolean(m));\n if (messages.length > 0) detail = `: ${messages.join(\"; \")}`;\n else if (body.rawAiResponse) detail = `: ${body.rawAiResponse}`;\n else if (text) detail = `: ${text.slice(0, 200)}`;\n } catch {\n if (text) detail = `: ${text.slice(0, 200)}`;\n }\n } catch {\n // Body unreadable — fall back to the status code alone.\n }\n return new BrowserRenderingError(\n `Browser Run ${action} failed (${response.status})${detail}`,\n response.status\n );\n}\n\nasync function quickActionJson<T>(\n browser: QuickActionBinding,\n action: QuickAction,\n params: QuickActionInput\n): Promise<T> {\n const response = await runQuickAction(browser, action, params);\n if (!response.ok) throw await quickActionError(action, response);\n const payload = (await response.json()) as {\n success?: boolean;\n result?: T;\n errors?: { message?: string }[];\n };\n if (payload.success === false || payload.result === undefined) {\n const messages = (payload.errors ?? [])\n .map((e) => e.message)\n .filter((m): m is string => Boolean(m));\n throw new BrowserRenderingError(\n `Browser Run ${action} returned no result${messages.length > 0 ? `: ${messages.join(\"; \")}` : \"\"}`,\n response.status\n );\n }\n return payload.result;\n}\n\nasync function quickActionBinary(\n browser: QuickActionBinding,\n action: QuickAction,\n params: QuickActionInput\n): Promise<QuickActionBinary> {\n const response = await runQuickAction(browser, action, params);\n if (!response.ok) throw await quickActionError(action, response);\n const buffer = await response.arrayBuffer();\n return {\n data: new Uint8Array(buffer),\n contentType:\n response.headers.get(\"content-type\") ?? \"application/octet-stream\"\n };\n}\n\n/** Fetch a page's fully rendered HTML via `/content`. */\nexport function browserContent(\n browser: QuickActionBinding,\n input: QuickActionPage\n): Promise<string> {\n return quickActionJson<string>(browser, \"content\", input);\n}\n\n/** Convert a page (or raw HTML) to Markdown via `/markdown`. */\nexport function browserMarkdown(\n browser: QuickActionBinding,\n input: QuickActionPage\n): Promise<string> {\n return quickActionJson<string>(browser, \"markdown\", input);\n}\n\n/**\n * Extract structured data from a page with AI via `/json`. Provide a `prompt`,\n * a `response_format` JSON Schema, or both.\n */\nexport function browserExtract<T = unknown>(\n browser: QuickActionBinding,\n input: QuickActionExtractInput\n): Promise<T> {\n return quickActionJson<T>(browser, \"json\", input);\n}\n\n/** Retrieve every link on a page via `/links`. */\nexport function browserLinks(\n browser: QuickActionBinding,\n input: QuickActionPage\n): Promise<string[]> {\n return quickActionJson<string[]>(browser, \"links\", input);\n}\n\n/** Scrape specific elements (by CSS selector) via `/scrape`. */\nexport function browserScrape(\n browser: QuickActionBinding,\n input: QuickActionScrapeInput\n): Promise<QuickActionScrapeResult[]> {\n return quickActionJson<QuickActionScrapeResult[]>(browser, \"scrape\", input);\n}\n\n/** Capture rendered HTML plus a base64 screenshot in one request via `/snapshot`. */\nexport function browserSnapshot(\n browser: QuickActionBinding,\n input: QuickActionPage\n): Promise<QuickActionSnapshot> {\n return quickActionJson<QuickActionSnapshot>(browser, \"snapshot\", input);\n}\n\n/**\n * Render a screenshot via `/screenshot`. Returns the raw bytes and their\n * content type — by default a PNG (`image/png`). Note that passing\n * `screenshotOptions.encoding: \"base64\"` makes the service return a `text/plain`\n * data-URI string instead of binary, which this helper hands back verbatim.\n */\nexport function browserScreenshot(\n browser: QuickActionBinding,\n input: QuickActionScreenshotInput\n): Promise<QuickActionBinary> {\n return quickActionBinary(browser, \"screenshot\", input);\n}\n\n/** Render a PDF via `/pdf`. Returns the PDF bytes. */\nexport function browserPdf(\n browser: QuickActionBinding,\n input: QuickActionPage\n): Promise<QuickActionBinary> {\n return quickActionBinary(browser, \"pdf\", input);\n}\n","/**\n * Chrome DevTools Protocol spec fetching + caching.\n *\n * The raw `/json/protocol` payload is normalized into a searchable shape and\n * cached per source: `cdpUrl` specs by endpoint + headers, Browser Rendering\n * specs by the binding itself (a WeakMap) so two different bindings in the\n * same isolate don't share an entry. The CDP protocol is identical across\n * bindings, but per-binding keys avoid surprising cross-binding cache reads.\n */\n\nimport type { BrowserBinding } from \"./browser-run\";\n\ninterface RawCdpCommand {\n name: string;\n description?: string;\n}\n\ninterface RawCdpEvent {\n name: string;\n description?: string;\n}\n\ninterface RawCdpType {\n id: string;\n description?: string;\n}\n\n/** Raw CDP protocol domain from `/json/protocol` */\ninterface RawCdpDomain {\n domain: string;\n description?: string;\n commands?: RawCdpCommand[];\n events?: RawCdpEvent[];\n types?: RawCdpType[];\n}\n\nexport interface SearchableCdpSpec {\n domains: Array<{\n name: string;\n description?: string;\n commands: Array<{ name: string; method: string; description?: string }>;\n events: Array<{ name: string; event: string; description?: string }>;\n types: Array<{ id: string; name: string; description?: string }>;\n }>;\n}\n\nexport interface CdpSpecSource {\n /** Browser Rendering binding (Fetcher) — used in production */\n browser?: BrowserBinding;\n /** CDP base URL override (e.g. http://localhost:9222) */\n cdpUrl?: string;\n /** Headers to send with CDP URL discovery requests */\n cdpHeaders?: Record<string, string>;\n}\n\nconst MISSING_BROWSER_CONFIG =\n \"Either 'browser' (Fetcher binding) or 'cdpUrl' must be provided\";\n\ninterface SpecCacheEntry {\n spec: SearchableCdpSpec;\n cachedAt: number;\n}\n\nconst urlSpecCache = new Map<string, SpecCacheEntry>();\nconst bindingSpecCache = new WeakMap<BrowserBinding, SpecCacheEntry>();\n\nconst CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\nfunction normalizeCdpSpec(spec: {\n domains?: RawCdpDomain[];\n}): SearchableCdpSpec {\n return {\n domains: (spec.domains ?? []).map((domain) => ({\n name: domain.domain,\n description: domain.description,\n commands: (domain.commands ?? []).map((command) => ({\n name: command.name,\n method: `${domain.domain}.${command.name}`,\n description: command.description\n })),\n events: (domain.events ?? []).map((event) => ({\n name: event.name,\n event: `${domain.domain}.${event.name}`,\n description: event.description\n })),\n types: (domain.types ?? []).map((type) => ({\n id: type.id,\n name: `${domain.domain}.${type.id}`,\n description: type.description\n }))\n }))\n };\n}\n\nfunction getSpecCacheKey(\n source: string,\n headers?: Record<string, string>\n): string {\n const headerEntries = Object.entries(headers ?? {}).sort(([a], [b]) =>\n a.localeCompare(b)\n );\n return `${source}:${JSON.stringify(headerEntries)}`;\n}\n\nasync function getCachedSpec<K>(\n cache: {\n get(key: K): SpecCacheEntry | undefined;\n set(key: K, entry: SpecCacheEntry): void;\n },\n key: K,\n load: () => Promise<{ domains?: RawCdpDomain[] }>\n): Promise<SearchableCdpSpec> {\n const cached = cache.get(key);\n if (cached && Date.now() - cached.cachedAt < CACHE_TTL_MS) {\n return cached.spec;\n }\n\n const spec = normalizeCdpSpec(await load());\n cache.set(key, { spec, cachedAt: Date.now() });\n return spec;\n}\n\nasync function fetchCdpSpecFromUrl(\n cdpBaseUrl: string,\n headers?: Record<string, string>\n): Promise<SearchableCdpSpec> {\n const endpoint = new URL(\"/json/protocol\", cdpBaseUrl).toString();\n\n return getCachedSpec(\n urlSpecCache,\n getSpecCacheKey(endpoint, headers),\n async () => {\n const response = await fetch(endpoint, { headers });\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch CDP spec from ${endpoint}: ${response.status}`\n );\n }\n\n return (await response.json()) as { domains?: RawCdpDomain[] };\n }\n );\n}\n\nasync function fetchCdpSpecFromBrowser(\n browser: BrowserBinding\n): Promise<SearchableCdpSpec> {\n return getCachedSpec(bindingSpecCache, browser, async () => {\n const createResponse = await browser.fetch(\n \"https://localhost/v1/devtools/browser\",\n {\n method: \"POST\"\n }\n );\n\n if (!createResponse.ok) {\n throw new Error(\n \"Failed to create Browser Rendering session for protocol fetch: \" +\n `${createResponse.status}`\n );\n }\n\n const payload = (await createResponse.json()) as { sessionId?: string };\n const sessionId = payload.sessionId;\n if (!sessionId) {\n throw new Error(\n \"Browser Rendering session response did not include a sessionId\"\n );\n }\n\n try {\n const response = await browser.fetch(\n `https://localhost/v1/devtools/browser/${sessionId}/json/protocol`\n );\n\n if (!response.ok) {\n throw new Error(\n \"Failed to fetch CDP spec from Browser Rendering: \" +\n `${response.status}`\n );\n }\n\n return (await response.json()) as { domains?: RawCdpDomain[] };\n } finally {\n try {\n await browser.fetch(\n `https://localhost/v1/devtools/browser/${sessionId}`,\n {\n method: \"DELETE\"\n }\n );\n } catch {\n // Cleanup failure should not mask the original result or error\n }\n }\n });\n}\n\n/** Load the (cached) searchable CDP spec for a browser source. */\nexport async function loadCdpSpec(\n source: CdpSpecSource\n): Promise<SearchableCdpSpec> {\n if (source.cdpUrl) {\n return fetchCdpSpecFromUrl(source.cdpUrl, source.cdpHeaders);\n }\n if (source.browser) {\n return fetchCdpSpecFromBrowser(source.browser);\n }\n throw new Error(MISSING_BROWSER_CONFIG);\n}\n","type MaybePromise<T> = T | Promise<T>;\n\nexport interface StoredBrowserSession {\n sessionId: string;\n createdAt: number;\n updatedAt: number;\n /**\n * Set when a sweep closed this entry's Browser Run session but kept the\n * entry as a tombstone, so a later resume of the owning execution fails\n * loudly instead of silently continuing in a fresh browser.\n */\n closedAt?: number;\n}\n\nexport interface BrowserSessionLock {\n release(): MaybePromise<void>;\n}\n\nexport interface BrowserSessionStore {\n /**\n * Acquire an exclusive lock for this session key. The lock must serialize\n * all holders using the same key. Held only around storage reads/writes —\n * never across Browser Rendering network calls.\n */\n acquireLock(key: string): MaybePromise<BrowserSessionLock>;\n get(key: string): MaybePromise<StoredBrowserSession | undefined>;\n set(key: string, session: StoredBrowserSession): MaybePromise<void>;\n delete(key: string): MaybePromise<void>;\n /**\n * List stored sessions by key prefix. Optional — used by sweeps to find\n * orphaned per-execution sessions; without it only the shared session key\n * is swept.\n */\n list?(prefix: string): MaybePromise<Map<string, StoredBrowserSession>>;\n}\n\nexport class DurableBrowserSessionStore implements BrowserSessionStore {\n static #queues = new WeakMap<\n DurableObjectStorage,\n Map<string, Promise<void>>\n >();\n\n constructor(private readonly storage: DurableObjectStorage) {}\n\n async acquireLock(key: string): Promise<BrowserSessionLock> {\n let queues = DurableBrowserSessionStore.#queues.get(this.storage);\n if (!queues) {\n queues = new Map();\n DurableBrowserSessionStore.#queues.set(this.storage, queues);\n }\n\n const previous = queues.get(key) ?? Promise.resolve();\n let releaseQueue: () => void = () => undefined;\n const current = previous.then(\n () =>\n new Promise<void>((resolve) => {\n releaseQueue = resolve;\n })\n );\n queues.set(key, current);\n await previous;\n\n let released = false;\n return {\n release: () => {\n if (released) return;\n released = true;\n if (queues.get(key) === current) {\n queues.delete(key);\n }\n releaseQueue();\n }\n };\n }\n\n async get(key: string): Promise<StoredBrowserSession | undefined> {\n return this.storage.get<StoredBrowserSession>(this.#storageKey(key));\n }\n\n async set(key: string, session: StoredBrowserSession): Promise<void> {\n await this.storage.put(this.#storageKey(key), session);\n }\n\n async delete(key: string): Promise<void> {\n await this.storage.delete(this.#storageKey(key));\n }\n\n async list(prefix: string): Promise<Map<string, StoredBrowserSession>> {\n const storagePrefix = this.#storageKey(prefix);\n const entries = await this.storage.list<StoredBrowserSession>({\n prefix: storagePrefix\n });\n const result = new Map<string, StoredBrowserSession>();\n for (const [storageKey, value] of entries) {\n result.set(storageKey.slice(\"browser-session:\".length), value);\n }\n return result;\n }\n\n #storageKey(key: string): string {\n return `browser-session:${key}`;\n }\n}\n\n/**\n * Default idle window used by {@link BrowserConnector.sweep} for the shared\n * (reuse/promoted) session entry.\n */\nexport const DEFAULT_SWEEP_IDLE_MS = 10 * 60 * 1000;\n","import { Validator, type OutputUnit, type Schema } from \"@cfworker/json-schema\";\nimport {\n CodemodeConnector,\n type ConnectorTool,\n type ConnectorTools,\n type ExecutionEndStatus,\n type PassEndStatus,\n type ToolExecuteContext\n} from \"@cloudflare/codemode\";\nimport { CdpSession, connectUrl } from \"./cdp-session\";\nimport {\n connectBrowser,\n connectBrowserSession,\n createBrowserSession,\n deleteBrowserSession,\n listBrowserTargets,\n BrowserRenderingError,\n type BrowserBinding,\n type BrowserSessionInfo,\n type BrowserTargetInfo\n} from \"./browser-run\";\nimport { loadCdpSpec, type SearchableCdpSpec } from \"./spec\";\nimport type {\n BrowserSessionStore,\n StoredBrowserSession\n} from \"./session-manager\";\nimport { DEFAULT_SWEEP_IDLE_MS } from \"./session-manager\";\n\n/** Browser session lifecycle for the connector (binding-backed only). */\nexport interface BrowserConnectorSessionOptions {\n /**\n * - `\"one-shot\"` (default) — one Browser Run session per codemode\n * execution, deleted when the execution ends.\n * - `\"reuse\"` — all executions share one stored session under `key`.\n * - `\"dynamic\"` — per-execution sessions by default; the model can call\n * `cdp.startSession()` to promote the current session into the shared\n * slot so later executions reuse it.\n */\n mode?: \"one-shot\" | \"reuse\" | \"dynamic\";\n /** Logical owner key for the shared (reuse/promoted) session. Default `\"default\"`. */\n key?: string;\n /** Browser Run inactivity timeout. Browser Run currently caps this server-side. */\n keepAliveMs?: number;\n /**\n * Opt into Browser Run [session recording](https://developers.cloudflare.com/browser-run/features/session-recording/)\n * for sessions this connector creates: an rrweb capture of everything the\n * agent did, finalized when the session closes. Retrieve it afterward with\n * {@link getBrowserRecording} using the session id from\n * {@link BrowserConnector.liveView}/`sessionInfo()`.\n */\n recording?: boolean;\n /**\n * Select the browser engine. Defaults to Chromium. Kitesurf is scoped to\n * one CDP WebSocket, so it supports only one-shot execution without\n * pause/resume, Live View, recording, or keep-alive.\n */\n browser?: \"kitesurf\";\n}\n\nexport type BrowserConnectorOptions = (\n | {\n /** Browser Rendering binding (Fetcher) — used in production. */\n browser: BrowserBinding;\n /**\n * Durable store for Browser Run session ids. Required with the binding:\n * a session must survive a pause (approval) and resume on a fresh\n * instance, so its id cannot live in connector memory.\n */\n store: BrowserSessionStore;\n session?: BrowserConnectorSessionOptions;\n cdpUrl?: never;\n cdpHeaders?: never;\n }\n | {\n /**\n * CDP base URL override (e.g. http://localhost:9222). The browser is\n * externally managed: no Browser Run sessions are created or deleted,\n * and session modes don't apply.\n */\n cdpUrl: string;\n /** Headers to send with CDP URL discovery requests (e.g. Access headers). */\n cdpHeaders?: Record<string, string>;\n browser?: never;\n store?: never;\n session?: never;\n }\n) & {\n /** CDP command timeout in milliseconds (default: 10000). */\n timeout?: number;\n};\n\nexport interface BrowserConnectorSweepOptions {\n /**\n * Close the shared (reuse/promoted) session when idle for at least this\n * many milliseconds. Defaults to the connector's `keepAliveMs`, or\n * {@link DEFAULT_SWEEP_IDLE_MS}.\n */\n maxIdleMs?: number;\n /**\n * Close *per-execution* sessions when idle for at least this many\n * milliseconds. Defaults to {@link DEFAULT_EXEC_SWEEP_IDLE_MS} (24h) —\n * deliberately at least as long as the codemode runtime's default paused\n * TTL, so a run awaiting approval is normally expired (and disposed) by\n * `expirePaused` before the sweep backstop ever touches its browser.\n */\n maxExecIdleMs?: number;\n}\n\nexport interface BrowserConnectorSweepResult {\n /** Store keys (and their Browser Run session ids) closed by this sweep. */\n swept: Array<{ key: string; sessionId: string }>;\n}\n\n/**\n * Live View rendering mode (the `mode` query param the hosted UI at\n * `live.browser.run` understands):\n *\n * - `\"tab\"` — a standalone, interactive page view (best for handing control\n * to a human).\n * - `\"devtools\"` — the full DevTools inspector panel (Elements, Console,\n * Network, …).\n *\n * Omit it to use whatever mode the binding's `devtoolsFrontendUrl` defaults\n * to.\n */\nexport type LiveViewMode = \"tab\" | \"devtools\";\n\n/** A single tab's Live View URL. */\nexport interface BrowserLiveViewUrl {\n /** Open this in a browser to watch/control the tab in real time. */\n url: string;\n /** CDP target (tab) id the URL points at. */\n targetId: string;\n /** Milliseconds the URL stays valid from when it was generated (~5 min). */\n expiresInMs: number;\n}\n\nexport interface BrowserLiveViewTarget {\n targetId: string;\n /** Embeddable Live View URL (the `devtoolsFrontendUrl`) for this tab. */\n url: string;\n /** The page the tab is currently showing (e.g. `https://example.com`). */\n pageUrl?: string;\n title?: string;\n type?: string;\n}\n\n/** Live View URLs for every tab in a (shared) session. */\nexport interface BrowserLiveView {\n sessionId: string;\n targets: BrowserLiveViewTarget[];\n /** Milliseconds the URLs stay valid from when they were generated (~5 min). */\n expiresInMs: number;\n}\n\nconst EXEC_KEY_PREFIX = \"cdp:exec:\";\n/**\n * Prefix of the synthetic session id stored for a Kitesurf execution: the\n * connection is scoped to its execution, so the entry is a marker rather than\n * a Browser Run session that can be reconnected to or deleted.\n */\nconst KITESURF_SESSION_PREFIX = \"kitesurf:\";\nconst REUSE_KEY_PREFIX = \"cdp:reuse:\";\n\n/**\n * Default idle window before {@link BrowserConnector.sweep} reclaims a\n * per-execution session. Matches the codemode runtime's default paused TTL\n * (24h): an execution paused for approval keeps its browser until the run\n * itself is expired.\n */\nexport const DEFAULT_EXEC_SWEEP_IDLE_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Minimum interval between `updatedAt` bumps on a per-execution store entry.\n * Touching on every CDP call would write-amplify; once a minute is enough to\n * keep an active or recently-resumed execution out of sweep range.\n */\nconst EXEC_TOUCH_INTERVAL_MS = 60 * 1000;\n\n/**\n * Browser Run mints `devtoolsFrontendUrl`s (the Live View links) that are\n * valid for ~5 minutes. We surface the window so callers can decide how long\n * a shared link is good for before re-listing targets.\n */\nconst LIVE_VIEW_URL_TTL_MS = 5 * 60 * 1000;\n\nfunction isMissingBrowserSession(error: unknown): boolean {\n // Browser Run uses 404 for unknown ids and 410 after keep_alive expiry.\n return (\n error instanceof BrowserRenderingError &&\n (error.status === 404 || error.status === 410)\n );\n}\n\nfunction formatToolValidationError(\n connector: string,\n tool: string,\n errors: OutputUnit[]\n): string {\n // A failing property emits both a generic parent `properties` error and a\n // specific child error. Prefer the latter so the model sees what to fix.\n const specific = errors.filter((error) => error.keyword !== \"properties\");\n const relevant = specific.length > 0 ? specific : errors;\n const details = relevant.map((error) => {\n const location = error.instanceLocation\n .replace(/^#\\/?/, \"\")\n .replaceAll(\"~1\", \"/\")\n .replaceAll(\"~0\", \"~\")\n .replaceAll(\"/\", \".\");\n return `${location ? ` at ${location}` : \"\"}: ${error.error}`;\n });\n return `Invalid arguments for ${connector}.${tool}${details.join(\";\")}`;\n}\n\n/**\n * Rewrite the hosted Live View UI's `mode` query param (`tab` | `devtools`).\n * The raw `devtoolsFrontendUrl` is returned unchanged when no mode is asked\n * for or the URL can't be parsed.\n */\nfunction applyLiveViewMode(rawUrl: string, mode?: LiveViewMode): string {\n if (!mode) return rawUrl;\n try {\n const url = new URL(rawUrl);\n url.searchParams.set(\"mode\", mode === \"devtools\" ? \"devtools\" : \"tab\");\n return url.toString();\n } catch {\n return rawUrl;\n }\n}\n\ninterface CachedSocket {\n session: CdpSession;\n /** Browser Run session id the socket is attached to (undefined for cdpUrl). */\n browserSessionId?: string;\n /**\n * Live CDP session id per attach handle, valid for this socket only.\n * Rebuilt lazily after a reconnect (sockets are per-pass).\n */\n attached: Map<string, string>;\n}\n\n/**\n * `cdp.attachToTarget` returns `{ sessionId: \"target:<targetId>\" }` — a stable\n * handle instead of the raw CDP session id. (The object shape mirrors the real\n * `Target.attachToTarget` response, which is what models reach for.) Raw ids\n * are connection-scoped: a run that pauses\n * for approval resumes on a fresh WebSocket where the old id is invalid, and\n * the durable replay log would otherwise pin the stale value. The handle is a\n * pure function of the target, so replayed code computes identical arguments,\n * and `send` resolves it to a live session id on the current socket —\n * re-attaching lazily after a reconnect.\n */\nconst ATTACH_HANDLE_PREFIX = \"target:\";\n\n/**\n * Codemode connector exposing a live browser over the Chrome DevTools\n * Protocol as the `cdp` global.\n *\n * Per-execution resources are keyed by the codemode `executionId`:\n *\n * - The Browser Run session id is stored durably under `cdp:exec:<id>`, so a\n * run that pauses for approval reconnects to the *same* browser when it\n * resumes — even on a fresh instance.\n * - The CDP WebSocket is per-pass: `onPassEnd` disconnects it (a paused run\n * holds no socket), and the next pass reconnects from the stored id.\n * - `disposeExecution` deletes the session unless it was promoted to the\n * shared slot via `cdp.startSession()` (dynamic mode).\n *\n * Locks on the session store are held only around store reads/writes, never\n * across network calls to Browser Run or while a socket is open.\n */\nexport class BrowserConnector extends CodemodeConnector {\n #options: BrowserConnectorOptions;\n #sockets = new Map<string, CachedSocket>();\n #connecting = new Map<string, Promise<CdpSession>>();\n\n constructor(\n ctx: DurableObjectState | ExecutionContext,\n options: BrowserConnectorOptions\n ) {\n super(ctx, {});\n if (!options.cdpUrl && !options.browser) {\n throw new Error(\n \"BrowserConnector requires either 'browser' (Fetcher binding) or 'cdpUrl'\"\n );\n }\n if (options.browser && !options.store) {\n throw new Error(\n \"BrowserConnector requires 'store' when using the Browser Rendering binding\"\n );\n }\n if (options.session?.browser === \"kitesurf\") {\n if (\n options.session.mode !== undefined &&\n options.session.mode !== \"one-shot\"\n ) {\n throw new Error('Kitesurf only supports session mode \"one-shot\"');\n }\n if (options.session.keepAliveMs) {\n throw new Error(\"Kitesurf does not support keepAliveMs\");\n }\n if (options.session.recording) {\n throw new Error(\"Kitesurf does not support session recording\");\n }\n }\n this.#options = options;\n }\n\n name(): string {\n return \"cdp\";\n }\n\n protected instructions(): string {\n const mode = this.#mode();\n const lines = [\n \"Issue CDP calls sequentially — never in parallel (no Promise.all): call order is recorded for durable replay.\",\n \"cdp.send returns the CDP method result directly, not the outer JSON-RPC envelope: Target.createTarget returns { targetId }, Runtime.evaluate returns { result: { value } }, and Page.captureScreenshot returns { data }.\",\n \"Browser-/Target-scoped commands (Target.createTarget, Target.getTargets) need no sessionId. Page-scoped commands (Page.navigate, Runtime.evaluate) require one: `const { sessionId } = await cdp.attachToTarget({ targetId });` then pass it to every page-scoped send. Use this helper instead of sending Target.attachToTarget manually.\",\n \"Write large textual outputs such as page dumps to a file or workspace and pass around small references. For screenshots, follow the host tool's documented screenshot result format.\",\n \"If a command fails or times out, check cdp.getDebugLog() for recent protocol traffic.\"\n ];\n if (this.#isKitesurf()) {\n lines.push(\n \"Kitesurf implements a subset of CDP and does not expose protocol discovery.\",\n \"Kitesurf is scoped to this connection. Complete the whole browser task in one execution and do not pause for approval: the browser cannot reconnect when execution resumes.\",\n \"Kitesurf Page.navigate may resolve before layout and paint. Before a screenshot: call Page.enable; navigate; poll Runtime.evaluate with returnByValue: true until result.value reports document.readyState === 'complete' and non-empty body text; then wait 1000ms before Page.captureScreenshot. Do not capture if readiness fails.\"\n );\n } else {\n lines.push(\n \"Use cdp.spec() to discover commands, events, and types when unsure.\",\n \"When a step needs a human (login, MFA, CAPTCHA, sensitive input), call cdp.getLiveViewUrl() to get a link they can open to control the browser live — surface it, then make an approval-gated call so the run pauses until they're done.\"\n );\n }\n if (mode === \"one-shot\") {\n lines.push(\n \"The browser session lasts for this execution only and is closed when it ends.\"\n );\n } else if (mode === \"reuse\") {\n lines.push(\n \"The browser session is shared and persists across executions — tabs and state you leave behind will still be there next time.\"\n );\n } else {\n lines.push(\n \"The browser session is one-shot by default. If browser state must persist after this execution (e.g. a logged-in page), call cdp.startSession() to keep it alive for later executions.\"\n );\n }\n return lines.join(\"\\n\");\n }\n\n protected override tool(name: string, tool: ConnectorTool): ConnectorTool {\n if (!tool.inputSchema) return tool;\n\n // Both types describe draft-7 schemas, but @cfworker's `Schema` type is\n // narrower than JSONSchema7 around boolean subschemas.\n const schema = tool.inputSchema as unknown as Schema;\n const validator = new Validator(schema, \"7\", false);\n return {\n ...tool,\n execute: async (args, ctx) => {\n // Browser's argumentless tools are documented as `cdp.spec()` etc.;\n // treat an omitted argument as the empty object their schemas expect.\n const input = args === undefined ? {} : args;\n const result = validator.validate(input);\n if (!result.valid) {\n throw new Error(\n formatToolValidationError(this.name(), name, result.errors)\n );\n }\n return await tool.execute(input, ctx);\n }\n };\n }\n\n protected tools(): ConnectorTools {\n const tools: ConnectorTools = {\n send: {\n description:\n \"Send a CDP command and return its method result directly (the outer JSON-RPC envelope is removed). Page-scoped commands require a sessionId — pass the handle returned by attachToTarget.\",\n inputSchema: {\n type: \"object\",\n properties: {\n method: {\n type: \"string\",\n description: 'CDP method, e.g. \"Target.createTarget\"'\n },\n params: {\n type: \"object\",\n description: \"CDP command parameters\"\n },\n sessionId: {\n type: \"string\",\n description:\n \"Session handle from attachToTarget, for page-scoped 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?: unknown;\n sessionId?: string;\n timeoutMs?: number;\n };\n const executionId = this.#executionId(ctx);\n const socket = await this.#socket(executionId);\n const resolved = await this.#resolveSessionHandle(\n executionId,\n sessionId\n );\n try {\n return await socket.send(method, params, {\n sessionId: resolved,\n timeoutMs\n });\n } catch (err) {\n // \"Method wasn't found\" is almost always one of two model\n // mistakes. Teach the fix instead of leaving a bare protocol\n // error: either the method is actually an event (events can't be\n // sent), or a page-scoped command went to the browser-level\n // session because no sessionId was passed.\n if (\n err instanceof Error &&\n /-32601|wasn't found/.test(err.message)\n ) {\n if (await this.#isSpecEvent(method)) {\n throw new Error(\n `${err.message}. '${method}' is a CDP *event*, not a ` +\n `command — it cannot be called via cdp.send. To wait for ` +\n `page state, poll instead (e.g. Runtime.evaluate of ` +\n `document.readyState until \"complete\").`\n );\n }\n if (!sessionId) {\n throw new Error(\n `${err.message}. Page-scoped commands need a sessionId: ` +\n `const { sessionId } = await cdp.attachToTarget({ targetId }); ` +\n `then pass sessionId to cdp.send.`\n );\n }\n }\n throw err;\n }\n }\n },\n\n attachToTarget: {\n description: this.#isKitesurf()\n ? \"Attach to a target (tab) and return { sessionId } to pass to page-scoped send calls for this connection.\"\n : \"Attach to a target (tab) and return { sessionId } — a stable session handle to pass as sessionId in page-scoped send calls. The handle stays valid across pauses/resumes.\",\n inputSchema: {\n type: \"object\",\n properties: {\n targetId: {\n type: \"string\",\n description: \"Target id from Target.createTarget/getTargets\"\n },\n timeoutMs: { type: \"number\" }\n },\n required: [\"targetId\"]\n },\n outputSchema: {\n type: \"object\",\n properties: {\n sessionId: {\n type: \"string\",\n description: this.#isKitesurf()\n ? \"Session handle for page-scoped send calls on this connection\"\n : \"Stable session handle for page-scoped send calls (valid across pauses/resumes)\"\n }\n },\n required: [\"sessionId\"]\n },\n execute: async (args, ctx) => {\n const { targetId, timeoutMs } = args as {\n targetId: string;\n timeoutMs?: number;\n };\n const executionId = this.#executionId(ctx);\n await this.#attach(executionId, targetId, timeoutMs);\n return { sessionId: `${ATTACH_HANDLE_PREFIX}${targetId}` };\n }\n },\n\n spec: {\n description:\n \"Return the searchable Chrome DevTools Protocol spec: domains with their commands, events, and types. Use it to discover method names and capabilities.\",\n replay: \"reexecute\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (): Promise<SearchableCdpSpec> => {\n if (this.#isKitesurf()) {\n throw new Error(\n \"Kitesurf does not expose a CDP protocol specification\"\n );\n }\n return loadCdpSpec(this.#options);\n }\n },\n\n getDebugLog: {\n description:\n \"Return recent CDP protocol traffic (sends, receives, warnings) for this execution's connection — useful to diagnose failures and timeouts.\",\n replay: \"reexecute\",\n inputSchema: {\n type: \"object\",\n properties: {\n limit: {\n type: \"number\",\n description: \"Max entries to return (default 50)\"\n }\n }\n },\n execute: async (args, ctx) => {\n const { limit } = (args ?? {}) as { limit?: number };\n const socket = await this.#socket(this.#executionId(ctx));\n return socket.getDebugLog(limit);\n }\n },\n\n clearDebugLog: {\n description: \"Clear the CDP debug log for this execution's connection.\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (_args, ctx) => {\n const socket = await this.#socket(this.#executionId(ctx));\n socket.clearDebugLog();\n return null;\n }\n }\n };\n\n if (this.#isKitesurf()) {\n delete tools.spec;\n } else {\n tools.getLiveViewUrl = {\n description:\n \"Return a Live View URL for a tab — a link a human can open in a \" +\n \"browser to watch and control this session in real time. Use it \" +\n \"for human-in-the-loop steps (login, MFA, CAPTCHA, sensitive \" +\n \"input): get the URL, surface it to the user, then make a call \" +\n \"that pauses for approval so they can act before the run \" +\n \"continues. The URL is valid for ~5 minutes.\",\n replay: \"reexecute\",\n inputSchema: {\n type: \"object\",\n properties: {\n targetId: {\n type: \"string\",\n description:\n \"Target (tab) id to view; defaults to the first open page\"\n },\n mode: {\n type: \"string\",\n enum: [\"tab\", \"devtools\"],\n description:\n \"tab = standalone interactive page view (best for handoff); \" +\n \"devtools = full DevTools inspector panel\"\n }\n }\n },\n execute: async (args, ctx) => {\n const { targetId, mode } = (args ?? {}) as {\n targetId?: string;\n mode?: LiveViewMode;\n };\n return this.#liveViewUrl(this.#executionId(ctx), { targetId, mode });\n }\n };\n }\n\n const mode = this.#mode();\n if (mode === \"reuse\" || mode === \"dynamic\") {\n tools.startSession = {\n description:\n mode === \"dynamic\"\n ? \"Promote the current browser session into the shared slot so it persists after this execution. Later executions reuse it. Returns the session info.\"\n : \"Ensure the shared browser session exists and return its info.\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (_args, ctx) =>\n this.#startSession(this.#executionId(ctx))\n };\n tools.sessionInfo = {\n description:\n \"Return info about the shared browser session (id and open targets), or null when none exists.\",\n replay: \"reexecute\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async () => (await this.sessionInfo()) ?? null\n };\n tools.closeSession = {\n description:\n \"Close the shared browser session, discarding its tabs and state.\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (_args, ctx) => {\n await this.#closeReusableFor(this.#executionId(ctx));\n return null;\n }\n };\n tools.resetSession = {\n description:\n \"Close the shared browser session and start a fresh one. Returns the new session info.\",\n inputSchema: { type: \"object\", properties: {} },\n execute: async (_args, ctx) =>\n this.#resetSession(this.#executionId(ctx))\n };\n }\n\n return tools;\n }\n\n // ---------------------------------------------------------------------\n // Lifecycle hooks\n // ---------------------------------------------------------------------\n\n /**\n * A pass is over (completed, errored, or paused awaiting approval) — drop\n * the CDP socket. The Browser Run session itself stays alive; a resume\n * reconnects from the durably stored session id.\n */\n override async onPassEnd(\n executionId: string,\n status: PassEndStatus\n ): Promise<void> {\n this.#dropSocket(executionId);\n if (!this.#isKitesurf() || status !== \"paused\") return;\n\n const key = this.#execKey(executionId);\n const lock = await this.#store.acquireLock(key);\n try {\n const stored = await this.#store.get(key);\n // Only a Kitesurf marker is gone with its connection; a session left by\n // an earlier Chromium run is still live and must stay reclaimable.\n if (stored?.sessionId.startsWith(KITESURF_SESSION_PREFIX)) {\n await this.#store.set(key, { ...stored, closedAt: Date.now() });\n }\n } finally {\n await lock.release();\n }\n }\n\n /**\n * The execution is terminal — delete its Browser Run session unless it was\n * promoted to the shared slot via `cdp.startSession()`.\n */\n override async disposeExecution(\n executionId: string,\n _status: ExecutionEndStatus\n ): Promise<void> {\n this.#dropSocket(executionId);\n if (!this.#options.browser) return;\n\n if (this.#isKitesurf()) {\n const key = this.#execKey(executionId);\n const lock = await this.#store.acquireLock(key);\n // An entry written before the connector was switched to Kitesurf still\n // holds a real Browser Run session that has to be closed.\n let stale: StoredBrowserSession | undefined;\n try {\n const stored = await this.#store.get(key);\n if (\n stored &&\n stored.closedAt === undefined &&\n !stored.sessionId.startsWith(KITESURF_SESSION_PREFIX)\n ) {\n stale = stored;\n }\n await this.#store.delete(key);\n } finally {\n await lock.release();\n }\n if (stale) {\n try {\n await deleteBrowserSession(this.#options.browser, stale.sessionId);\n } catch (error) {\n console.warn(\n `[agents/browser] Failed to delete Browser Run session ${stale.sessionId} for execution ${executionId}`,\n error\n );\n }\n }\n return;\n }\n\n const store = this.#options.store;\n const execKey = this.#execKey(executionId);\n const lock = await store.acquireLock(execKey);\n // Decide and update storage under the lock; the Browser Rendering delete\n // happens after release (locks wrap storage only).\n let toClose: StoredBrowserSession | undefined;\n try {\n const stored = await store.get(execKey);\n if (!stored) return;\n\n let promoted = false;\n if (this.#mode() === \"dynamic\") {\n const shared = await store.get(this.#reuseKey());\n promoted = shared?.sessionId === stored.sessionId;\n }\n\n if (!promoted && stored.closedAt === undefined) {\n toClose = stored;\n }\n await store.delete(execKey);\n } finally {\n await lock.release();\n }\n\n if (toClose) {\n try {\n await deleteBrowserSession(this.#options.browser, toClose.sessionId);\n } catch (error) {\n console.warn(\n `[agents/browser] Failed to delete Browser Run session ${toClose.sessionId} for execution ${executionId}`,\n error\n );\n }\n }\n }\n\n // ---------------------------------------------------------------------\n // Host-side helpers — for callables and scheduled tasks on the agent.\n // ---------------------------------------------------------------------\n\n /** Info about the shared (reuse/promoted) session, if one exists. */\n async sessionInfo(): Promise<BrowserSessionInfo | undefined> {\n if (!this.#options.browser || this.#isKitesurf()) return undefined;\n const store = this.#options.store;\n const key = this.#reuseKey();\n const lock = await store.acquireLock(key);\n let stored: StoredBrowserSession | undefined;\n try {\n stored = await store.get(key);\n } finally {\n await lock.release();\n }\n if (!stored) return undefined;\n try {\n return {\n sessionId: stored.sessionId,\n targets: await listBrowserTargets(\n this.#options.browser,\n stored.sessionId\n )\n };\n } catch (error) {\n if (isMissingBrowserSession(error)) {\n await this.#deleteStoredEntry(key, stored.sessionId);\n return undefined;\n }\n throw error;\n }\n }\n\n /**\n * Live View URLs for the shared (reuse/promoted) session's tabs, or\n * `undefined` when no shared session exists. Each URL opens an interactive,\n * real-time view of the browser — surface them in your UI (or send them via\n * Slack/email) to let a human watch or take over a running session\n * (human-in-the-loop). URLs are valid for ~5 minutes; call again for fresh\n * ones. Only meaningful with the Browser Rendering binding in\n * `reuse`/`dynamic` mode.\n */\n async liveView(options?: {\n mode?: LiveViewMode;\n }): Promise<BrowserLiveView | undefined> {\n const info = await this.sessionInfo();\n if (!info) return undefined;\n const targets = (info.targets ?? [])\n .filter((target) => target.devtoolsFrontendUrl)\n .map((target) => ({\n targetId: target.id,\n url: applyLiveViewMode(target.devtoolsFrontendUrl!, options?.mode),\n pageUrl: target.url,\n title: target.title,\n type: target.type\n }));\n return {\n sessionId: info.sessionId,\n targets,\n expiresInMs: LIVE_VIEW_URL_TTL_MS\n };\n }\n\n /** Close the shared (reuse/promoted) session, if one exists. */\n async closeSession(): Promise<void> {\n if (!this.#options.browser || this.#isKitesurf()) return;\n await this.#closeStoredSession(this.#reuseKey());\n }\n\n /**\n * Close stored sessions (shared and per-execution) idle past the threshold.\n * Per-execution entries normally die with `disposeExecution` (or the\n * codemode runtime's `expirePaused`); the sweep is the backstop for crashed\n * hosts. Call it from a recurring alarm/scheduled task.\n *\n * Active executions bump their entry's `updatedAt` on use, so only runs\n * idle past `maxExecIdleMs` (default 24h) are reclaimed. A swept\n * per-execution entry is kept as a tombstone (`closedAt`) rather than\n * deleted, so a later resume fails with a clear \"session expired\" error\n * instead of silently continuing in a fresh browser; tombstones are\n * deleted once they age past the threshold again.\n *\n * Kitesurf entries are reclaimed the same way, minus the Browser Run\n * delete: their stored id is a synthetic per-execution marker, not a\n * session, and the connection died with the execution.\n */\n async sweep(\n options?: BrowserConnectorSweepOptions\n ): Promise<BrowserConnectorSweepResult> {\n if (!this.#options.browser) return { swept: [] };\n const browser = this.#options.browser;\n const store = this.#options.store;\n const maxIdleMs =\n options?.maxIdleMs ??\n this.#options.session?.keepAliveMs ??\n DEFAULT_SWEEP_IDLE_MS;\n const maxExecIdleMs = options?.maxExecIdleMs ?? DEFAULT_EXEC_SWEEP_IDLE_MS;\n\n const keys = new Set<string>([this.#reuseKey()]);\n if (store.list) {\n for (const key of (await store.list(\"cdp:\")).keys()) {\n keys.add(key);\n }\n }\n\n const swept: Array<{ key: string; sessionId: string }> = [];\n for (const key of keys) {\n const isExec = key.startsWith(EXEC_KEY_PREFIX);\n const idleMs = isExec ? maxExecIdleMs : maxIdleMs;\n const lock = await store.acquireLock(key);\n let toClose: StoredBrowserSession | undefined;\n try {\n const stored = await store.get(key);\n if (!stored) continue;\n const now = Date.now();\n if (stored.closedAt !== undefined) {\n // Tombstone from a previous sweep — its session is already gone.\n // Drop it once it has aged past the threshold again.\n if (now - stored.closedAt >= idleMs) await store.delete(key);\n continue;\n }\n if (now - stored.updatedAt < idleMs) continue;\n if (isExec) {\n await store.set(key, { ...stored, closedAt: now });\n } else {\n await store.delete(key);\n }\n toClose = stored;\n } finally {\n await lock.release();\n }\n // Kitesurf entries hold a synthetic marker rather than a Browser Run\n // session id: the connection died with its execution, so there is\n // nothing remote to close. Entries written before the connector was\n // reconfigured still need their session deleted, so this is decided per\n // entry rather than from the current options.\n if (!toClose.sessionId.startsWith(KITESURF_SESSION_PREFIX)) {\n try {\n await deleteBrowserSession(browser, toClose.sessionId);\n } catch (error) {\n console.warn(\n `[agents/browser] Sweep failed to delete Browser Run session ${toClose.sessionId}`,\n error\n );\n }\n }\n swept.push({ key, sessionId: toClose.sessionId });\n }\n return { swept };\n }\n\n // ---------------------------------------------------------------------\n // Session + socket resolution\n // ---------------------------------------------------------------------\n\n #isKitesurf(): boolean {\n return this.#options.session?.browser === \"kitesurf\";\n }\n\n #mode(): \"one-shot\" | \"reuse\" | \"dynamic\" {\n return this.#options.session?.mode ?? \"one-shot\";\n }\n\n #execKey(executionId: string): string {\n return `${EXEC_KEY_PREFIX}${executionId}`;\n }\n\n #reuseKey(): string {\n return `${REUSE_KEY_PREFIX}${this.#options.session?.key ?? \"default\"}`;\n }\n\n #executionId(ctx?: ToolExecuteContext): string {\n if (!ctx?.executionId) {\n throw new Error(\n \"BrowserConnector requires an execution context — use it through createCodemodeRuntime\"\n );\n }\n return ctx.executionId;\n }\n\n #dropSocket(executionId: string): void {\n const cached = this.#sockets.get(executionId);\n if (!cached) return;\n this.#sockets.delete(executionId);\n cached.session.disconnect();\n }\n\n /** Attach the current socket to a target, caching the live CDP session id. */\n async #attach(\n executionId: string,\n targetId: string,\n timeoutMs?: number\n ): Promise<string> {\n const socket = await this.#socket(executionId);\n const cached = this.#sockets.get(executionId);\n const handle = `${ATTACH_HANDLE_PREFIX}${targetId}`;\n const existing = cached?.attached.get(handle);\n if (existing) return existing;\n const live = await socket.attachToTarget(targetId, { timeoutMs });\n cached?.attached.set(handle, live);\n return live;\n }\n\n /**\n * List the current tabs (targets) for this execution's browser, including\n * their `devtoolsFrontendUrl` (the Live View link). For the binding this is\n * the current Browser Run session; for an externally-managed `cdpUrl` it is\n * the standard CDP `/json/list`.\n */\n async #liveTargets(executionId: string): Promise<BrowserTargetInfo[]> {\n if (this.#options.cdpUrl) {\n const endpoint = new URL(\"/json/list\", this.#options.cdpUrl).toString();\n const response = await fetch(endpoint, {\n headers: this.#options.cdpHeaders\n });\n if (!response.ok) {\n throw new Error(\n `Failed to list targets at ${endpoint}: ${response.status}`\n );\n }\n const payload = (await response.json()) as unknown;\n return Array.isArray(payload) ? (payload as BrowserTargetInfo[]) : [];\n }\n\n const browser = this.#options.browser;\n if (!browser) throw new Error(\"BrowserConnector has no browser binding\");\n if (this.#isKitesurf()) {\n throw new Error(\"Kitesurf does not support Browser Run Live View\");\n }\n // Ensure a session + socket exist, then read the resolved Browser Run id.\n await this.#socket(executionId);\n const sessionId = this.#sockets.get(executionId)?.browserSessionId;\n if (!sessionId) return [];\n return listBrowserTargets(browser, sessionId);\n }\n\n /** Build a Live View URL for one tab in this execution's browser. */\n async #liveViewUrl(\n executionId: string,\n options: { targetId?: string; mode?: LiveViewMode }\n ): Promise<BrowserLiveViewUrl> {\n const targets = await this.#liveTargets(executionId);\n const target = options.targetId\n ? targets.find((candidate) => candidate.id === options.targetId)\n : (targets.find(\n (candidate) =>\n candidate.type === \"page\" && candidate.devtoolsFrontendUrl\n ) ?? targets.find((candidate) => candidate.devtoolsFrontendUrl));\n\n if (!target) {\n throw new Error(\n options.targetId\n ? `No target ${options.targetId} found. List tabs with Target.getTargets or open one with Target.createTarget.`\n : \"No browser tab is open yet. Create one (Target.createTarget) before requesting a Live View URL.\"\n );\n }\n if (!target.devtoolsFrontendUrl) {\n throw new Error(\n `Target ${target.id} has no Live View URL (devtoolsFrontendUrl). Live View needs the Browser Rendering binding.`\n );\n }\n\n return {\n url: applyLiveViewMode(target.devtoolsFrontendUrl, options.mode),\n targetId: target.id,\n expiresInMs: LIVE_VIEW_URL_TTL_MS\n };\n }\n\n /**\n * Resolve a model-facing session handle to the live CDP session id on the\n * current socket, re-attaching lazily after a reconnect. Raw CDP session\n * ids (from manual Target.attachToTarget sends) pass through untouched.\n */\n /**\n * True when `method` is a CDP *event* (e.g. `Page.loadEventFired`) rather\n * than a command. Used only on the `send` failure path to produce a better\n * error; any spec-loading failure just means no extra hint.\n */\n async #isSpecEvent(method: string): Promise<boolean> {\n try {\n if (this.#isKitesurf()) return false;\n const spec = await loadCdpSpec(this.#options);\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 async #resolveSessionHandle(\n executionId: string,\n sessionId?: string\n ): Promise<string | undefined> {\n if (!sessionId?.startsWith(ATTACH_HANDLE_PREFIX)) return sessionId;\n const targetId = sessionId.slice(ATTACH_HANDLE_PREFIX.length);\n return this.#attach(executionId, targetId);\n }\n\n /**\n * Get or open the CDP socket for an execution. Concurrent calls for the\n * same execution (model code that ignores the \"sequential calls\" rule and\n * uses Promise.all) share one in-flight connect instead of racing and\n * leaking the loser's WebSocket.\n */\n #socket(executionId: string): Promise<CdpSession> {\n const inFlight = this.#connecting.get(executionId);\n if (inFlight) return inFlight;\n const promise = this.#socketInner(executionId).finally(() => {\n if (this.#connecting.get(executionId) === promise) {\n this.#connecting.delete(executionId);\n }\n });\n this.#connecting.set(executionId, promise);\n return promise;\n }\n\n async #socketInner(executionId: string): Promise<CdpSession> {\n if (this.#options.cdpUrl) {\n const cached = this.#sockets.get(executionId);\n if (cached) return cached.session;\n const session = await connectUrl(this.#options.cdpUrl, {\n timeoutMs: this.#options.timeout,\n headers: this.#options.cdpHeaders\n });\n this.#sockets.set(executionId, { session, attached: new Map() });\n return session;\n }\n\n const browser = this.#options.browser;\n if (!browser) throw new Error(\"BrowserConnector has no browser binding\");\n\n if (this.#isKitesurf()) {\n const cached = this.#sockets.get(executionId);\n if (cached) return cached.session;\n\n const key = this.#execKey(executionId);\n const lock = await this.#store.acquireLock(key);\n try {\n if (await this.#store.get(key)) {\n throw new Error(\n \"Kitesurf's connection was closed and cannot be resumed; start a new execution\"\n );\n }\n const now = Date.now();\n await this.#store.set(key, {\n sessionId: `${KITESURF_SESSION_PREFIX}${crypto.randomUUID()}`,\n createdAt: now,\n updatedAt: now\n });\n } finally {\n await lock.release();\n }\n\n try {\n const session = await connectBrowser(browser, {\n browser: \"kitesurf\",\n timeoutMs: this.#options.timeout\n });\n this.#sockets.set(executionId, { session, attached: new Map() });\n return session;\n } catch (error) {\n const failed = await this.#readStored(key);\n if (failed) await this.#deleteStoredEntry(key, failed.sessionId);\n throw error;\n }\n }\n\n const stored = await this.#resolveSession(executionId);\n const cached = this.#sockets.get(executionId);\n if (cached?.browserSessionId === stored.sessionId) {\n return cached.session;\n }\n if (cached) this.#dropSocket(executionId);\n\n const session = await connectBrowserSession(\n browser,\n stored.sessionId,\n this.#options.timeout\n );\n this.#sockets.set(executionId, {\n session,\n browserSessionId: stored.sessionId,\n attached: new Map()\n });\n return session;\n }\n\n /**\n * Resolve the Browser Run session for an execution:\n *\n * - An existing `cdp:exec:<id>` entry wins. If its session is gone (e.g.\n * expired while the run was paused), the run fails with a clear error\n * rather than silently continuing in a fresh browser.\n * - In `reuse` mode the shared session is used (created if missing).\n * - In `dynamic` mode an alive shared session is used; otherwise a fresh\n * per-execution session is created.\n * - In `one-shot` mode a fresh per-execution session is created.\n */\n async #resolveSession(executionId: string): Promise<StoredBrowserSession> {\n const browser = this.#options.browser;\n if (!browser) throw new Error(\"BrowserConnector has no browser binding\");\n const mode = this.#mode();\n const execKey = this.#execKey(executionId);\n\n if (mode === \"reuse\") {\n return this.#ensureStoredSession(this.#reuseKey());\n }\n\n // one-shot / dynamic: a session this execution already opened wins.\n const existing = await this.#readStored(execKey);\n if (existing) {\n if (existing.closedAt === undefined && (await this.#isAlive(existing))) {\n // Keep the entry fresh so the sweep backstop never reclaims an\n // active (or recently resumed) execution's session.\n if (Date.now() - existing.updatedAt >= EXEC_TOUCH_INTERVAL_MS) {\n await this.#touchStored(execKey, existing);\n }\n return existing;\n }\n await this.#deleteStoredEntry(execKey, existing.sessionId);\n throw new Error(\n `Browser session ${existing.sessionId} expired or was swept while this execution was paused — the run cannot continue. Start a new execution.`\n );\n }\n\n if (mode === \"dynamic\") {\n const shared = await this.#readStored(this.#reuseKey());\n if (shared) {\n if (await this.#isAlive(shared)) {\n await this.#touchStored(this.#reuseKey(), shared);\n return shared;\n }\n await this.#deleteStoredEntry(this.#reuseKey(), shared.sessionId);\n }\n }\n\n // Create a fresh per-execution session. The Browser Rendering call\n // happens outside the store lock; the lock only guards the commit, so\n // two concurrent tool calls for the same execution don't double-create\n // (the loser's session is deleted).\n return this.#createAndCommit(execKey);\n }\n\n /**\n * Get the stored session under `key`, validating and creating as needed.\n *\n * Network calls (the liveness probe, session creation) happen OUTSIDE the\n * store lock — locks wrap storage only, so a hung Browser Rendering call\n * can't serialize every other operation on this key. The lock is\n * re-acquired to commit, with a sessionId re-check to detect a concurrent\n * swap; on a swap the new entry is re-validated from the top.\n */\n async #ensureStoredSession(key: string): Promise<StoredBrowserSession> {\n const browser = this.#options.browser;\n if (!browser) throw new Error(\"BrowserConnector has no browser binding\");\n const store = this.#store;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const existing = await store.get(key);\n if (!existing) return this.#createAndCommit(key);\n\n const alive = await this.#isAlive(existing);\n const lock = await store.acquireLock(key);\n try {\n const current = await store.get(key);\n if (current?.sessionId !== existing.sessionId) {\n // Entry was swapped while we probed — validate the new one.\n continue;\n }\n if (alive) {\n const refreshed = { ...current, updatedAt: Date.now() };\n await store.set(key, refreshed);\n return refreshed;\n }\n await store.delete(key);\n } finally {\n await lock.release();\n }\n // Dead entry deleted — the next iteration creates a fresh session.\n }\n throw new Error(\n `Browser session entry ${key} kept changing concurrently — retry`\n );\n }\n\n /**\n * Create a Browser Run session (outside any lock) and commit it under\n * `key`. If a concurrent caller committed first, their entry wins and the\n * redundant session is deleted best-effort.\n */\n async #createAndCommit(key: string): Promise<StoredBrowserSession> {\n const browser = this.#options.browser;\n if (!browser) throw new Error(\"BrowserConnector has no browser binding\");\n const store = this.#store;\n\n const info = await createBrowserSession(browser, {\n keepAliveMs: this.#options.session?.keepAliveMs,\n recording: this.#options.session?.recording\n });\n const now = Date.now();\n const stored: StoredBrowserSession = {\n sessionId: info.sessionId,\n createdAt: now,\n updatedAt: now\n };\n\n const lock = await store.acquireLock(key);\n let winner: StoredBrowserSession | undefined;\n try {\n const raced = await store.get(key);\n if (raced) {\n winner = raced;\n } else {\n await store.set(key, stored);\n }\n } finally {\n await lock.release();\n }\n\n if (winner) {\n try {\n await deleteBrowserSession(browser, stored.sessionId);\n } catch (error) {\n console.warn(\n `[agents/browser] Failed to delete redundant Browser Run session ${stored.sessionId}`,\n error\n );\n }\n return winner;\n }\n return stored;\n }\n\n async #isAlive(stored: StoredBrowserSession): Promise<boolean> {\n const browser = this.#options.browser;\n if (!browser) return false;\n try {\n await listBrowserTargets(browser, stored.sessionId);\n return true;\n } catch (error) {\n if (isMissingBrowserSession(error)) return false;\n throw error;\n }\n }\n\n // ---------------------------------------------------------------------\n // Session tools (reuse/dynamic)\n // ---------------------------------------------------------------------\n\n async #startSession(executionId: string): Promise<BrowserSessionInfo> {\n const browser = this.#options.browser;\n if (!browser) {\n throw new Error(\"startSession requires the Browser Rendering binding\");\n }\n const store = this.#options.store;\n const reuseKey = this.#reuseKey();\n\n if (this.#mode() === \"dynamic\") {\n // Promote this execution's session into the shared slot, if it has one.\n const exec = await this.#readStored(this.#execKey(executionId));\n if (exec && exec.closedAt === undefined) {\n const lock = await store.acquireLock(reuseKey);\n let replaced: StoredBrowserSession | undefined;\n try {\n const shared = await store.get(reuseKey);\n if (shared?.sessionId !== exec.sessionId) {\n replaced = shared;\n await store.set(reuseKey, { ...exec, updatedAt: Date.now() });\n }\n } finally {\n await lock.release();\n }\n if (replaced) {\n try {\n await deleteBrowserSession(browser, replaced.sessionId);\n } catch (error) {\n console.warn(\n `[agents/browser] Failed to delete replaced Browser Run session ${replaced.sessionId}`,\n error\n );\n }\n }\n return {\n sessionId: exec.sessionId,\n targets: await listBrowserTargets(browser, exec.sessionId)\n };\n }\n }\n\n const stored = await this.#ensureStoredSession(reuseKey);\n return {\n sessionId: stored.sessionId,\n targets: await listBrowserTargets(browser, stored.sessionId)\n };\n }\n\n async #resetSession(executionId: string): Promise<BrowserSessionInfo> {\n const browser = this.#options.browser;\n if (!browser) {\n throw new Error(\"resetSession requires the Browser Rendering binding\");\n }\n await this.#closeReusableFor(executionId);\n const stored = await this.#ensureStoredSession(this.#reuseKey());\n return {\n sessionId: stored.sessionId,\n targets: await listBrowserTargets(browser, stored.sessionId)\n };\n }\n\n /**\n * Close the shared session from inside an execution. If this execution's\n * socket is attached to that session, drop it first.\n */\n async #closeReusableFor(executionId: string): Promise<void> {\n const reuseKey = this.#reuseKey();\n const stored = await this.#readStored(reuseKey);\n if (!stored) return;\n const cached = this.#sockets.get(executionId);\n if (cached?.browserSessionId === stored.sessionId) {\n this.#dropSocket(executionId);\n }\n await this.#closeStoredSession(reuseKey);\n // In reuse mode the execution continues against a fresh shared session on\n // the next send. In dynamic mode the exec entry (if any) still points at\n // the closed session; clear it so the next send fails loudly instead of\n // silently targeting a deleted browser.\n const exec = await this.#readStored(this.#execKey(executionId));\n if (exec?.sessionId === stored.sessionId) {\n await this.#deleteStoredEntry(this.#execKey(executionId), exec.sessionId);\n }\n }\n\n // ---------------------------------------------------------------------\n // Store access — locks held only around the store operation itself.\n // ---------------------------------------------------------------------\n\n get #store(): BrowserSessionStore {\n const store = this.#options.store;\n if (!store) {\n throw new Error(\n \"BrowserConnector session storage requires the Browser Rendering binding\"\n );\n }\n return store;\n }\n\n async #readStored(key: string): Promise<StoredBrowserSession | undefined> {\n const store = this.#store;\n const lock = await store.acquireLock(key);\n try {\n return await store.get(key);\n } finally {\n await lock.release();\n }\n }\n\n async #writeStored(key: string, value: StoredBrowserSession): Promise<void> {\n const store = this.#store;\n const lock = await store.acquireLock(key);\n try {\n await store.set(key, value);\n } finally {\n await lock.release();\n }\n }\n\n async #touchStored(key: string, value: StoredBrowserSession): Promise<void> {\n await this.#writeStored(key, { ...value, updatedAt: Date.now() });\n }\n\n /** Delete the store entry only if it still points at `sessionId`. */\n async #deleteStoredEntry(key: string, sessionId: string): Promise<void> {\n const store = this.#store;\n const lock = await store.acquireLock(key);\n try {\n const current = await store.get(key);\n if (current?.sessionId === sessionId) {\n await store.delete(key);\n }\n } finally {\n await lock.release();\n }\n }\n\n /** Delete the stored entry under `key` and its Browser Run session. */\n async #closeStoredSession(key: string): Promise<void> {\n const browser = this.#options.browser;\n if (!browser) return;\n const store = this.#options.store;\n const lock = await store.acquireLock(key);\n let stored: StoredBrowserSession | undefined;\n try {\n stored = await store.get(key);\n if (stored) await store.delete(key);\n } finally {\n await lock.release();\n }\n if (stored) {\n await deleteBrowserSession(browser, stored.sessionId);\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"lifecycle-CMRGjZdw.js","names":[],"sources":["../src/lifecycle/capability-runner.ts","../src/lifecycle/abort.ts","../src/lifecycle/job-queue.ts","../src/lifecycle/job-driver.ts","../src/lifecycle/transport-errors.ts","../src/lifecycle/durable-object-lifecycle.ts"],"sourcesContent":["import { lifecycleCapabilityId } from \"./capability\";\nimport type { LifecycleRouteContext } from \"./capability\";\nimport type { WSMessage } from \"./types\";\nimport type {\n LifecycleJob,\n LifecycleJobContext,\n LifecycleJobOutcome\n} from \"./job-queue\";\n\ntype MaybePromise<T> = T | Promise<T>;\n\n/** One best-effort event published by a Lifecycle capability. */\nexport type LifecycleEvent = {\n /** Stable capability or subsystem name. */\n readonly source: string;\n /** Stable event name within that source. */\n readonly type: string;\n /** Event-specific data. */\n readonly payload: unknown;\n};\n\n/** Terminal sink for best-effort Lifecycle events. */\nexport type LifecycleEventSink = (\n event: LifecycleEvent\n) => void | Promise<void>;\n\n/** Context supplied when durable capabilities start. */\nexport type CapabilityStartContext<Props extends object = object> = {\n /** Properties supplied while resolving the Durable Object. */\n readonly props: Props | undefined;\n};\n\n/** Context supplied when durable capabilities inspect an HTTP request. */\nexport type CapabilityRequestContext = {\n /** The request entering the Durable Object. */\n readonly request: Request;\n};\n\n/** Context supplied when a capability inspects a WebSocket upgrade. */\nexport type CapabilityWebSocketUpgradeContext = {\n /** The WebSocket upgrade request entering the Durable Object. */\n readonly request: Request;\n};\n\n/**\n * Context supplied when the alarm memory-limit circuit breaker records a\n * strike (#1825), to capabilities and the host alike.\n */\nexport type MemoryLimitContext = {\n /** Whether the breaker hit its strike budget and sealed recovery work. */\n readonly sealed: boolean;\n /** The backoff wake time (epoch ms) armed for an unsealed strike. */\n readonly nextTime?: number;\n /**\n * The queue job that was executing when the strike landed. Absent when the\n * reset happened during startup or host alarm work. Lifecycle has already\n * backed off or purged its row before invoking memory-limit policy.\n *\n * Capabilities whose durable state outlives their queue row use this to\n * apply the same policy to the underlying work — Tasks routes a struck\n * routed job's owner this way (see `setTaskRoutedMemoryLimitHandler`).\n */\n readonly executing?: LifecycleJob;\n /**\n * Recovery-loop jobs removed when this strike sealed the breaker. This is\n * a pre-purge snapshot because the durable rows no longer exist when\n * policy hooks run. No current capability reads this — Scheduler's own\n * former use of it (routing a sealed strike to every purged row's owning\n * dynamic agent) was retired once Tasks took over routed chat-recovery\n * wakes — but it stays available for a capability whose routed rows can\n * be purged as a pack, unlike Tasks' one-run-at-a-time model.\n */\n readonly purgedRecoveryLoopJobs?: ReadonlyArray<LifecycleJob>;\n};\n\n/**\n * A capability installed into a Durable Object lifecycle.\n *\n * Capabilities extending `LifecycleCapability` receive the standard storage,\n * readiness, alarm, event, and routing surface. Host-specific bindings and\n * protocol adapters remain explicit constructor dependencies. Hook parameters\n * carry only phase data; hooks do not run in ambient host context — a\n * capability-held user callback re-enters host context exactly once,\n * through `LifecycleServices.runInHostContext(fn, scope)`.\n *\n * A capability interacts with Lifecycle through exactly three channels:\n * these declared hooks, the `LifecycleServices` surface, and\n * composition-root `set*()` apertures. Any other direct reach in either\n * direction is a design smell.\n *\n * Dispatch contract, hook by hook:\n * - `onRequest` and `onWebSocketUpgrade` are offered in declaration\n * order, fallbacks last; the first capability to return a `Response`\n * claims the request, and a claimed upgrade's socket belongs to that\n * capability for its whole lifetime.\n * - `onWebSocketMessage`/`onWebSocketClose`/`onWebSocketError` are\n * platform wakes, offered in declaration order; return `true` to\n * consume one. Socket ownership is the capability's to determine —\n * keep a private hibernation-attachment namespace and recognize your\n * own sockets by it.\n * - `onRoute` is addressed to one capability by its id; `onJob` is\n * addressed by the due job's owning capability, with Lifecycle owning\n * the queue and the one physical alarm.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport interface DurableObjectCapability<Props extends object = object> {\n /** Initialize or recover the capability before the host handles work. */\n onStart?(context: CapabilityStartContext<Props>): MaybePromise<void>;\n\n /**\n * Act as middleware over HTTP requests, ahead of the host's request handler.\n *\n * Return a response to handle the request, or `undefined` to pass it to the\n * next capability and finally the host.\n */\n onRequest?(\n context: CapabilityRequestContext\n ): MaybePromise<Response | undefined | void>;\n\n /**\n * Claim a WebSocket upgrade before the host's legacy connection path.\n *\n * A capability that returns a response owns that socket and its lifetime,\n * including any hibernation attachment it needs to recognize the socket\n * later. Return `undefined` to decline.\n */\n onWebSocketUpgrade?(\n context: CapabilityWebSocketUpgradeContext\n ): MaybePromise<Response | undefined | void>;\n\n /**\n * Handle a platform `webSocketMessage` wake for a socket this capability\n * owns. Return `true` to consume the event; anything else offers it to\n * the next capability and finally the host's legacy path. Ownership is\n * the capability's to determine — typically via its own hibernation\n * attachment namespace.\n */\n onWebSocketMessage?(\n ws: WebSocket,\n message: WSMessage\n ): MaybePromise<boolean | void>;\n\n /** Handle a platform `webSocketClose` wake for an owned socket. */\n onWebSocketClose?(\n ws: WebSocket,\n code: number,\n reason: string,\n wasClean: boolean\n ): MaybePromise<boolean | void>;\n\n /** Handle a platform `webSocketError` wake for an owned socket. */\n onWebSocketError?(\n ws: WebSocket,\n error: unknown\n ): MaybePromise<boolean | void>;\n\n /**\n * Drive one due job this capability pushed into the Lifecycle queue.\n * Return an outcome to reschedule or retain the job; returning nothing\n * completes it.\n *\n * Dispatch must be bounded: the event loop awaits each job inline, so a\n * long-running `onJob` delays every other job on this object. Detach\n * unbounded work (start it, keep durable evidence, return) instead of\n * awaiting it here; a dispatch that outlives the job's hung timeout\n * logs a warning and emits `job:slow_dispatch`.\n */\n onJob?(\n context: LifecycleJobContext\n ): MaybePromise<LifecycleJobOutcome | void>;\n\n /**\n * Observe one job's terminal application failure after retry exhaustion.\n * The returned outcome decides advancement; returning nothing completes\n * the job.\n */\n onJobError?(\n context: LifecycleJobContext,\n error: unknown\n ): MaybePromise<LifecycleJobOutcome | void>;\n\n /**\n * Apply domain policy after the alarm memory-limit circuit breaker\n * records a strike (#1825). Lifecycle has already handled the queue: the\n * executing job and every `recoveryLoop`-flagged job are backed off (or\n * purged when `sealed`). Runs at the outermost alarm frame, post-unwind,\n * best-effort — the isolate resets right after, so keep writes small.\n */\n onMemoryLimit?(context: MemoryLimitContext): MaybePromise<void>;\n\n /** Handle one message routed to this capability identity. */\n onRoute?(context: LifecycleRouteContext): MaybePromise<unknown>;\n\n /** Release live or in-memory resources during explicit host destruction. */\n dispose?(): MaybePromise<void>;\n}\n\n/**\n * Runs ordered lifecycle phases for capabilities installed in a Durable Object.\n *\n * Capabilities are resolved lazily on the first phase and retained for the\n * lifetime of this runner. Startup runs in declaration order.\n * Requests dispatch as a middleware chain: the first capability to return a\n * response handles the request.\n */\nexport class CapabilityRunner<Props extends object = object> {\n readonly #resolveCapabilities: () => Iterable<DurableObjectCapability<Props>>;\n\n #capabilities: ReadonlyArray<DurableObjectCapability<Props>> | undefined;\n #startPromise: Promise<void> | undefined;\n #started = false;\n\n /**\n * Create a lifecycle whose capabilities are resolved immediately before the\n * first phase.\n *\n * @param resolveCapabilities - Returns capabilities in their startup order.\n */\n constructor(\n resolveCapabilities: () => Iterable<DurableObjectCapability<Props>>\n ) {\n this.#resolveCapabilities = resolveCapabilities;\n }\n\n /**\n * Start every capability sequentially.\n *\n * Concurrent callers share one startup attempt. A failed attempt is not\n * cached, allowing the host to retry its complete startup phase.\n *\n * @param context - Properties supplied while resolving the Durable Object.\n */\n async start(context: CapabilityStartContext<Props>): Promise<void> {\n if (this.#started) return;\n\n const pending = this.#startPromise;\n if (pending) {\n await pending;\n return;\n }\n\n const attempt = this.#runStart(context);\n this.#startPromise = attempt;\n try {\n await attempt;\n } catch (error) {\n if (this.#startPromise === attempt) {\n this.#startPromise = undefined;\n }\n throw error;\n }\n }\n\n /**\n * Offer a request to each capability middleware in registration order.\n *\n * @param context - The request entering the Durable Object.\n * @returns The first capability response, or `undefined` when no\n * capability claimed the request.\n */\n async request(\n context: CapabilityRequestContext\n ): Promise<Response | undefined> {\n await this.#ensureReady(\"handle a request\");\n for (const capability of this.#getCapabilities()) {\n const response = await capability.onRequest?.(context);\n if (response !== undefined) return response;\n }\n return undefined;\n }\n\n /**\n * Offer a WebSocket upgrade to each capability in declaration order.\n *\n * @param context - The upgrade request entering the Durable Object.\n * @returns The first capability response, or `undefined` when unclaimed.\n */\n async webSocketUpgrade(\n context: CapabilityWebSocketUpgradeContext\n ): Promise<Response | undefined> {\n await this.#ensureReady(\"handle a WebSocket upgrade\");\n for (const capability of this.#getCapabilities()) {\n const response = await capability.onWebSocketUpgrade?.(context);\n if (response !== undefined) return response;\n }\n return undefined;\n }\n\n /**\n * Offer a platform `webSocketMessage` wake to each capability in\n * declaration order.\n *\n * @returns Whether a capability consumed the event.\n */\n async webSocketMessage(ws: WebSocket, message: WSMessage): Promise<boolean> {\n await this.#ensureReady(\"handle a WebSocket message\");\n for (const capability of this.#getCapabilities()) {\n if ((await capability.onWebSocketMessage?.(ws, message)) === true) {\n return true;\n }\n }\n return false;\n }\n\n /** Offer a platform `webSocketClose` wake to each capability. */\n async webSocketClose(\n ws: WebSocket,\n code: number,\n reason: string,\n wasClean: boolean\n ): Promise<boolean> {\n await this.#ensureReady(\"handle a WebSocket close\");\n for (const capability of this.#getCapabilities()) {\n if (\n (await capability.onWebSocketClose?.(ws, code, reason, wasClean)) ===\n true\n ) {\n return true;\n }\n }\n return false;\n }\n\n /** Offer a platform `webSocketError` wake to each capability. */\n async webSocketError(ws: WebSocket, error: unknown): Promise<boolean> {\n await this.#ensureReady(\"handle a WebSocket error\");\n for (const capability of this.#getCapabilities()) {\n if ((await capability.onWebSocketError?.(ws, error)) === true) {\n return true;\n }\n }\n return false;\n }\n\n /** Find one installed capability by its stable id. */\n async findById(\n capabilityId: string\n ): Promise<DurableObjectCapability<Props> | undefined> {\n await this.#ensureReady(\"dispatch capability work\");\n return this.#getCapabilities().find(\n (candidate) => lifecycleCapabilityId(candidate) === capabilityId\n );\n }\n\n /** Route one message to an installed named capability. */\n async route(\n capabilityId: string,\n context: LifecycleRouteContext\n ): Promise<unknown> {\n await this.#ensureReady(\"route a capability message\");\n const capability = this.#getCapabilities().find(\n (candidate) => lifecycleCapabilityId(candidate) === capabilityId\n );\n if (!capability?.onRoute) {\n throw new Error(\n `Lifecycle capability ${JSON.stringify(capabilityId)} cannot receive routed messages`\n );\n }\n return capability.onRoute(context);\n }\n\n /**\n * Offer a memory-limit strike to every capability, best-effort.\n *\n * Deliberately not gated on startup: a strike can land while startup\n * itself is the work that exceeded the memory limit, and the breaker's\n * policy must still reach capabilities. One capability's failure does not\n * stop the next — the isolate is about to reset either way.\n */\n async memoryLimit(context: MemoryLimitContext): Promise<void> {\n for (const capability of this.#getCapabilities()) {\n try {\n await capability.onMemoryLimit?.(context);\n } catch (error) {\n console.error(\"Lifecycle capability memory-limit policy failed\", error);\n }\n }\n }\n\n /** Dispose installed capabilities in reverse registration order. */\n async dispose(): Promise<void> {\n for (const capability of [...this.#getCapabilities()].reverse()) {\n try {\n await capability.dispose?.();\n } catch (error) {\n console.error(\"Lifecycle capability disposal failed\", error);\n }\n }\n }\n\n async #runStart(context: CapabilityStartContext<Props>): Promise<void> {\n for (const capability of this.#getCapabilities()) {\n await capability.onStart?.(context);\n }\n this.#started = true;\n }\n\n async #ensureReady(operation: string): Promise<void> {\n const pending = this.#startPromise;\n if (pending) await pending;\n if (!this.#started) {\n throw new Error(\n `Cannot ${operation} before the Durable Object lifecycle has started`\n );\n }\n }\n\n #getCapabilities(): ReadonlyArray<DurableObjectCapability<Props>> {\n if (!this.#capabilities) {\n this.#capabilities = Object.freeze([...this.#resolveCapabilities()]);\n }\n return this.#capabilities;\n }\n}\n","/**\n * `DurableObjectState.abort()` accepts an options object newer than our\n * pinned `@cloudflare/workers-types`: `{ retryAlarm?: boolean }`. When\n * `retryAlarm` is false and the abort happens inside an alarm handler, the\n * platform does not retry that alarm (workerd `AbortOptions`,\n * `EXCEPTION_DURABLE_OBJECT_ABORT_NO_RETRY`). It has no effect outside an\n * alarm handler, and runtimes predating the option ignore the extra\n * argument, so passing it is always safe.\n */\ntype AbortWithOptions = (\n reason?: string,\n options?: { retryAlarm?: boolean }\n) => void;\n\n/**\n * Reset the Durable Object instance without the platform retrying the alarm\n * this invocation was handling. Never returns: `abort()` terminates\n * execution.\n */\nexport function abortWithoutAlarmRetry(\n ctx: DurableObjectState,\n reason: string\n): void {\n (ctx.abort as AbortWithOptions)(reason, { retryAlarm: false });\n}\n","/**\n * Durable job queue owned by Lifecycle.\n *\n * One timestamp-ordered table holds every pending job for the Durable\n * Object. A job is a serialisable callback address — owning capability plus\n * function name — with a due time and a payload. Capabilities and the host\n * push jobs through their scoped `LifecycleJobs` surface; Lifecycle's alarm\n * event loop drives due jobs and derives the physical alarm from queue\n * state. Payloads are opaque to the queue.\n */\n\nimport { nanoid } from \"nanoid\";\nimport type { RetryOptions } from \"../retries\";\nimport { SqlError } from \"../sql-error\";\n\n/** Capability id under which host-owned jobs are stored. */\nexport const HOST_JOB_CAPABILITY = \"host\";\n\n/** Seconds before an in-flight single-flight job is treated as hung. */\nconst DEFAULT_HUNG_TIMEOUT_SECONDS = 30;\n\n/** One durable job in the Lifecycle queue. */\nexport type LifecycleJob = {\n /** Unique job id. Stable across reschedules. */\n readonly id: string;\n /** Owning capability id, or `\"host\"`. */\n readonly capability: string;\n /** Serialisable function name the owner dispatches on. */\n readonly fn: string;\n /** Due time in epoch milliseconds. */\n readonly time: number;\n /** Owner-defined payload, JSON round-tripped. */\n readonly payload: unknown;\n /** Retry policy for dispatch, when the pusher supplied one. */\n readonly retry: RetryOptions | undefined;\n /** Whether the job is skipped while a previous run is in flight. */\n readonly singleflight: boolean;\n /** Whether the job suppresses ordinary alarm candidates while pending. */\n readonly exclusive: boolean;\n /** Whether the alarm memory-limit breaker governs this pending job (#1825). */\n readonly recoveryLoop: boolean;\n /** Creation time in epoch seconds. */\n readonly createdAt: number;\n};\n\n/** Options accepted when pushing one job. */\nexport type LifecycleJobPushOptions = {\n /** Serialisable function name the owner dispatches on. */\n readonly fn: string;\n /** Due time in epoch milliseconds. */\n readonly time: number;\n /** Owner-defined payload. Must be JSON-serializable. */\n readonly payload?: unknown;\n /**\n * Stable job id. A push with an existing id replaces that job.\n * Omitted ids are generated.\n */\n readonly id?: string;\n /** Retry policy for dispatch, overriding the queue default. */\n readonly retry?: RetryOptions;\n /** Skip this job while a previous run of it is still in flight. */\n readonly singleflight?: boolean;\n /**\n * Seconds before an in-flight single-flight run is treated as hung, and\n * before any long dispatch triggers the slow-dispatch warning. Default: 30.\n */\n readonly hungTimeoutSeconds?: number;\n /** Suppress ordinary alarm candidates while this job is pending. */\n readonly exclusive?: boolean;\n /**\n * Mark this job as part of a recovery loop that can deterministically\n * exhaust memory. On an alarm memory-limit strike the circuit breaker\n * (#1825) backs off every pending flagged job to the strike's backoff\n * time, and purges them all when it seals at the strike budget — so a\n * doomed loop cannot re-trigger through a sibling row while unrelated\n * jobs stay untouched.\n */\n readonly recoveryLoop?: boolean;\n};\n\n/**\n * What the owner tells Lifecycle after one job ran — the drive result.\n *\n * `undefined` (or no return) completes the job and deletes it.\n * `{ rescheduleAt }` suspends the job until a future time.\n * `\"yield\"` leaves the job due, waking again immediately.\n *\n * A same-id `push()` or `reschedule()` made while the job is dispatching\n * supersedes the drive result: the newer durable intent wins, and the\n * result is quietly discarded. Owners that both push and return outcomes\n * for the same job should derive both from the same durable state so the\n * two always agree.\n */\nexport type LifecycleJobOutcome =\n | undefined\n | { readonly rescheduleAt: number }\n | \"yield\";\n\n/** Context supplied when a job is dispatched to its owner. */\nexport type LifecycleJobContext = {\n /** The due job being executed. */\n readonly job: LifecycleJob;\n /** 1-indexed dispatch attempt within the current alarm invocation. */\n readonly attempt: number;\n};\n\n/** Job-queue access scoped to one owning capability. */\nexport type LifecycleJobs = {\n /**\n * Push one job. A push with an existing id replaces that job — ids are\n * scoped to their owner, so replacing (or colliding with) another\n * owner's job is impossible; a cross-owner id collision throws instead.\n */\n readonly push: (options: LifecycleJobPushOptions) => Promise<LifecycleJob>;\n /** Cancel one owned job. Returns false when no job matched. */\n readonly cancel: (id: string) => Promise<boolean>;\n /** Re-time one owned job. Returns false when no job matched. */\n readonly reschedule: (id: string, time: number) => Promise<boolean>;\n /** Read one owned job. */\n readonly get: (id: string) => LifecycleJob | undefined;\n /** List every owned job, ordered by due time. */\n readonly list: () => LifecycleJob[];\n /**\n * Recompute the physical alarm from queue state without mutating it.\n * Mutations re-arm automatically; use this only to recover a lost alarm\n * for existing jobs (e.g. an idempotent push that deduplicated).\n */\n readonly rearm: () => Promise<void>;\n};\n\n/** @internal Raw `cf_agents_jobs` SQLite row. */\nexport type JobStorageRow = {\n id: string;\n capability: string;\n fn: string;\n time: number;\n payload: string | null;\n retry_options: string | null;\n singleflight: number;\n hung_timeout_seconds: number | null;\n exclusive: number;\n recovery_loop: number;\n running: number;\n execution_started_at: number | null;\n created_at: number;\n};\n\n/** @internal Convert one raw queue row into its public job shape. */\nexport function jobFromRow(row: JobStorageRow): LifecycleJob {\n return {\n id: row.id,\n capability: row.capability,\n fn: row.fn,\n time: row.time,\n payload:\n typeof row.payload === \"string\" ? JSON.parse(row.payload) : undefined,\n retry:\n typeof row.retry_options === \"string\"\n ? (JSON.parse(row.retry_options) as RetryOptions)\n : undefined,\n singleflight: row.singleflight === 1,\n exclusive: row.exclusive === 1,\n recoveryLoop: row.recovery_loop === 1,\n createdAt: row.created_at\n };\n}\n\n/** @internal One row's hung/slow-dispatch threshold in milliseconds. */\nexport function hungTimeoutMs(row: JobStorageRow): number {\n return (row.hung_timeout_seconds ?? DEFAULT_HUNG_TIMEOUT_SECONDS) * 1000;\n}\n\n/** Whether an in-flight single-flight job has crossed its hung timeout. */\nexport function isHungRow(row: JobStorageRow, nowMs: number): boolean {\n return nowMs - (row.execution_started_at ?? 0) >= hungTimeoutMs(row);\n}\n\n/**\n * @internal SQL-backed job queue. Lifecycle owns the single instance; the\n * scoped `LifecycleJobs` surfaces delegate here with a fixed capability id.\n */\nexport class JobQueue {\n readonly #storage: DurableObjectStorage;\n #tableEnsured = false;\n\n constructor(storage: DurableObjectStorage) {\n this.#storage = storage;\n }\n\n #sql<T = JobStorageRow>(\n query: string,\n ...params: (string | number | null)[]\n ): T[] {\n this.#ensureTable();\n try {\n return [...this.#storage.sql.exec(query, ...params)] as T[];\n } catch (cause) {\n throw new SqlError(query, cause);\n }\n }\n\n #ensureTable(): void {\n if (this.#tableEnsured) return;\n this.#storage.sql.exec(`\n CREATE TABLE IF NOT EXISTS cf_agents_jobs (\n id TEXT PRIMARY KEY NOT NULL,\n capability TEXT NOT NULL,\n fn TEXT NOT NULL,\n time INTEGER NOT NULL,\n payload TEXT,\n retry_options TEXT,\n singleflight INTEGER NOT NULL DEFAULT 0,\n hung_timeout_seconds INTEGER,\n exclusive INTEGER NOT NULL DEFAULT 0,\n recovery_loop INTEGER NOT NULL DEFAULT 0,\n running INTEGER NOT NULL DEFAULT 0,\n execution_started_at INTEGER,\n created_at INTEGER NOT NULL DEFAULT (unixepoch())\n ) WITHOUT ROWID`);\n this.#tableEnsured = true;\n }\n\n push(capability: string, options: LifecycleJobPushOptions): LifecycleJob {\n if (!Number.isFinite(options.time) || options.time < 0) {\n throw new Error(`Invalid job time: ${String(options.time)}`);\n }\n if (typeof options.fn !== \"string\" || options.fn.trim() === \"\") {\n throw new Error(\"Jobs require a non-empty fn\");\n }\n const id = options.id ?? nanoid(9);\n // Job ids are scoped to their owner, like every other queue verb: a\n // same-id push replaces only the pusher's own job (the conflict update\n // is a no-op against another owner's row, surfaced as the ownership\n // error below), and it clears any in-flight dispatch marker so this\n // newer durable intent wins over a concurrently returned drive result.\n this.#sql(\n `INSERT INTO cf_agents_jobs\n (id, capability, fn, time, payload, retry_options, singleflight,\n hung_timeout_seconds, exclusive, recovery_loop, running,\n execution_started_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, NULL)\n ON CONFLICT(id) DO UPDATE SET\n fn = excluded.fn,\n time = excluded.time,\n payload = excluded.payload,\n retry_options = excluded.retry_options,\n singleflight = excluded.singleflight,\n hung_timeout_seconds = excluded.hung_timeout_seconds,\n exclusive = excluded.exclusive,\n recovery_loop = excluded.recovery_loop,\n running = 0,\n execution_started_at = NULL\n WHERE cf_agents_jobs.capability = excluded.capability`,\n id,\n capability,\n options.fn,\n Math.floor(options.time),\n options.payload === undefined ? null : JSON.stringify(options.payload),\n options.retry ? JSON.stringify(options.retry) : null,\n options.singleflight ? 1 : 0,\n options.hungTimeoutSeconds ?? null,\n options.exclusive ? 1 : 0,\n options.recoveryLoop ? 1 : 0\n );\n const job = this.get(capability, id);\n if (!job) {\n const owner = this.#sql<{ capability: string }>(\n \"SELECT capability FROM cf_agents_jobs WHERE id = ?\",\n id\n )[0]?.capability;\n throw new Error(\n owner !== undefined\n ? `Job id ${JSON.stringify(id)} already belongs to ` +\n `${JSON.stringify(owner)}; job ids are scoped to their owner`\n : `Failed to persist job ${id}`\n );\n }\n return job;\n }\n\n cancel(capability: string, id: string): boolean {\n const existing = this.#sql(\n \"SELECT id FROM cf_agents_jobs WHERE id = ? AND capability = ?\",\n id,\n capability\n );\n if (existing.length === 0) return false;\n this.#sql(\n \"DELETE FROM cf_agents_jobs WHERE id = ? AND capability = ?\",\n id,\n capability\n );\n return true;\n }\n\n reschedule(capability: string, id: string, time: number): boolean {\n if (!Number.isFinite(time) || time < 0) {\n throw new Error(`Invalid job time: ${String(time)}`);\n }\n const existing = this.#sql(\n \"SELECT id FROM cf_agents_jobs WHERE id = ? AND capability = ?\",\n id,\n capability\n );\n if (existing.length === 0) return false;\n this.#sql(\n `UPDATE cf_agents_jobs\n SET time = ?, running = 0, execution_started_at = NULL\n WHERE id = ? AND capability = ?`,\n Math.floor(time),\n id,\n capability\n );\n return true;\n }\n\n get(capability: string, id: string): LifecycleJob | undefined {\n const rows = this.#sql(\n \"SELECT * FROM cf_agents_jobs WHERE id = ? AND capability = ?\",\n id,\n capability\n );\n return rows[0] ? jobFromRow(rows[0]) : undefined;\n }\n\n list(capability: string): LifecycleJob[] {\n return this.#sql(\n \"SELECT * FROM cf_agents_jobs WHERE capability = ? ORDER BY time ASC\",\n capability\n ).map(jobFromRow);\n }\n\n /** Raw due rows at `nowMs`, ordered by due time. */\n due(nowMs: number): JobStorageRow[] {\n return this.#sql(\n \"SELECT * FROM cf_agents_jobs WHERE time <= ? ORDER BY time ASC\",\n Math.floor(nowMs)\n );\n }\n\n /** One job's current row when it still exists and is still due. */\n dueRow(id: string, nowMs: number): JobStorageRow | undefined {\n return this.#sql(\n \"SELECT * FROM cf_agents_jobs WHERE id = ? AND time <= ?\",\n id,\n Math.floor(nowMs)\n )[0];\n }\n\n markRunning(id: string, nowMs: number): void {\n this.#sql(\n `UPDATE cf_agents_jobs\n SET running = 1, execution_started_at = ?\n WHERE id = ?`,\n Math.floor(nowMs),\n id\n );\n }\n\n clearRunning(id: string): void {\n this.#sql(\n `UPDATE cf_agents_jobs\n SET running = 0, execution_started_at = NULL\n WHERE id = ?`,\n id\n );\n }\n\n delete(id: string): void {\n this.#sql(\"DELETE FROM cf_agents_jobs WHERE id = ?\", id);\n }\n\n /**\n * Unguarded retime for the alarm memory-limit breaker's backoff: the\n * platform-failure path clears the dispatch marker before the breaker\n * runs, so the guarded {@link applyOutcome} would no-op — and the\n * breaker's backoff must land regardless, it is protecting the object.\n */\n retime(id: string, time: number): void {\n this.#sql(\n `UPDATE cf_agents_jobs\n SET time = ?, running = 0, execution_started_at = NULL\n WHERE id = ?`,\n Math.floor(time),\n id\n );\n }\n\n /**\n * Back off every pending recovery-loop job that would fire before the\n * breaker's backoff time (#1825), so a doomed loop's sibling rows cannot\n * re-trigger it on the next wake. Unguarded like {@link retime}: the\n * breaker's backoff must land regardless of dispatch markers.\n */\n delayRecoveryLoopJobs(time: number): void {\n this.#sql(\n `UPDATE cf_agents_jobs\n SET time = ?, running = 0, execution_started_at = NULL\n WHERE recovery_loop = 1 AND time <= ?`,\n Math.floor(time),\n Math.floor(time)\n );\n }\n\n /**\n * Read every recovery-loop job before breaker sealing. The memory-limit\n * policy phase uses this snapshot after the rows are purged so routed owners\n * can terminalize their own durable recovery state.\n */\n recoveryLoopJobs(): LifecycleJob[] {\n return this.#sql(\n \"SELECT * FROM cf_agents_jobs WHERE recovery_loop = 1 ORDER BY time ASC\"\n ).map(jobFromRow);\n }\n\n /**\n * Purge every recovery-loop job when the breaker seals at its strike\n * budget (#1825). Unrelated jobs are untouched.\n */\n purgeRecoveryLoopJobs(): void {\n this.#sql(\"DELETE FROM cf_agents_jobs WHERE recovery_loop = 1\");\n }\n\n /**\n * Apply one drive result, guarded on the dispatch marker: every driven\n * job carries `running = 1` for the duration of its dispatch, and a\n * same-id `push()` or `reschedule()` made meanwhile clears it. A cleared\n * marker means newer durable intent exists, so the outcome quietly\n * defers to it instead of deleting or retiming the fresher job.\n */\n applyOutcome(id: string, outcome: LifecycleJobOutcome): void {\n if (outcome === undefined) {\n this.#sql(\"DELETE FROM cf_agents_jobs WHERE id = ? AND running = 1\", id);\n return;\n }\n if (outcome === \"yield\") {\n this.clearRunning(id);\n return;\n }\n if (\n typeof outcome === \"object\" &&\n Number.isFinite(outcome.rescheduleAt) &&\n outcome.rescheduleAt >= 0\n ) {\n this.#sql(\n `UPDATE cf_agents_jobs\n SET time = ?, running = 0, execution_started_at = NULL\n WHERE id = ? AND running = 1`,\n Math.floor(outcome.rescheduleAt),\n id\n );\n return;\n }\n throw new Error(`Invalid job outcome for ${id}`);\n }\n\n /**\n * The next physical alarm time derived from queue state, or `null` when\n * the queue holds nothing to wake for.\n *\n * Exclusive jobs suppress ordinary candidates. An ordinary candidate is\n * the earliest ready job clamped to the future (overdue rows survive\n * restarts and must re-fire immediately), merged with the earliest\n * hung-timeout recheck for in-flight single-flight jobs.\n */\n nextAlarmTime(nowMs: number): number | null {\n const exclusive = this.#sql<{ time: number | null }>(\n \"SELECT MIN(time) AS time FROM cf_agents_jobs WHERE exclusive = 1\"\n );\n if (exclusive[0]?.time !== null && exclusive[0]?.time !== undefined) {\n return exclusive[0].time;\n }\n\n const now = Math.floor(nowMs);\n let candidate: number | null = null;\n\n const ready = this.#sql<{ time: number | null }>(\n `SELECT MIN(time) AS time FROM cf_agents_jobs\n WHERE singleflight = 0\n OR running = 0\n OR coalesce(execution_started_at, 0) + coalesce(hung_timeout_seconds, ?) * 1000 <= ?`,\n DEFAULT_HUNG_TIMEOUT_SECONDS,\n now\n );\n if (ready[0]?.time !== null && ready[0]?.time !== undefined) {\n candidate = Math.max(ready[0].time, now + 1);\n }\n\n const inFlight = this.#sql<{ recheck: number | null }>(\n `SELECT MIN(coalesce(execution_started_at, 0) + coalesce(hung_timeout_seconds, ?) * 1000) AS recheck\n FROM cf_agents_jobs\n WHERE singleflight = 1\n AND running = 1\n AND coalesce(execution_started_at, 0) + coalesce(hung_timeout_seconds, ?) * 1000 > ?`,\n DEFAULT_HUNG_TIMEOUT_SECONDS,\n DEFAULT_HUNG_TIMEOUT_SECONDS,\n now\n );\n const recheck = inFlight[0]?.recheck;\n if (recheck !== null && recheck !== undefined) {\n candidate = candidate === null ? recheck : Math.min(candidate, recheck);\n }\n\n return candidate;\n }\n}\n","/**\n * Alarm event loop for the Lifecycle job queue.\n *\n * The driver owns everything that happens when the physical alarm fires:\n * the deadman pre-arm, driving due jobs in due order (single-flight skip and\n * hung recovery, per-job retries, platform-failure deferral, terminal\n * failure hooks), the backlog warning, and the alarm memory-limit circuit\n * breaker (#1825). Lifecycle wires it to the host and capabilities through\n * the narrow {@link JobDriverOptions} contract and keeps only the alarm\n * entry point itself.\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport {\n isDurableObjectCodeUpdateReset,\n isDurableObjectMemoryLimitReset,\n isPlatformFailure,\n tryN\n} from \"../retries\";\nimport type { MemoryLimitContext } from \"./capability-runner\";\nimport {\n hungTimeoutMs,\n isHungRow,\n jobFromRow,\n type JobQueue,\n type JobStorageRow,\n type LifecycleJob,\n type LifecycleJobContext,\n type LifecycleJobOutcome\n} from \"./job-queue\";\n\n/** Default consecutive memory-limit strikes tolerated before sealing. */\nconst DEFAULT_MAX_ALARM_MEMORY_LIMIT_STRIKES = 3;\n\n/** Durable storage key for the alarm memory-limit strike counter (#1825). */\nconst OOM_ALARM_STRIKES_KEY = \"cf_agents:oom_alarm_strikes\";\n\n/** Default retry policy applied to jobs pushed without one. */\nconst DEFAULT_JOB_RETRY = {\n maxAttempts: 3,\n baseDelayMs: 100,\n maxDelayMs: 3000\n} as const;\n\n/** Due jobs for one capability above this count log a backlog warning. */\nconst JOB_BACKLOG_WARNING_THRESHOLD = 10;\n\n/**\n * Deadman pre-arm delay: armed before the event loop drives due jobs so an\n * isolate death mid-drive still wakes this object to resume its queue.\n */\nconst DEADMAN_ALARM_DELAY_MS = 30_000;\n\n/** The dispatch hooks one job owner exposes to the driver. */\nexport type JobDispatch = {\n readonly onJob: (\n context: LifecycleJobContext\n ) => Promise<LifecycleJobOutcome | void>;\n readonly onJobError?: (\n context: LifecycleJobContext,\n error: unknown\n ) => Promise<LifecycleJobOutcome | void>;\n};\n\n/** What the driver needs from its owning Lifecycle. */\nexport type JobDriverOptions = {\n readonly queue: JobQueue;\n readonly storage: DurableObjectStorage;\n /** Live teardown flag: once true, stop touching storage mid-phase. */\n readonly disabled: () => boolean;\n /** Resolve a job owner to its dispatch hooks, `undefined` when missing. */\n readonly resolveDispatch: (owner: string) => Promise<JobDispatch | undefined>;\n /** Consecutive memory-limit strikes tolerated before sealing (#1825). */\n readonly maxMemoryLimitStrikes: () => number | undefined;\n /** Capability and host domain policy applied on each memory-limit strike. */\n readonly onMemoryLimit: (context: MemoryLimitContext) => void | Promise<void>;\n /** Best-effort lifecycle telemetry. */\n readonly emit: (type: string, payload: unknown) => void;\n /** Recompute the physical alarm from queue state. */\n readonly rearm: () => Promise<void>;\n /**\n * Schedule an isolate reset after a memory-limit strike is fully\n * recorded, suppressing any retry of the current alarm. Returns\n * immediately; the reset lands after the invocation settles, and the next\n * wake is the backoff alarm the strike armed.\n */\n readonly reset: (reason: string) => void;\n};\n\n/** The dispatch an async flow belongs to while an alarm drives it. */\ntype AlarmScope = { readonly executing: JobStorageRow | undefined };\n\n/**\n * Carries the row a platform failure escaped from out to `runAlarm`'s catch,\n * across the rethrow from `#driveJob`. Attribution must not live in a shared\n * instance field: overlapping `alarm()` invocations (a deadman or the\n * platform's own re-fire racing a still-running invocation) dispatch jobs\n * concurrently, and a field would let a later dispatch overwrite the row an\n * earlier one is still unwinding for.\n */\nclass AttributedPlatformFailure {\n constructor(\n readonly row: JobStorageRow,\n readonly cause: unknown\n ) {}\n}\n\n/** One recorded memory-limit strike, shared by every flow that observed it. */\ntype MemoryLimitStrike = {\n readonly strikes: number;\n readonly limit: number;\n readonly sealed: boolean;\n /** The backoff wake time armed for an unsealed strike. */\n readonly nextTime: number | undefined;\n /** Recovery-loop jobs purged by a sealing strike, snapshotted beforehand. */\n readonly purgedRecoveryLoopJobs: LifecycleJob[] | undefined;\n};\n\n/** @internal Drives the job queue when the Durable Object alarm fires. */\nexport class JobDriver {\n readonly #options: JobDriverOptions;\n /**\n * Ambient dispatch identity for `trackAlarmWork`. Read through the async\n * flow rather than an instance slot so attribution stays correct when\n * alarm invocations overlap (tests drive `alarm()` by hand while the\n * platform fires its own).\n */\n readonly #alarmScope = new AsyncLocalStorage<AlarmScope>();\n #alarmsInFlight = 0;\n /**\n * Work handed off by alarm-driven jobs that has not settled yet. While it\n * is non-empty the alarm domain is not quiescent, so a clean alarm must not\n * clear the strike counter: a still-running handoff may yet report the\n * memory reset that alarm started.\n */\n readonly #outstandingAlarmWork = new Set<Promise<unknown>>();\n /**\n * The strike being recorded for the current memory-limit event. One reset\n * is often observed by several flows (an in-alarm job plus handed-off work,\n * or several handoffs awaiting the same condemned storage); they share this\n * record so the counter moves once per event. Cleared by a clean,\n * quiescent classification.\n */\n #strike: Promise<MemoryLimitStrike> | undefined;\n /**\n * Once a strike has been fully recorded in this isolate, no later\n * settlement may clear the durable counter — a slower, unrelated clean\n * sibling finishing after the strike (but before the isolate reset it\n * scheduled actually lands) must not erase what was just recorded. The\n * isolate reset always follows a recorded strike, so the next genuinely\n * clean cycle runs in a fresh isolate with a fresh `JobDriver` and this\n * flag back at its default; there is no cross-isolate state to reset.\n */\n #strikeRecordedThisIsolate = false;\n\n constructor(options: JobDriverOptions) {\n this.#options = options;\n }\n\n /**\n * Run one alarm invocation: initialize the lifecycle, drive due jobs, run\n * the host's alarm callback, and re-arm the physical alarm from queue\n * state — all inside the alarm memory-limit circuit breaker (#1825). A\n * memory-limit reset that propagates here is intercepted — every other\n * error re-throws unchanged so platform alarm-retry semantics hold — and\n * broken from this outermost frame, where the heavy turn has unwound and\n * small writes can land. Initialization runs inside the breaker because a\n * severe reset can be thrown before any job runs (boot hydration, #1825);\n * left unhandled it would re-throw to the platform, which auto-retries\n * the alarm forever.\n */\n async runAlarm(\n initialize: () => Promise<void>,\n runHostAlarm: () => Promise<void>\n ): Promise<void> {\n this.#alarmsInFlight++;\n // Only a clean pass (no memory-limit reset seen by this invocation\n // itself) is ever eligible to trigger the quiescence-clear check below —\n // a pass that just recorded a strike must not immediately re-check\n // quiescence and undo what it just set. Reaching quiescence again is a\n // job for some LATER, genuinely clean invocation or handoff settlement.\n let clean = false;\n try {\n try {\n await initialize();\n await this.#driveDueJobs();\n await this.#alarmScope.run({ executing: undefined }, runHostAlarm);\n clean = true;\n } catch (error) {\n // A platform failure from #driveJob carries its row out of the\n // rethrow; anything else (initialize/runHostAlarm) has no job to\n // attribute. Unwrap either way before classifying the real error.\n const attributed = error instanceof AttributedPlatformFailure;\n const cause = attributed ? error.cause : error;\n if (!isDurableObjectMemoryLimitReset(cause)) {\n throw attributed ? cause : error;\n }\n await this.#handleMemoryLimitReset(\n cause,\n attributed ? error.row : undefined\n );\n return;\n }\n } finally {\n // Re-check quiescence exactly when this alarm's own \"in flight\" status\n // ends, using the freshest counters — one of the two points (the\n // other is a handoff settling, see #settleAlarmWork) that must not be\n // skipped: whichever transition happens last is what performs the\n // clear, and each transition re-evaluates both conditions itself\n // rather than trusting a stale snapshot taken before the other side's\n // own transition landed.\n this.#alarmsInFlight--;\n if (clean) await this.#clearMemoryLimitStrikesWhenQuiescent();\n }\n await this.#options.rearm();\n }\n\n /**\n * Keep work a job handed off at a bounded return inside this alarm's\n * memory-limit breaker domain (#1825). The alarm itself returns promptly,\n * so other jobs stay live; the handoff is classified when it settles. A\n * memory-limit reset it reports records a strike against the job that\n * handed it off, exactly as an in-alarm reset would. Strikes clear only\n * once no handed-off work is outstanding and the last of it settled clean.\n *\n * @returns True when called from an alarm-driven dispatch or the host\n * alarm hook; false otherwise, in which case nothing is tracked. Tracking\n * the same promise again (a claim-backstop wake for an attempt already\n * handed off) is a no-op.\n */\n trackAlarmWork(work: Promise<unknown>): boolean {\n const scope = this.#alarmScope.getStore();\n if (!scope) return false;\n if (this.#outstandingAlarmWork.has(work)) return true;\n this.#outstandingAlarmWork.add(work);\n void work.then(\n () => this.#settleAlarmWork(work, undefined, scope.executing),\n (error) => this.#settleAlarmWork(work, error, scope.executing)\n );\n return true;\n }\n\n async #settleAlarmWork(\n work: Promise<unknown>,\n error: unknown,\n executing: JobStorageRow | undefined\n ): Promise<void> {\n try {\n if (this.#options.disabled()) return;\n if (isDurableObjectMemoryLimitReset(error)) {\n // Still outstanding while the strike is recorded, so an alarm\n // finishing concurrently cannot clear it from underneath.\n await this.#handleMemoryLimitReset(error, executing);\n return;\n }\n } finally {\n this.#outstandingAlarmWork.delete(work);\n }\n // This settle is itself a quiescence transition — re-check freshly\n // rather than trusting whether an alarm looked in flight before this\n // delete landed (see runAlarm's matching call for why neither side may\n // skip its own check).\n await this.#clearMemoryLimitStrikesWhenQuiescent();\n }\n\n /**\n * Clear the strike counter once the alarm domain is fully quiescent: no\n * alarm invocation in flight, no handed-off work outstanding, and no\n * strike recorded in this isolate that a fresh isolate hasn't yet\n * superseded. Called at every transition that could make either counter\n * newly zero (an alarm ending, a handoff settling) — each call re-reads\n * both fresh, so whichever transition happens last is the one that\n * performs the clear. Idempotent: redundant calls no-op.\n */\n async #clearMemoryLimitStrikesWhenQuiescent(): Promise<void> {\n if (this.#alarmsInFlight > 0) return;\n if (this.#outstandingAlarmWork.size > 0) return;\n if (this.#strikeRecordedThisIsolate) return;\n this.#strike = undefined;\n await this.#clearMemoryLimitStrikes();\n }\n\n /** Drive every due job once, in due-time order. */\n async #driveDueJobs(): Promise<void> {\n const nowMs = Date.now();\n const due = this.#options.queue.due(nowMs);\n if (due.length === 0) return;\n this.#warnBacklog(due);\n\n // Deadman pre-arm: before driving any job, arm a fallback alarm so a\n // death mid-drive that the platform cannot retry (or that swallows its\n // error) still wakes this object to resume. The normal re-arm at the end\n // of the alarm phase overwrites it.\n if (!this.#options.disabled()) {\n await this.#options.storage.setAlarm(nowMs + DEADMAN_ALARM_DELAY_MS);\n }\n\n for (const stale of due) {\n // Host teardown mid-phase: its storage is gone, stop touching it.\n if (this.#options.disabled()) return;\n\n // Refetch before claiming: an earlier dispatch in this loop may have\n // pushed, rescheduled, or cancelled this job since the due snapshot\n // was taken. A row that is gone or no longer due belongs to that\n // newer intent — skip it (the final re-arm owns any future wake). A\n // row that changed but is still due dispatches with its fresh data.\n const row = this.#options.queue.dueRow(stale.id, nowMs);\n if (!row) continue;\n\n if (row.singleflight === 1 && row.running === 1) {\n if (!isHungRow(row, nowMs)) {\n console.warn(\n `Skipping job ${row.id}: previous execution still running`\n );\n continue;\n }\n console.warn(\n `Forcing reset of hung job ${row.id} (started ${Math.round(\n (nowMs - (row.execution_started_at ?? 0)) / 1000\n )}s ago)`\n );\n }\n // Every dispatch is marked, not just single-flight: the marker is\n // what lets a same-id push made mid-dispatch supersede the returned\n // drive result (see JobQueue.applyOutcome).\n this.#options.queue.markRunning(row.id, nowMs);\n\n await this.#driveJob(row);\n }\n }\n\n /** Dispatch one due row to its owner with retry and failure policy. */\n async #driveJob(row: JobStorageRow): Promise<void> {\n const { queue, resolveDispatch, disabled } = this.#options;\n const job = jobFromRow(row);\n const dispatch = await resolveDispatch(row.capability);\n if (!dispatch) {\n console.error(\n `No installed capability or host handler for job ${row.id} ` +\n `(owner ${JSON.stringify(row.capability)}); dropping it`\n );\n queue.delete(row.id);\n return;\n }\n\n const maxAttempts = job.retry?.maxAttempts ?? DEFAULT_JOB_RETRY.maxAttempts;\n\n // Dispatch must be bounded: the drive loop awaits each job inline, so\n // one long dispatch delays every other job on this object. The queue\n // cannot safely abandon owner code, so the contract is enforced by\n // visibility — a dispatch that outlives the job's hung timeout warns\n // loudly and emits telemetry naming the owner.\n const slowWatchdog = setTimeout(() => {\n const seconds = Math.round(hungTimeoutMs(row) / 1000);\n console.warn(\n `Job ${row.id} (${row.capability}/${row.fn}) has been dispatching ` +\n `for over ${seconds}s. Long dispatches starve every other job on ` +\n `this object; onJob must detach unbounded work and return.`\n );\n try {\n this.#options.emit(\"job:slow_dispatch\", {\n capability: row.capability,\n fn: row.fn,\n id: row.id,\n thresholdMs: hungTimeoutMs(row)\n });\n } catch {\n // telemetry never blocks the dispatch\n }\n }, hungTimeoutMs(row));\n\n let outcome: LifecycleJobOutcome | void;\n try {\n outcome = await this.#alarmScope.run({ executing: row }, () =>\n tryN(maxAttempts, (attempt) => dispatch.onJob({ job, attempt }), {\n baseDelayMs: job.retry?.baseDelayMs ?? DEFAULT_JOB_RETRY.baseDelayMs,\n maxDelayMs: job.retry?.maxDelayMs ?? DEFAULT_JOB_RETRY.maxDelayMs,\n // In-process retries are futile on a superseded isolate (code\n // never reloads mid-invocation) and on a memory-limit reset (the\n // isolate is condemned, and a retry can read half-claimed state\n // as \"nothing to do\", converting the reset into a silent success\n // that the breaker never sees). Defer both to the alarm boundary.\n shouldRetry: (error) =>\n !isDurableObjectCodeUpdateReset(error) &&\n !isDurableObjectMemoryLimitReset(error)\n })\n );\n } catch (error) {\n if (disabled()) return;\n if (isPlatformFailure(error)) {\n // Platform-class failure: preserve the job and re-throw so the\n // platform retries a fresh invocation (or the memory-limit breaker\n // engages at the alarm boundary). Best-effort dispatch-marker reset\n // so the preserved job is not mistaken for one still in flight (and\n // a single-flight job does not wait out its hung timeout first).\n try {\n queue.clearRunning(row.id);\n } catch {\n // the hung timeout eventually recovers the flag\n }\n console.warn(\n `Deferring job ${row.id} to a fresh invocation after a ` +\n `platform failure; the job is preserved.`\n );\n // Carry the row out with the error rather than through a shared\n // field: an overlapping alarm's own #driveJob may already be\n // dispatching a different row by the time this unwinds to\n // runAlarm's catch.\n throw new AttributedPlatformFailure(row, error);\n }\n // Application failure after retry exhaustion: the owner observes it\n // and decides advancement; default is completion.\n try {\n outcome = await dispatch.onJobError?.(\n { job, attempt: maxAttempts },\n error\n );\n } catch (hookError) {\n console.error(`Job failure hook threw for ${row.id}`, hookError);\n }\n } finally {\n clearTimeout(slowWatchdog);\n }\n\n if (disabled()) return;\n queue.applyOutcome(row.id, outcome ?? undefined);\n }\n\n #warnBacklog(due: ReadonlyArray<JobStorageRow>): void {\n const counts = new Map<string, number>();\n for (const row of due) {\n counts.set(row.capability, (counts.get(row.capability) ?? 0) + 1);\n }\n for (const [owner, count] of counts) {\n if (count < JOB_BACKLOG_WARNING_THRESHOLD) continue;\n try {\n console.warn(\n `Processing ${count} due jobs for ${JSON.stringify(owner)} ` +\n `in a single alarm cycle. This usually means one-shot jobs are ` +\n `pushed repeatedly without a stable id.`\n );\n this.#options.emit(\"job:backlog_warning\", {\n capability: owner,\n count\n });\n } catch {\n // warning emission never blocks job processing\n }\n }\n }\n\n /**\n * Clear the durable memory-limit strike counter after a clean alarm so the\n * breaker counts CONSECUTIVE resets rather than lifetime ones (#1825).\n * Reads first and only writes when a strike is recorded. Best-effort.\n */\n async #clearMemoryLimitStrikes(): Promise<void> {\n const { storage } = this.#options;\n try {\n const prior = await storage.get<number>(OOM_ALARM_STRIKES_KEY);\n if (typeof prior === \"number\" && prior > 0) {\n await storage.delete(OOM_ALARM_STRIKES_KEY);\n }\n } catch {\n // a stale strike only costs one extra tolerated spike later\n }\n }\n\n /**\n * Alarm-boundary circuit breaker for Durable Object memory-limit resets\n * (#1825). Unhandled, the platform would auto-retry the alarm forever,\n * re-running the doomed work each cycle. A durable strike counter\n * tolerates a few consecutive resets — backing off the executing job and\n * every pending recovery-loop job so the retry is not a hot loop — then\n * seals: those jobs are purged and the capability + host memory-limit\n * policy hooks run.\n *\n * One reset is one event even when several flows observe it. The strike\n * is recorded once per event ({@link #recordMemoryLimitStrike}); every\n * observer then applies the per-job policy for the job it belongs to, and\n * the first observer finishes the event by re-arming, syncing, and\n * resetting the isolate. Each step is best-effort: even these small writes\n * can OOM, but swallowing still halts the platform's auto-retry, and a\n * later wake re-arms legitimate work.\n */\n async #handleMemoryLimitReset(\n error: unknown,\n executing: JobStorageRow | undefined\n ): Promise<void> {\n const { queue } = this.#options;\n const first = this.#strike === undefined;\n // Set before the first await below: closes the window as tightly as\n // possible against a still-outstanding clean sibling reaching quiescence\n // and clearing what this event is about to record.\n this.#strikeRecordedThisIsolate = true;\n this.#strike ??= this.#recordMemoryLimitStrike(error);\n const strike = await this.#strike;\n\n try {\n if (executing) {\n if (strike.sealed) {\n queue.delete(executing.id);\n } else if (strike.nextTime !== undefined) {\n queue.retime(executing.id, strike.nextTime);\n }\n }\n } catch {\n // best-effort at a failure boundary\n }\n\n try {\n await this.#options.onMemoryLimit({\n sealed: strike.sealed,\n nextTime: strike.nextTime,\n executing: executing ? jobFromRow(executing) : undefined,\n purgedRecoveryLoopJobs: first\n ? strike.purgedRecoveryLoopJobs\n : undefined\n });\n } catch {\n // best-effort domain policy; the purge above already broke the loop\n }\n\n if (!first) return;\n\n // Re-arm so unrelated work continues. Wrapped because it can itself OOM;\n // if it does, the next external wake re-arms.\n try {\n await this.#options.rearm();\n } catch {\n // best-effort\n }\n\n // Finish on a fresh isolate: the strike is durable and the backoff alarm\n // owns the next wake, so schedule a reset to reclaim the memory\n // footprint instead of limping on in the pressured isolate. Sync first —\n // a reset cancels unconfirmed writes, and the strike/backoff writes must\n // land. If any of this fails, fall through to the swallow-and-return\n // exit, which still halts the platform's alarm auto-retry.\n try {\n await this.#options.storage.sync();\n this.#options.reset(\n `Alarm memory-limit strike ${strike.strikes}/${strike.limit}${strike.sealed ? \" (sealed)\" : \"\"}; resetting isolate (#1825)`\n );\n } catch {\n // best-effort\n }\n }\n\n /**\n * Record one strike durably and apply the queue-wide policy that belongs\n * to the event rather than to any one job: recovery-loop rows back off (or\n * purge) as a pack, a sealing strike resets the counter, and the event is\n * emitted once.\n */\n async #recordMemoryLimitStrike(error: unknown): Promise<MemoryLimitStrike> {\n const { queue, storage } = this.#options;\n\n let strikes = 1;\n try {\n const prior = await storage.get<number>(OOM_ALARM_STRIKES_KEY);\n strikes = (typeof prior === \"number\" ? prior : 0) + 1;\n await storage.put(OOM_ALARM_STRIKES_KEY, strikes);\n } catch {\n // even the strike write OOMed; still progress toward sealing\n }\n\n const limit =\n this.#options.maxMemoryLimitStrikes() ??\n DEFAULT_MAX_ALARM_MEMORY_LIMIT_STRIKES;\n const sealed = strikes >= limit;\n console.error(\n `Alarm hit a Durable Object memory-limit reset (strike ${strikes}/${limit}` +\n `${sealed ? \", sealing recovery\" : \", will retry with backoff\"}). ` +\n \"Breaking the platform alarm-retry loop (#1825).\",\n error instanceof Error ? error.message : String(error)\n );\n\n const nextTime = sealed\n ? undefined\n : Date.now() + Math.min(300, 30 * strikes) * 1000;\n // Capture routed ownership before sealing deletes the rows. Domain policy\n // runs afterward, when the loop is already broken, and uses this snapshot\n // only to terminalize durable state owned outside the alarm host.\n let purgedRecoveryLoopJobs: LifecycleJob[] | undefined;\n try {\n if (sealed) purgedRecoveryLoopJobs = queue.recoveryLoopJobs();\n } catch {\n // best-effort at a failure boundary\n }\n\n try {\n // Recovery-loop rows travel as a pack: a doomed loop's sibling rows\n // would re-trigger it on the next wake, so they back off (or purge)\n // together with the row that struck.\n if (sealed) {\n queue.purgeRecoveryLoopJobs();\n } else if (nextTime !== undefined) {\n queue.delayRecoveryLoopJobs(nextTime);\n }\n } catch {\n // best-effort at a failure boundary\n }\n\n if (sealed) {\n try {\n await storage.delete(OOM_ALARM_STRIKES_KEY);\n } catch {\n // best-effort counter reset\n }\n }\n\n try {\n this.#options.emit(\"alarm:memory_limit_reset\", {\n strikes,\n limit,\n sealed,\n error: error instanceof Error ? error.message : String(error)\n });\n } catch {\n // event emission is non-critical\n }\n\n return { strikes, limit, sealed, nextTime, purgedRecoveryLoopJobs };\n }\n}\n","// Internal helpers for classifying WebSocket transport errors.\n// Not re-exported from the package entry point; imported by `index.ts` and\n// exercised directly by `tests/transport-errors.test.ts`.\n\n/** Standard `WebSocket.readyState` values. */\nconst CLOSING = 2;\nconst CLOSED = 3;\n\n/**\n * A retryable transport-teardown error (\"Network connection lost\" /\n * \"WebSocket peer disconnected\") that fires on a connection which is already\n * CLOSING/CLOSED is just the socket going away during or right after the close\n * handshake - not an application error. Surfacing it via `onError` spams logs\n * on every abrupt client disconnect, and even on clean closes when the peer\n * tears down its transport before our reciprocal Close frame lands. Suppress\n * it in that specific case only; genuine mid-connection (OPEN) errors still\n * reach `onError`.\n *\n * Detection prefers the structured `retryable` flag over message text so it\n * stays correct across `enhanced-error-serialization` (compat date\n * >= 2026-04-21), with a substring fallback for older error shapes.\n */\nexport function isBenignTeardownError(\n ws: { readyState?: number },\n error: unknown\n): boolean {\n const state = ws.readyState;\n if (state !== CLOSING && state !== CLOSED) return false;\n if (typeof error !== \"object\" || error === null) return false;\n const typed = error as { retryable?: boolean; message?: unknown };\n if (typed.retryable === true) return true;\n const message = typeof typed.message === \"string\" ? typed.message : \"\";\n return /Network connection lost|WebSocket peer disconnected/i.test(message);\n}\n","import { DurableObject } from \"cloudflare:workers\";\n\nimport { publishDiagnosticsEvent } from \"../observability/diagnostics\";\nimport {\n CapabilityRunner,\n type DurableObjectCapability,\n type LifecycleEvent,\n type LifecycleEventSink\n} from \"./capability-runner\";\nimport { abortWithoutAlarmRetry } from \"./abort\";\nimport { JobDriver, type JobDispatch } from \"./job-driver\";\nimport {\n HOST_JOB_CAPABILITY,\n JobQueue,\n type LifecycleJobs,\n type LifecycleJobPushOptions\n} from \"./job-queue\";\nimport {\n bindLifecycleCapability,\n lifecycleCapabilityId,\n LifecycleCapability,\n type LifecycleHostContextScope,\n type LifecycleRouteAddress,\n type LifecycleServices\n} from \"./capability\";\nimport {\n runInLifecycleHostContext,\n runWithoutCurrentAgent,\n type LifecycleObject\n} from \"./current-agent\";\nimport { isBenignTeardownError } from \"./transport-errors\";\nimport type { WSMessage } from \"./types\";\n\nexport {\n type CapabilityRequestContext,\n type CapabilityWebSocketUpgradeContext,\n type LifecycleEvent,\n type CapabilityStartContext,\n type DurableObjectCapability,\n type MemoryLimitContext\n} from \"./capability-runner\";\nexport {\n type LifecycleJobContext,\n type LifecycleJobs,\n type LifecycleJob,\n type LifecycleJobOutcome,\n type LifecycleJobPushOptions\n} from \"./job-queue\";\nexport * from \"./types\";\n\nconst LEGACY_NAME_STORAGE_KEY = \"__ps_name\";\n\nfunction mutableRequest(request: Request): Request {\n return new Request(request);\n}\n\n/**\n * Decode props from the internal lifecycle props header.\n *\n * Handles both base64-encoded lifecycle props and, for\n * backwards compatibility with stubs/requests created by older versions,\n * raw JSON. Base64 never starts with `{` or `[`, so a leading brace/bracket\n * unambiguously identifies the legacy raw-JSON form.\n */\nfunction decodeProps(header: string): unknown {\n const trimmed = header.trim();\n if (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\n return JSON.parse(trimmed);\n }\n const binary = atob(header);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return JSON.parse(new TextDecoder().decode(bytes));\n}\n\n/** Internal envelope transported between routed Lifecycle instances. */\nexport type LifecycleRouteEnvelope = {\n readonly capability: string;\n readonly source: LifecycleRouteAddress | undefined;\n readonly payload: unknown;\n};\n\n/** Internal transport supplied by a host with routed child Lifecycles. */\nexport type LifecycleRouteTransport = {\n readonly source: LifecycleRouteAddress | undefined;\n readonly toRoot: (envelope: LifecycleRouteEnvelope) => Promise<unknown>;\n readonly to: (\n target: LifecycleRouteAddress,\n envelope: LifecycleRouteEnvelope\n ) => Promise<unknown>;\n};\n\ntype LifecycleHost<\n Env extends object,\n Props extends Record<string, unknown>\n> = LifecycleObject<Env, Props> & {\n readonly ctx: DurableObjectState;\n readonly constructor: { readonly name: string };\n};\n\n/**\n * Boundary wrapping user callbacks that capabilities run through\n * `LifecycleServices.runInHostContext`. The default boundary is\n * {@link runInLifecycleHostContext}; a host composition root may substitute\n * its own invocation wrapper (Agent adds tracing span scope). The optional\n * scope carries the live connection/request the callback runs on behalf of.\n */\nexport type LifecycleHostInvoker = <T>(\n run: () => T,\n scope?: LifecycleHostContextScope\n) => T;\n\nconst lifecycleEventSinks = new WeakMap<object, LifecycleEventSink>();\nconst lifecycleRouteTransports = new WeakMap<object, LifecycleRouteTransport>();\nconst lifecycleHostInvokers = new WeakMap<object, LifecycleHostInvoker>();\n\n/** @internal Adapt the host invocation boundary at a composition root. */\nexport function setLifecycleHostInvoker<\n Env extends object,\n Props extends Record<string, unknown>\n>(lifecycle: Lifecycle<Env, Props>, invoker: LifecycleHostInvoker): void {\n lifecycleHostInvokers.set(lifecycle, invoker);\n}\n\n/** @internal Supply a host's routed Lifecycle transport. */\nexport function setLifecycleRouteTransport<\n Env extends object,\n Props extends Record<string, unknown>\n>(lifecycle: Lifecycle<Env, Props>, transport: LifecycleRouteTransport): void {\n lifecycleRouteTransports.set(lifecycle, transport);\n}\n\n/** @internal Adapt Lifecycle's default diagnostics sink at a composition root. */\nexport function setLifecycleEventSink<\n Env extends object,\n Props extends Record<string, unknown>\n>(lifecycle: Lifecycle<Env, Props>, sink: LifecycleEventSink): void {\n lifecycleEventSinks.set(lifecycle, sink);\n}\n\n/** Configuration accepted when constructing a {@link Lifecycle}. */\nexport type LifecycleOptions = {\n /**\n * Consecutive alarm invocations that may end in a Durable Object\n * memory-limit reset before the circuit breaker (#1825) seals recovery\n * work instead of backing it off. Default: 3.\n */\n readonly maxAlarmMemoryLimitStrikes?: number;\n};\n\n/** Placement of a capability in the dispatch order. */\nexport type LifecycleUseOptions = {\n /**\n * Dispatch after every non-fallback capability, whenever it was\n * installed. For a host's catch-all, such as a WebSockets capability\n * that claims every upgrade, so middleware installed later still runs\n * first.\n */\n readonly fallback?: boolean;\n};\n\n/**\n * Installs and coordinates the runtime lifecycle for a Durable Object.\n *\n * Construct this as an instance field on a class that directly extends\n * `DurableObject`, then call {@link Lifecycle.installHandlers}\n * from that class's constructor.\n *\n * @experimental The API surface may change before stabilizing.\n */\nexport class Lifecycle<\n Env extends object = Cloudflare.Env,\n Props extends Record<string, unknown> = Record<string, unknown>\n> {\n readonly #host: LifecycleHost<Env, Props>;\n readonly #ctx: DurableObjectState;\n readonly #parentClassName: string;\n readonly #capabilities: DurableObjectCapability<Props>[] = [];\n readonly #capabilityRunner = new CapabilityRunner<Props>(\n () => this.#capabilities\n );\n readonly #jobQueue: JobQueue;\n readonly #jobDriver: JobDriver;\n\n #status: \"zero\" | \"starting\" | \"started\" = \"zero\";\n #alarmRearmQueue: Promise<void> = Promise.resolve();\n #rearmRequestedDuringStart = false;\n #pendingEvents: LifecycleEvent[] = [];\n #alarmsDisabled = false;\n #capabilitiesLocked = false;\n readonly #fallbacks = new Set<DurableObjectCapability<Props>>();\n #handlersInstalled = false;\n\n /**\n * Construct and install a lifecycle in one explicit operation.\n *\n * @param host - The Durable Object whose runtime handlers the lifecycle owns.\n * @returns The installed lifecycle.\n */\n static install<\n Env extends object,\n Props extends Record<string, unknown> = Record<string, unknown>\n >(\n host: DurableObject<Env>,\n options?: LifecycleOptions\n ): Lifecycle<Env, Props> {\n const lifecycle = new Lifecycle<Env, Props>(host, options);\n lifecycle.installHandlers();\n return lifecycle;\n }\n\n /**\n * Bind a lifecycle to a Durable Object instance without mutating its handlers.\n *\n * @param host - The Durable Object whose runtime lifecycle this object owns.\n * @param options - Policy configuration for this lifecycle.\n */\n constructor(host: DurableObject<Env>, options?: LifecycleOptions) {\n // SAFETY: DurableObject exposes ctx as protected to subclasses. The\n // lifecycle is constructed by that subclass with `this`, so this boundary\n // accesses the same runtime-owned context without exposing it publicly.\n this.#host = host as unknown as LifecycleHost<Env, Props>;\n this.#ctx = this.#host.ctx;\n this.#parentClassName = this.#host.constructor.name;\n this.#jobQueue = new JobQueue(this.#ctx.storage);\n this.#jobDriver = new JobDriver({\n queue: this.#jobQueue,\n storage: this.#ctx.storage,\n disabled: () => this.#alarmsDisabled,\n resolveDispatch: (owner) => this.#resolveJobDispatch(owner),\n maxMemoryLimitStrikes: () => options?.maxAlarmMemoryLimitStrikes,\n onMemoryLimit: async (context) => {\n // Capabilities first (each best-effort inside the runner), then the\n // host hook — a failed capability policy must not silence the host's.\n await this.#capabilityRunner.memoryLimit(context);\n await runInLifecycleHostContext({ host: this.#host }, () =>\n this.#host.onAlarmMemoryLimit?.(context)\n );\n },\n emit: (type, payload) =>\n this.#emitCapabilityEvent({ source: \"lifecycle\", type, payload }),\n rearm: () => this.rearmAlarm(),\n // Deferred a tick so the current invocation settles (its RPC/alarm\n // completes and its writes confirm) before the instance resets —\n // `abort()` throws an uncatchable error, mirroring Agent.destroy().\n reset: (reason) => {\n setTimeout(() => abortWithoutAlarmRetry(this.#ctx, reason), 0);\n }\n });\n }\n\n /**\n * Install platform fetch, alarm, and hibernating WebSocket handlers.\n *\n * Existing handlers are preserved for framework-owned dispatch such as the\n * Agent's sub-agent router and alarm circuit breaker. Calling this method\n * more than once is an error.\n */\n installHandlers(): void {\n if (this.#handlersInstalled) {\n throw new Error(\n \"Durable Object lifecycle handlers are already installed\"\n );\n }\n this.#handlersInstalled = true;\n\n const handlers = {\n fetch: this.fetch.bind(this),\n alarm: this.alarm.bind(this),\n webSocketMessage: this.webSocketMessage.bind(this),\n webSocketClose: this.webSocketClose.bind(this),\n webSocketError: this.webSocketError.bind(this)\n };\n for (const [name, handler] of Object.entries(handlers)) {\n if (name in this.#host) continue;\n Object.defineProperty(this.#host, name, {\n value: handler,\n configurable: true\n });\n }\n }\n\n /**\n * Add a reusable capability before this lifecycle starts.\n *\n * Capabilities dispatch in registration order, except that fallbacks\n * always come after non-fallbacks.\n *\n * @param capability - The capability to add.\n * @param options - Dispatch placement.\n * @returns This lifecycle.\n */\n use(\n capability: DurableObjectCapability<Props>,\n options?: LifecycleUseOptions\n ): this {\n if (this.#capabilitiesLocked) {\n throw new Error(\"Lifecycle capabilities must be added before startup\");\n }\n const capabilityId = lifecycleCapabilityId(capability);\n if (\n capabilityId &&\n this.#capabilities.some(\n (candidate) => lifecycleCapabilityId(candidate) === capabilityId\n )\n ) {\n throw new Error(\n `Lifecycle capability ${JSON.stringify(capabilityId)} is already installed`\n );\n }\n\n const firstFallback = this.#capabilities.findIndex((candidate) =>\n this.#fallbacks.has(candidate)\n );\n if (options?.fallback) this.#fallbacks.add(capability);\n this.#capabilities.splice(\n options?.fallback || firstFallback === -1\n ? this.#capabilities.length\n : firstFallback,\n 0,\n capability\n );\n\n if (capability instanceof LifecycleCapability) {\n bindLifecycleCapability(\n capability,\n this.#servicesForCapability(capability.capabilityId)\n );\n }\n return this;\n }\n\n #servicesForCapability(capabilityId: string): LifecycleServices {\n const lifecycle = this;\n const envelope = (payload: unknown): LifecycleRouteEnvelope => ({\n capability: capabilityId,\n source: lifecycleRouteTransports.get(lifecycle)?.source,\n payload\n });\n return Object.freeze({\n storage: this.#ctx.storage,\n sockets: Object.freeze({\n accept: (ws: WebSocket, tags: string[]) =>\n this.#ctx.acceptWebSocket(ws, tags),\n get: (tag?: string) => this.#ctx.getWebSockets(tag)\n }),\n ready: () => this.#readyForCapabilityOperation(),\n starting: () => this.#status === \"starting\",\n jobs: this.#jobsForOwner(capabilityId),\n trackAlarmWork: (work: Promise<unknown>) =>\n this.#jobDriver.trackAlarmWork(work),\n runInHostContext: async (\n fn: () => unknown,\n scope?: LifecycleHostContextScope\n ) => this.#runInHostBoundary(fn, scope),\n events: Object.freeze({\n emit: (type: string, payload: unknown) =>\n this.#emitCapabilityEvent({ source: capabilityId, type, payload })\n }),\n routes: Object.freeze({\n get source() {\n return lifecycleRouteTransports.get(lifecycle)?.source;\n },\n toRoot: (payload: unknown) => {\n const transport = lifecycleRouteTransports.get(lifecycle);\n return transport\n ? transport.toRoot(envelope(payload))\n : this.#dispatchRoute(envelope(payload));\n },\n to: (target: LifecycleRouteAddress, payload: unknown) => {\n const transport = lifecycleRouteTransports.get(lifecycle);\n if (!transport) {\n throw new Error(\n \"Lifecycle has no transport for routed capabilities\"\n );\n }\n return transport.to(target, envelope(payload));\n }\n })\n });\n }\n\n /**\n * Run a user callback inside the host invocation boundary — plain host\n * context by default, or the composition root's substitute (Agent installs\n * its tracing invocation scope).\n */\n #runInHostBoundary(\n fn: () => unknown,\n scope?: LifecycleHostContextScope\n ): Promise<unknown> {\n const boundary = lifecycleHostInvokers.get(this);\n return Promise.resolve(\n boundary\n ? boundary(fn, scope)\n : runInLifecycleHostContext(\n {\n host: this.#host,\n connection: scope?.connection,\n request: scope?.request\n },\n fn\n )\n );\n }\n\n async #readyForCapabilityOperation(): Promise<void> {\n if (this.#status === \"starting\" || this.#status === \"started\") return;\n await this.start();\n }\n\n async #dispatchRoute(envelope: LifecycleRouteEnvelope): Promise<unknown> {\n await this.#ensureInitialized();\n return runWithoutCurrentAgent(() =>\n this.#capabilityRunner.route(envelope.capability, {\n source: envelope.source,\n payload: envelope.payload\n })\n );\n }\n\n /** @internal Deliver a generic capability envelope to this Lifecycle. */\n route(envelope: LifecycleRouteEnvelope): Promise<unknown> {\n return this.#dispatchRoute(envelope);\n }\n\n #emitCapabilityEvent(event: LifecycleEvent): void {\n if (event.source.trim() === \"\" || event.type.trim() === \"\") {\n throw new Error(\"Lifecycle events require non-empty source and type\");\n }\n if (this.#status !== \"started\") {\n this.#pendingEvents.push(event);\n return;\n }\n this.#publishCapabilityEvent(event);\n }\n\n #publishCapabilityEvent(event: LifecycleEvent): void {\n runWithoutCurrentAgent(() => {\n const sink = lifecycleEventSinks.get(this);\n try {\n if (!sink) {\n publishDiagnosticsEvent({\n source: event.source,\n type: event.type,\n agent: this.#parentClassName,\n name: this.name,\n payload: event.payload,\n timestamp: Date.now()\n });\n return;\n }\n const pending = sink(event);\n if (pending !== undefined) {\n this.#ctx.waitUntil(\n Promise.resolve(pending).catch((error) => {\n this.#reportEventSinkFailure(event, error);\n })\n );\n }\n } catch (error) {\n this.#reportEventSinkFailure(event, error);\n }\n });\n }\n\n #reportEventSinkFailure(event: LifecycleEvent, error: unknown): void {\n console.error(\n `Lifecycle event sink failed for ${event.source}:${event.type}`,\n error\n );\n }\n\n #deliverPendingEvents(): void {\n for (const event of this.#pendingEvents.splice(0)) {\n this.#publishCapabilityEvent(event);\n }\n }\n\n /**\n * Execute SQL queries against the Durable Object's database\n * @template T Type of the returned rows\n * @param strings SQL query template strings\n * @param values Values to be inserted into the query\n * @returns Array of query results\n */\n sql<T = Record<string, string | number | boolean | null>>(\n strings: TemplateStringsArray,\n ...values: (string | number | boolean | null)[]\n ) {\n let query = \"\";\n try {\n // Construct the SQL query with placeholders\n query = strings.reduce(\n (acc, str, i) => acc + str + (i < values.length ? \"?\" : \"\"),\n \"\"\n );\n\n // Execute the SQL query with the provided values\n return [...this.#ctx.storage.sql.exec(query, ...values)] as T[];\n } catch (error) {\n console.error(`failed to execute sql query: ${query}`, error);\n throw error;\n }\n }\n\n /**\n * Handle an incoming request for the owning Durable Object.\n *\n * Non-upgrade requests run through the capability middleware chain first,\n * then fall through to the host's `onRequest`.\n */\n async fetch(request: Request): Promise<Response> {\n try {\n const encodedProps = request.headers.get(\"x-agents-lifecycle-props\");\n if (encodedProps) {\n this.#props = decodeProps(encodedProps) as Props;\n request = mutableRequest(request);\n request.headers.delete(\"x-agents-lifecycle-props\");\n }\n\n await this.#ensureInitialized();\n\n if (request.headers.get(\"Upgrade\")?.toLowerCase() !== \"websocket\") {\n const capabilityResponse = await runWithoutCurrentAgent(() =>\n this.#capabilityRunner.request({ request })\n );\n if (capabilityResponse !== undefined) return capabilityResponse;\n if (this.#host.onRequest) {\n return await runInLifecycleHostContext(\n { host: this.#host, request },\n () => this.#host.onRequest!(request)\n );\n }\n return new Response(\"Not implemented\", { status: 404 });\n } else {\n // Lifecycle does not model WebSockets. A capability that owns\n // connection behavior (e.g. the WebSockets capability) claims the\n // upgrade here; without one, upgrades are not supported.\n const upgradeResponse = await runWithoutCurrentAgent(() =>\n this.#capabilityRunner.webSocketUpgrade({ request })\n );\n if (upgradeResponse !== undefined) return upgradeResponse;\n\n return new Response(\n \"WebSocket upgrades are not enabled on this Durable Object. Install a capability that claims them (e.g. WebSockets).\",\n { status: 404 }\n );\n }\n } catch (err) {\n console.error(\n `Error in ${this.#parentClassName}:${this.#ctx.id.name ?? \"<unnamed>\"} fetch:`,\n err\n );\n if (!(err instanceof Error)) throw err;\n if (request.headers.get(\"Upgrade\") === \"websocket\") {\n // Annoyingly, if we return an HTTP error in response to a WebSocket request, Chrome devtools\n // won't show us the response body! So... let's send a WebSocket response with an error\n // frame instead.\n const pair = new WebSocketPair();\n pair[1].accept();\n pair[1].send(JSON.stringify({ error: err.stack }));\n pair[1].close(1011, \"Uncaught exception during session setup\");\n return new Response(null, { status: 101, webSocket: pair[0] });\n } else {\n return new Response(err.stack, { status: 500 });\n }\n }\n }\n\n /** @internal Dispatch a hibernating WebSocket message. */\n async webSocketMessage(ws: WebSocket, message: WSMessage): Promise<void> {\n try {\n await this.#ensureInitialized();\n\n // Sockets are owned by whichever capability claimed their upgrade\n // (recognized via its own hibernation attachment). Wakes for sockets\n // no capability owns — e.g. `state.acceptWebSocket()` in user code —\n // are ignored.\n await runWithoutCurrentAgent(() =>\n this.#capabilityRunner.webSocketMessage(ws, message)\n );\n } catch (e) {\n console.error(\n `Error in ${this.#parentClassName}:${this.#ctx.id.name ?? \"<unnamed>\"} webSocketMessage:`,\n e\n );\n }\n }\n\n /** @internal Dispatch a hibernating WebSocket close. */\n async webSocketClose(\n ws: WebSocket,\n code: number,\n reason: string,\n wasClean: boolean\n ): Promise<void> {\n try {\n await this.#ensureInitialized();\n // The owning capability also reciprocates the close handshake, as\n // the Hibernation API contract requires.\n await runWithoutCurrentAgent(() =>\n this.#capabilityRunner.webSocketClose(ws, code, reason, wasClean)\n );\n } catch (e) {\n console.error(\n `Error in ${this.#parentClassName}:${this.#ctx.id.name ?? \"<unnamed>\"} webSocketClose:`,\n e\n );\n }\n }\n\n /** @internal Dispatch a hibernating WebSocket error. */\n async webSocketError(ws: WebSocket, error: unknown): Promise<void> {\n // Suppress retryable transport-teardown errors on an already closing/closed\n // socket — the connection going away during/after the close handshake, not\n // an application error. Genuine mid-connection (OPEN) errors still reach\n // the owning handler below.\n if (isBenignTeardownError(ws, error)) {\n return;\n }\n\n try {\n await this.#ensureInitialized();\n await runWithoutCurrentAgent(() =>\n this.#capabilityRunner.webSocketError(ws, error)\n );\n } catch (e) {\n console.error(\n `Error in ${this.#parentClassName}:${this.#ctx.id.name ?? \"<unnamed>\"} webSocketError:`,\n e\n );\n }\n }\n\n /**\n * Start lifecycle capabilities and the owning Durable Object.\n *\n * Runtime fetch, alarm, and WebSocket entry points call this automatically.\n * RPC methods may call it explicitly because native RPC bypasses fetch.\n *\n * @param props - Optional properties supplied to capability and host startup.\n */\n async start(props?: Props): Promise<void> {\n if (props !== undefined) this.#props = props;\n await this.#ensureInitialized();\n }\n\n async #ensureInitialized(): Promise<void> {\n if (this.#status === \"started\") return;\n\n if (this.#ctx.id.name === undefined && this.#legacyName === undefined) {\n this.#legacyName = await this.#ctx.storage.get<string>(\n LEGACY_NAME_STORAGE_KEY\n );\n }\n // Fail before host startup if neither native nor migrated identity exists.\n void this.name;\n\n this.#capabilitiesLocked = true;\n let error: unknown;\n await this.#ctx.blockConcurrencyWhile(async () => {\n this.#status = \"starting\";\n try {\n await runWithoutCurrentAgent(() =>\n this.#capabilityRunner.start({ props: this.#props })\n );\n await runInLifecycleHostContext({ host: this.#host }, () =>\n this.#host.onStart?.(this.#props)\n );\n this.#status = \"started\";\n } catch (cause) {\n this.#status = \"zero\";\n error = cause;\n }\n });\n // Re-throw outside blockConcurrencyWhile so the input gate is not\n // permanently broken and a later invocation can retry startup.\n if (error) {\n this.#rearmRequestedDuringStart = false;\n this.#pendingEvents.length = 0;\n throw error;\n }\n this.#deliverPendingEvents();\n if (this.#rearmRequestedDuringStart) {\n this.#rearmRequestedDuringStart = false;\n await this.rearmAlarm();\n }\n }\n\n #legacyName: string | undefined;\n\n /**\n * The name used to address this Durable Object.\n *\n * Native `ctx.id.name` is authoritative. A read-only legacy storage fallback\n * lets objects created by older PartyServer releases migrate without new\n * name writes.\n */\n get name(): string {\n const name = this.#ctx.id.name ?? this.#legacyName;\n if (name !== undefined) return name;\n throw new Error(\n `${this.#parentClassName} could not determine its Durable Object name. ` +\n \"Address it with idFromName() or getByName(). In local development, \" +\n \"update Wrangler/workerd and use a current compatibility_date. \" +\n \"newUniqueId(), idFromString(), and names over 1,024 bytes do not \" +\n \"expose ctx.id.name. Alarms created before 2026-03-15 must be \" +\n \"rescheduled from a named fetch or RPC handler.\"\n );\n }\n\n #props?: Props;\n\n /**\n * The host's scoped access to the Lifecycle work queue. Items pushed here\n * are dispatched to the host's `onJob` inside the host invocation\n * boundary.\n */\n get jobs(): LifecycleJobs {\n return this.#jobsForOwner(HOST_JOB_CAPABILITY);\n }\n\n #jobsForOwner(owner: string): LifecycleJobs {\n const rearmAfter = async <T>(mutate: () => T): Promise<T> => {\n const result = mutate();\n await this.rearmAlarm();\n return result;\n };\n return Object.freeze({\n push: (options: LifecycleJobPushOptions) =>\n rearmAfter(() => this.#jobQueue.push(owner, options)),\n cancel: (id: string) =>\n rearmAfter(() => this.#jobQueue.cancel(owner, id)),\n reschedule: (id: string, time: number) =>\n rearmAfter(() => this.#jobQueue.reschedule(owner, id, time)),\n get: (id: string) => this.#jobQueue.get(owner, id),\n list: () => this.#jobQueue.list(owner),\n rearm: () => this.rearmAlarm()\n });\n }\n\n /**\n * Recompute the physical Durable Object alarm from job-queue state.\n *\n * Concurrent requests are serialized so a later durable-state change cannot\n * be overwritten by an earlier alarm calculation. Queue mutations call this\n * automatically; it stays public for composition roots and tests.\n */\n async rearmAlarm(): Promise<void> {\n if (this.#alarmsDisabled) return;\n if (this.#status === \"starting\") {\n this.#rearmRequestedDuringStart = true;\n return;\n }\n\n const prior = this.#alarmRearmQueue;\n const next = prior\n .catch(() => {})\n .then(async () => {\n if (this.#alarmsDisabled) return;\n const alarm = this.#jobQueue.nextAlarmTime(Date.now());\n if (alarm === null) {\n await this.#ctx.storage.deleteAlarm();\n } else {\n await this.#ctx.storage.setAlarm(alarm);\n }\n });\n this.#alarmRearmQueue = next;\n await next;\n }\n\n /**\n * Keep work a job handed off at a bounded return inside the current\n * alarm's memory-limit breaker domain (#1825). Hosts call this where a\n * queue-driven callback detaches long work and returns.\n *\n * @returns True when called during an alarm invocation; false otherwise.\n */\n trackAlarmWork(work: Promise<unknown>): boolean {\n return this.#jobDriver.trackAlarmWork(work);\n }\n\n /** Dispose installed capabilities in reverse registration order. */\n async dispose(): Promise<void> {\n await runWithoutCurrentAgent(() => this.#capabilityRunner.dispose());\n }\n\n /** Permanently disable and clear alarms during explicit object teardown. */\n async disableAlarms(): Promise<void> {\n this.#alarmsDisabled = true;\n await this.#alarmRearmQueue.catch(() => {});\n await this.#ctx.storage.deleteAlarm();\n }\n\n /**\n * Run one alarm invocation. The job driver owns the event loop — deadman\n * pre-arm, due-job dispatch with retry and deferral policy, the alarm\n * memory-limit circuit breaker (#1825) — and re-arms the physical alarm\n * from queue state. The host's `onAlarm()` runs after due jobs, inside\n * the host invocation boundary.\n */\n async alarm(): Promise<void> {\n await this.#jobDriver.runAlarm(\n () => this.#ensureInitialized(),\n () =>\n runInLifecycleHostContext({ host: this.#host }, async () => {\n await this.#host.onAlarm?.();\n })\n );\n }\n\n /**\n * Resolve a job owner to its dispatch hooks. Host jobs run inside the\n * host invocation boundary; capability jobs run outside ambient host\n * context, like every other capability hook.\n */\n async #resolveJobDispatch(owner: string): Promise<JobDispatch | undefined> {\n if (owner === HOST_JOB_CAPABILITY) {\n const host = this.#host;\n if (!host.onJob) return undefined;\n // No host onJobError: a host job's terminal application failure\n // completes it, and the host re-derives its jobs from durable state.\n return {\n onJob: async (context) =>\n runInLifecycleHostContext({ host }, () => host.onJob!(context))\n };\n }\n const capability = await this.#capabilityRunner.findById(owner);\n if (!capability?.onJob) return undefined;\n return {\n onJob: async (context) =>\n runWithoutCurrentAgent(() => capability.onJob!(context)),\n onJobError: capability.onJobError\n ? async (context, error) =>\n runWithoutCurrentAgent(() => capability.onJobError!(context, error))\n : undefined\n };\n }\n}\n"],"mappings":"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"}