Download packages/cli/src/ui/components/messages/SubagentProgressDisplay.tsx from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 6.33 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/ui/components/messages/SubagentProgressDisplay.tsx
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/cli/src/ui/components/messages/SubagentProgressDisplay.tsx
-
curl -L -o SubagentProgressDisplay.tsx https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/ui/components/messages/SubagentProgressDisplay.tsx
6.33 kB
| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import type React from 'react'; | |
| import { Box, Text } from 'ink'; | |
| import { theme } from '../../semantic-colors.js'; | |
| import Spinner from 'ink-spinner'; | |
| import { MarkdownDisplay } from '../../utils/MarkdownDisplay.js'; | |
| import { | |
| type SubagentProgress, | |
| type SubagentActivityItem, | |
| SubagentState, | |
| } from '@google/gemini-cli-core'; | |
| import { TOOL_STATUS } from '../../constants.js'; | |
| import { STATUS_INDICATOR_WIDTH } from './ToolShared.js'; | |
| import { safeJsonToMarkdown } from '@google/gemini-cli-core'; | |
| export interface SubagentProgressDisplayProps { | |
| progress: SubagentProgress; | |
| terminalWidth: number; | |
| historyOverrides?: SubagentActivityItem[]; | |
| } | |
| export const formatToolArgs = (args?: string): string => { | |
| if (!args) return ''; | |
| try { | |
| const parsed: unknown = JSON.parse(args); | |
| if (typeof parsed !== 'object' || parsed === null) { | |
| return args; | |
| } | |
| if ( | |
| 'description' in parsed && | |
| typeof parsed.description === 'string' && | |
| parsed.description | |
| ) { | |
| return parsed.description; | |
| } | |
| if ('command' in parsed && typeof parsed.command === 'string') | |
| return parsed.command; | |
| if ('file_path' in parsed && typeof parsed.file_path === 'string') | |
| return parsed.file_path; | |
| if ('dir_path' in parsed && typeof parsed.dir_path === 'string') | |
| return parsed.dir_path; | |
| if ('query' in parsed && typeof parsed.query === 'string') | |
| return parsed.query; | |
| if ('url' in parsed && typeof parsed.url === 'string') return parsed.url; | |
| if ('target' in parsed && typeof parsed.target === 'string') | |
| return parsed.target; | |
| return args; | |
| } catch { | |
| return args; | |
| } | |
| }; | |
| export const SubagentProgressDisplay: React.FC< | |
| SubagentProgressDisplayProps | |
| > = ({ progress, terminalWidth, historyOverrides }) => { | |
| let headerText: string | undefined; | |
| let headerColor = theme.text.secondary; | |
| if (progress.state === SubagentState.CANCELLED) { | |
| headerText = `Subagent ${progress.agentName} was cancelled.`; | |
| headerColor = theme.status.warning; | |
| } else if (progress.state === SubagentState.ERROR) { | |
| headerText = `Subagent ${progress.agentName} failed.`; | |
| headerColor = theme.status.error; | |
| } else if (progress.state === SubagentState.COMPLETED) { | |
| headerText = `Subagent ${progress.agentName} completed.`; | |
| headerColor = theme.status.success; | |
| } else { | |
| headerText = `Running subagent ${progress.agentName}...`; | |
| headerColor = theme.text.primary; | |
| } | |
| return ( | |
| <Box flexDirection="column" paddingY={0}> | |
| {headerText && ( | |
| <Box marginBottom={1}> | |
| <Text color={headerColor} italic> | |
| {headerText} | |
| </Text> | |
| </Box> | |
| )} | |
| <Box flexDirection="column" marginLeft={0} gap={0}> | |
| {(historyOverrides ?? progress.recentActivity).map( | |
| (item: SubagentActivityItem) => { | |
| if (item.type === 'thought') { | |
| const isCancellation = item.content === 'Request cancelled.'; | |
| const icon = isCancellation ? 'ℹ ' : '💭'; | |
| const color = isCancellation | |
| ? theme.status.warning | |
| : theme.text.secondary; | |
| return ( | |
| <Box key={item.id} flexDirection="row"> | |
| <Box minWidth={STATUS_INDICATOR_WIDTH}> | |
| <Text color={color}>{icon}</Text> | |
| </Box> | |
| <Box flexGrow={1}> | |
| <Text color={color}>{item.content}</Text> | |
| </Box> | |
| </Box> | |
| ); | |
| } else if (item.type === 'tool_call') { | |
| const statusSymbol = | |
| item.status === SubagentState.RUNNING ? ( | |
| <Spinner type="dots" /> | |
| ) : item.status === SubagentState.COMPLETED ? ( | |
| <Text color={theme.status.success}> | |
| {TOOL_STATUS.SUCCESS} | |
| </Text> | |
| ) : item.status === SubagentState.CANCELLED ? ( | |
| <Text color={theme.status.warning} bold> | |
| {TOOL_STATUS.CANCELED} | |
| </Text> | |
| ) : ( | |
| <Text color={theme.status.error}>{TOOL_STATUS.ERROR}</Text> | |
| ); | |
| const formattedArgs = | |
| item.description || formatToolArgs(item.args); | |
| const displayArgs = | |
| formattedArgs.length > 60 | |
| ? formattedArgs.slice(0, 60) + '...' | |
| : formattedArgs; | |
| return ( | |
| <Box key={item.id} flexDirection="row"> | |
| <Box minWidth={STATUS_INDICATOR_WIDTH}>{statusSymbol}</Box> | |
| <Box flexDirection="row" flexGrow={1} flexWrap="wrap"> | |
| <Text | |
| bold | |
| color={theme.text.primary} | |
| strikethrough={item.status === SubagentState.CANCELLED} | |
| > | |
| {item.displayName || item.content} | |
| </Text> | |
| {displayArgs && ( | |
| <Box marginLeft={1}> | |
| <Text | |
| color={theme.text.secondary} | |
| wrap="truncate" | |
| strikethrough={ | |
| item.status === SubagentState.CANCELLED | |
| } | |
| > | |
| {displayArgs} | |
| </Text> | |
| </Box> | |
| )} | |
| </Box> | |
| </Box> | |
| ); | |
| } | |
| return null; | |
| }, | |
| )} | |
| </Box> | |
| {progress.result && ( | |
| <Box flexDirection="column" marginTop={1}> | |
| {progress.terminateReason && progress.terminateReason !== 'GOAL' && ( | |
| <Box marginBottom={1}> | |
| <Text color={theme.status.warning} bold> | |
| Agent Finished Early ({progress.terminateReason}) | |
| </Text> | |
| </Box> | |
| )} | |
| <MarkdownDisplay | |
| text={safeJsonToMarkdown(progress.result)} | |
| isPending={progress.state !== SubagentState.COMPLETED} | |
| terminalWidth={terminalWidth} | |
| /> | |
| </Box> | |
| )} | |
| </Box> | |
| ); | |
| }; | |