Skip to content

feat(agents): add the browser-sessions Lifecycle capability - #2293

Merged
ben-reitz merged 3 commits into
feat/browser-session-corefrom
feat/browser-lifecycle-capability
Sep 24, 2026
Merged

ben-reitz merged 3 commits into
feat/browser-session-corefrom
feat/browser-lifecycle-capability

Conversation

@ben-reitz

@ben-reitz ben-reitz commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

What this is

The host wiring for the session engine one PR down: BrowserSessions, a Lifecycle capability any Agent subclass or plain Durable Object adds in one line. Internal: not exported for now.

readonly browser = new BrowserSessions({ browser: env.BROWSER });
readonly lifecycle = Lifecycle.install(this).use(this.browser);

await this.browser.resolve("checkout");                   // reattach-or-create
await this.browser.sessions();                            // every name, live/expired + timestamps
await this.browser.liveView("checkout", { mode: "tab" }); // fresh human link, ~5 min to connect

API

new BrowserSessions({
  browser: env.BROWSER, // required: the Browser Rendering binding
  store,                // custom BrowserSessionStore; defaults to one over the object's own storage
  create: {             // reapplied on every create, including restarts
    keepAliveMs,        //   default: the platform max (600s)
    recording,          //   opt into rrweb session recording
    guardrails          //   allowedDomains / allowedDomainSets, fixed at launch
  },
  timeoutMs             // default CDP command timeout for connect()
});
Method Does
resolve(name?) reattach-or-create → { name, sessionId, restarted, createdAt, updatedAt }
connect(name?) resolve + attach a CDP socket → { name, sessionId, restarted, cdp }
close(name?) close the session and delete its browser; the next resolve reports restarted: true
sessions() named sessions that own a browser, with live / expired status + timestamps
liveView(name?, { mode }) fresh human links, or undefined when unknown, closed, or dead

Every name defaults to "default".

Why

The engine below leaves a host two chores: supply a store and build its own observability. This capability handles both:

  • Store: defaults to a DurableBrowserSessionStore over the object's own storage. Custom stores still plug in.
  • Observability, host-only: sessions() lists named browsers. expired means no agent activity for a full keep_alive window, so the platform has most likely reclaimed it. It's a best guess, since Live View activity doesn't update the record. liveView() issues fresh links on every call; they're bearer credentials, so they're never persisted or handed to the model. Issuing a link counts as activity.

It schedules nothing. Browser Run's keep_alive reclaims idle browsers, and the next resolve replaces a lost one with restarted: true (#2358 removed the earlier host-side sweep).

Also in here

Public API impact

None. BrowserSessions is unexported, and the connector's re-exports match the old names exactly. We intend to export it once the API has been proven in real use.

Reviewing

  • Start with capability.ts: options, then the host methods.
  • 10 tests in browser-capability.test.ts cover both setups (Agent subclass and plain Durable Object), including that an object with browser sessions has no jobs or alarm.

@changeset-bot

changeset-bot Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d52258b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@ben-reitz
ben-reitz added this pull request to stack #2295 September 16, 2026 22:31
@agent-think

agent-think Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

🟡 agents import sizes

Measured 344 runtime imports as minified bundles. The primary size is gzip; raw minified size is included for diagnosis. An existing import growing by more than 10% is marked red. This report is informational.

Red Yellow Green Unchanged New Removed
0 26 1 317 0 0

Compared ff32623b with d52258ba. Open workflow run.

