fix: keep the agent bridge alive while tasks are running (v0.6.9) - #49
Open
luyang950 wants to merge 2 commits into
Open
fix: keep the agent bridge alive while tasks are running (v0.6.9)#49luyang950 wants to merge 2 commits into
luyang950 wants to merge 2 commits into
Conversation
Generating two documents in a row could leave the first one spinning forever. ensureBridgeForCwd closes the current bridge client whenever the requested working directory differs from the running one, and the working directory two callers ask for is not the same: Generate with noProject resolves to the app workspace, while ensureBridge (ListImageTemplates, GetCapabilities, the PPTist planner) resolves to the active project. Any of those calls therefore killed the child process mid-task, and because Client.Stop only fails pending RPCs -- task/invoke has already returned "running" by then -- the task never received a terminal event and stayed `running` in the local store for good. - retireBridge parks a replaced client that still has work in flight, keeping its process and listeners alive until its last task finishes, instead of killing it. A grace timer bounds the parking lot. - Client tracks the tasks it still owes an answer for and synthesizes task.failed for them when the process goes away, whether that is Stop, Close, or an unexpected exit. Interactive waits do not count: stale respond recovery replays those against a fresh process. - Metadata-only calls reuse whichever client is connected rather than resolving a working directory of their own. - A workspace-only settings change now retires the bridge instead of closing it; binary, provider and proxy changes still close it, but now report the interrupted tasks as failed. - Startup marks tasks left `running` by a previous session as failed. No bridge child survives a restart, so those cards could only ever spin. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hotfix released as v0.6.9, branched from v0.6.8. Merging it back so
maincarries the fix.The bug
Generating two documents in a row could leave the first one spinning forever.
ensureBridgeForCwdcloses the current bridge client whenever the requested working directory differs from the running one, and two callers disagree about that directory:GeneratewithnoProjectresolves to the app workspace, whileensureBridge(ListImageTemplates,GetCapabilities, the PPTist planner) resolves to the active project. Either one therefore killed the child process mid-task, and sinceClient.Stoponly fails pending RPCs —task/invokehas already returnedrunningby then — the task never got a terminal event and stayedrunningin the local store for good.Reproduced on the shipped 0.6.8 build: three image tasks 10s apart, the first two stuck at
generate_llmwith no further events, the third (nothing started after it) completed normally. Only oneofficecli agent-bridgeprocess was left alive, started at the third task's timestamp.The fix
retireBridgeparks a replaced client that still has work in flight, keeping its process and listeners alive until its last task finishes. A grace timer bounds the parking lot.bridge.Clienttracks the tasks it still owes an answer for and synthesizestask.failedfor them when the process goes away —Stop,Close, or an unexpected exit. Interactive waits (task.question/task.plan) do not count: stale-respond recovery replays those against a fresh process.runningby a previous session as failed. No bridge child survives a restart, so those cards could only ever spin.This also covers quitting the app or changing settings mid-generation, which used to leave the same permanently-running rows.
Testing
internal/bridge/client_stranded_test.goandapp_bridge_retire_test.go, mutation-checked: revertingretireBridgeto an unconditionalClose()failsTestRetireBridgeKeepsTaskRunningUntilItFinishes, and droppingfailStrandedTasksfromStopfailsTestCloseReportsStrandedTasksAsFailed.go test ./...green under both build tags, 479 renderer tests green,tsc --noEmitclean.Also on
develop/1.0viafix/bridge-task-lifecycle.🤖 Generated with Claude Code