Skip to content

feat(tui): show per-turn completion time and duration - #53195

Closed
Nowaker wants to merge 1 commit into
anomalyco:devfrom
Nowaker:tui-turn-timing
Closed

Nowaker wants to merge 1 commit into
anomalyco:devfrom
Nowaker:tui-turn-timing

Conversation

@Nowaker

@Nowaker Nowaker commented Oct 4, 2026 •

Copy link
Copy Markdown

Note: I'm aware v1 is now the maintenance branch and new features go to v2 only. This PR is here for others who want to use it on v1. I will submit a v2 version once I've migrated my plugin setup to v2.

Issue for this PR

Closes #53192

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Today the assistant footer appears only on the final message of a prompt, and it shows only the total since that prompt. Intermediate tool-call turns get no footer, so you can't tell when a turn finished or which step took the time.

This adds turn_timing to tui.json as two booleans, both defaulting to false, so the UI is unchanged unless you enable them:

  • time: the turn's time.completed: time of day if today, otherwise the date followed by the time (10/4/2026 11:26 PM). This uses a new Locale.todayTimeOrDateFirst, so Locale.todayTimeOrDateTime keeps its time-then-date order for /timestamps and opencode session list.
  • duration: completed - created for each turn. The final turn keeps the existing total since the prompt and labels it total, so both numbers are shown.

When either option is on, every completed assistant turn gets the footer. Otherwise the existing condition (last, final, or interrupted) still applies.

/turn-times and /turn-durations toggle the two options at runtime. They also appear in the palette and can be bound via session_toggle_turn_time / session_toggle_turn_duration, with no default keys. As with /timestamps, a toggled value persists in kv.json, and tui.json only supplies the default.

I made these two settings rather than a mode enum because the two pieces of information are independent. Some people only want the clock time, others only want to know where the time went.

Docs: tui.mdx options list and example config.

How did you verify your code works?

  • bun typecheck in packages/tui and packages/opencode.
  • New test loads turn timing config in packages/opencode/test/config/tui.test.ts passes. Four plugin-merge tests in that file fail on dev with or without this change.
  • I ran the TUI against a local OpenAI-compatible fake that answers every prompt with two tool-call steps and then a final text step, then captured the tmux pane:

Before (dev, and this branch with defaults; identical):

     ✱ Glob "*.txt" (1 match)
     All done, here is the final answer.
     ▣  Build · Fake · 15.8s

After /turn-times and /turn-durations:

     ✱ Glob "*.txt" (1 match)
     ▣  Build · Fake · 1:07 PM · 8.3s
     Step 2: looking around.
     ✱ Glob "*.txt" (1 match)
     ▣  Build · Fake · 1:07 PM · 3.5s
     All done, here is the final answer.
     ▣  Build · Fake · 1:07 PM · 3.7s · 15.6s total

A turn from yesterday puts the date first; today's turns stay time-only (row shifted back 24h in a scratch DB):

     ▣  Build · Fake · 10/4/2026 4:59 AM · 7.1s
     ▣  Build · Fake · 10/4/2026 4:59 AM · 1.9s · 9.1s total
     ▣  Build · Fake · 5:09 AM · 14.2s
     ▣  Build · Fake · 5:09 AM · 2.0s · 16.4s total

Time only:

     ▣  Build · Fake · 1:07 PM
     ▣  Build · Fake · 1:07 PM
     ▣  Build · Fake · 1:07 PM · 15.6s

With {"turn_timing":{"duration":true}} in tui.json, no kv override, and a restart, durations show from the start. The toggled kv value also persisted across the restart.

Screenshots / recordings

Terminal captures above.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

This PR is AI generated, but under direct supervision and on request of @Nowaker.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Nowaker added a commit to Nowaker/opencode that referenced this pull request Oct 4, 2026
17dca85 adds turn_timing.time / turn_timing.duration to tui.json and
the /turn-times and /turn-durations toggles, so every assistant turn can
show when it finished and how long it took, and the final turn also
keeps the total since the prompt. Defaults stay as upstream. Offered
upstream as issue anomalyco#53192 and PR anomalyco#53195.

AI-Tool: opencode 1.18.33-vt-60-2fa3363c92
AI-Model: anthropic/claude-opus-5-5
AI-Variant: high
AI-Platform: linux
AI-Harness: Vibeterm e8a11eb
AI-Session-ID: ses_ef81c1485ffeC5Sb59U9mVI77g
The assistant footer only appears on the final message of a prompt and
shows one number: the time since that prompt. Intermediate tool-call
turns show no footer, so there is no way to see when a turn finished or
which step of a long run took the time.

Add a `turn_timing` option to tui.json with two independent booleans:

- `time`: when each assistant turn finished, as the time of day if
  today and the date followed by the time otherwise
  (Locale.todayTimeOrDateFirst, e.g. `10/4/2026 11:26 PM`).
  Locale.todayTimeOrDateTime keeps its time-then-date order for its
  existing callers.