Changed imports (27)
Status Import Base gzip Head gzip Delta
🟡 agents/browser#BrowserConnector 50.6 KiB 50.7 KiB +11 B (+0.02%)
🟡 agents/browser#browserScreenshot 36.3 KiB 36.3 KiB +6 B (+0.02%)
🟡 agents/browser#browserExtract 36.3 KiB 36.3 KiB +6 B (+0.02%)
🟡 agents/browser#browserContent 36.3 KiB 36.3 KiB +6 B (+0.02%)
🟡 agents/browser#browserMarkdown 36.3 KiB 36.3 KiB +6 B (+0.02%)
🟡 agents/browser#DEFAULT_EXEC_SWEEP_IDLE_MS 36.0 KiB 36.0 KiB +5 B (+0.01%)
🟡 agents/browser#DEFAULT_SWEEP_IDLE_MS 36.0 KiB 36.0 KiB +5 B (+0.01%)
🟡 agents/browser#runQuickAction 36.0 KiB 36.0 KiB +5 B (+0.01%)
🟡 agents/browser#BrowserRenderingError 36.0 KiB 36.0 KiB +5 B (+0.01%)
🟡 agents/browser#deleteBrowserSession 36.1 KiB 36.1 KiB +5 B (+0.01%)
🟡 agents/browser#listBrowserTargets 36.1 KiB 36.1 KiB +5 B (+0.01%)
🟡 agents/browser#getBrowserRecording 36.2 KiB 36.2 KiB +5 B (+0.01%)
🟡 agents/browser#browserLinks 36.3 KiB 36.3 KiB +5 B (+0.01%)
🟡 agents/browser#createBrowserSession 36.4 KiB 36.4 KiB +5 B (+0.01%)
🟡 agents/browser#connectBrowserSession 37.6 KiB 37.6 KiB +4 B (+0.01%)
🟡 agents/browser#CodemodeRuntime 39.6 KiB 39.6 KiB +3 B (+0.01%)
🟡 agents/browser/tanstack-ai#createBrowserTools 162.9 KiB 162.9 KiB +12 B (+0.01%)
🟡 agents/browser#DurableBrowserSessionStore 36.4 KiB 36.4 KiB +2 B (+0.01%)
🟡 agents/browser#connectUrl 37.7 KiB 37.7 KiB +2 B (+0.01%)
🟡 agents/browser#connectBrowser 37.9 KiB 37.9 KiB +2 B (+0.01%)
🟡 agents/browser#browserPdf 36.3 KiB 36.3 KiB +1 B (+0%)
🟡 agents/browser#browserScrape 36.3 KiB 36.3 KiB +1 B (+0%)
🟡 agents/browser#browserSnapshot 36.3 KiB 36.3 KiB +1 B (+0%)
🟡 agents/browser#CdpSession 37.3 KiB 37.3 KiB +1 B (+0%)
🟡 agents/browser/ai#createBrowserRuntime 147.2 KiB 147.2 KiB +2 B (+0%)
🟡 agents/browser/ai#createBrowserTools 147.2 KiB 147.2 KiB +2 B (+0%)
🟢 agents/browser#loadCdpSpec 36.6 KiB 36.6 KiB -1 B (-0%)
All 344 current runtime imports
Status Import Gzip Raw minified
⚪ agents#__DO_NOT_USE_WILL_BREAK__agentContext 261.1 KiB 1141.0 KiB
⚪ agents#__DO_NOT_USE_WILL_BREAK__withInvocationScope 261.1 KiB 1141.0 KiB
⚪ agents#Agent 261.1 KiB 1141.0 KiB
⚪ agents#AGENT_TOOL_MILESTONE_PART 261.1 KiB 1141.0 KiB
⚪ agents#AGENT_TOOL_PROGRESS_PART 261.1 KiB 1141.0 KiB
⚪ agents#buildAgentPath 261.7 KiB 1143.3 KiB
⚪ agents#buildAgentUrl 261.8 KiB 1143.7 KiB
⚪ agents#callable 261.1 KiB 1141.0 KiB
⚪ agents#camelCaseToKebabCase 261.1 KiB 1141.0 KiB
⚪ agents#createHeaderBasedEmailResolver 261.3 KiB 1141.4 KiB
⚪ agents#DEFAULT_AGENT_STATIC_OPTIONS 261.1 KiB 1141.0 KiB
⚪ agents#DurableObjectOAuthClientProvider 261.1 KiB 1141.0 KiB
⚪ agents#getAgentByName 261.1 KiB 1141.0 KiB
⚪ agents#getCurrentAgent 261.1 KiB 1141.0 KiB
⚪ agents#getSubAgentByName 261.4 KiB 1141.6 KiB
⚪ agents#isDurableObjectCodeUpdateReset 261.1 KiB 1141.0 KiB
⚪ agents#isDurableObjectMemoryLimitReset 261.1 KiB 1141.0 KiB
⚪ agents#isDurableObjectStorageReset 261.1 KiB 1141.0 KiB
⚪ agents#isPlatformTransientError 261.1 KiB 1141.0 KiB
⚪ agents#MCP_SERVER_ID_MAX_LENGTH 261.1 KiB 1141.0 KiB
⚪ agents#MessageType 261.2 KiB 1141.3 KiB
⚪ agents#normalizeServerId 261.1 KiB 1141.0 KiB
⚪ agents#parseSubAgentPath 261.1 KiB 1141.0 KiB
⚪ agents#routeAgentEmail 261.4 KiB 1141.7 KiB
⚪ agents#routeAgentRequest 261.7 KiB 1142.9 KiB
⚪ agents#routeSubAgentRequest 261.3 KiB 1141.5 KiB
⚪ agents#SqlError 261.1 KiB 1141.0 KiB
⚪ agents#StreamingResponse 261.1 KiB 1141.0 KiB
⚪ agents#SUB_PREFIX 261.1 KiB 1141.0 KiB
⚪ agents#unstable_callable 261.2 KiB 1141.2 KiB
⚪ agents/agent-tools#agentTool 112.5 KiB 538.2 KiB
🟡 agents/browser#BrowserConnector 50.7 KiB 177.3 KiB
🟡 agents/browser#browserContent 36.3 KiB 127.4 KiB
🟡 agents/browser#browserExtract 36.3 KiB 127.4 KiB
🟡 agents/browser#browserLinks 36.3 KiB 127.4 KiB
🟡 agents/browser#browserMarkdown 36.3 KiB 127.4 KiB
🟡 agents/browser#browserPdf 36.3 KiB 127.3 KiB
🟡 agents/browser#BrowserRenderingError 36.0 KiB 126.7 KiB
🟡 agents/browser#browserScrape 36.3 KiB 127.4 KiB
🟡 agents/browser#browserScreenshot 36.3 KiB 127.3 KiB
🟡 agents/browser#browserSnapshot 36.3 KiB 127.4 KiB
🟡 agents/browser#CdpSession 37.3 KiB 130.1 KiB
🟡 agents/browser#CodemodeRuntime 39.6 KiB 139.0 KiB
🟡 agents/browser#connectBrowser 37.9 KiB 131.7 KiB
🟡 agents/browser#connectBrowserSession 37.6 KiB 130.8 KiB
🟡 agents/browser#connectUrl 37.7 KiB 130.9 KiB
🟡 agents/browser#createBrowserSession 36.4 KiB 127.7 KiB
🟡 agents/browser#DEFAULT_EXEC_SWEEP_IDLE_MS 36.0 KiB 126.6 KiB
🟡 agents/browser#DEFAULT_SWEEP_IDLE_MS 36.0 KiB 126.6 KiB
🟡 agents/browser#deleteBrowserSession 36.1 KiB 126.9 KiB
🟡 agents/browser#DurableBrowserSessionStore 36.4 KiB 127.6 KiB
🟡 agents/browser#getBrowserRecording 36.2 KiB 127.1 KiB
🟡 agents/browser#listBrowserTargets 36.1 KiB 126.9 KiB
🟢 agents/browser#loadCdpSpec 36.6 KiB 128.3 KiB
🟡 agents/browser#runQuickAction 36.0 KiB 126.6 KiB
🟡 agents/browser/ai#createBrowserRuntime 147.2 KiB 633.5 KiB
🟡 agents/browser/ai#createBrowserTools 147.2 KiB 633.5 KiB
⚪ agents/browser/ai#createQuickActionTools 122.5 KiB 554.3 KiB
🟡 agents/browser/tanstack-ai#createBrowserTools 162.9 KiB 702.4 KiB
⚪ agents/channels#ChannelHost 3.3 KiB 9.1 KiB
⚪ agents/channels#consumeChunks 237 B 321 B
⚪ agents/channels#createUserIdentityStore 1.3 KiB 3.2 KiB
⚪ agents/channels#fallback 155 B 160 B
⚪ agents/channels#fallbackChannel 893 B 1.9 KiB
⚪ agents/channels#fanout 151 B 156 B
⚪ agents/channels#fanoutChannel 875 B 1.9 KiB
⚪ agents/channels#identityKey 178 B 223 B
⚪ agents/channels#isChannelMessageSurface 271 B 452 B
⚪ agents/channels#linkChannelIdentities 113 B 99 B
⚪ agents/channels#matchesPath 110 B 96 B
⚪ agents/channels#routes 307 B 507 B
⚪ agents/channels#UserIdentityConflictError 248 B 335 B
⚪ agents/channels/ai-sdk#createSendMessageTool 112.2 KiB 537.4 KiB
⚪ agents/channels/ai-sdk#toChannelChunks 112.5 KiB 538.4 KiB
⚪ agents/channels/email#email 23.5 KiB 75.4 KiB
⚪ agents/channels/email#inboundEmail 22.3 KiB 72.3 KiB
⚪ agents/channels/slack#slack 5.5 KiB 14.6 KiB
⚪ agents/channels/slack#slackWebhook 2.2 KiB 5.1 KiB
⚪ agents/channels/tanstack-ai#createSendMessageTool 16.2 KiB 68.4 KiB
⚪ agents/channels/telegram#telegram 3.8 KiB 10.3 KiB
⚪ agents/channels/telegram#telegramWebhook 1.6 KiB 3.6 KiB
⚪ agents/channels/voice#browserVoice 1010 B 2.2 KiB
⚪ agents/chat#AbortRegistry 2.5 KiB 8.9 KiB
⚪ agents/chat#AGENT_TOOL_STREAM_PROGRESS_BUMP_THROTTLE_MS 2.3 KiB 8.2 KiB
⚪ agents/chat#AgentToolProgressEmitter 2.7 KiB 9.5 KiB
⚪ agents/chat#AgentToolStreamProgressThrottle 2.4 KiB 8.3 KiB
⚪ agents/chat#aiSdkRecoveryCodec 2.3 KiB 8.2 KiB
⚪ agents/chat#applyAgentToolEvent 3.2 KiB 11.0 KiB
⚪ agents/chat#applyChunkToParts 2.3 KiB 8.2 KiB
⚪ agents/chat#applyToolUpdate 2.4 KiB 8.4 KiB
⚪ agents/chat#AutoContinuationController 2.3 KiB 8.2 KiB
⚪ agents/chat#awaitWithDeadline 2.4 KiB 8.4 KiB
⚪ agents/chat#broadcastTransition 3.2 KiB 11.6 KiB
⚪ agents/chat#buildChatRecoveringFrame 2.4 KiB 8.4 KiB
⚪ agents/chat#buildInClauseStrings 2.4 KiB 8.4 KiB
⚪ agents/chat#bumpChatRecoveryProgress 2.4 KiB 8.3 KiB
⚪ agents/chat#byteLength 2.5 KiB 8.5 KiB
⚪ agents/chat#CHAT_LAST_TERMINAL_KEY 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_MESSAGE_TYPES 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_RECOVERING_FLAG_TTL_MS 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_RECOVERING_KEY 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_RECOVERY_ALARM_DEBOUNCE_MS 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_RECOVERY_INCIDENT_KEY_PREFIX 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_RECOVERY_INCIDENT_TTL_MS 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_RECOVERY_PROGRESS_KEY 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_RECOVERY_STABLE_RETRY_DELAY_SECONDS 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_RECOVERY_TASK_NAME 2.3 KiB 8.2 KiB
⚪ agents/chat#CHAT_STREAM_PROGRESS_CREDIT_THROTTLE_MS 2.3 KiB 8.2 KiB
⚪ agents/chat#ChatRecoveryEngine 4.5 KiB 15.5 KiB
⚪ agents/chat#chatRecoveryTaskRunOptions 2.4 KiB 8.6 KiB
⚪ agents/chat#ChatStreamStalledError 2.4 KiB 8.3 KiB
⚪ agents/chat#classifyAgentToolChildRecovery 2.4 KiB 8.5 KiB
⚪ agents/chat#clearChatTerminal 2.3 KiB 8.3 KiB
⚪ agents/chat#clientResolvableToolNames 2.3 KiB 8.3 KiB
⚪ agents/chat#ContinuationState 2.7 KiB 9.8 KiB
⚪ agents/chat#createAgentToolEventState 2.3 KiB 8.3 KiB
⚪ agents/chat#createChatFiberSnapshot 2.5 KiB 8.6 KiB
⚪ agents/chat#createChatRecoveryTaskDefinition 2.6 KiB 9.0 KiB
⚪ agents/chat#createChatStreams 6.4 KiB 22.1 KiB
⚪ agents/chat#createChatTurnTaskDefinition 2.7 KiB 8.9 KiB
⚪ agents/chat#createToolsFromClientSchemas 114.3 KiB 545.4 KiB
⚪ agents/chat#crossMessageToolResultUpdate 2.4 KiB 8.6 KiB
⚪ agents/chat#DEFAULT_CHAT_RECOVERY_MAX_ATTEMPTS 2.3 KiB 8.2 KiB
⚪ agents/chat#DEFAULT_CHAT_RECOVERY_MAX_OOM_RETRIES 2.3 KiB 8.2 KiB
⚪ agents/chat#DEFAULT_CHAT_RECOVERY_MAX_WORK 2.3 KiB 8.2 KiB
⚪ agents/chat#DEFAULT_CHAT_RECOVERY_NO_PROGRESS_TIMEOUT_MS 2.3 KiB 8.2 KiB
⚪ agents/chat#DEFAULT_CHAT_RECOVERY_STABLE_TIMEOUT_MS 2.3 KiB 8.2 KiB
⚪ agents/chat#DEFAULT_CHAT_RECOVERY_TERMINAL_MESSAGE 2.4 KiB 8.3 KiB
⚪ agents/chat#dispatchChatRecoveryToHandoff 3.0 KiB 9.9 KiB
⚪ agents/chat#drainInteractionApplies 2.3 KiB 8.3 KiB
⚪ agents/chat#enforceRowSizeLimit 3.5 KiB 11.2 KiB
⚪ agents/chat#hasIncompleteToolBatch 2.4 KiB 8.6 KiB
⚪ agents/chat#interceptAgentToolBroadcast 2.5 KiB 8.7 KiB
⚪ agents/chat#isPlatformFailure 2.6 KiB 8.9 KiB
⚪ agents/chat#isReplayChunk 2.4 KiB 8.7 KiB
⚪ agents/chat#iterateWithStallWatchdog 2.6 KiB 8.8 KiB
⚪ agents/chat#KV_DELETE_MAX_KEYS 2.3 KiB 8.2 KiB
⚪ agents/chat#listActiveChatRecoveryIncidents 2.4 KiB 8.4 KiB
⚪ agents/chat#MAX_BOUND_PARAMS 2.3 KiB 8.2 KiB
⚪ agents/chat#MessageType 2.4 KiB 9.0 KiB
⚪ agents/chat#normalizeToolInput 2.3 KiB 8.2 KiB
⚪ agents/chat#parseProtocolMessage 2.5 KiB 9.0 KiB
⚪ agents/chat#partAwaitsClientInteraction 2.4 KiB 8.6 KiB
⚪ agents/chat#pausedExecutionUpdate 2.4 KiB 8.4 KiB
⚪ agents/chat#pendingChatTerminal 2.3 KiB 8.3 KiB
⚪ agents/chat#persistReconstructedOrphan 3.1 KiB 11.0 KiB
⚪ agents/chat#PreStreamTurns 2.6 KiB 9.3 KiB
⚪ agents/chat#readChatRecoveryProgress 2.3 KiB 8.3 KiB
⚪ agents/chat#reconcileMessages 2.8 KiB 9.6 KiB
⚪ agents/chat#reconcileOrphanPartial 2.4 KiB 8.5 KiB
⚪ agents/chat#recordChatTerminal 2.4 KiB 8.3 KiB
⚪ agents/chat#repairInterruptedToolParts 2.6 KiB 9.1 KiB
⚪ agents/chat#resolveChatRecoveryConfig 2.6 KiB 8.9 KiB
⚪ agents/chat#resolveToolMergeId 2.4 KiB 8.5 KiB
⚪ agents/chat#ResumableStream 5.2 KiB 17.3 KiB
⚪ agents/chat#ResumeHandshake 3.0 KiB 10.4 KiB
⚪ agents/chat#ROW_MAX_BYTES 2.3 KiB 8.2 KiB
⚪ agents/chat#runChatRecoveryExhaustion 2.6 KiB 8.9 KiB
⚪ agents/chat#sanitizeMessage 2.5 KiB 8.8 KiB
⚪ agents/chat#sendIfOpen 2.4 KiB 8.4 KiB
⚪ agents/chat#setChatRecovering 2.5 KiB 8.5 KiB
⚪ agents/chat#shouldCreditStreamProgress 2.4 KiB 8.3 KiB
⚪ agents/chat#STREAM_RESUME_NONE_REASONS 2.3 KiB 8.2 KiB
⚪ agents/chat#StreamAccumulator 2.9 KiB 10.7 KiB
⚪ agents/chat#StreamProgressCreditThrottle 2.4 KiB 8.3 KiB
⚪ agents/chat#SubmitConcurrencyController 2.9 KiB 10.3 KiB
⚪ agents/chat#sweepStaleChatRecoveryIncidents 2.4 KiB 8.5 KiB
⚪ agents/chat#TextSegmentJoiner 2.7 KiB 9.2 KiB
⚪ agents/chat#TIMED_OUT 2.3 KiB 8.2 KiB
⚪ agents/chat#toolApprovalUpdate 2.4 KiB 8.5 KiB
⚪ agents/chat#toolPartHasSettledResult 2.3 KiB 8.4 KiB
⚪ agents/chat#toolResultUpdate 2.4 KiB 8.5 KiB
⚪ agents/chat#truncateOlderMessages 3.2 KiB 10.5 KiB
⚪ agents/chat#truncateOlderToolResults 3.3 KiB 10.9 KiB
⚪ agents/chat#TurnQueue 2.6 KiB 9.2 KiB
⚪ agents/chat#unwrapChatFiberSnapshot 2.4 KiB 8.5 KiB
⚪ agents/chat#wrapChatFiberSnapshot 2.3 KiB 8.2 KiB
⚪ agents/chat-sdk#ChatSdkStateAdapter 263.5 KiB 1152.6 KiB
⚪ agents/chat-sdk#ChatSdkStateAgent 262.8 KiB 1150.0 KiB
⚪ agents/chat-sdk#createChatSdkState 263.5 KiB 1152.6 KiB
⚪ agents/chat-sdk#defaultKeyShard 261.2 KiB 1141.2 KiB
⚪ agents/chat-sdk#defaultThreadShard 261.1 KiB 1141.0 KiB
⚪ agents/chat/react#detectToolsRequiringConfirmation 3.3 KiB 8.3 KiB
⚪ agents/chat/react#extractClientToolSchemas 3.2 KiB 8.3 KiB
⚪ agents/chat/react#getAgentMessages 3.4 KiB 8.6 KiB
⚪ agents/chat/react#getToolApproval 3.1 KiB 8.0 KiB
⚪ agents/chat/react#getToolCallId 3.1 KiB 8.0 KiB
⚪ agents/chat/react#getToolInput 3.1 KiB 8.0 KiB
⚪ agents/chat/react#getToolOutput 3.1 KiB 8.0 KiB
⚪ agents/chat/react#getToolPartState 3.2 KiB 8.2 KiB
⚪ agents/chat/react#useAgentChat 133.5 KiB 611.6 KiB
⚪ agents/chat/react#WebSocketChatTransport 6.2 KiB 18.7 KiB
⚪ agents/chat/transport#WebSocketChatTransport 3.3 KiB 10.7 KiB
⚪ agents/client#AgentClient 21.8 KiB 75.2 KiB
⚪ agents/client#AgentConnectionError 16.3 KiB 57.8 KiB
⚪ agents/client#agentFetch 19.7 KiB 69.0 KiB
⚪ agents/client#createStubProxy 16.4 KiB 57.8 KiB
⚪ agents/client#DEFAULT_CALL_TIMEOUT_MS 16.2 KiB 57.6 KiB
⚪ agents/client#isTerminalCloseEvent 16.3 KiB 57.6 KiB
⚪ agents/client#nativeCall 16.5 KiB 58.3 KiB
⚪ agents/client#NativeCallQueue 16.7 KiB 58.9 KiB
⚪ agents/client#splitCallOptions 16.3 KiB 57.7 KiB
⚪ agents/context#AgentContextProvider 412 B 792 B
⚪ agents/context#AgentSearchProvider 640 B 1.3 KiB
⚪ agents/context#ContextBlocks 87.4 KiB 429.7 KiB
⚪ agents/email#createAddressBasedEmailResolver 193 B 227 B
⚪ agents/email#createCatchAllEmailResolver 110 B 97 B
⚪ agents/email#createHeaderBasedEmailResolver 334 B 492 B
⚪ agents/email#createSecureReplyEmailResolver 718 B 1.3 KiB
⚪ agents/email#DEFAULT_MAX_AGE_SECONDS 56 B 39 B
⚪ agents/email#isAutoReplyEmail 201 B 249 B
⚪ agents/email#signAgentHeaders 424 B 812 B
⚪ agents/experimental/webmcp#registerWebMcp 85.2 KiB 295.8 KiB
⚪ agents/lifecycle#getCurrentAgent 376 B 798 B
⚪ agents/lifecycle#Lifecycle 8.4 KiB 26.1 KiB
⚪ agents/lifecycle#LifecycleCapability 497 B 999 B
⚪ agents/mcp#createLegacyMcpHandler 378.6 KiB 1583.3 KiB
⚪ agents/mcp#createMcpHandler 390.9 KiB 1628.5 KiB
⚪ agents/mcp#DurableObjectEventStore 345.1 KiB 1441.8 KiB
⚪ agents/mcp#ElicitRequestSchema 345.1 KiB 1441.8 KiB
⚪ agents/mcp#experimental_createMcpHandler 378.7 KiB 1583.6 KiB
⚪ agents/mcp#getMcpAuthContext 345.1 KiB 1441.9 KiB
⚪ agents/mcp#MCP_SERVER_ID_MAX_LENGTH 345.1 KiB 1441.9 KiB
⚪ agents/mcp#McpAgent 345.1 KiB 1441.8 KiB
⚪ agents/mcp#normalizeServerId 345.1 KiB 1441.8 KiB
⚪ agents/mcp#RPC_DO_PREFIX 345.1 KiB 1441.8 KiB
⚪ agents/mcp#RPCClientTransport 345.1 KiB 1441.8 KiB
⚪ agents/mcp#RPCServerTransport 345.1 KiB 1441.8 KiB
⚪ agents/mcp#SSEEdgeClientTransport 345.2 KiB 1442.1 KiB
⚪ agents/mcp#StreamableHTTPEdgeClientTransport 345.2 KiB 1442.1 KiB
⚪ agents/mcp#WorkerTransport 348.5 KiB 1458.7 KiB
⚪ agents/mcp/client#getNamespacedData 62.9 KiB 240.0 KiB
⚪ agents/mcp/client#MCP_SERVER_ID_MAX_LENGTH 62.9 KiB 239.9 KiB
⚪ agents/mcp/client#MCPClientManager 158.6 KiB 702.6 KiB
⚪ agents/mcp/client#normalizeServerId 63.0 KiB 240.2 KiB
⚪ agents/mcp/do-oauth-client-provider#DurableObjectOAuthClientProvider 2.1 KiB 6.6 KiB
⚪ agents/mcp/server#createMcpHandler 80.5 KiB 307.2 KiB
⚪ agents/mcp/server#getMcpAuthContext 64.0 KiB 245.5 KiB
⚪ agents/observability#channels 259 B 549 B
⚪ agents/observability#genericObservability 470 B 1.2 KiB
⚪ agents/observability#subscribe 324 B 668 B
⚪ agents/observability/ai#wrapAISDK 8.8 KiB 30.5 KiB
⚪ agents/queue#Queue 3.1 KiB 9.6 KiB
⚪ agents/react#_testUtils 19.3 KiB 66.4 KiB
⚪ agents/react#useAgent 27.1 KiB 89.9 KiB
⚪ agents/react#useAgentToolEvents 21.1 KiB 73.7 KiB
⚪ agents/routing#getAgentByName 795 B 1.7 KiB
⚪ agents/routing#routeAgentRequest 1.6 KiB 3.6 KiB
⚪ agents/routing#RoutedAgents 2.4 KiB 6.2 KiB
⚪ agents/schedule#getSchedulePrompt 85.8 KiB 424.7 KiB
⚪ agents/schedule#scheduleSchema 85.3 KiB 423.6 KiB
⚪ agents/schedule#unstable_getSchedulePrompt 85.9 KiB 424.9 KiB
⚪ agents/schedule#unstable_scheduleSchema 85.3 KiB 423.6 KiB
⚪ agents/schedules#Scheduler 6.8 KiB 22.0 KiB
⚪ agents/schedules/parser#getSchedulePrompt 85.8 KiB 424.7 KiB
⚪ agents/schedules/parser#scheduleSchema 85.3 KiB 423.6 KiB
⚪ agents/sessions#COMPACTION_PREFIX 147 B 160 B
⚪ agents/sessions#createCompactFunction 1.7 KiB 4.0 KiB
⚪ agents/sessions#isCompactionMessage 177 B 200 B
⚪ agents/sessions#Session 2.0 KiB 6.3 KiB
⚪ agents/sessions#Sessions 9.6 KiB 34.3 KiB
⚪ agents/skills#fromManifest 309.8 KiB 1084.0 KiB
⚪ agents/skills#parseSkillFrontmatter 328.4 KiB 1146.2 KiB
⚪ agents/skills#parseSkillMarkdown 328.6 KiB 1146.5 KiB
⚪ agents/skills#r2 330.2 KiB 1150.4 KiB
⚪ agents/skills#runner 369.0 KiB 1297.8 KiB
⚪ agents/skills#SkillRegistry 416.4 KiB 1581.7 KiB
⚪ agents/skills/compile#compileSkillScript 15.4 KiB 43.4 KiB
⚪ agents/skills/compile#isCompilableSkillScript 15.4 KiB 43.3 KiB
⚪ agents/state#State 1.1 KiB 2.4 KiB
⚪ agents/streams#DEFAULT_MAX_CHUNK_BYTES 94 B 96 B
⚪ agents/streams#sseResponse 857 B 1.6 KiB
⚪ agents/streams#StreamClosedError 175 B 212 B
⚪ agents/streams#StreamNotFoundError 215 B 276 B
⚪ agents/streams#Streams 4.3 KiB 13.9 KiB
⚪ agents/streams#StreamSerializationError 171 B 201 B
⚪ agents/tasks#DuplicateTaskStepError 328 B 463 B
⚪ agents/tasks#MAX_SERIALIZED_BYTES 190 B 232 B
⚪ agents/tasks#MissingTaskDefinitionError 358 B 536 B
⚪ agents/tasks#NonRetryableError 238 B 308 B
⚪ agents/tasks#TaskReplayDivergedError 341 B 483 B
⚪ agents/tasks#Tasks 8.9 KiB 31.8 KiB
⚪ agents/tasks#TaskSerializationError 258 B 339 B
⚪ agents/types#MessageType 211 B 365 B
⚪ agents/vite#default 353.8 KiB 1356.1 KiB
⚪ agents/voice#addSFUTracks 324 B 424 B
⚪ agents/voice#createSFUSession 255 B 306 B
⚪ agents/voice#createSFUWebSocketAdapter 331 B 429 B
⚪ agents/voice#decodeVarint 157 B 160 B
⚪ agents/voice#downsample48kStereoTo16kMono 238 B 324 B
⚪ agents/voice#encodePayloadToProtobuf 189 B 279 B
⚪ agents/voice#encodeVarint 129 B 122 B
⚪ agents/voice#extractPayloadFromProtobuf 271 B 425 B
⚪ agents/voice#iterateText 1.6 KiB 3.8 KiB
⚪ agents/voice#renegotiateSFUSession 329 B 428 B
⚪ agents/voice#SentenceChunker 550 B 1.1 KiB
⚪ agents/voice#sfuFetch 294 B 358 B
⚪ agents/voice#upsample16kMonoTo48kStereo 211 B 272 B
⚪ agents/voice#VOICE_PROTOCOL_VERSION 51 B 31 B
⚪ agents/voice#withVoice 9.5 KiB 32.7 KiB
⚪ agents/voice#withVoiceInput 4.8 KiB 16.0 KiB
⚪ agents/voice#WorkersAIFluxSTT 1.5 KiB 4.3 KiB
⚪ agents/voice#WorkersAINova3STT 1.6 KiB 4.3 KiB
⚪ agents/voice#WorkersAITTS 682 B 1.4 KiB
⚪ agents/voice/client#VOICE_PROTOCOL_VERSION 473 B 768 B
⚪ agents/voice/client#VoiceClient 10.1 KiB 31.6 KiB
⚪ agents/voice/client#WebSocketVoiceTransport 4.6 KiB 13.3 KiB
⚪ agents/voice/errors#logVoiceError 132 B 173 B
⚪ agents/voice/errors#toVoiceError 94 B 80 B
⚪ agents/voice/errors#voiceErrorMessage 125 B 111 B
⚪ agents/voice/errors#VoiceProviderError 190 B 345 B
⚪ agents/voice/react#useVoiceAgent 13.6 KiB 42.5 KiB
⚪ agents/voice/react#useVoiceInput 13.3 KiB 41.4 KiB
⚪ agents/voice/react#WebSocketVoiceTransport 7.4 KiB 21.3 KiB
⚪ agents/voice/sfu#addSFUTracks 323 B 424 B
⚪ agents/voice/sfu#createSFUSession 254 B 306 B
⚪ agents/voice/sfu#createSFUWebSocketAdapter 329 B 429 B
⚪ agents/voice/sfu#decodeVarint 155 B 160 B
⚪ agents/voice/sfu#downsample48kStereoTo16kMono 236 B 324 B
⚪ agents/voice/sfu#encodePayloadToProtobuf 188 B 279 B
⚪ agents/voice/sfu#encodeVarint 129 B 122 B
⚪ agents/voice/sfu#extractPayloadFromProtobuf 270 B 425 B
⚪ agents/voice/sfu#renegotiateSFUSession 329 B 428 B
⚪ agents/voice/sfu#sfuFetch 292 B 358 B
⚪ agents/voice/sfu#upsample16kMonoTo48kStereo 209 B 272 B
⚪ agents/voice/text#iterateText 1.6 KiB 3.8 KiB
⚪ agents/voice/text#SentenceChunker 549 B 1.1 KiB
⚪ agents/voice/types#VOICE_PROTOCOL_VERSION 51 B 31 B
⚪ agents/voice/workers-ai#WorkersAIFluxSTT 1.5 KiB 4.3 KiB
⚪ agents/voice/workers-ai#WorkersAINova3STT 1.6 KiB 4.3 KiB
⚪ agents/voice/workers-ai#WorkersAITTS 682 B 1.4 KiB
⚪ agents/websockets#CAPNWEB_TRANSPORT_QUERY 12.4 KiB 43.3 KiB
⚪ agents/websockets#CAPNWEB_TRANSPORT_VALUE 12.4 KiB 43.3 KiB
⚪ agents/websockets#capnWebTransportUrl 12.5 KiB 43.5 KiB
⚪ agents/websockets#CF_NO_PROTOCOL_KEY 12.4 KiB 43.3 KiB
⚪ agents/websockets#CF_READONLY_KEY 12.4 KiB 43.3 KiB
⚪ agents/websockets#isCapnWebTransportUpgrade 12.5 KiB 43.4 KiB
⚪ agents/websockets#registerInternalConnectionKeys 12.4 KiB 43.4 KiB
⚪ agents/websockets#WebSockets 20.0 KiB 69.3 KiB
⚪ agents/workflows#AgentWorkflow 262.4 KiB 1145.7 KiB
⚪ agents/workflows#WorkflowRejectedError 261.2 KiB 1141.2 KiB
⚪ agents/x402#normalizeNetwork 14.7 KiB 61.1 KiB
⚪ agents/x402#withX402 23.0 KiB 89.2 KiB
⚪ agents/x402#withX402Client 104.1 KiB 346.5 KiB

