feat(dashboard): redesign LLM Calls tab with activity visibility#1011
Merged
zbigniewsobiecki merged 2 commits intodevfrom Mar 23, 2026
Merged
feat(dashboard): redesign LLM Calls tab with activity visibility#1011zbigniewsobiecki merged 2 commits intodevfrom
zbigniewsobiecki merged 2 commits intodevfrom
Conversation
Add a rich Activity column to the LLM Calls table so users can see
what each call was doing at a glance — without expanding every row.
**Parser layer (new)**
- Add `src/utils/llmResponseParser.ts` and frontend twin
`web/src/lib/llm-response-parser.ts` that normalize all four engine
response formats (Claude Code/OpenCode JSON arrays, Codex JSON object,
LLMist gadget markup, raw text fallback) into a canonical
`ParsedLlmResponse` with `blocks[]`, `toolNames[]`, and `textPreview`.
- `toolNames` carries one entry per invocation (NOT deduplicated) so
×N badge counts reflect actual call frequency.
- `summarizeInput` extracts human-readable summaries for well-known tools
(Read/Write/Edit → file_path, Bash → command, Glob/Grep → pattern, etc.)
with consistent 100-char truncation.
- Internal helpers (`flushGadgetArg`, `finalizeGadget`, `handleGadgetStart`,
`processLlmistLine`, `processClaudeBlock`) extracted to module scope so
each function stays under the cognitive complexity limit.
**API layer**
- `listLlmCallsMeta` now selects `response` alongside token/cost metadata.
- `listLlmCalls` router runs the parser server-side and returns `toolNames`
+ `textPreview` per call; raw `response` payloads are NOT forwarded to
the client.
**UI — list view**
- New Activity column: colored tool-name badges (sky=read, amber=bash,
emerald=write, violet=web/agent) with ×N counts + truncated text preview.
- `getToolStyle` extracted to `web/src/lib/tool-style.ts` (was duplicated
in two components).
- Inter-call Δ Time column computed from `createdAt` timestamps.
- Summary stat cards (Total Calls, Input Tokens, Output Tokens, Cached %).
- Row expansion uses `<Fragment key>` to avoid React key warnings.
- Keyboard-accessible rows (`tabIndex={0}`, Enter/Space toggles).
- `isError` guard added alongside the existing `isLoading` guard.
**UI — detail view**
- Structured blocks view: text (muted bg), tool_use (colored badge +
monospace inputSummary), thinking (collapsible `<details>`).
- "Raw" / "Structured" toggle; raw JSON parse is lazy (only runs when
the pane is shown).
- Metadata bar with model (font-mono), time, tokens, cached, cost.
- `buildMetaItems` extracted to reduce component complexity; `MetaItem`
type replaces fragile string-identity check for `font-mono`.
- `isError` guard added.
**Tests**
- New `tests/unit/utils/llmResponseParser.test.ts` covering all five
format branches (Claude Code, Codex, LLMist, fallback, empty/null)
plus edge cases (dedup, truncation, multi-line args, unknown blocks).
- New router test verifies `toolNames` and `textPreview` are extracted
from a real Claude Code response payload, not just from `null` responses.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
The test asserted response was excluded from listLlmCallsMeta, but the router now needs response to extract toolNames/textPreview server-side. Update the test to reflect the new contract: request is still excluded, response is now included. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
Summary
parseLlmResponseutility normalizes all four engine formats (Claude Code/OpenCode JSON arrays, Codex, LLMist!!!GADGET_STARTmarkup, raw text fallback) into a canonical{ blocks[], toolNames[], textPreview }. Extracted tosrc/utils/llmResponseParser.ts(backend) +web/src/lib/llm-response-parser.ts(frontend twin, kept in sync via comment). Tool input summaries extracted with consistent 100-char truncation.listLlmCallsruns the parser server-side and returnstoolNames+textPreviewper call. Raw response payloads are not forwarded to the client.isErrorguard.isErrorguard.getToolStyleextracted to sharedtool-style.ts;buildMetaItemsextracted to reduce component complexity; all parser helper functions lifted to module scope;Fragment keyfixes;noArrayIndexKeyfixes; all biome complexity violations resolved.Test plan
tests/unit/utils/llmResponseParser.test.ts— all five format branches (Claude Code, Codex, LLMist, fallback, null/empty) + edge cases (dedup, truncation, multi-line args, unknown blocks)tests/unit/api/routers/runs.test.ts— new test verifiestoolNames/textPreviewextraction from a real Claude Code payloadnpm run lint— clean (0 errors)npm run typecheck+cd web && npx tsc --noEmit— cleannpm run test:unit— 6415 tests passinputSummarypopulate correctly in expanded view🤖 Generated with Claude Code