mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-27 13:34:15 -07:00
feat(cli): overhaul thinking UI (#18725)
This commit is contained in:
@@ -7,84 +7,156 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { renderWithProviders } from '../../../test-utils/render.js';
|
||||
import { ThinkingMessage } from './ThinkingMessage.js';
|
||||
import React from 'react';
|
||||
|
||||
describe('ThinkingMessage', () => {
|
||||
it('renders subject line', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
it('renders subject line with vertical rule and "Thinking..." header', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{ subject: 'Planning', description: 'test' }}
|
||||
terminalWidth={80}
|
||||
isFirstThinking={true}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
const output = renderResult.lastFrame();
|
||||
expect(output).toContain(' Thinking...');
|
||||
expect(output).toContain('│');
|
||||
expect(output).toContain('Planning');
|
||||
expect(output).toMatchSnapshot();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('uses description when subject is empty', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const renderResult = renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{ subject: '', description: 'Processing details' }}
|
||||
terminalWidth={80}
|
||||
isFirstThinking={true}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
const output = renderResult.lastFrame();
|
||||
expect(output).toContain('Processing details');
|
||||
expect(output).toContain('│');
|
||||
expect(output).toMatchSnapshot();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('renders full mode with left border and full text', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const renderResult = renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Planning',
|
||||
description: 'I am planning the solution.',
|
||||
}}
|
||||
terminalWidth={80}
|
||||
isFirstThinking={true}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
const output = renderResult.lastFrame();
|
||||
expect(output).toContain('│');
|
||||
expect(output).toContain('Planning');
|
||||
expect(output).toContain('I am planning the solution.');
|
||||
expect(output).toMatchSnapshot();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('indents summary line correctly', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
it('renders "Thinking..." header when isFirstThinking is true', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Summary line',
|
||||
description: 'First body line',
|
||||
}}
|
||||
terminalWidth={80}
|
||||
isFirstThinking={true}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
const output = renderResult.lastFrame();
|
||||
expect(output).toContain(' Thinking...');
|
||||
expect(output).toContain('Summary line');
|
||||
expect(output).toContain('│');
|
||||
expect(output).toMatchSnapshot();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('normalizes escaped newline tokens', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
const renderResult = renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Matching the Blocks',
|
||||
description: '\\n\\nSome more text',
|
||||
}}
|
||||
terminalWidth={80}
|
||||
isFirstThinking={true}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
expect(renderResult.lastFrame()).toMatchSnapshot();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('renders empty state gracefully', async () => {
|
||||
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
|
||||
<ThinkingMessage thought={{ subject: '', description: '' }} />,
|
||||
const renderResult = renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{ subject: '', description: '' }}
|
||||
terminalWidth={80}
|
||||
isFirstThinking={true}
|
||||
/>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
expect(lastFrame({ allowEmpty: true })).toBe('');
|
||||
unmount();
|
||||
expect(renderResult.lastFrame({ allowEmpty: true })).toBe('');
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('renders multiple thinking messages sequentially correctly', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
<React.Fragment>
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Initial analysis',
|
||||
description:
|
||||
'This is a multiple line paragraph for the first thinking message of how the model analyzes the problem.',
|
||||
}}
|
||||
terminalWidth={80}
|
||||
isFirstThinking={true}
|
||||
/>
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Planning execution',
|
||||
description:
|
||||
'This a second multiple line paragraph for the second thinking message explaining the plan in detail so that it wraps around the terminal display.',
|
||||
}}
|
||||
terminalWidth={80}
|
||||
/>
|
||||
<ThinkingMessage
|
||||
thought={{
|
||||
subject: 'Refining approach',
|
||||
description:
|
||||
'And finally a third multiple line paragraph for the third thinking message to refine the solution.',
|
||||
}}
|
||||
terminalWidth={80}
|
||||
/>
|
||||
</React.Fragment>,
|
||||
);
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
expect(renderResult.lastFrame()).toMatchSnapshot();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
renderResult.unmount();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,6 +13,30 @@ import { normalizeEscapedNewlines } from '../../utils/textUtils.js';
|
||||
|
||||
interface ThinkingMessageProps {
|
||||
thought: ThoughtSummary;
|
||||
terminalWidth: number;
|
||||
isFirstThinking?: boolean;
|
||||
}
|
||||
|
||||
const THINKING_LEFT_PADDING = 1;
|
||||
|
||||
function normalizeThoughtLines(thought: ThoughtSummary): string[] {
|
||||
const subject = normalizeEscapedNewlines(thought.subject).trim();
|
||||
const description = normalizeEscapedNewlines(thought.description).trim();
|
||||
|
||||
if (!subject && !description) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!subject) {
|
||||
return description.split('\n');
|
||||
}
|
||||
|
||||
if (!description) {
|
||||
return [subject];
|
||||
}
|
||||
|
||||
const bodyLines = description.split('\n');
|
||||
return [subject, ...bodyLines];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -21,60 +45,47 @@ interface ThinkingMessageProps {
|
||||
*/
|
||||
export const ThinkingMessage: React.FC<ThinkingMessageProps> = ({
|
||||
thought,
|
||||
terminalWidth,
|
||||
isFirstThinking,
|
||||
}) => {
|
||||
const { summary, body } = useMemo(() => {
|
||||
const subject = normalizeEscapedNewlines(thought.subject).trim();
|
||||
const description = normalizeEscapedNewlines(thought.description).trim();
|
||||
const fullLines = useMemo(() => normalizeThoughtLines(thought), [thought]);
|
||||
|
||||
if (!subject && !description) {
|
||||
return { summary: '', body: '' };
|
||||
}
|
||||
|
||||
if (!subject) {
|
||||
const lines = description
|
||||
.split('\n')
|
||||
.map((l) => l.trim())
|
||||
.filter(Boolean);
|
||||
return {
|
||||
summary: lines[0] || '',
|
||||
body: lines.slice(1).join('\n'),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
summary: subject,
|
||||
body: description,
|
||||
};
|
||||
}, [thought]);
|
||||
|
||||
if (!summary && !body) {
|
||||
if (fullLines.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box width="100%" marginBottom={1} paddingLeft={1} flexDirection="column">
|
||||
{summary && (
|
||||
<Box paddingLeft={2}>
|
||||
<Box width={terminalWidth} flexDirection="column">
|
||||
{isFirstThinking && (
|
||||
<Text color={theme.text.primary} italic>
|
||||
{' '}
|
||||
Thinking...{' '}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
<Box
|
||||
marginLeft={THINKING_LEFT_PADDING}
|
||||
paddingLeft={1}
|
||||
borderStyle="single"
|
||||
borderLeft={true}
|
||||
borderRight={false}
|
||||
borderTop={false}
|
||||
borderBottom={false}
|
||||
borderColor={theme.text.secondary}
|
||||
flexDirection="column"
|
||||
>
|
||||
<Text> </Text>
|
||||
{fullLines.length > 0 && (
|
||||
<Text color={theme.text.primary} bold italic>
|
||||
{summary}
|
||||
{fullLines[0]}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
{body && (
|
||||
<Box
|
||||
borderStyle="single"
|
||||
borderLeft
|
||||
borderRight={false}
|
||||
borderTop={false}
|
||||
borderBottom={false}
|
||||
borderColor={theme.border.default}
|
||||
paddingLeft={1}
|
||||
>
|
||||
<Text color={theme.text.secondary} italic>
|
||||
{body}
|
||||
)}
|
||||
{fullLines.slice(1).map((line, index) => (
|
||||
<Text key={`body-line-${index}`} color={theme.text.secondary} italic>
|
||||
{line}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="88" viewBox="0 0 920 88">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="920" height="88" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<text x="0" y="2" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs" font-style="italic"> Thinking... </text>
|
||||
<text x="9" y="19" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="9" y="36" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="36" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Matching the Blocks</text>
|
||||
<text x="9" y="53" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="53" fill="#afafaf" textLength="126" lengthAdjust="spacingAndGlyphs" font-style="italic">Some more text</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
+14
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="88" viewBox="0 0 920 88">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="920" height="88" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<text x="0" y="2" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs" font-style="italic"> Thinking... </text>
|
||||
<text x="9" y="19" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="9" y="36" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="36" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Summary line</text>
|
||||
<text x="9" y="53" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="53" fill="#afafaf" textLength="135" lengthAdjust="spacingAndGlyphs" font-style="italic">First body line</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
+14
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="88" viewBox="0 0 920 88">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="920" height="88" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<text x="0" y="2" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs" font-style="italic"> Thinking... </text>
|
||||
<text x="9" y="19" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="9" y="36" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="36" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Planning</text>
|
||||
<text x="9" y="53" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="53" fill="#afafaf" textLength="243" lengthAdjust="spacingAndGlyphs" font-style="italic">I am planning the solution.</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
+30
@@ -0,0 +1,30 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="241" viewBox="0 0 920 241">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="920" height="241" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<text x="0" y="2" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs" font-style="italic"> Thinking... </text>
|
||||
<text x="9" y="19" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="9" y="36" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="36" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Initial analysis</text>
|
||||
<text x="9" y="53" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="53" fill="#afafaf" textLength="675" lengthAdjust="spacingAndGlyphs" font-style="italic">This is a multiple line paragraph for the first thinking message of how the</text>
|
||||
<text x="9" y="70" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="70" fill="#afafaf" textLength="243" lengthAdjust="spacingAndGlyphs" font-style="italic">model analyzes the problem.</text>
|
||||
<text x="9" y="87" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="9" y="104" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="104" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Planning execution</text>
|
||||
<text x="9" y="121" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="121" fill="#afafaf" textLength="621" lengthAdjust="spacingAndGlyphs" font-style="italic">This a second multiple line paragraph for the second thinking message</text>
|
||||
<text x="9" y="138" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="138" fill="#afafaf" textLength="675" lengthAdjust="spacingAndGlyphs" font-style="italic">explaining the plan in detail so that it wraps around the terminal display.</text>
|
||||
<text x="9" y="155" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="9" y="172" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="172" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Refining approach</text>
|
||||
<text x="9" y="189" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="189" fill="#afafaf" textLength="693" lengthAdjust="spacingAndGlyphs" font-style="italic">And finally a third multiple line paragraph for the third thinking message to</text>
|
||||
<text x="9" y="206" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="206" fill="#afafaf" textLength="180" lengthAdjust="spacingAndGlyphs" font-style="italic">refine the solution.</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
+14
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="88" viewBox="0 0 920 88">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="920" height="88" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<text x="0" y="2" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs" font-style="italic"> Thinking... </text>
|
||||
<text x="9" y="19" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="9" y="36" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="36" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Planning</text>
|
||||
<text x="9" y="53" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="53" fill="#afafaf" textLength="36" lengthAdjust="spacingAndGlyphs" font-style="italic">test</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1016 B |
+12
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="71" viewBox="0 0 920 71">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="920" height="71" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<text x="0" y="2" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs" font-style="italic"> Thinking... </text>
|
||||
<text x="9" y="19" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="9" y="36" fill="#afafaf" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="36" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Processing details</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 812 B |
+88
-11
@@ -1,30 +1,107 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`ThinkingMessage > indents summary line correctly 1`] = `
|
||||
" Summary line
|
||||
│ First body line
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > normalizes escaped newline tokens 1`] = `
|
||||
" Matching the Blocks
|
||||
" Thinking...
|
||||
│
|
||||
│ Matching the Blocks
|
||||
│ Some more text
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > normalizes escaped newline tokens 2`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Matching the Blocks
|
||||
│ Some more text"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > renders "Thinking..." header when isFirstThinking is true 1`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Summary line
|
||||
│ First body line
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > renders "Thinking..." header when isFirstThinking is true 2`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Summary line
|
||||
│ First body line"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > renders full mode with left border and full text 1`] = `
|
||||
" Planning
|
||||
" Thinking...
|
||||
│
|
||||
│ Planning
|
||||
│ I am planning the solution.
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > renders subject line 1`] = `
|
||||
" Planning
|
||||
exports[`ThinkingMessage > renders full mode with left border and full text 2`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Planning
|
||||
│ I am planning the solution."
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > renders multiple thinking messages sequentially correctly 1`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Initial analysis
|
||||
│ This is a multiple line paragraph for the first thinking message of how the
|
||||
│ model analyzes the problem.
|
||||
│
|
||||
│ Planning execution
|
||||
│ This a second multiple line paragraph for the second thinking message
|
||||
│ explaining the plan in detail so that it wraps around the terminal display.
|
||||
│
|
||||
│ Refining approach
|
||||
│ And finally a third multiple line paragraph for the third thinking message to
|
||||
│ refine the solution.
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > renders multiple thinking messages sequentially correctly 2`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Initial analysis
|
||||
│ This is a multiple line paragraph for the first thinking message of how the
|
||||
│ model analyzes the problem.
|
||||
│
|
||||
│ Planning execution
|
||||
│ This a second multiple line paragraph for the second thinking message
|
||||
│ explaining the plan in detail so that it wraps around the terminal display.
|
||||
│
|
||||
│ Refining approach
|
||||
│ And finally a third multiple line paragraph for the third thinking message to
|
||||
│ refine the solution."
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > renders subject line with vertical rule and "Thinking..." header 1`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Planning
|
||||
│ test
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > renders subject line with vertical rule and "Thinking..." header 2`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Planning
|
||||
│ test"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > uses description when subject is empty 1`] = `
|
||||
" Processing details
|
||||
" Thinking...
|
||||
│
|
||||
│ Processing details
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > uses description when subject is empty 2`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Processing details"
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user