Reported by agent-think[bot].

@pkg-pr-new

pkg-pr-new Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@2293

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@2293

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@2293

hono-agents

npm i https://pkg.pr.new/hono-agents@2293

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@2293

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@2293

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@2293

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@2293

commit: d52258b

@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from 8f31138 to 51cc083 Compare September 17, 2026 00:00
@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from 51cc083 to 4b6da54 Compare September 17, 2026 00:16
@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from 4b6da54 to c6ad7a1 Compare September 17, 2026 09:43
@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch 2 times, most recently from 75d9e93 to 205d9ef Compare September 17, 2026 13:52
@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from 205d9ef to f4369b2 Compare September 17, 2026 14:46
@ben-reitz
ben-reitz removed this pull request from stack #2295 September 18, 2026 09:51
@ben-reitz
ben-reitz changed the base branch from feat/browser-named-sessions to feat/browser-session-core September 18, 2026 10:04
@ben-reitz
ben-reitz added this pull request to stack #2303 September 18, 2026 10:04
@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from f4369b2 to 5a6516d Compare September 18, 2026 10:46
@ben-reitz
ben-reitz marked this pull request as ready for review September 18, 2026 10:49
devin-ai-integration[bot]

This comment was marked as resolved.

@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from 5a6516d to 0b5b819 Compare September 18, 2026 12:27
@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch 2 times, most recently from f4369b2 to 6d3972d Compare September 19, 2026 15:02
devin-ai-integration[bot]

