mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
Sticky headers where the top rounded border is sticky. (#12971)
This commit is contained in:
@@ -19,6 +19,7 @@ import { calculateMainAreaWidth } from '../ui/utils/ui-sizing.js';
|
|||||||
import { VimModeProvider } from '../ui/contexts/VimModeContext.js';
|
import { VimModeProvider } from '../ui/contexts/VimModeContext.js';
|
||||||
import { MouseProvider } from '../ui/contexts/MouseContext.js';
|
import { MouseProvider } from '../ui/contexts/MouseContext.js';
|
||||||
import { ScrollProvider } from '../ui/contexts/ScrollProvider.js';
|
import { ScrollProvider } from '../ui/contexts/ScrollProvider.js';
|
||||||
|
import { StreamingContext } from '../ui/contexts/StreamingContext.js';
|
||||||
|
|
||||||
import { type Config } from '@google/gemini-cli-core';
|
import { type Config } from '@google/gemini-cli-core';
|
||||||
|
|
||||||
@@ -69,6 +70,9 @@ const mockConfig = {
|
|||||||
getTargetDir: () =>
|
getTargetDir: () =>
|
||||||
'/Users/test/project/foo/bar/and/some/more/directories/to/make/it/long',
|
'/Users/test/project/foo/bar/and/some/more/directories/to/make/it/long',
|
||||||
getDebugMode: () => false,
|
getDebugMode: () => false,
|
||||||
|
isTrustedFolder: () => true,
|
||||||
|
getIdeMode: () => false,
|
||||||
|
getEnableInteractiveShell: () => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const configProxy = new Proxy(mockConfig, {
|
const configProxy = new Proxy(mockConfig, {
|
||||||
@@ -177,20 +181,22 @@ export const renderWithProviders = (
|
|||||||
<UIStateContext.Provider value={finalUiState}>
|
<UIStateContext.Provider value={finalUiState}>
|
||||||
<VimModeProvider settings={finalSettings}>
|
<VimModeProvider settings={finalSettings}>
|
||||||
<ShellFocusContext.Provider value={shellFocus}>
|
<ShellFocusContext.Provider value={shellFocus}>
|
||||||
<KeypressProvider>
|
<StreamingContext.Provider value={finalUiState.streamingState}>
|
||||||
<MouseProvider mouseEventsEnabled={mouseEventsEnabled}>
|
<KeypressProvider>
|
||||||
<ScrollProvider>
|
<MouseProvider mouseEventsEnabled={mouseEventsEnabled}>
|
||||||
<Box
|
<ScrollProvider>
|
||||||
width={terminalWidth}
|
<Box
|
||||||
flexShrink={0}
|
width={terminalWidth}
|
||||||
flexGrow={0}
|
flexShrink={0}
|
||||||
flexDirection="column"
|
flexGrow={0}
|
||||||
>
|
flexDirection="column"
|
||||||
{component}
|
>
|
||||||
</Box>
|
{component}
|
||||||
</ScrollProvider>
|
</Box>
|
||||||
</MouseProvider>
|
</ScrollProvider>
|
||||||
</KeypressProvider>
|
</MouseProvider>
|
||||||
|
</KeypressProvider>
|
||||||
|
</StreamingContext.Provider>
|
||||||
</ShellFocusContext.Provider>
|
</ShellFocusContext.Provider>
|
||||||
</VimModeProvider>
|
</VimModeProvider>
|
||||||
</UIStateContext.Provider>
|
</UIStateContext.Provider>
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import type { HistoryItem, HistoryItemWithoutId } from '../types.js';
|
|||||||
import { Text } from 'ink';
|
import { Text } from 'ink';
|
||||||
import { renderWithProviders } from '../../test-utils/render.js';
|
import { renderWithProviders } from '../../test-utils/render.js';
|
||||||
import type { Config } from '@google/gemini-cli-core';
|
import type { Config } from '@google/gemini-cli-core';
|
||||||
import type { ToolMessageProps } from './messages/ToolMessage.js';
|
|
||||||
|
|
||||||
vi.mock('../contexts/AppContext.js', () => ({
|
vi.mock('../contexts/AppContext.js', () => ({
|
||||||
useAppContext: () => ({
|
useAppContext: () => ({
|
||||||
@@ -32,14 +31,6 @@ vi.mock('../GeminiRespondingSpinner.js', () => ({
|
|||||||
GeminiRespondingSpinner: () => <Text>Spinner</Text>,
|
GeminiRespondingSpinner: () => <Text>Spinner</Text>,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('./messages/ToolMessage.js', () => ({
|
|
||||||
ToolMessage: (props: ToolMessageProps) => (
|
|
||||||
<Text>
|
|
||||||
ToolMessage: {props.name} - {props.status}
|
|
||||||
</Text>
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const mockHistory: HistoryItem[] = [
|
const mockHistory: HistoryItem[] = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|||||||
@@ -10,9 +10,14 @@ import { StickyHeader } from './StickyHeader.js';
|
|||||||
import { renderWithProviders } from '../../test-utils/render.js';
|
import { renderWithProviders } from '../../test-utils/render.js';
|
||||||
|
|
||||||
describe('StickyHeader', () => {
|
describe('StickyHeader', () => {
|
||||||
it('renders children', () => {
|
it.each([true, false])('renders children with isFirst=%s', (isFirst) => {
|
||||||
const { lastFrame } = renderWithProviders(
|
const { lastFrame } = renderWithProviders(
|
||||||
<StickyHeader width={80}>
|
<StickyHeader
|
||||||
|
isFirst={isFirst}
|
||||||
|
width={80}
|
||||||
|
borderColor="green"
|
||||||
|
borderDimColor={false}
|
||||||
|
>
|
||||||
<Text>Hello Sticky</Text>
|
<Text>Hello Sticky</Text>
|
||||||
</StickyHeader>,
|
</StickyHeader>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,11 +11,17 @@ import { theme } from '../semantic-colors.js';
|
|||||||
export interface StickyHeaderProps {
|
export interface StickyHeaderProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
width: number;
|
width: number;
|
||||||
|
isFirst: boolean;
|
||||||
|
borderColor: string;
|
||||||
|
borderDimColor: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StickyHeader: React.FC<StickyHeaderProps> = ({
|
export const StickyHeader: React.FC<StickyHeaderProps> = ({
|
||||||
children,
|
children,
|
||||||
width,
|
width,
|
||||||
|
isFirst,
|
||||||
|
borderColor,
|
||||||
|
borderDimColor,
|
||||||
}) => (
|
}) => (
|
||||||
<Box
|
<Box
|
||||||
sticky
|
sticky
|
||||||
@@ -24,20 +30,43 @@ export const StickyHeader: React.FC<StickyHeaderProps> = ({
|
|||||||
width={width}
|
width={width}
|
||||||
stickyChildren={
|
stickyChildren={
|
||||||
<Box
|
<Box
|
||||||
borderStyle="single"
|
borderStyle="round"
|
||||||
|
flexDirection="column"
|
||||||
width={width}
|
width={width}
|
||||||
opaque
|
opaque
|
||||||
borderColor={theme.ui.dark}
|
borderColor={borderColor}
|
||||||
borderTop={false}
|
borderDimColor={borderDimColor}
|
||||||
borderLeft={false}
|
borderBottom={false}
|
||||||
borderRight={false}
|
borderTop={isFirst}
|
||||||
paddingX={1}
|
paddingTop={isFirst ? 0 : 1}
|
||||||
>
|
>
|
||||||
{children}
|
<Box paddingX={1}>{children}</Box>
|
||||||
|
{/* Dark border to separate header from content. */}
|
||||||
|
<Box
|
||||||
|
width={width - 2}
|
||||||
|
borderColor={theme.ui.dark}
|
||||||
|
borderStyle="single"
|
||||||
|
borderTop={false}
|
||||||
|
borderBottom={true}
|
||||||
|
borderLeft={false}
|
||||||
|
borderRight={false}
|
||||||
|
></Box>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Box paddingX={1} width={width}>
|
<Box
|
||||||
|
borderStyle="round"
|
||||||
|
width={width}
|
||||||
|
borderColor={borderColor}
|
||||||
|
borderDimColor={borderDimColor}
|
||||||
|
borderBottom={false}
|
||||||
|
borderTop={isFirst}
|
||||||
|
borderLeft={true}
|
||||||
|
borderRight={true}
|
||||||
|
paddingX={1}
|
||||||
|
paddingBottom={1}
|
||||||
|
paddingTop={isFirst ? 0 : 1}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
+6
-3
@@ -17,12 +17,15 @@ Tips for getting started:
|
|||||||
3. Create GEMINI.md files to customize your interactions with Gemini.
|
3. Create GEMINI.md files to customize your interactions with Gemini.
|
||||||
4. /help for more information.
|
4. /help for more information.
|
||||||
╭──────────────────────────────────────────────────────────────────────────────╮
|
╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ToolMessage: tool1 - Success │
|
│ ✓ tool1 Description for tool 1 │
|
||||||
|
│ │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||||
╭──────────────────────────────────────────────────────────────────────────────╮
|
╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ToolMessage: tool2 - Success │
|
│ ✓ tool2 Description for tool 2 │
|
||||||
|
│ │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||||
╭──────────────────────────────────────────────────────────────────────────────╮
|
╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ToolMessage: tool3 - Pending │
|
│ o tool3 Description for tool 3 │
|
||||||
|
│ │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
terminalWidth,
|
terminalWidth,
|
||||||
}) => {
|
}) => {
|
||||||
const { onConfirm } = confirmationDetails;
|
const { onConfirm } = confirmationDetails;
|
||||||
const childWidth = terminalWidth - 2; // 2 for padding
|
|
||||||
|
|
||||||
const isAlternateBuffer = useAlternateBuffer();
|
const isAlternateBuffer = useAlternateBuffer();
|
||||||
|
|
||||||
@@ -249,21 +248,15 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
||||||
bodyContent = (
|
bodyContent = isAlternateBuffer ? (
|
||||||
<Box flexDirection="column">
|
commandBox
|
||||||
<Box paddingX={1}>
|
) : (
|
||||||
{isAlternateBuffer ? (
|
<MaxSizedBox
|
||||||
commandBox
|
maxHeight={bodyContentHeight}
|
||||||
) : (
|
maxWidth={Math.max(terminalWidth, 1)}
|
||||||
<MaxSizedBox
|
>
|
||||||
maxHeight={bodyContentHeight}
|
{commandBox}
|
||||||
maxWidth={Math.max(childWidth, 1)}
|
</MaxSizedBox>
|
||||||
>
|
|
||||||
{commandBox}
|
|
||||||
</MaxSizedBox>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
);
|
);
|
||||||
} else if (confirmationDetails.type === 'info') {
|
} else if (confirmationDetails.type === 'info') {
|
||||||
const infoProps = confirmationDetails;
|
const infoProps = confirmationDetails;
|
||||||
@@ -274,7 +267,7 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
);
|
);
|
||||||
|
|
||||||
bodyContent = (
|
bodyContent = (
|
||||||
<Box flexDirection="column" paddingX={1}>
|
<Box flexDirection="column">
|
||||||
<Text color={theme.text.link}>
|
<Text color={theme.text.link}>
|
||||||
<RenderInline
|
<RenderInline
|
||||||
text={infoProps.prompt}
|
text={infoProps.prompt}
|
||||||
@@ -299,7 +292,7 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
const mcpProps = confirmationDetails as ToolMcpConfirmationDetails;
|
const mcpProps = confirmationDetails as ToolMcpConfirmationDetails;
|
||||||
|
|
||||||
bodyContent = (
|
bodyContent = (
|
||||||
<Box flexDirection="column" paddingX={1}>
|
<Box flexDirection="column">
|
||||||
<Text color={theme.text.link}>MCP Server: {mcpProps.serverName}</Text>
|
<Text color={theme.text.link}>MCP Server: {mcpProps.serverName}</Text>
|
||||||
<Text color={theme.text.link}>Tool: {mcpProps.toolName}</Text>
|
<Text color={theme.text.link}>Tool: {mcpProps.toolName}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -315,7 +308,6 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
availableTerminalHeight,
|
availableTerminalHeight,
|
||||||
terminalWidth,
|
terminalWidth,
|
||||||
isAlternateBuffer,
|
isAlternateBuffer,
|
||||||
childWidth,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (confirmationDetails.type === 'edit') {
|
if (confirmationDetails.type === 'edit') {
|
||||||
@@ -326,7 +318,8 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
borderStyle="round"
|
borderStyle="round"
|
||||||
borderColor={theme.border.default}
|
borderColor={theme.border.default}
|
||||||
justifyContent="space-around"
|
justifyContent="space-around"
|
||||||
padding={1}
|
paddingTop={1}
|
||||||
|
paddingBottom={1}
|
||||||
overflow="hidden"
|
overflow="hidden"
|
||||||
>
|
>
|
||||||
<Text color={theme.text.primary}>Modify in progress: </Text>
|
<Text color={theme.text.primary}>Modify in progress: </Text>
|
||||||
@@ -342,23 +335,17 @@ export const ToolConfirmationMessage: React.FC<
|
|||||||
<Box flexDirection="column" paddingTop={0} paddingBottom={1}>
|
<Box flexDirection="column" paddingTop={0} paddingBottom={1}>
|
||||||
{/* Body Content (Diff Renderer or Command Info) */}
|
{/* Body Content (Diff Renderer or Command Info) */}
|
||||||
{/* No separate context display here anymore for edits */}
|
{/* No separate context display here anymore for edits */}
|
||||||
<Box
|
<Box flexGrow={1} flexShrink={1} overflow="hidden" marginBottom={1}>
|
||||||
flexGrow={1}
|
|
||||||
flexShrink={1}
|
|
||||||
overflow="hidden"
|
|
||||||
marginBottom={1}
|
|
||||||
paddingLeft={1}
|
|
||||||
>
|
|
||||||
{bodyContent}
|
{bodyContent}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Confirmation Question */}
|
{/* Confirmation Question */}
|
||||||
<Box marginBottom={1} flexShrink={0} paddingX={1}>
|
<Box marginBottom={1} flexShrink={0}>
|
||||||
<Text color={theme.text.primary}>{question}</Text>
|
<Text color={theme.text.primary}>{question}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Select Input for Options */}
|
{/* Select Input for Options */}
|
||||||
<Box flexShrink={0} paddingX={1}>
|
<Box flexShrink={0}>
|
||||||
<RadioButtonSelect
|
<RadioButtonSelect
|
||||||
items={options}
|
items={options}
|
||||||
onSelect={handleSelect}
|
onSelect={handleSelect}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
import { renderWithProviders } from '../../../test-utils/render.js';
|
import { renderWithProviders } from '../../../test-utils/render.js';
|
||||||
import { describe, it, expect, vi } from 'vitest';
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
import { Text } from 'ink';
|
|
||||||
import { ToolGroupMessage } from './ToolGroupMessage.js';
|
import { ToolGroupMessage } from './ToolGroupMessage.js';
|
||||||
import type { IndividualToolCallDisplay } from '../../types.js';
|
import type { IndividualToolCallDisplay } from '../../types.js';
|
||||||
import { ToolCallStatus } from '../../types.js';
|
import { ToolCallStatus } from '../../types.js';
|
||||||
@@ -252,20 +251,32 @@ describe('<ToolGroupMessage />', () => {
|
|||||||
unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
it('renders header when scrolled', () => {
|
it('renders header when scrolled', () => {
|
||||||
|
=======
|
||||||
|
it('renders sticky header when scrolled', () => {
|
||||||
|
>>>>>>> ee7065f6 (Sticky headers where the top rounded border is sticky. (#12971))
|
||||||
const toolCalls = [
|
const toolCalls = [
|
||||||
createToolCall({
|
createToolCall({
|
||||||
callId: '1',
|
callId: '1',
|
||||||
name: 'tool-1',
|
name: 'tool-1',
|
||||||
|
<<<<<<< HEAD
|
||||||
description:
|
description:
|
||||||
'Description 1. This is a long description that will need to be truncated if the terminal width is small.',
|
'Description 1. This is a long description that will need to be truncated if the terminal width is small.',
|
||||||
resultDisplay: 'line1\nline2\nline3\nline4\nline5',
|
resultDisplay: 'line1\nline2\nline3\nline4\nline5',
|
||||||
|
=======
|
||||||
|
description: 'Description 1\n'.repeat(5),
|
||||||
|
>>>>>>> ee7065f6 (Sticky headers where the top rounded border is sticky. (#12971))
|
||||||
}),
|
}),
|
||||||
createToolCall({
|
createToolCall({
|
||||||
callId: '2',
|
callId: '2',
|
||||||
name: 'tool-2',
|
name: 'tool-2',
|
||||||
|
<<<<<<< HEAD
|
||||||
description: 'Description 2',
|
description: 'Description 2',
|
||||||
resultDisplay: 'line1\nline2',
|
resultDisplay: 'line1\nline2',
|
||||||
|
=======
|
||||||
|
description: 'Description 2\n'.repeat(5),
|
||||||
|
>>>>>>> ee7065f6 (Sticky headers where the top rounded border is sticky. (#12971))
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
const { lastFrame, unmount } = renderWithProviders(
|
const { lastFrame, unmount } = renderWithProviders(
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import { ToolConfirmationMessage } from './ToolConfirmationMessage.js';
|
|||||||
import { theme } from '../../semantic-colors.js';
|
import { theme } from '../../semantic-colors.js';
|
||||||
import { SHELL_COMMAND_NAME, SHELL_NAME } from '../../constants.js';
|
import { SHELL_COMMAND_NAME, SHELL_NAME } from '../../constants.js';
|
||||||
import { useConfig } from '../../contexts/ConfigContext.js';
|
import { useConfig } from '../../contexts/ConfigContext.js';
|
||||||
import { useAlternateBuffer } from '../../hooks/useAlternateBuffer.js';
|
|
||||||
|
|
||||||
interface ToolGroupMessageProps {
|
interface ToolGroupMessageProps {
|
||||||
groupId: number;
|
groupId: number;
|
||||||
@@ -48,7 +47,6 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const isAlternateBuffer = useAlternateBuffer();
|
|
||||||
const isShellCommand = toolCalls.some(
|
const isShellCommand = toolCalls.some(
|
||||||
(t) => t.name === SHELL_COMMAND_NAME || t.name === SHELL_NAME,
|
(t) => t.name === SHELL_COMMAND_NAME || t.name === SHELL_NAME,
|
||||||
);
|
);
|
||||||
@@ -59,10 +57,10 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
|||||||
? theme.status.warning
|
? theme.status.warning
|
||||||
: theme.border.default;
|
: theme.border.default;
|
||||||
|
|
||||||
|
const borderDimColor =
|
||||||
|
hasPending && (!isShellCommand || !isEmbeddedShellFocused);
|
||||||
|
|
||||||
const staticHeight = /* border */ 2 + /* marginBottom */ 1;
|
const staticHeight = /* border */ 2 + /* marginBottom */ 1;
|
||||||
// This is a bit of a magic number, but it accounts for the border and
|
|
||||||
// marginLeft in regular mode and just the border in alternate buffer mode.
|
|
||||||
const innerWidth = isAlternateBuffer ? terminalWidth - 3 : terminalWidth - 4;
|
|
||||||
|
|
||||||
// only prompt for tool approval on the first 'confirming' tool in the list
|
// 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
|
// note, after the CTA, this automatically moves over to the next 'confirming' tool
|
||||||
@@ -89,9 +87,11 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
// This box doesn't have a border even though it conceptually does because
|
||||||
|
// we need to allow the sticky headers to render the borders themselves so
|
||||||
|
// that the top border can be sticky.
|
||||||
<Box
|
<Box
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
borderStyle="round"
|
|
||||||
/*
|
/*
|
||||||
This width constraint is highly important and protects us from an Ink rendering bug.
|
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
|
Since the ToolGroup can typically change rendering states frequently, it can cause
|
||||||
@@ -99,52 +99,65 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
|||||||
cause tearing.
|
cause tearing.
|
||||||
*/
|
*/
|
||||||
width={terminalWidth}
|
width={terminalWidth}
|
||||||
borderDimColor={
|
|
||||||
hasPending && (!isShellCommand || !isEmbeddedShellFocused)
|
|
||||||
}
|
|
||||||
borderColor={borderColor}
|
|
||||||
gap={1}
|
|
||||||
>
|
>
|
||||||
{toolCalls.map((tool) => {
|
{toolCalls.map((tool, index) => {
|
||||||
const isConfirming = toolAwaitingApproval?.callId === tool.callId;
|
const isConfirming = toolAwaitingApproval?.callId === tool.callId;
|
||||||
|
const isFirst = index === 0;
|
||||||
|
const isLast = index === toolCalls.length - 1;
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
key={tool.callId}
|
key={tool.callId}
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
minHeight={1}
|
minHeight={1}
|
||||||
width={innerWidth}
|
width={terminalWidth}
|
||||||
>
|
>
|
||||||
<ToolMessage
|
<ToolMessage
|
||||||
{...tool}
|
{...tool}
|
||||||
availableTerminalHeight={availableTerminalHeightPerToolMessage}
|
availableTerminalHeight={availableTerminalHeightPerToolMessage}
|
||||||
terminalWidth={innerWidth}
|
terminalWidth={terminalWidth}
|
||||||
emphasis={
|
emphasis={
|
||||||
isConfirming ? 'high' : toolAwaitingApproval ? 'low' : 'medium'
|
isConfirming ? 'high' : toolAwaitingApproval ? 'low' : 'medium'
|
||||||
}
|
}
|
||||||
activeShellPtyId={activeShellPtyId}
|
activeShellPtyId={activeShellPtyId}
|
||||||
embeddedShellFocused={embeddedShellFocused}
|
embeddedShellFocused={embeddedShellFocused}
|
||||||
config={config}
|
config={config}
|
||||||
|
isFirst={isFirst}
|
||||||
|
borderColor={borderColor}
|
||||||
|
borderDimColor={borderDimColor}
|
||||||
/>
|
/>
|
||||||
{tool.status === ToolCallStatus.Confirming &&
|
<Box
|
||||||
isConfirming &&
|
borderLeft={true}
|
||||||
tool.confirmationDetails && (
|
borderRight={true}
|
||||||
<ToolConfirmationMessage
|
borderTop={false}
|
||||||
confirmationDetails={tool.confirmationDetails}
|
borderBottom={isLast}
|
||||||
config={config}
|
borderColor={borderColor}
|
||||||
isFocused={isFocused}
|
borderDimColor={borderDimColor}
|
||||||
availableTerminalHeight={
|
flexDirection="column"
|
||||||
availableTerminalHeightPerToolMessage
|
borderStyle="round"
|
||||||
}
|
paddingLeft={1}
|
||||||
terminalWidth={innerWidth}
|
paddingRight={1}
|
||||||
/>
|
>
|
||||||
|
{tool.status === ToolCallStatus.Confirming &&
|
||||||
|
isConfirming &&
|
||||||
|
tool.confirmationDetails && (
|
||||||
|
<ToolConfirmationMessage
|
||||||
|
confirmationDetails={tool.confirmationDetails}
|
||||||
|
config={config}
|
||||||
|
isFocused={isFocused}
|
||||||
|
availableTerminalHeight={
|
||||||
|
availableTerminalHeightPerToolMessage
|
||||||
|
}
|
||||||
|
terminalWidth={terminalWidth - 4}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{tool.outputFile && (
|
||||||
|
<Box>
|
||||||
|
<Text color={theme.text.primary}>
|
||||||
|
Output too long and was saved to: {tool.outputFile}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
)}
|
)}
|
||||||
{tool.outputFile && (
|
</Box>
|
||||||
<Box marginX={1}>
|
|
||||||
<Text color={theme.text.primary}>
|
|
||||||
Output too long and was saved to: {tool.outputFile}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ describe('<ToolMessage />', () => {
|
|||||||
terminalWidth: 80,
|
terminalWidth: 80,
|
||||||
confirmationDetails: undefined,
|
confirmationDetails: undefined,
|
||||||
emphasis: 'medium',
|
emphasis: 'medium',
|
||||||
|
isFirst: true,
|
||||||
|
borderColor: 'green',
|
||||||
|
borderDimColor: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
it('renders basic tool information', () => {
|
it('renders basic tool information', () => {
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ export interface ToolMessageProps extends IndividualToolCallDisplay {
|
|||||||
renderOutputAsMarkdown?: boolean;
|
renderOutputAsMarkdown?: boolean;
|
||||||
activeShellPtyId?: number | null;
|
activeShellPtyId?: number | null;
|
||||||
embeddedShellFocused?: boolean;
|
embeddedShellFocused?: boolean;
|
||||||
|
isFirst: boolean;
|
||||||
|
borderColor: string;
|
||||||
|
borderDimColor: boolean;
|
||||||
config?: Config;
|
config?: Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +61,9 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({
|
|||||||
embeddedShellFocused,
|
embeddedShellFocused,
|
||||||
ptyId,
|
ptyId,
|
||||||
config,
|
config,
|
||||||
|
isFirst,
|
||||||
|
borderColor,
|
||||||
|
borderDimColor,
|
||||||
}) => {
|
}) => {
|
||||||
const { renderMarkdown } = useUIState();
|
const { renderMarkdown } = useUIState();
|
||||||
const isAlternateBuffer = useAlternateBuffer();
|
const isAlternateBuffer = useAlternateBuffer();
|
||||||
@@ -116,7 +122,8 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({
|
|||||||
if (availableHeight && !isAlternateBuffer) {
|
if (availableHeight && !isAlternateBuffer) {
|
||||||
renderOutputAsMarkdown = false;
|
renderOutputAsMarkdown = false;
|
||||||
}
|
}
|
||||||
const childWidth = terminalWidth;
|
const combinedPaddingAndBorderWidth = 4;
|
||||||
|
const childWidth = terminalWidth - combinedPaddingAndBorderWidth;
|
||||||
|
|
||||||
const truncatedResultDisplay = React.useMemo(() => {
|
const truncatedResultDisplay = React.useMemo(() => {
|
||||||
if (typeof resultDisplay === 'string') {
|
if (typeof resultDisplay === 'string') {
|
||||||
@@ -131,7 +138,7 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({
|
|||||||
if (!truncatedResultDisplay) return null;
|
if (!truncatedResultDisplay) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box width={terminalWidth} flexDirection="column" paddingLeft={1}>
|
<Box width={childWidth} flexDirection="column">
|
||||||
<Box flexDirection="column">
|
<Box flexDirection="column">
|
||||||
{typeof truncatedResultDisplay === 'string' &&
|
{typeof truncatedResultDisplay === 'string' &&
|
||||||
renderOutputAsMarkdown ? (
|
renderOutputAsMarkdown ? (
|
||||||
@@ -189,15 +196,16 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({
|
|||||||
renderMarkdown,
|
renderMarkdown,
|
||||||
isAlternateBuffer,
|
isAlternateBuffer,
|
||||||
availableHeight,
|
availableHeight,
|
||||||
terminalWidth,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// We have the StickyHeader intentionally exceedsthe allowed width for this
|
|
||||||
// component by 1 so tne horizontal line it renders can extend into the 1
|
|
||||||
// pixel of padding of the box drawn by the parent of the ToolMessage.
|
|
||||||
<>
|
<>
|
||||||
<StickyHeader width={terminalWidth + 1}>
|
<StickyHeader
|
||||||
|
width={terminalWidth}
|
||||||
|
isFirst={isFirst}
|
||||||
|
borderColor={borderColor}
|
||||||
|
borderDimColor={borderDimColor}
|
||||||
|
>
|
||||||
<ToolStatusIndicator status={status} name={name} />
|
<ToolStatusIndicator status={status} name={name} />
|
||||||
<ToolInfo
|
<ToolInfo
|
||||||
name={name}
|
name={name}
|
||||||
@@ -214,15 +222,28 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({
|
|||||||
)}
|
)}
|
||||||
{emphasis === 'high' && <TrailingIndicator />}
|
{emphasis === 'high' && <TrailingIndicator />}
|
||||||
</StickyHeader>
|
</StickyHeader>
|
||||||
{renderedResult}
|
<Box
|
||||||
{isThisShellFocused && config && (
|
width={terminalWidth}
|
||||||
<Box paddingLeft={STATUS_INDICATOR_WIDTH} marginTop={1}>
|
borderStyle="round"
|
||||||
<ShellInputPrompt
|
borderColor={borderColor}
|
||||||
activeShellPtyId={activeShellPtyId ?? null}
|
borderDimColor={borderDimColor}
|
||||||
focus={embeddedShellFocused}
|
borderTop={false}
|
||||||
/>
|
borderBottom={false}
|
||||||
</Box>
|
borderLeft={true}
|
||||||
)}
|
borderRight={true}
|
||||||
|
paddingX={1}
|
||||||
|
flexDirection="column"
|
||||||
|
>
|
||||||
|
{renderedResult}
|
||||||
|
{isThisShellFocused && config && (
|
||||||
|
<Box paddingLeft={STATUS_INDICATOR_WIDTH} marginTop={1}>
|
||||||
|
<ShellInputPrompt
|
||||||
|
activeShellPtyId={activeShellPtyId ?? null}
|
||||||
|
focus={embeddedShellFocused}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ describe('<ToolMessage /> - Raw Markdown Display Snapshots', () => {
|
|||||||
terminalWidth: 80,
|
terminalWidth: 80,
|
||||||
confirmationDetails: undefined,
|
confirmationDetails: undefined,
|
||||||
emphasis: 'medium',
|
emphasis: 'medium',
|
||||||
|
isFirst: true,
|
||||||
|
borderColor: 'green',
|
||||||
|
borderDimColor: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
|
|||||||
+107
-33
@@ -2,37 +2,53 @@
|
|||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Border Color Logic > uses gray border when all tools are successful and no shell commands 1`] = `
|
exports[`<ToolGroupMessage /> > Border Color Logic > uses gray border when all tools are successful and no shell commands 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-123]: ✓ test-tool - A tool for testing (medium) │
|
│ ✓ test-tool A tool for testing │
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-2]: ✓ another-tool - A tool for testing (medium) │
|
│ Test result │
|
||||||
|
│ │
|
||||||
|
│ ✓ another-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Border Color Logic > uses yellow border for shell commands even when successful 1`] = `
|
exports[`<ToolGroupMessage /> > Border Color Logic > uses yellow border for shell commands even when successful 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-123]: ✓ run_shell_command - A tool for testing (medium) │
|
│ ✓ run_shell_command A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Border Color Logic > uses yellow border when tools are pending 1`] = `
|
exports[`<ToolGroupMessage /> > Border Color Logic > uses yellow border when tools are pending 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-123]: o test-tool - A tool for testing (medium) │
|
│ o test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Confirmation Handling > shows confirmation dialog for first confirming tool only 1`] = `
|
exports[`<ToolGroupMessage /> > Confirmation Handling > shows confirmation dialog for first confirming tool only 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-1]: ? first-confirm - A tool for testing (high) │
|
│ ? first-confirm A tool for testing ← │
|
||||||
│MockConfirmation: Confirm first tool │
|
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-2]: ? second-confirm - A tool for testing (low) │
|
│ Test result │
|
||||||
|
│ Confirm first tool │
|
||||||
|
│ │
|
||||||
|
│ Do you want to proceed? │
|
||||||
|
│ │
|
||||||
|
│ ● 1. Yes, allow once │
|
||||||
|
│ 2. Yes, allow always │
|
||||||
|
│ 3. No, suggest changes (esc) │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ ? second-confirm A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders empty tool calls array 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders empty tool calls array 1`] = `""`;
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders header when scrolled 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders header when scrolled 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
@@ -49,41 +65,87 @@ exports[`<ToolGroupMessage /> > Golden Snapshots > renders header when scrolled
|
|||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders mixed tool calls including shell command 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders mixed tool calls including shell command 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-1]: ✓ read_file - Read a file (medium) │
|
│ ✓ read_file Read a file │
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-2]: ⊷ run_shell_command - Run command (medium) │
|
│ Test result │
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-3]: o write_file - Write to file (medium) │
|
│ ⊷ run_shell_command Run command │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
|
│ │
|
||||||
|
│ o write_file Write to file │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders multiple tool calls with different statuses 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders multiple tool calls with different statuses 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-1]: ✓ successful-tool - This tool succeeded (medium) │
|
│ ✓ successful-tool This tool succeeded │
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-2]: o pending-tool - This tool is pending (medium) │
|
│ Test result │
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-3]: x error-tool - This tool failed (medium) │
|
│ o pending-tool This tool is pending │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
|
│ │
|
||||||
|
│ x error-tool This tool failed │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders shell command with yellow border 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders shell command with yellow border 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[shell-1]: ✓ run_shell_command - Execute shell command (medium) │
|
│ ✓ run_shell_command Execute shell command │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders single successful tool call 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders single successful tool call 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-123]: ✓ test-tool - A tool for testing (medium) │
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders sticky header when scrolled 1`] = `
|
||||||
|
"│ │
|
||||||
|
│ ✓ tool-2 Description 2 │
|
||||||
|
│ Description 2 │
|
||||||
|
│ Description 2 │
|
||||||
|
│ Description 2 │ ▄
|
||||||
|
│ Description 2 │ █
|
||||||
|
│ │ █
|
||||||
|
│ │ █
|
||||||
|
│ Test result │ █
|
||||||
|
╰──────────────────────────────────────────────────────────────────────────────╯ █"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders tool call awaiting confirmation 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders tool call awaiting confirmation 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-confirm]: ? confirmation-tool - This tool needs confirmation │
|
│ ? confirmation-tool This tool needs confirmation ← │
|
||||||
│(high) │
|
│ │
|
||||||
│MockConfirmation: Are you sure you want to proceed? │
|
│ Test result │
|
||||||
|
│ Are you sure you want to proceed? │
|
||||||
|
│ │
|
||||||
|
│ Do you want to proceed? │
|
||||||
|
│ │
|
||||||
|
│ ● 1. Yes, allow once │
|
||||||
|
│ 2. Yes, allow always │
|
||||||
|
│ 3. No, suggest changes (esc) │
|
||||||
|
│ │
|
||||||
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders tool call with outputFile 1`] = `
|
||||||
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
|
│ ✓ tool-with-file Tool that saved output to file │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
|
│ Output too long and was saved to: /path/to/output.txt │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -97,34 +159,46 @@ exports[`<ToolGroupMessage /> > Golden Snapshots > renders tool call with output
|
|||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders when not focused 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders when not focused 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-123]: ✓ test-tool - A tool for testing (medium) │
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders with limited terminal height 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders with limited terminal height 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-1]: ✓ tool-with-result - Tool with output (medium) │
|
│ ✓ tool-with-result Tool with output │
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-2]: ✓ another-tool - Another tool (medium) │
|
│ This is a long result that might need height constraints │
|
||||||
|
│ │
|
||||||
|
│ ✓ another-tool Another tool │
|
||||||
|
│ │
|
||||||
|
│ More output here │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders with narrow terminal width 1`] = `
|
exports[`<ToolGroupMessage /> > Golden Snapshots > renders with narrow terminal width 1`] = `
|
||||||
"╭──────────────────────────────────────╮
|
"╭──────────────────────────────────────╮
|
||||||
│MockTool[tool-123]: ✓ │
|
│ ✓ very-long-tool-name-that-might-wr │
|
||||||
│very-long-tool-name-that-might-wrap │
|
│ ap This is a very long │
|
||||||
│- This is a very long description │
|
│ description that might cause │
|
||||||
│that might cause wrapping issues │
|
│ wrapping issues │
|
||||||
│(medium) │
|
│ │
|
||||||
|
│ Test result │
|
||||||
╰──────────────────────────────────────╯"
|
╰──────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolGroupMessage /> > Height Calculation > calculates available height correctly with multiple tools with results 1`] = `
|
exports[`<ToolGroupMessage /> > Height Calculation > calculates available height correctly with multiple tools with results 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
│MockTool[tool-1]: ✓ test-tool - A tool for testing (medium) │
|
│ ✓ test-tool A tool for testing │
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-2]: ✓ test-tool - A tool for testing (medium) │
|
│ Result 1 │
|
||||||
|
│ │
|
||||||
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Result 2 │
|
||||||
|
│ │
|
||||||
|
│ ✓ test-tool A tool for testing │
|
||||||
│ │
|
│ │
|
||||||
│MockTool[tool-3]: ✓ test-tool - A tool for testing (medium) │
|
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰──────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|||||||
+24
-12
@@ -1,31 +1,43 @@
|
|||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=false, useAlternateBuffer=false '(raw markdown, regular buffer)' 1`] = `
|
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=false, useAlternateBuffer=false '(raw markdown, regular buffer)' 1`] = `
|
||||||
" ✓ test-tool A tool for testing
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
Test **bold** and \`code\` markdown"
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test **bold** and \`code\` markdown │"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=false, useAlternateBuffer=true '(raw markdown, alternate buffer)' 1`] = `
|
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=false, useAlternateBuffer=true '(raw markdown, alternate buffer)' 1`] = `
|
||||||
" ✓ test-tool A tool for testing
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
Test **bold** and \`code\` markdown"
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test **bold** and \`code\` markdown │"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=true, useAlternateBuffer=false '(constrained height, regular buffer -…' 1`] = `
|
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=true, useAlternateBuffer=false '(constrained height, regular buffer -…' 1`] = `
|
||||||
" ✓ test-tool A tool for testing
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
Test **bold** and \`code\` markdown"
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test **bold** and \`code\` markdown │"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=true, useAlternateBuffer=false '(default, regular buffer)' 1`] = `
|
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=true, useAlternateBuffer=false '(default, regular buffer)' 1`] = `
|
||||||
" ✓ test-tool A tool for testing
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
Test bold and code markdown"
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test bold and code markdown │"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=true, useAlternateBuffer=true '(constrained height, alternate buffer…' 1`] = `
|
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=true, useAlternateBuffer=true '(constrained height, alternate buffer…' 1`] = `
|
||||||
" ✓ test-tool A tool for testing
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
Test bold and code markdown"
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test bold and code markdown │"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=true, useAlternateBuffer=true '(default, alternate buffer)' 1`] = `
|
exports[`<ToolMessage /> - Raw Markdown Display Snapshots > renders with renderMarkdown=true, useAlternateBuffer=true '(default, alternate buffer)' 1`] = `
|
||||||
" ✓ test-tool A tool for testing
|
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||||
Test bold and code markdown"
|
│ ✓ test-tool A tool for testing │
|
||||||
|
│ │
|
||||||
|
│ Test bold and code markdown │"
|
||||||
`;
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user