Repository navigation
Conversation
Contributor
|
Hey! Your PR title Please update it to start with one of:
Where See CONTRIBUTING.md for details. |
Contributor
|
The following comment was made by an LLM, it may be inaccurate: |
InlineTool rows and BlockTool titles now carry a muted elapsed badge that ticks once per second while the part runs and freezes on its total once finished, reusing Locale.duration. Pure formatter covered by unit tests.
BasicTool trigger rows gain a muted elapsed badge driven by new optional startedAt/endedAt props, threaded once through the Dynamic call site; per-tool renderers pick it up via prop spread, GenericTool forwards explicitly. Ticks while pending, frozen text when done, formatted with the existing ui.message.duration i18n strings.
The badge was only wired into the completed row: running tools take the spinner branch and spinner-less pending tools take the fallback branch, so neither ever displayed it. Covered by render tests.
BoYanZh
force-pushed
the
feat/tui-tool-elapsed-time
branch
from
September 23, 2026 11:44
d7c9393 to
7abf2db
Compare
The shell renderer (and any function trigger) bypasses the title branch where the badge lived, so shell rows never showed timing. Add the badge slot to the function-trigger and fallback branches; branches are exclusive so it can never double-render. Covered by a function-trigger story, verified with a headless screenshot.
The badge relied on a text-space separator that collapses against custom trigger layouts, leaving it glued to the command. Use a fixed 8px margin (matching existing trigger gaps) plus muted, tabular styling.
…r timed Shell rows now read \Shell 11s <cmd>\: the badge moved inside the shell trigger between title and command via a shared ToolElapsed component (BasicTool refactored onto it; tight mode avoids double spacing inside flex-gap containers). The turn Thinking indicator gains the same live badge timed from the user message.
The turn Thinking indicator no longer disappears with the first visible output; it ticks live while working and freezes on the turn total when done (shimmer animation also stops). Errors and retries still suppress it.
…eline The main web session view builds its own timeline (app timeline rows), not session-ui SessionTurn, so the earlier thinking change never reached it. Now: Thinking rows persist after completion with frozen totals (live tick while busy), and Exploring-style group headers plus their rows carry group/per-part timing. Existing row tests updated for the new persistent rows; new test locks busy-vs-done timing fields.
Group header now reads \�xplored 1s 1 read\: the badge moved before the count summary inside the flex-gap title row.
Their custom JSX triggers bypassed the generic badge slot, leaving the timer on the next line. Place ToolElapsed inside the flex-gap title row (same pattern as shell) and suppress the generic slot.
Thinking is the cause and the reply is the effect: push the Thinking row before assistant parts so completed turns read Thinking total first, answer second. Row tests reordered accordingly.
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 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊 |
3 of 6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes #50891
Type of change
What does this PR do?
Tool calls show no timing anywhere: the TUI renders them as static one-liners with a spinner while running, and the Web UI only shows per-message turn duration. Since parts already carry
time.start/time.end, this wires that data into both frontends:packages/tui): newuseToolElapsedhook +toolElapsedTextformatter.InlineToolrows andBlockTooltitles gain a muted· Xsbadge that ticks once per second while the part runs and freezes on its total once finished. Nothing renders while timestamps are unknown (pending parts), so idle output is unchanged.packages/session-ui):BasicTooltrigger rows gain the same badge via new optionalstartedAt/endedAtprops, threaded once through theDynamiccall site (per-tool renderers pick it up via prop spread,GenericToolforwards explicitly). Ticks while pending, frozen when done, formatted with the existingui.message.duration.*strings — no new i18n keys. Shell rows render it inline asShell 11s <cmd>via a sharedToolElapsedcomponent (function triggers bypass the default title branch, so shell places its own badge and suppresses the generic one); the turnThinkingindicator carries the same live badge timed from the user message. Follow-ups: shell rows readShell 11s <cmd>(badge moved inside the shell trigger; ahideElapsedBadgeescape hatch suppresses the generic slot), and the Thinking row now stays mounted after the turn with a frozen total instead of vanishing with the first visible output (shimmer stops when idle; errors/retries still suppress it). Correction from live testing: the main web session view builds its own timeline (packages/app/.../timeline/rows.ts), not session-uiSessionTurn, so Thinking persistence andExploring-style group header/item timing are implemented there (TimelineRow.ThinkinggainsstartedAt/endedAt/running; group time range = earliest start to latest end, ticking until all parts finish).How did you verify your code works?
tool-elapsed.test.ts(formatter edge cases) in both packages, plustool-elapsed-hook.test.tscovering the TUI hook's pending/running/completed/error states viacreateRoot— all pass.inline-tool-elapsed.test.tsx,testRender+captureCharFrame): badge shows on completed/spinner/pending rows, absent without elapsed, and — driving the real hook — two frames 2.2s apart show different tick values, proving live updates through the production row component.session-uisuite: 89/89. Fulltuisuite: only failure is a pre-existing Windows home-path test that fails identically on the clean tree.sleep 5/sleep 25turns return tool parts withtime: {start, end}spanning 5.4s / 25.4s — the exact fields the badge reads, matching wall clock.tsgo --noEmitclean in both packages;oxlintshows no new warnings on touched files.Screenshots / recordings
Web UI verified with headless-Chrome storybook screenshots: running tool shows a ticking badge (
Working... 19s, advancing between captures), completed tool shows the frozen total (Done 3s). TUI screenshots pending an unlocked desktop; the headless render tests above cover the same rows.Checklist