Conversation
- project `thread.turn-start-requested` into thread session state (`starting`) in server pipeline/read model - add latest-turn timestamp observation guard so ChatView clears pending send even if `running` was never observed - extend session-logic and projection tests for restart and fast-complete plan-mode flows
|
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)
📝 Coding Plan
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 Tip You can disable the changed files summary in the walkthrough.Disable the |
There was a problem hiding this comment.
🟢 Low
The test "keeps projector forward-compatible for unhandled event types" at line 125 uses thread.turn-start-requested, which now has a handler (added in this diff). The test passes only because the thread doesn't exist, causing the handler to return nextBase unchanged—not because it falls through to the default case. The test description is now misleading and no longer validates forward-compatibility behavior. Consider using an actually unhandled event type or updating the test description to reflect what it actually verifies.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file apps/server/src/orchestration/projector.test.ts around line 125:
The test "keeps projector forward-compatible for unhandled event types" at line 125 uses `thread.turn-start-requested`, which now has a handler (added in this diff). The test passes only because the thread doesn't exist, causing the handler to return `nextBase` unchanged—not because it falls through to the `default` case. The test description is now misleading and no longer validates forward-compatibility behavior. Consider using an actually unhandled event type or updating the test description to reflect what it actually verifies.
Evidence trail:
- Test at apps/server/src/orchestration/projector.test.ts:125-151 - uses `thread.turn-start-requested` with an empty model, expects threads to remain empty
- New handler added at apps/server/src/orchestration/projector.ts:394-424 (see git_diff MERGE_BASE..REVIEWED_COMMIT) - contains `if (!thread) { return nextBase; }` early return
- Default case at apps/server/src/orchestration/projector.ts:657 - `default: return Effect.succeed(nextBase);` is the actual forward-compatibility mechanism
What Changed
startingas soon asthread.turn-start-requestedis emitted so threads stop reading as completed during provider handoff.runningstate was never observed.bun fmt,bun lint,bun typecheck, plus targeted web and server Vitest coverage.Why
Plan mode could leave an individual thread in a state-sync hole between projected session status and local composer state. In that case the thread row could still show the previous completed state while the next turn was starting, and once the turn finished the composer could remain artificially locked until the thread view remounted.
This change fixes both sides of that race. The server now projects a
startingsession immediately on turn request, and the web app now clears its local send latch as soon as it observes the turn that started after the current send.Some of my threads that were running when my macbook crashed exhibit this behaviour.
UI Changes
None. This is a state-management and interaction fix only.
Checklist
Note
Fix plan mode thread state desync by updating session to 'starting' on turn-start-requested
thread.turn-start-requestedevent is received, the projector and projection pipeline now immediately upsert a session row withstatus: 'starting',runtimeMode, andproviderNamebefore anythread.session-setevent arrives.ChatViewexits the sending phase (re-enabling the send button) when any turn observation (requestedAt,startedAt, orcompletedAt) occurs at or aftersendStartedAt, covering turns that complete without an observed running phase.hasLatestTurnObservationSinceutility in session-logic.ts detects whether the latest turn has any observation at or after a given timestamp.runningphase.📊 Macroscope summarized 2b0ffab. 8 files reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted
🗂️ Filtered Issues