/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import React, { useMemo } from 'react'; import { Box } from 'ink'; import { IndividualToolCallDisplay, StreamingState, ToolCallStatus, } from '../../types.js'; import { ToolMessage } from './ToolMessage.js'; import { ToolConfirmationMessage } from './ToolConfirmationMessage.js'; import { Colors } from '../../colors.js'; interface ToolGroupMessageProps { groupId: number; toolCalls: IndividualToolCallDisplay[]; availableTerminalHeight: number; streamingState?: StreamingState; } // Main component renders the border and maps the tools using ToolMessage export const ToolGroupMessage: React.FC = ({ toolCalls, availableTerminalHeight, streamingState, }) => { const hasPending = !toolCalls.every( (t) => t.status === ToolCallStatus.Success, ); const borderColor = hasPending ? Colors.AccentYellow : Colors.SubtleComment; const staticHeight = /* border */ 2 + /* marginBottom */ 1; // only prompt for tool approval on the first 'confirming' tool in the list // note, after the CTA, this automatically moves over to the next 'confirming' tool const toolAwaitingApproval = useMemo( () => toolCalls.find((tc) => tc.status === ToolCallStatus.Confirming), [toolCalls], ); return ( {toolCalls.map((tool) => { const isConfirming = toolAwaitingApproval?.callId === tool.callId; return ( {tool.status === ToolCallStatus.Confirming && isConfirming && tool.confirmationDetails && ( )} ); })} ); };