Skip to content

fix(chat): settle screenshots chain-insert at the turn instead of after your next message - #578

Merged
milind-soni merged 1 commit into
mainfrom
fix/turn-artifact-ordering
Aug 30, 2026
Merged

fix(chat): settle screenshots chain-insert at the turn instead of after your next message#578
milind-soni merged 1 commit into
mainfrom
fix/turn-artifact-ordering

Conversation

@milind-soni

@milind-soni milind-soni commented Aug 30, 2026

Copy link
Copy Markdown
Owner

What changed

  • server/index.ts turn.completed fold: the settle-time screen capture records the turn's real last message (store.activePath(...).at(-1)) before the async capture, and delivers the frame via chain-insert instead of a plain append.
  • server/store.ts: new insertMessageAfter(threadId, anchorId, message) — plain append when the anchor is still the leaf (or unknown); otherwise the artifact is parented to the anchor and the anchor's children are re-parented onto it, announced as message + message.patch so live clients converge. Screen-frame pruning still applies.
  • src/state/store.tsx: messageAdded adopts the incoming message as activeLeafId only when it chains onto the current leaf — a mid-branch insert leaves the leaf (the user's follow-up) in place.

Why

Field report: with browser mode on, a message sent right after a turn appeared above the last message. Root cause: void finalScreenFrame(...).then(pushMessage) runs after busy clears, so a quick send (or the steer-queue drain) appends first and the screenshot then chains after it — and browser/computer turns end with that capture, making it near-deterministic.

After: the transcript reads turn → screenshot → your message, and your message stays the tail.

How it was verified

  • server/store.test.ts: mid-chain insert yields anchor → artifact → follow-up with the leaf preserved and the re-parent announced; anchor-still-leaf and unknown-anchor degrade to plain appends.
  • src/state/store.test.ts: reducer keeps the leaf for a mid-branch insert, adopts it for a chaining message.
  • Mutation check: forcing the plain-append path fails the chain-insert test.
  • pnpm typecheck clean; lint parity with main on every touched file.
  • Rebased onto current main (0.1.40): the reducer's new early duplicate-return kept; only the leaf-adoption rule grafted in.

Known scope cut

Room threads render by array order, not parent chains, so a room's settle frame keeps the old append (noted in the fold comment).

Checklist

  • pnpm typecheck and the touched test files pass locally
  • Server behavior changes come with tests
  • No dist-server/ edits · no macOS-only code · no shell: true · no secrets

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed final screenshots occasionally appearing above a user’s follow-up message during fast responses.
    • Preserved the active conversation branch when late screenshots or other artifacts arrive.
    • Improved transcript consistency across live clients when messages are inserted into an existing conversation chain.
  • Tests
    • Added coverage for message ordering, branch updates, and late-arriving screenshot handling.

…r your next message

In computer/browser modes every turn ends with a screen capture that runs
AFTER the bot goes idle (a real screenshot round trip). A fast follow-up
send — or the steer-queue drain — landed first, and the frame then chained
onto the new leaf, stranding the user's message ABOVE the screenshot. In
browser mode this reproduced on nearly every send.

The fold now anchors the frame to the turn's actual last message before the
capture starts, and the store gains insertMessageAfter: when the anchor is
no longer the leaf, the artifact is inserted mid-chain and the anchor's
children are re-parented onto it, so the transcript reads
turn → screenshot → follow-up and the leaf stays with the user's message.
The renderer adopts a new message as the leaf only when it actually chains
onto the current one, matching the server rule.

Room threads keep the old append (their order is array-based, not chained);
called out in the fold comment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openmausbot-docs Ready Ready Preview Aug 30, 2026 8:18am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b334e8a4-097a-4767-b380-48abeb7f7d23

📥 Commits

Reviewing files that changed from the base of the PR and between 6a8131e and 80018f9.

📒 Files selected for processing (5)
  • server/index.ts
  • server/store.test.ts
  • server/store.ts
  • src/state/store.test.ts
  • src/state/store.tsx

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

The store now supports inserting messages after an active-chain anchor. One-to-one turn completion uses this path for final screenshots. The client preserves a newer follow-up as the active leaf when a late screenshot arrives.

Changes

Screen settlement ordering

Layer / File(s) Summary
Message insertion and re-parenting
server/store.ts, server/store.test.ts
insertMessageAfter inserts an artifact after an anchor, re-parents existing children, persists changes, and emits updates. Tests cover mid-chain insertion and append fallbacks.
Turn completion settlement wiring
server/index.ts
One-to-one turns capture settleLeafId before the final screenshot and insert the screenshot after that message. Group turns continue to append screenshots.
Client active-leaf handling
src/state/store.tsx, src/state/store.test.ts
messageAdded updates activeLeafId only when the new message chains from the current leaf. Tests cover normal chaining and late screenshot insertion.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: 🟡 Moderate · up to 80018

The change fixes screenshot ordering during live conversations, but persisted transcript state can still differ from the live branch after a restart, and an interrupted or repeated settlement can leave broken parent links or duplicate screenshots. The PR is not merge-ready until these persistence and retry risks are fixed or explicitly accepted by the owner.

Suggested reviewers: aivsomkar, willsigmon

Sequence Diagram(s)

sequenceDiagram
  participant TurnCompletion
  participant Store
  participant MessageDB
  participant ClientState
  TurnCompletion->>TurnCompletion: Capture settleLeafId
  TurnCompletion->>Store: Insert final screen after settleLeafId
  Store->>MessageDB: Persist screen and parent updates
  Store->>ClientState: Emit message and message.patch events
  ClientState->>ClientState: Preserve activeLeafId for late artifact
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: chain-inserting settle screenshots instead of appending them after a follow-up message.
Description check ✅ Passed The description explains what changed, why it changed, how it was verified, the scope limitation for room threads, and the checklist status. The omitted screenshots section is not required because thi…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains what changed, why it changed, how it was verified, the scope limitation for room threads, and the checklist status. The omitted screenshots section is not required because this is not a UI change.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/turn-artifact-ordering

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@milind-soni
milind-soni merged commit c996e88 into main Aug 30, 2026
9 checks passed
@milind-soni
milind-soni deleted the fix/turn-artifact-ordering branch August 30, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant