fix(bot-mode): keep active turns running after viewer detach - #94697
fix(bot-mode): keep active turns running after viewer detach#94697dokterdok wants to merge 2 commits into
Conversation
5d1b55c to
38781f6
Compare
This PR adds a A few technical concerns:
The compression-lineage root lookup is a thoughtful detail — without it, a compressed Bot Chat would lose its background-work policy exactly when long work needs it most. |
|
Thanks for the careful review. I pushed
Validation on the new head: |
2701aa7 to
ae155d5
Compare
ae155d5 to
35b5d16
Compare
Recreates the backend-only portions of NousResearch#94697 commits 8cb3e09 and 35b5d16 against post-NousResearch#96726 main. Explicit interrupt, Stop, session close, and backend shutdown remain authoritative.
35b5d16 to
580ef43
Compare
Recreates the backend-only portions of NousResearch#94697 commits 8cb3e09 and 35b5d16 against post-NousResearch#96726 main. Explicit interrupt, Stop, session close, and backend shutdown remain authoritative.
580ef43 to
72fbcd0
Compare
What does this PR do?
Start a long task in Bot A, then open Bot B or quit Desktop. Nobody pressed
Stop, but current gateway behavior can interrupt Bot A one WebSocket-orphan
grace period later and lose the remaining work.
This makes viewer loss different from Stop. A Bot-owned turn that the backend
already accepted keeps running while the user switches Bots or gateways,
navigates elsewhere, or quits Desktop. Returning from the same or another
client rehydrates its durable Bot Chat history.
Ordinary Sessions keep their existing orphan cleanup. Explicit Stop,
session.interrupt, sidecarclose_on_disconnect, provider/tool limits, andgateway shutdown remain authoritative.
Why the boundary is explicit
The gateway normally interrupts a running session after its final WebSocket
viewer has been gone for the configured grace period. That protects generic
sessions from consuming compute after a killed client, but it contradicts Bot
Mode's backend-resident work contract.
This PR adds an opt-in per-session policy. While an opted-in Bot turn is
running, the orphan reaper preserves it. After the turn settles, the detached
runtime is reclaimed normally.
Related work
explicitly preserves Bot-owned work across viewer loss. Its current head
overlaps three gateway lifecycle files; whichever lands second must preserve
the ordinary-session/Bot-session policy split.
Changes Made
optional
preserve_running_on_disconnectstate.compressed continuation lineage, so older Desktop clients gain direct-Bot
protection.
activate, and submit.
canonical-chat.tsandgroup-turns.tsrequest it for direct Bot Chats andGroup Chat member sessions.
unchanged.
Compatibility
The request field is optional. Older gateways ignore it and retain their
previous disconnect behavior. The continuity guarantee begins on a backend
containing this server policy.
This does not make an app-managed local backend survive termination of its own
process. Persistent hosting is a separate lifecycle boundary.
For a Group Chat, this preserves a member turn already admitted by its gateway.
It does not by itself move room coordination out of Desktop; hosted Group Chat
authority is layered separately.
How to Test
orphan grace period.
the completed timeline is present.
Validation
Post-#96726 head
72fbcd0303onmain7eee066c30:git diff --check: passedReal two-gateway UAT on the integrated field build reproduced the orphan
interruption, then verified navigation-away, Desktop hard-quit, backend
completion, and transcript rehydration with this policy enabled. The current
PR is the narrow exact rebase of that lifecycle boundary; cross-gateway room
coordination remains outside this PR.
The two commits remain independently reviewable: backend lifecycle policy,
then typed Desktop opt-in wiring.