Skip to content

Time a message sent mid-turn from when it was sent - #1035

Open
zcy22606 wants to merge 1 commit into
hardbeat920:mainfrom
zcy22606:fix/mid-turn-timer-from-sent
Open

zcy22606 wants to merge 1 commit into
hardbeat920:mainfrom
zcy22606:fix/mid-turn-timer-from-sent

Conversation

@zcy22606

@zcy22606 zcy22606 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

What changed

A message sent while a turn is running now times its fold line from its own sentAt, so "Working for …" counts from when you sent it. This is a follow-up correction to #1021, which anchored it to the start of the turn it joined. The day separator check reads the same start, and joinedTurnStart is removed.

Why

groupTurns gives a mid-turn message (appendSteerUser, which stamps sentAt and no startedAt) a turn of its own, with its own live fold line. Before #1021 that line had no start and fell back to the moment it mounted (useElapsedFrom's Date.now() fallback), so it restarted at 0 every time you switched back to the session. #1021 fixed that by walking back to the joined turn's startedAt. The side effect: a message sent eight minutes into a long turn opens its fold line already reading "Working for 8m 43s", which looks like that message took eight minutes.

sentAt fixes the restart too, without that side effect. sanitizeBlock keeps sentAt on user blocks when saving and hydrating, so the start survives a session switch or a reload. The fallback order is now startedAt ?? sentAt ?? monoHabit.at ?? turn[0].startedAt. A message with neither still falls back to mount time, the same as before #1021.

The day separator uses this startedAt, so previousAt now reads the previous user block's sentAt too. Without that, every mid-turn message after the first gets a separator, because the previous turn has no startedAt and opensNewStretch(at, undefined) returns true. This already happens on main since #1021. In the app, daySeparators is only turned on together with inlineWork (Mono views), and those group mid-turn messages into the turn they joined. So this part is for consistency and isn't visible today.

stampTurnDuration doesn't change: the turn's recorded duration still runs from the prompt that started it.

UI

No layout change. Only the elapsed time on a mid-turn message's live fold line changes: it now counts from when the message was sent.

Validation

  • AgentTranscript.test.ts: the Keep the running clock when a message joins a turn mid-way #1021 test ("times a message sent mid-turn …") now expects Working for 5s for a message sent 5s ago into a turn that started 90s ago. That rules out the joined turn's start (1m 30s) and the mount fallback (0s), so the "switching back restarts at 0" case is still covered. Fails on main ("Working for 1m 30s").
  • New test: with daySeparators, two mid-turn messages in a row add no separator after the first turn's. Fails on main (2 separators instead of 1).
  • Removed the two joinedTurnStart unit tests along with the helper.
  • npm run check:web (vitest + tsc --noEmit): 483 files / 5362 tests passed, 13 skipped. No Rust changes, so I didn't run check:rust.

Checklist

  • I ran npm run check (check:web; no Rust files changed)
  • This PR is small and focused
  • I did not mix unrelated changes

Summary by CodeRabbit

  • Bug Fixes
    • Mid-turn messages now show elapsed time based on when they were sent if no turn start time is available.
    • Mid-turn messages no longer create extra day separators in the transcript.

hardbeat920#1021 walked a mid-turn message's fold line back to the start of the turn
it joined, so a message sent eight minutes into a long turn opened already
reading "Working for 8m 43s". Its own sentAt is saved with the block, so it
fixes the restart-at-0 on switching back without that side effect. The day
separator check reads the previous message's sentAt too, so two mid-turn
messages in a row no longer get a separator between them.
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5bd5d1f6-b56f-4107-9d94-c1ed6950ceb3
📥 Commits

Reviewing files that changed from the base of the PR and between e49a5ae and 8072770.

📒 Files selected for processing: 4
  • src/features/sessions/model/transcriptActivity.test.ts
  • src/features/sessions/model/transcriptActivity.ts
  • src/features/sessions/ui/AgentTranscript.test.ts
  • src/features/sessions/ui/AgentTranscript.tsx
💤 Files with no reviewable changes: 2
  • src/features/sessions/model/transcriptActivity.ts
  • src/features/sessions/model/transcriptActivity.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Walkthrough

Transcript timestamps now use a mid-turn message’s sentAt when startedAt is absent. The joinedTurnStart helper and its tests were removed. UI tests now check elapsed time from sentAt and day-separator rendering.

Changes: Transcript timestamps

Layer / File(s) Summary
Timestamp selection and validation
src/features/sessions/model/transcriptActivity.ts, src/features/sessions/model/transcriptActivity.test.ts, src/features/sessions/ui/AgentTranscript.tsx, src/features/sessions/ui/AgentTranscript.test.ts
Current and previous turn timestamp selection checks the user block’s sentAt. The joinedTurnStart helper and its tests were removed. UI tests verify elapsed time from sentAt and day-separator rendering.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: hardbeat920

Merge Risk: ⚪ Minimal · up to 80727

The change aligns live elapsed time and day-separator timing with mid-turn messages. No concrete merge-blocking risk is established by the supplied context.

Pre-merge checks: Passed 4 · Failed 1

Failed 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 2 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description check Passed The description includes all required sections, explains the change and reason, states that there is no layout change, and completes the checklist. It also documents validation results and scope.
Title check Passed The title clearly and concisely describes the main change: timing a mid-turn message from when it was sent.
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

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