This comment was marked as resolved.

@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch 2 times, most recently from a620a4b to 8c7bdff Compare September 21, 2026 08:58
devin-ai-integration[bot]

This comment was marked as resolved.

@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from 8c7bdff to fd3feb1 Compare September 21, 2026 09:20

@aron-cf aron-cf left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a look, looking good, some inline feedback, some for the API some for lifecycle/capabilities in general.

Comment on lines +116 to +122
if (this.lifecycle.jobs.get(BROWSER_SWEEP_JOB_ID)) {
// The row is durable but the physical alarm may not be: a prior life
// can die between the row write and `setAlarm`. Like Scheduler and
// Tasks, recover it explicitly (deferred until startup completes).
await this.lifecycle.jobs.rearm();
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed? Worth checking. I don't think a capability should have to manage rearming the jobs list. /cc @mattzcarey

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should follow up on this as the general point here still stands - lifecycle should own the rearm on startup rather than requiring capabilities to do this. I looked into it a bit and it seems like there are ways that an alarm can go missing and solving that should live in the lifecycle startup.

It's not relevant for this PR though anymore as i've overhauled the capability so that it's no longer got any hooks or schedules.

Comment thread packages/agents/src/browser/capability.ts Outdated
Comment thread packages/agents/src/browser/capability.ts Outdated
Comment thread packages/agents/src/browser/live-view.ts Outdated
Comment thread packages/agents/src/browser/capability.ts Outdated
@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from fd3feb1 to b1da548 Compare September 21, 2026 15:55
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@ben-reitz

Copy link
Copy Markdown
Contributor Author

I've removed the sweep entirely (#2358, now merged into this PR).

@aron-cf's comments on rearming and on moving cleanup into the Scheduler made me think more about whether the sweep needed to exist at all. Browser Run's keep_alive already deletes a browser after 10 minutes without activity, and resolve() already detects a missing browser and replaces it with restarted: true. The sweep was kind of duplicating the platform's job a second time, and most of this file existed only to keep it running reliably.

ben-reitz and others added 3 commits September 24, 2026 14:22
BrowserSessions (capability id "browser") packages the named-session core
for Lifecycle hosts — Agent subclasses and plain Durable Objects alike:

- auto-supplies a DurableBrowserSessionStore over the host's own storage
  (custom stores still pluggable; list-less stores sweep manually)
- schedules the idle sweep through the Lifecycle job queue, armed only
  while sessions or tombstones exist, with onStart crash recovery
- host-only observability: sessions() views and liveView() links minted
  fresh per call from a live target listing, never persisted

Live View vocabulary (mode, URL shapes, TTL, minting) moves to
browser/live-view.ts; connector.ts re-exports it unchanged. The shared
isMissingBrowserSession judgment moves into browser-run.ts.
…ons (#2358)

* refactor(agents): let Browser Run keep_alive reclaim idle named sessions

Drop the scheduled sweep from BrowserSessions. Browser Run already deletes
a browser once keep_alive elapses without activity, and resolve() already
detects that loss and replaces the browser with restarted: true, so the
sweep only duplicated platform behavior while waking otherwise idle
objects.

- BrowserSessions schedules nothing: no sweep job, no onStart/onJob/
  onJobError hooks, no sweepIdleMs, no manual sweep().
- close() and dead-session recovery move the record to its
  browser:retired: marker under the name's lock instead of leaving a
  tombstone, so listing named sessions yields only live records.
- sessions() reports "live" or "expired" from updatedAt versus
  keep_alive; closed names are no longer listed.
- NamedBrowserSessions drops sweep(), tombstone pruning, and the
  in-memory activity map; activity touches stay, capped at half the
  keep-alive window, so status stays accurate.

* refactor(agents): expose named sessions through a lazy private getter

* fix(agents): read restart evidence when a named session commits

A resolve that found the name unused checked for the retired marker before its Browser Run create, then committed whenever the key was empty. If another resolver created and closed the name during that create, the commit returned restarted: false even though the name had already lost a browser. Retired markers are permanent, so reading the marker under the commit lock always sees such a close.
@ben-reitz
ben-reitz force-pushed the feat/browser-lifecycle-capability branch from 46efc63 to d52258b Compare September 24, 2026 13:22
@ben-reitz
ben-reitz merged commit ad890ff into main Sep 24, 2026
16 checks passed
@ben-reitz
ben-reitz deleted the feat/browser-lifecycle-capability branch September 24, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants