No intentional different behavior aside for tweaks suggested from the code review of #506 Refactor: Extract console message logic to custom hook This commit refactors the console message handling from App.tsx into a new custom hook useConsoleMessages. This change improves the testability of the console message logic and declutters the main App component. Created useConsoleMessages.ts to encapsulate console message state and update logic. Updated App.tsx to utilize the new useConsoleMessages hook. Added unit tests for useConsoleMessages.ts to ensure its functionality. I deleted and started over on LoadingIndicator.test.tsx as I spent way too much time trying to fix it before just regenerating the tests as the code was easier to write tests for from scratch and the existing tests were not that good (I added them in the previous pull request).
89 lines
2.9 KiB
TypeScript
89 lines
2.9 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import React, { useMemo } from 'react';
|
|
import { Box } from 'ink';
|
|
import { IndividualToolCallDisplay, 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;
|
|
}
|
|
|
|
// Main component renders the border and maps the tools using ToolMessage
|
|
export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
|
toolCalls,
|
|
availableTerminalHeight,
|
|
}) => {
|
|
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 (
|
|
<Box
|
|
flexDirection="column"
|
|
borderStyle="round"
|
|
/*
|
|
This width constraint is highly important and protects us from an Ink rendering bug.
|
|
Since the ToolGroup can typically change rendering states frequently, it can cause
|
|
Ink to render the border of the box incorrectly and span multiple lines and even
|
|
cause tearing.
|
|
*/
|
|
width="100%"
|
|
marginLeft={1}
|
|
borderDimColor={hasPending}
|
|
borderColor={borderColor}
|
|
marginBottom={1}
|
|
>
|
|
{toolCalls.map((tool) => {
|
|
const isConfirming = toolAwaitingApproval?.callId === tool.callId;
|
|
return (
|
|
<Box key={tool.callId} flexDirection="column">
|
|
<Box flexDirection="row" alignItems="center">
|
|
<ToolMessage
|
|
callId={tool.callId}
|
|
name={tool.name}
|
|
description={tool.description}
|
|
resultDisplay={tool.resultDisplay}
|
|
status={tool.status}
|
|
confirmationDetails={tool.confirmationDetails}
|
|
availableTerminalHeight={availableTerminalHeight - staticHeight}
|
|
emphasis={
|
|
isConfirming
|
|
? 'high'
|
|
: toolAwaitingApproval
|
|
? 'low'
|
|
: 'medium'
|
|
}
|
|
/>
|
|
</Box>
|
|
{tool.status === ToolCallStatus.Confirming &&
|
|
isConfirming &&
|
|
tool.confirmationDetails && (
|
|
<ToolConfirmationMessage
|
|
confirmationDetails={tool.confirmationDetails}
|
|
/>
|
|
)}
|
|
</Box>
|
|
);
|
|
})}
|
|
</Box>
|
|
);
|
|
};
|