reconcile provider session state and settle stuck turns#2666
reconcile provider session state and settle stuck turns#2666justsomelegs wants to merge 15 commits into
Conversation
|
React Review found Copy prompt for agentReviewed by react-review for commit d2742fc. Configure here. |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Needs human review This PR introduces new runtime behavior for reconciling provider session state on startup and automatically settling stuck turns when sessions become inactive. These changes affect startup flow and turn state management across multiple layers, representing a new capability rather than a simple fix. You can customize Macroscope's approvability policy. Learn more. |
|
@justsomelegs I've built and ran dist:desktop:dmg version and it still hangs on waiting, while the session on opencode is completed
but I am able to end a chat session now so I think your change only fixed a local state of event cycle ingestion
|
|
@eersnington it was subscribing to the wrong event stream as the client.subscribe.event() has been broken upstream and the current fix it to subscribe to the global.event.subscribe() method made the change and it should now work. |
|
tbh as its an upstream issue it will most likley be fixed as the client event stream seems to just drop after the |


What Changed
Fixes several provider session / turn lifecycle cases where T3 Code could leave a thread in the wrong state after provider runtime events, interrupts, stop failures, or server restart.
Main changes:
Treat active
turn.completedevents as lifecycle-ending events:readyerroractiveTurnIdis clearedTreat active
turn.abortedevents as lifecycle-ending events:readyactiveTurnIdis clearedIgnore completion/abort events for non-active turns so auxiliary provider work, like OpenCode title generation, does not incorrectly stop the main running turn.
Reconcile projected running sessions on server startup:
Make
thread.session.stopnon-destructive on provider stop failure:lastErrorPreserve failed turn state in server and web projections:
errorsettle the latest running turn aserrorinterruptedFix OpenCode adapter interrupt handling:
readyturn.abortedeventWhy
A few different provider lifecycle paths were being treated too loosely.
The main symptom was that a thread could stay stuck as “working” even after the provider had already finished, aborted, or lost the active session. This was especially visible with OpenCode, but the underlying fixes are in shared provider orchestration and projection code, so they apply more broadly than just OpenCode.
This approach keeps the existing event model, but makes the lifecycle rules stricter:
Fixes #2644
Fixes #2633
Fixes #2573
UI Changes
No UI changes.
Testing
bun run test src/orchestration/Layers/ProviderRuntimeIngestion.test.ts src/orchestration/Layers/ProjectionPipeline.test.ts src/orchestration/Layers/ProviderCommandReactor.test.ts src/provider/Layers/OpenCodeAdapter.test.tsbun run test src/store.test.tsbun fmtbun lintbun typecheckbun lintpasses with existing unrelated warnings.Checklist
Note
Reconcile provider session state and settle stuck running turns on session transitions
reconcileStaleRunningSessionstoProviderCommandReactorthat runs on startup, comparing projected 'running' sessions against live provider sessions and marking stale ones as 'stopped' with cleared active turnProjectionPipelineand the webstorereducer to settle any running turn to 'interrupted' or 'error' (withcompletedAt) whenever a session transitions away from 'running'turn.abortedevents inProviderRuntimeIngestionandOpenCodeAdapter, transitioning the session to 'ready' and clearing the active turn; removes spuriousturn.abortedemission on prompt send failuresprocessSessionStopRequestedfrom real failures, recording a failure activity and retaining 'running' state for genuine errorsthread.session-stop-requested) now also immediately settles the latest turn to 'interrupted' in the client storeMacroscope summarized 9b21444.