Skip to content

Feat/tool call timestamps#1

Merged
krishnaclouds merged 3 commits into
mainfrom
feat/tool-call-timestamps
Jun 7, 2026
Merged

Feat/tool call timestamps#1
krishnaclouds merged 3 commits into
mainfrom
feat/tool-call-timestamps

Conversation

@krishnaclouds
Copy link
Copy Markdown
Owner

Summary

Adds visibility into how long tool calls take inside the TUI — both per-call and at the session level.

  • Per-tool timing. Every tool call now shows its start time and elapsed duration right next to it (HH:MM:SS · 234ms for finished, HH:MM:SS · running 12.3s for in-flight). Live-ticks at 1Hz while running, freezes on completion. Tool calls running longer than 30s flip to the theme's warning color so slow calls stand out.
  • Sidebar total. The session sidebar's Context block gains a in tools line that sums execution time across every tool call in the session, ticking live while any tool is running.
  • Toggle. Bound to the existing timestamps setting. Adds /timing and /toggle-timing slash aliases alongside the existing /timestamps. Renames the menu entry to "tool timing." Default changes from hide → show; users with an explicit prior choice keep it (kv persistence).
  • Refactor. A small routes/session/timing.ts module owns SLOW_TOOL_MS, the Elapsed type, and the format helper — replaces three copies of the timing-string builder across InlineTool/BlockTool with one call.
  • Helper. New Locale.clockTime(ms) produces 24-hour HH:MM:SS.

What changed and why?

Test Plan

  • bun test packages/opencode/test/util/locale.test.ts — passes (new clockTime cases)
  • bun turbo typecheck — passes (pre-push hook, all 5 packages green)
  • Run a fast tool in a session → inline row renders HH:MM:SS · and freezes on completion
  • Run a slow tool (>30s) → inline timing turns warning-colored while running, locks to muted on completion
  • Sidebar Context block shows in tools and gains (running) while a tool is in-flight, ticking once per second
  • /timing, /toggle-timing, and /timestamps all toggle visibility; preference persists across sessions
  • Block-style tools (spinner variants) render timing inside the spinner label

Checklist

  • Tests added/updated — unit coverage for Locale.clockTime; reactive hooks (useElapsed, toolTime) intentionally not unit-tested (no lightweight harness for this Solid-on-TUI renderer; tracked as known testing debt)
  • Documentation updated (if needed) — no docs reference the prior /timestamps UX; new aliases discoverable via the existing command palette
  • CHANGELOG updated (if user-facing) — toggle default flip from hide → show is the only behavior change for existing users; worth a one-liner if this repo keeps a CHANGELOG

Each tool block (BlockTool + InlineTool) now renders `HH:MM:SS · 1.2s`
in the title row. Running tools tick the elapsed counter at 1Hz and
freeze on completion; tools running >=30s switch to theme.warning so
slow calls stand out at a glance.

- Add Locale.clockTime() for 24-hour HH:MM:SS formatting.
- Add useElapsed(part) hook: returns {start, ms, running}; live-ticks
  only while status === "running" and cleans up the interval on
  transition to completed/error.
- Gate visibility behind the existing showTimestamps toggle; default
  flipped from "hide" -> "show". Toggle relabeled "Show tool timing"
  and aliased to /timing in addition to /timestamps.
- Pending parts (no time.start yet) render no timing row, so the UX
  stays clean during the brief pre-running window.

Tests: 2 new Locale.clockTime cases; existing TUI suite (157) still
passes; tsgo typecheck clean.
Aggregates duration across every ToolPart in the session — completed
and error tools by (end - start), the currently running tool by
(now - start), live-ticking once a second only while a tool is running.
Renders under the existing Context block as '… in tools' (with a
'(running)' suffix when active), hidden when zero.
Pulls SLOW_TOOL_MS, the Elapsed type, and the 'HH:MM:SS · running …'
suffix builder into routes/session/timing.ts. Collapses three copies
of the timing format string across InlineTool and BlockTool down to
a single formatElapsed() call, and drops a redundant 'as ToolPart'
cast in the sidebar — the part.type === 'tool' discriminant already
narrows the union.
@krishnaclouds krishnaclouds merged commit a024d9d into main Jun 7, 2026
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