- `duration`: how long each turn took (created -> completed). The
  final turn keeps the existing total since the prompt and labels it
  `total`, so both numbers are visible.

Either option gives every completed assistant turn a footer. Both
default to false, so the footer is unchanged unless enabled.

/turn-times and /turn-durations (also in the command palette and
bindable via session_toggle_turn_time / session_toggle_turn_duration)
toggle them at runtime. Like /timestamps, a toggled value persists in
kv.json and takes precedence over tui.json, which supplies the
default.
Nowaker added a commit to Nowaker/opencode that referenced this pull request Oct 5, 2026
A turn that did not finish today rendered `11:26 PM · 10/4/2026`
because the footer reused Locale.todayTimeOrDateTime, whose datetime
form is time first. It now uses Locale.todayTimeOrDateFirst and reads
`10/4/2026 11:26 PM`; today's turns stay time-only.
todayTimeOrDateTime keeps its order for /timestamps and
`opencode session list`.

The same change is folded into the feature commit on tui-turn-timing
(PR anomalyco#53195).

AI-Tool: opencode 1.18.33-vt-60-2fa3363c92
AI-Model: anthropic/claude-opus-5-5
AI-Variant: high
AI-Platform: linux
AI-Harness: Vibeterm e8a11eb
AI-Session-ID: ses_ef81c1485ffeC5Sb59U9mVI77g
Nowaker added a commit to Nowaker/opencode that referenced this pull request Oct 5, 2026
d80de8e renders a turn that did not finish today as
`10/4/2026 11:26 PM` rather than `11:26 PM · 10/4/2026`, on user
feedback; the same change is amended into PR anomalyco#53195's head b14b75e.
Desktop and m4max installed 1.18.34-vt-91-907b3bc518.

AI-Tool: opencode 1.18.33-vt-60-2fa3363c92
AI-Model: anthropic/claude-opus-5-5
AI-Variant: high
AI-Platform: linux
AI-Harness: Vibeterm e8a11eb
AI-Session-ID: ses_ef81c1485ffeC5Sb59U9mVI77g
@thdxr

thdxr commented Oct 10, 2026

Copy link
Copy Markdown
Member

This branch has been upgraded to V2. We're no longer taking PRs for V1. If you think this is still relevant, please port it over and open it for V2.

— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

@thdxr thdxr closed this Oct 10, 2026
Nowaker added a commit to Nowaker/opencode that referenced this pull request Oct 11, 2026
17dca85 adds turn_timing.time / turn_timing.duration to tui.json and
the /turn-times and /turn-durations toggles, so every assistant turn can
show when it finished and how long it took, and the final turn also
keeps the total since the prompt. Defaults stay as upstream. Offered
upstream as issue anomalyco#53192 and PR anomalyco#53195.

AI-Tool: opencode 1.18.33-vt-60-2fa3363c92
AI-Model: anthropic/claude-opus-5-5
AI-Variant: high
AI-Platform: linux
AI-Harness: Vibeterm e8a11eb
AI-Session-ID: ses_ef81c1485ffeC5Sb59U9mVI77g
Nowaker added a commit to Nowaker/opencode that referenced this pull request Oct 11, 2026
A turn that did not finish today rendered `11:26 PM · 10/4/2026`
because the footer reused Locale.todayTimeOrDateTime, whose datetime
form is time first. It now uses Locale.todayTimeOrDateFirst and reads
`10/4/2026 11:26 PM`; today's turns stay time-only.
todayTimeOrDateTime keeps its order for /timestamps and
`opencode session list`.

The same change is folded into the feature commit on tui-turn-timing
(PR anomalyco#53195).

AI-Tool: opencode 1.18.33-vt-60-2fa3363c92
AI-Model: anthropic/claude-opus-5-5
AI-Variant: high
AI-Platform: linux
AI-Harness: Vibeterm e8a11eb
AI-Session-ID: ses_ef81c1485ffeC5Sb59U9mVI77g
Nowaker added a commit to Nowaker/opencode that referenced this pull request Oct 11, 2026
d80de8e renders a turn that did not finish today as
`10/4/2026 11:26 PM` rather than `11:26 PM · 10/4/2026`, on user
feedback; the same change is amended into PR anomalyco#53195's head b14b75e.
Desktop and m4max installed 1.18.34-vt-91-907b3bc518.

AI-Tool: opencode 1.18.33-vt-60-2fa3363c92
AI-Model: anthropic/claude-opus-5-5
AI-Variant: high
AI-Platform: linux
AI-Harness: Vibeterm e8a11eb
AI-Session-ID: ses_ef81c1485ffeC5Sb59U9mVI77g
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.

[FEATURE]: Show completion time and duration for every assistant turn in the TUI

2 participants