Repository navigation
feat(session-ui): show when a turn finished in the response footer - #62345
lsequeiraa wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
The change looks sound. The finish time comes from the same last completed step as the duration, so prompt time + duration equals the time shown. It only renders where the copy footer already does, and the user message menu's formatting moved over unchanged. I ran bun test src/message and tsc -b in packages/session-ui, and both pass. I couldn't launch a browser here, so I didn't run the component specs or try the footer live.
Public API: unchanged. The only new prop is the internal turnCompletedAt on SessionAssistantContent/AssistantTextContent, and message-time.ts is a new internal helper.
One concern is worth fixing (see the inline comment): a time shown without a date doesn't update after midnight, so a session left open overnight shows yesterday's replies as if they finished today.
There was a problem hiding this comment.
My earlier midnight concern is resolved. The footer time and the menu's day name now come from useToday(), a memo over the existing shared 30-second useNow() clock. That clock runs one interval for every label on screen, so each footer adds no timer of its own, and labels redraw once at local midnight. The unit tests now pass a fixed day instead of faking the system clock, and the new story runs in the describe block that sets the timezone to UTC, so its assertions don't depend on the machine's timezone. I ran bun test src/message and tsc -b in packages/session-ui, and both pass. The component specs didn't run here because no browser could launch.
Public API: unchanged. The new useToday() and the extra today argument to messageTime are internal to session-ui.
No further concerns.
There was a problem hiding this comment.
The midnight concern stays fixed, and the labels now also catch up after the machine sleeps. The current day is one shared signal, set in the same tick as the shared clock, so labels only redraw when the date changes. The clock also ticks on visibilitychange and focus; those listeners are added for the first label on screen and removed after the last one, alongside the interval. I ran bun test src/message and tsc -b in packages/session-ui, and both pass. The component specs couldn't run here because no browser could launch.
Public API: unchanged.
No further concerns.
Issue for this PR
Closes #62344
Type of change
What does this PR do?
The response footer shows agent, model and duration on hover, but not when the turn finished. This adds the finish time to the end of that line: a bare time for today (
14:32),Yesterday, 23:10, thenNov 4, 9:15, with the year once it differs.The time is the completion time of the same step the duration measures to, so prompt time + duration = the time shown.
session-timeline-row.tsxpasses it down asturnCompletedAt; outside the timeline the footer falls back to its own message's completion time, as the duration does.The user message menu already had the Today / Yesterday / date formatting, so I moved it into
message/message-time.tsand use it in both places, with abareTodayoption for the footer. Both labels read the day from a shared clock (useToday()inrelative-time.ts), so they say Yesterday after midnight in a session left open overnight; before this, the menu kept saying Today. The clock ticks every 30 seconds and when the page is shown or focused again, since timers stop while the machine sleeps. A tick only redraws labels when the date changes, so its cost doesn't grow with the number of messages. Formatting comes fromIntl, so there are no new strings to translate. The time doesn't shrink; the model name truncates first in a narrow footer.I didn't add a feature flag, since this only adds a read-only label to an existing footer and there is no client-side flag path for session-ui today. Happy to gate it if you'd rather.
How did you verify your code works?
bun run testinpackages/session-ui, including a newmessage-time.test.tsthat passes the current day in (just after midnight, yesterday, earlier this year, last year, andbareToday).bun typecheckinpackages/session-uiandpackages/app, andbun run typecheck:tscinpackages/session-ui.session-message-projection.spec.tsandsession-timeline-mobile.spec.tspass. I added adatetimecheck to the response-speed test; it fails if the footer shows the wrong message's time. A new story test moves Playwright's clock past midnight and expects both labels to say Yesterday; it fails if either label reads the clock only once. Another pauses the clock, moves the date on and firesvisibilitychangeandfocus; it fails if either listener is missing.serve, with an imported session whose turns finished two days ago, last night and today; also at 390px wide and with the footer squeezed to check truncation.Visual
Screenshots / recordings
Before:


After:
Checklist
Added by the opencode bot (AI-generated).
Related: #53192, #35348