diff --git a/app/src/pages/conversations/components/ToolTimelineBlock.tsx b/app/src/pages/conversations/components/ToolTimelineBlock.tsx index e19b80c90..e4545c925 100644 --- a/app/src/pages/conversations/components/ToolTimelineBlock.tsx +++ b/app/src/pages/conversations/components/ToolTimelineBlock.tsx @@ -12,6 +12,7 @@ import { stripToolCallEnvelopes, } from '../../../utils/toolTimelineFormatting'; import { parseWorkerThreadRef } from '../utils/workerThreadRef'; +import { BubbleMarkdown } from './AgentMessageBubble'; import { agentNameTone, AgentTimelineRail } from './AgentTimelineRail'; import { WorkerThreadRefCard, type WorkerThreadStatus } from './WorkerThreadRefCard'; @@ -99,20 +100,30 @@ function ToolCallRow({ }) { const tone = toolCallTone(call.status); return ( -
- - +
+ + • + + {call.displayName ?? formatToolName(call.toolName)} + {/* The contextual arg (path / recipient / query) can be long, so it + truncates to a single line and absorbs the row's spare width — the + full value stays available on hover — instead of wrapping into a + multi-line box that knocks the name and status out of alignment. */} {call.detail ? ( - + {call.detail} ) : null} {/* Status reads as a tinted "Done" / "Failed" / "Running" tag. */} - + + + {call.elapsedMs != null && call.status !== 'running' ? ( - + {call.elapsedMs >= 1000 ? `${(call.elapsedMs / 1000).toFixed(1)}s` : `${call.elapsedMs}ms`} @@ -132,14 +143,21 @@ function ToolCallRow({ */ function ThoughtBlock({ text }: { text: string }) { // Drop any inline `` envelope the model emitted as - // text — the call already shows as its own row — then flatten to one line. - const clean = stripToolCallEnvelopes(text).replace(/\s+/g, ' ').trim(); + // text — the call already shows as its own row. Keep the original newlines + // (only trim the ends) so the markdown renderer can see headings, lists, + // code fences and emphasis instead of flattening them to one plain line. + const clean = stripToolCallEnvelopes(text).trim(); if (!clean) return null; + // Rendered through the shared `BubbleMarkdown` so a thought formats markdown + // (bold, code, lists) — but scaled back to the original quiet thought look: + // small (12px) and light/muted, not the larger, darker agent-bubble prose. + // Descendant overrides on `.prose` beat the typography plugin's base sizing; + // code keeps its accent colour so inline `tool_names` still read clearly. return (
- “{clean}” + className="my-0.5 break-words [&_.prose]:text-[12px] [&_.prose]:leading-relaxed [&_.prose]:text-content-muted [&_.prose_strong]:text-content-muted [&_.prose_:is(h1,h2,h3,h4,h5,h6)]:text-[12px] [&_.prose_:is(h1,h2,h3,h4,h5,h6)]:text-content-muted"> +
); }