mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-14 16:10:59 -07:00
feat: Display pending and confirming tool calls (#22106)
Co-authored-by: Spencer <spencertang@google.com>
This commit is contained in:
@@ -13,6 +13,10 @@ Tips for getting started:
|
||||
2. /help for more information
|
||||
3. Ask coding questions, edit code or run commands
|
||||
4. Be specific for the best results
|
||||
╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? confirming_tool Confirming tool description │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯
|
||||
|
||||
Action Required (was prompted):
|
||||
|
||||
@@ -41,6 +45,10 @@ Tips for getting started:
|
||||
│ ✓ tool2 Description for tool 2 │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯
|
||||
╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ o tool3 Description for tool 3 │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -97,6 +105,10 @@ Tips for getting started:
|
||||
2. /help for more information
|
||||
3. Ask coding questions, edit code or run commands
|
||||
4. Be specific for the best results
|
||||
╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ o tool3 Description for tool 3 │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
|
||||
@@ -159,4 +159,22 @@ describe('ThinkingMessage', () => {
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('filters out progress dots and empty lines', async () => {
|
||||
const renderResult = renderWithProviders(
|
||||
<ThinkingMessage
|
||||
thought={{ subject: '...', description: 'Thinking\n.\n..\n...\nDone' }}
|
||||
terminalWidth={80}
|
||||
isFirstThinking={true}
|
||||
/>,
|
||||
);
|
||||
await renderResult.waitUntilReady();
|
||||
|
||||
const output = renderResult.lastFrame();
|
||||
expect(output).toContain('Thinking');
|
||||
expect(output).toContain('Done');
|
||||
expect(renderResult.lastFrame()).toMatchSnapshot();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
renderResult.unmount();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,20 +23,26 @@ function normalizeThoughtLines(thought: ThoughtSummary): string[] {
|
||||
const subject = normalizeEscapedNewlines(thought.subject).trim();
|
||||
const description = normalizeEscapedNewlines(thought.description).trim();
|
||||
|
||||
if (!subject && !description) {
|
||||
return [];
|
||||
const isNoise = (text: string) => {
|
||||
const trimmed = text.trim();
|
||||
return !trimmed || /^\.+$/.test(trimmed);
|
||||
};
|
||||
|
||||
const lines: string[] = [];
|
||||
|
||||
if (subject && !isNoise(subject)) {
|
||||
lines.push(subject);
|
||||
}
|
||||
|
||||
if (!subject) {
|
||||
return description.split('\n');
|
||||
if (description) {
|
||||
const descriptionLines = description
|
||||
.split('\n')
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => !isNoise(line));
|
||||
lines.push(...descriptionLines);
|
||||
}
|
||||
|
||||
if (!description) {
|
||||
return [subject];
|
||||
}
|
||||
|
||||
const bodyLines = description.split('\n');
|
||||
return [subject, ...bodyLines];
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -118,9 +118,10 @@ describe('<ToolGroupMessage />', () => {
|
||||
{ config: baseMockConfig, settings: fullVerbositySettings },
|
||||
);
|
||||
|
||||
// Should render nothing because all tools in the group are confirming
|
||||
// Should now render confirming tools
|
||||
await waitUntilReady();
|
||||
expect(lastFrame({ allowEmpty: true })).toBe('');
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('test-tool');
|
||||
unmount();
|
||||
});
|
||||
|
||||
@@ -162,11 +163,11 @@ describe('<ToolGroupMessage />', () => {
|
||||
},
|
||||
},
|
||||
);
|
||||
// pending-tool should be hidden
|
||||
// pending-tool should now be visible
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('successful-tool');
|
||||
expect(output).not.toContain('pending-tool');
|
||||
expect(output).toContain('pending-tool');
|
||||
expect(output).toContain('error-tool');
|
||||
expect(output).toMatchSnapshot();
|
||||
unmount();
|
||||
@@ -280,12 +281,12 @@ describe('<ToolGroupMessage />', () => {
|
||||
},
|
||||
},
|
||||
);
|
||||
// write_file (Pending) should be hidden
|
||||
// write_file (Pending) should now be visible
|
||||
await waitUntilReady();
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('read_file');
|
||||
expect(output).toContain('run_shell_command');
|
||||
expect(output).not.toContain('write_file');
|
||||
expect(output).toContain('write_file');
|
||||
expect(output).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -841,7 +842,7 @@ describe('<ToolGroupMessage />', () => {
|
||||
);
|
||||
|
||||
await waitUntilReady();
|
||||
expect(lastFrame({ allowEmpty: true })).toBe('');
|
||||
expect(lastFrame({ allowEmpty: true })).not.toBe('');
|
||||
unmount();
|
||||
});
|
||||
|
||||
|
||||
@@ -110,10 +110,11 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
||||
() =>
|
||||
toolCalls.filter((t) => {
|
||||
const displayStatus = mapCoreStatusToDisplayStatus(t.status);
|
||||
return (
|
||||
displayStatus !== ToolCallStatus.Pending &&
|
||||
displayStatus !== ToolCallStatus.Confirming
|
||||
);
|
||||
// We used to filter out Pending and Confirming statuses here to avoid
|
||||
// duplication with the Global Queue, but this causes tools to appear to
|
||||
// "vanish" from the context after approval.
|
||||
// We now allow them to be visible here as well.
|
||||
return displayStatus !== ToolCallStatus.Canceled;
|
||||
}),
|
||||
|
||||
[toolCalls],
|
||||
|
||||
@@ -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">Thinking</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">Done</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1016 B |
@@ -1,5 +1,20 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`ThinkingMessage > filters out progress dots and empty lines 1`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Thinking
|
||||
│ Done
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > filters out progress dots and empty lines 2`] = `
|
||||
" Thinking...
|
||||
│
|
||||
│ Thinking
|
||||
│ Done"
|
||||
`;
|
||||
|
||||
exports[`ThinkingMessage > normalizes escaped newline tokens 1`] = `
|
||||
" Thinking...
|
||||
│
|
||||
|
||||
@@ -74,6 +74,10 @@ exports[`<ToolGroupMessage /> > Golden Snapshots > renders mixed tool calls incl
|
||||
│ ⊶ run_shell_command Run command │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ o write_file Write to file │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
@@ -84,6 +88,10 @@ exports[`<ToolGroupMessage /> > Golden Snapshots > renders multiple tool calls w
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ o pending-tool This tool is pending │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ x error-tool This tool failed │
|
||||
│ │
|
||||
│ Test result │
|
||||
|
||||
Reference in New Issue
Block a user