(progressMessages: ProgressMessage<Progress>[], {
tools,
verbose,
terminalSize,
inProgressToolCallCount,
isTranscriptMode = false
}: {
tools: Tools;
verbose: boolean;
terminalSize?: {
columns: number;
rows: number;
};
inProgressToolCallCount?: number;
isTranscriptMode?: boolean;
})
| 443 | } |
| 444 | const INITIALIZING_TEXT = 'Initializing…'; |
| 445 | export function renderToolUseProgressMessage(progressMessages: ProgressMessage<Progress>[], { |
| 446 | tools, |
| 447 | verbose, |
| 448 | terminalSize, |
| 449 | inProgressToolCallCount, |
| 450 | isTranscriptMode = false |
| 451 | }: { |
| 452 | tools: Tools; |
| 453 | verbose: boolean; |
| 454 | terminalSize?: { |
| 455 | columns: number; |
| 456 | rows: number; |
| 457 | }; |
| 458 | inProgressToolCallCount?: number; |
| 459 | isTranscriptMode?: boolean; |
| 460 | }): React.ReactNode { |
| 461 | if (!progressMessages.length) { |
| 462 | return <MessageResponse height={1}> |
| 463 | <Text dimColor>{INITIALIZING_TEXT}</Text> |
| 464 | </MessageResponse>; |
| 465 | } |
| 466 | |
| 467 | // Checks to see if we should show a super condensed progress message summary. |
| 468 | // This prevents flickers when the terminal size is too small to render all the dynamic content |
| 469 | const toolToolRenderLinesEstimate = (inProgressToolCallCount ?? 1) * ESTIMATED_LINES_PER_TOOL + TERMINAL_BUFFER_LINES; |
| 470 | const shouldUseCondensedMode = !isTranscriptMode && terminalSize && terminalSize.rows && terminalSize.rows < toolToolRenderLinesEstimate; |
| 471 | const getProgressStats = () => { |
| 472 | const toolUseCount = count(progressMessages, msg => { |
| 473 | if (!hasProgressMessage(msg.data)) { |
| 474 | return false; |
| 475 | } |
| 476 | const message = msg.data.message; |
| 477 | return message.message.content.some(content => content.type === 'tool_use'); |
| 478 | }); |
| 479 | const latestAssistant = progressMessages.findLast((msg): msg is ProgressMessage<AgentToolProgress> => hasProgressMessage(msg.data) && msg.data.message.type === 'assistant'); |
| 480 | let tokens = null; |
| 481 | if (latestAssistant?.data.message.type === 'assistant') { |
| 482 | const usage = latestAssistant.data.message.message.usage; |
| 483 | tokens = (usage.cache_creation_input_tokens ?? 0) + (usage.cache_read_input_tokens ?? 0) + usage.input_tokens + usage.output_tokens; |
| 484 | } |
| 485 | return { |
| 486 | toolUseCount, |
| 487 | tokens |
| 488 | }; |
| 489 | }; |
| 490 | if (shouldUseCondensedMode) { |
| 491 | const { |
| 492 | toolUseCount, |
| 493 | tokens |
| 494 | } = getProgressStats(); |
| 495 | return <MessageResponse height={1}> |
| 496 | <Text dimColor> |
| 497 | In progress… · <Text bold>{toolUseCount}</Text> tool{' '} |
| 498 | {toolUseCount === 1 ? 'use' : 'uses'} |
| 499 | {tokens && ` · ${formatNumber(tokens)} tokens`} ·{' '} |
| 500 | <ConfigurableShortcutHint action="app:toggleTranscript" context="Global" fallback="ctrl+o" description="expand" parens /> |
| 501 | </Text> |
| 502 | </MessageResponse>; |
no test coverage detected