feat(agents): add the browser-sessions Lifecycle capability - #2293
Conversation
|
🟡 agents import sizesMeasured 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.
Compared Changed imports (27)
All 344 current runtime imports
Reported by agent-think[bot]. |
agents
@cloudflare/ai-chat
@cloudflare/codemode
hono-agents
@cloudflare/shell
@cloudflare/think
@cloudflare/voice
@cloudflare/worker-bundler
commit: |
8f31138 to
51cc083
Compare
51cc083 to
4b6da54
Compare
4b6da54 to
c6ad7a1
Compare
75d9e93 to
205d9ef
Compare
205d9ef to
f4369b2
Compare
f4369b2 to
5a6516d
Compare
5a6516d to
0b5b819
Compare
f4369b2 to
6d3972d
Compare
a620a4b to
8c7bdff
Compare
8c7bdff to
fd3feb1
Compare
aron-cf
left a comment
There was a problem hiding this comment.
Took a look, looking good, some inline feedback, some for the API some for lifecycle/capabilities in general.
| 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; | ||
| } |
There was a problem hiding this comment.
Is this needed? Worth checking. I don't think a capability should have to manage rearming the jobs list. /cc @mattzcarey
There was a problem hiding this comment.
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.
fd3feb1 to
b1da548
Compare
29c4b8c to
ffd5bd3
Compare
9c8f9f2 to
e06a252
Compare
|
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 |
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.
46efc63 to
d52258b
Compare
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.API
resolve(name?){ name, sessionId, restarted, createdAt, updatedAt }connect(name?){ name, sessionId, restarted, cdp }close(name?)restarted: truesessions()live/expiredstatus + timestampsliveView(name?, { mode })undefinedwhen unknown, closed, or deadEvery
namedefaults to"default".Why
The engine below leaves a host two chores: supply a store and build its own observability. This capability handles both:
DurableBrowserSessionStoreover the object's own storage. Custom stores still plug in.sessions()lists named browsers.expiredmeans no agent activity for a fullkeep_alivewindow, 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_alivereclaims idle browsers, and the next resolve replaces a lost one withrestarted: true(#2358 removed the earlier host-side sweep).Also in here
browser:retired:<name>marker, which keepsrestartedaccurate.connector.tsto a sharedbrowser/live-view.ts. The connector re-exports the same names.browser-run.tsasisMissingBrowserSessioninstead of being duplicated per caller.Public API impact
None.
BrowserSessionsis 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
capability.ts: options, then the host methods.browser-capability.test.tscover both setups (Agent subclass and plain Durable Object), including that an object with browser sessions has no jobs or alarm.