mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-06 08:07:42 -07:00
Merge branch 'mb/atui/00-display-content' into mb/atui/01-ui-rendering
This commit is contained in:
@@ -34,8 +34,8 @@ export const ALL_ITEMS = [
|
||||
},
|
||||
{
|
||||
id: 'quota',
|
||||
header: '/stats',
|
||||
description: 'Remaining usage on daily limit (not shown when unavailable)',
|
||||
header: 'quota',
|
||||
description: 'Percentage of daily limit used (not shown when unavailable)',
|
||||
},
|
||||
{
|
||||
id: 'memory-usage',
|
||||
|
||||
@@ -281,7 +281,7 @@ describe('<Footer />', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(lastFrame()).toContain('85%');
|
||||
expect(lastFrame()).toContain('85% used');
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -306,7 +306,7 @@ describe('<Footer />', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(normalizeFrame(lastFrame())).not.toContain('used');
|
||||
expect(normalizeFrame(lastFrame())).toContain('15% used');
|
||||
expect(normalizeFrame(lastFrame())).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
@@ -351,13 +351,11 @@ export const Footer: React.FC = () => {
|
||||
<QuotaDisplay
|
||||
remaining={quotaStats.remaining}
|
||||
limit={quotaStats.limit}
|
||||
resetTime={quotaStats.resetTime}
|
||||
terse={true}
|
||||
forceShow={true}
|
||||
lowercase={true}
|
||||
/>
|
||||
),
|
||||
10, // "daily 100%" is 10 chars, but terse is "100%" (4 chars)
|
||||
9, // "100% used" is 9 chars
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -256,7 +256,7 @@ describe('<FooterConfigDialog />', () => {
|
||||
expect(nextLine).toContain('·');
|
||||
expect(nextLine).toContain('~/project/path');
|
||||
expect(nextLine).toContain('docker');
|
||||
expect(nextLine).toContain('97%');
|
||||
expect(nextLine).toContain('42% used');
|
||||
});
|
||||
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
|
||||
@@ -242,7 +242,7 @@ export const FooterConfigDialog: React.FC<FooterConfigDialogProps> = ({
|
||||
'context-used': (
|
||||
<Text color={getColor('context-used', itemColor)}>85% used</Text>
|
||||
),
|
||||
quota: <Text color={getColor('quota', itemColor)}>97%</Text>,
|
||||
quota: <Text color={getColor('quota', itemColor)}>42% used</Text>,
|
||||
'memory-usage': (
|
||||
<Text color={getColor('memory-usage', itemColor)}>260 MB</Text>
|
||||
),
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`<Footer /> > displays "Limit reached" message when remaining is 0 1`] = `
|
||||
" workspace (/directory) sandbox /model /stats
|
||||
" workspace (/directory) sandbox /model quota
|
||||
~/project/foo/bar/and/some/more/directories/to/make/it/long no sandbox gemini-pro limit reached
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<Footer /> > displays the usage indicator when usage is low 1`] = `
|
||||
" workspace (/directory) sandbox /model /stats
|
||||
~/project/foo/bar/and/some/more/directories/to/make/it/long no sandbox gemini-pro 85%
|
||||
" workspace (/directory) sandbox /model quota
|
||||
~/project/foo/bar/and/some/more/directories/to/make/it/long no sandbox gemini-pro 85% used
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -39,7 +39,7 @@ exports[`<Footer /> > footer configuration filtering (golden snapshots) > render
|
||||
`;
|
||||
|
||||
exports[`<Footer /> > hides the usage indicator when usage is not near limit 1`] = `
|
||||
" workspace (/directory) sandbox /model /stats
|
||||
~/project/foo/bar/and/some/more/directories/to/make/it/long no sandbox gemini-pro 15%
|
||||
" workspace (/directory) sandbox /model quota
|
||||
~/project/foo/bar/and/some/more/directories/to/make/it/long no sandbox gemini-pro 15% used
|
||||
"
|
||||
`;
|
||||
|
||||
+9
-9
@@ -50,7 +50,7 @@
|
||||
<text x="72" y="240" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs"> quota</text>
|
||||
<text x="891" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="257" fill="#afafaf" textLength="540" lengthAdjust="spacingAndGlyphs"> Remaining usage on daily limit (not shown when unavailable)</text>
|
||||
<text x="45" y="257" fill="#afafaf" textLength="540" lengthAdjust="spacingAndGlyphs"> Percentage of daily limit used (not shown when unavailable)</text>
|
||||
<text x="891" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="274" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs">[ ]</text>
|
||||
@@ -132,10 +132,10 @@
|
||||
<text x="0" y="631" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="631" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="631" fill="#afafaf" textLength="198" lengthAdjust="spacingAndGlyphs">workspace (/directory)</text>
|
||||
<text x="297" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">branch</text>
|
||||
<text x="405" y="631" fill="#afafaf" textLength="63" lengthAdjust="spacingAndGlyphs">sandbox</text>
|
||||
<text x="513" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">/model</text>
|
||||
<text x="693" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">/stats</text>
|
||||
<text x="288" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">branch</text>
|
||||
<text x="396" y="631" fill="#afafaf" textLength="63" lengthAdjust="spacingAndGlyphs">sandbox</text>
|
||||
<text x="504" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">/model</text>
|
||||
<text x="684" y="631" fill="#afafaf" textLength="45" lengthAdjust="spacingAndGlyphs">quota</text>
|
||||
<rect x="801" y="629" width="36" height="17" fill="#001a00" />
|
||||
<text x="801" y="631" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">diff</text>
|
||||
<rect x="837" y="629" width="18" height="17" fill="#001a00" />
|
||||
@@ -144,10 +144,10 @@
|
||||
<text x="0" y="648" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="27" y="648" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="648" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">~/project/path</text>
|
||||
<text x="297" y="648" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">main</text>
|
||||
<text x="405" y="648" fill="#00cd00" textLength="54" lengthAdjust="spacingAndGlyphs">docker</text>
|
||||
<text x="513" y="648" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">gemini-2.5-pro</text>
|
||||
<text x="693" y="648" fill="#ffffff" textLength="27" lengthAdjust="spacingAndGlyphs">97%</text>
|
||||
<text x="288" y="648" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">main</text>
|
||||
<text x="396" y="648" fill="#00cd00" textLength="54" lengthAdjust="spacingAndGlyphs">docker</text>
|
||||
<text x="504" y="648" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">gemini-2.5-pro</text>
|
||||
<text x="684" y="648" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">42% used</text>
|
||||
<rect x="801" y="646" width="27" height="17" fill="#001a00" />
|
||||
<text x="801" y="648" fill="#d7ffd7" textLength="27" lengthAdjust="spacingAndGlyphs">+12</text>
|
||||
<rect x="828" y="646" width="9" height="17" fill="#001a00" />
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
+9
-9
@@ -59,7 +59,7 @@
|
||||
<text x="72" y="240" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs"> quota</text>
|
||||
<text x="891" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="257" fill="#afafaf" textLength="540" lengthAdjust="spacingAndGlyphs"> Remaining usage on daily limit (not shown when unavailable)</text>
|
||||
<text x="45" y="257" fill="#afafaf" textLength="540" lengthAdjust="spacingAndGlyphs"> Percentage of daily limit used (not shown when unavailable)</text>
|
||||
<text x="891" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="274" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs">[ ]</text>
|
||||
@@ -133,10 +133,10 @@
|
||||
<text x="27" y="631" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<rect x="45" y="629" width="198" height="17" fill="#001a00" />
|
||||
<text x="45" y="631" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs">workspace (/directory)</text>
|
||||
<text x="324" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">branch</text>
|
||||
<text x="459" y="631" fill="#afafaf" textLength="63" lengthAdjust="spacingAndGlyphs">sandbox</text>
|
||||
<text x="594" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">/model</text>
|
||||
<text x="801" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">/stats</text>
|
||||
<text x="315" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">branch</text>
|
||||
<text x="450" y="631" fill="#afafaf" textLength="63" lengthAdjust="spacingAndGlyphs">sandbox</text>
|
||||
<text x="585" y="631" fill="#afafaf" textLength="54" lengthAdjust="spacingAndGlyphs">/model</text>
|
||||
<text x="783" y="631" fill="#afafaf" textLength="45" lengthAdjust="spacingAndGlyphs">quota</text>
|
||||
<text x="864" y="631" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="891" y="631" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="648" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
@@ -144,10 +144,10 @@
|
||||
<rect x="45" y="646" width="126" height="17" fill="#001a00" />
|
||||
<text x="45" y="648" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">~/project/path</text>
|
||||
<rect x="171" y="646" width="72" height="17" fill="#001a00" />
|
||||
<text x="324" y="648" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">main</text>
|
||||
<text x="459" y="648" fill="#00cd00" textLength="54" lengthAdjust="spacingAndGlyphs">docker</text>
|
||||
<text x="594" y="648" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">gemini-2.5-pro</text>
|
||||
<text x="801" y="648" fill="#ffffff" textLength="27" lengthAdjust="spacingAndGlyphs">97%</text>
|
||||
<text x="315" y="648" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">main</text>
|
||||
<text x="450" y="648" fill="#00cd00" textLength="54" lengthAdjust="spacingAndGlyphs">docker</text>
|
||||
<text x="585" y="648" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">gemini-2.5-pro</text>
|
||||
<text x="783" y="648" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">42% used</text>
|
||||
<text x="864" y="648" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="891" y="648" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="665" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
+8
-8
@@ -50,7 +50,7 @@
|
||||
<text x="72" y="240" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs"> quota</text>
|
||||
<text x="891" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="257" fill="#afafaf" textLength="540" lengthAdjust="spacingAndGlyphs"> Remaining usage on daily limit (not shown when unavailable)</text>
|
||||
<text x="45" y="257" fill="#afafaf" textLength="540" lengthAdjust="spacingAndGlyphs"> Percentage of daily limit used (not shown when unavailable)</text>
|
||||
<text x="891" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="274" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs">[ ]</text>
|
||||
@@ -131,13 +131,13 @@
|
||||
<text x="27" y="631" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="45" y="631" fill="#afafaf" textLength="126" lengthAdjust="spacingAndGlyphs">~/project/path</text>
|
||||
<text x="207" y="631" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs"> · </text>
|
||||
<text x="279" y="631" fill="#afafaf" textLength="36" lengthAdjust="spacingAndGlyphs">main</text>
|
||||
<text x="351" y="631" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs"> · </text>
|
||||
<text x="432" y="631" fill="#00cd00" textLength="54" lengthAdjust="spacingAndGlyphs">docker</text>
|
||||
<text x="522" y="631" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs"> · </text>
|
||||
<text x="594" y="631" fill="#afafaf" textLength="126" lengthAdjust="spacingAndGlyphs">gemini-2.5-pro</text>
|
||||
<text x="756" y="631" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs"> · </text>
|
||||
<text x="828" y="631" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs">97%</text>
|
||||
<text x="270" y="631" fill="#afafaf" textLength="36" lengthAdjust="spacingAndGlyphs">main</text>
|
||||
<text x="342" y="631" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs"> · </text>
|
||||
<text x="405" y="631" fill="#00cd00" textLength="54" lengthAdjust="spacingAndGlyphs">docker</text>
|
||||
<text x="495" y="631" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs"> · </text>
|
||||
<text x="558" y="631" fill="#afafaf" textLength="126" lengthAdjust="spacingAndGlyphs">gemini-2.5-pro</text>
|
||||
<text x="720" y="631" fill="#afafaf" textLength="27" lengthAdjust="spacingAndGlyphs"> · </text>
|
||||
<text x="783" y="631" fill="#afafaf" textLength="72" lengthAdjust="spacingAndGlyphs">42% used</text>
|
||||
<text x="864" y="631" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="891" y="631" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
<text x="0" y="648" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -16,7 +16,7 @@ exports[`<FooterConfigDialog /> > highlights the active item in the preview 1`]
|
||||
│ [✓] model-name │
|
||||
│ Current model identifier │
|
||||
│ [✓] quota │
|
||||
│ Remaining usage on daily limit (not shown when unavailable) │
|
||||
│ Percentage of daily limit used (not shown when unavailable) │
|
||||
│ [ ] context-used │
|
||||
│ Percentage of context window used │
|
||||
│ [ ] memory-usage │
|
||||
@@ -38,8 +38,8 @@ exports[`<FooterConfigDialog /> > highlights the active item in the preview 1`]
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Preview: │ │
|
||||
│ │ workspace (/directory) branch sandbox /model /stats diff │ │
|
||||
│ │ ~/project/path main docker gemini-2.5-pro 97% +12 -4 │ │
|
||||
│ │ workspace (/directory) branch sandbox /model quota diff │ │
|
||||
│ │ ~/project/path main docker gemini-2.5-pro 42% used +12 -4 │ │
|
||||
│ └────────────────────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
@@ -61,7 +61,7 @@ exports[`<FooterConfigDialog /> > renders correctly with default settings 1`] =
|
||||
│ [✓] model-name │
|
||||
│ Current model identifier │
|
||||
│ [✓] quota │
|
||||
│ Remaining usage on daily limit (not shown when unavailable) │
|
||||
│ Percentage of daily limit used (not shown when unavailable) │
|
||||
│ [ ] context-used │
|
||||
│ Percentage of context window used │
|
||||
│ [ ] memory-usage │
|
||||
@@ -83,8 +83,8 @@ exports[`<FooterConfigDialog /> > renders correctly with default settings 1`] =
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Preview: │ │
|
||||
│ │ workspace (/directory) branch sandbox /model /stats │ │
|
||||
│ │ ~/project/path main docker gemini-2.5-pro 97% │ │
|
||||
│ │ workspace (/directory) branch sandbox /model quota │ │
|
||||
│ │ ~/project/path main docker gemini-2.5-pro 42% used │ │
|
||||
│ └────────────────────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
@@ -107,7 +107,7 @@ exports[`<FooterConfigDialog /> > renders correctly with default settings 2`] =
|
||||
│ [✓] model-name │
|
||||
│ Current model identifier │
|
||||
│ [✓] quota │
|
||||
│ Remaining usage on daily limit (not shown when unavailable) │
|
||||
│ Percentage of daily limit used (not shown when unavailable) │
|
||||
│ [ ] context-used │
|
||||
│ Percentage of context window used │
|
||||
│ [ ] memory-usage │
|
||||
@@ -129,8 +129,8 @@ exports[`<FooterConfigDialog /> > renders correctly with default settings 2`] =
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Preview: │ │
|
||||
│ │ workspace (/directory) branch sandbox /model /stats │ │
|
||||
│ │ ~/project/path main docker gemini-2.5-pro 97% │ │
|
||||
│ │ workspace (/directory) branch sandbox /model quota │ │
|
||||
│ │ ~/project/path main docker gemini-2.5-pro 42% used │ │
|
||||
│ └────────────────────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
@@ -152,7 +152,7 @@ exports[`<FooterConfigDialog /> > updates the preview when Show footer labels is
|
||||
│ [✓] model-name │
|
||||
│ Current model identifier │
|
||||
│ [✓] quota │
|
||||
│ Remaining usage on daily limit (not shown when unavailable) │
|
||||
│ Percentage of daily limit used (not shown when unavailable) │
|
||||
│ [ ] context-used │
|
||||
│ Percentage of context window used │
|
||||
│ [ ] memory-usage │
|
||||
@@ -174,7 +174,7 @@ exports[`<FooterConfigDialog /> > updates the preview when Show footer labels is
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Preview: │ │
|
||||
│ │ ~/project/path · main · docker · gemini-2.5-pro · 97% │ │
|
||||
│ │ ~/project/path · main · docker · gemini-2.5-pro · 42% used │ │
|
||||
│ └────────────────────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
|
||||
@@ -22,8 +22,7 @@ import { theme } from '../../semantic-colors.js';
|
||||
import { useConfig } from '../../contexts/ConfigContext.js';
|
||||
import { isShellTool } from './ToolShared.js';
|
||||
import {
|
||||
shouldHideToolCall,
|
||||
CoreToolCallStatus,
|
||||
isVisibleInToolGroup,
|
||||
Kind,
|
||||
EDIT_DISPLAY_NAME,
|
||||
GLOB_DISPLAY_NAME,
|
||||
@@ -36,6 +35,7 @@ import {
|
||||
READ_MANY_FILES_DISPLAY_NAME,
|
||||
isFileDiff,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { buildToolVisibilityContextFromDisplay } from '../../utils/historyUtils.js';
|
||||
import { useUIState } from '../../contexts/UIStateContext.js';
|
||||
import { getToolGroupBorderAppearance } from '../../utils/borderStyles.js';
|
||||
import { useSettings } from '../../contexts/SettingsContext.js';
|
||||
@@ -125,40 +125,13 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
||||
// Filter out tool calls that should be hidden (e.g. in-progress Ask User, or Plan Mode operations).
|
||||
const visibleToolCalls = useMemo(
|
||||
() =>
|
||||
allToolCalls.filter((t) => {
|
||||
// Hide internal errors unless full verbosity
|
||||
if (
|
||||
isLowErrorVerbosity &&
|
||||
t.status === CoreToolCallStatus.Error &&
|
||||
!t.isClientInitiated
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// Standard hiding logic (e.g. Plan Mode internal edits)
|
||||
if (
|
||||
shouldHideToolCall({
|
||||
displayName: t.name,
|
||||
status: t.status,
|
||||
approvalMode: t.approvalMode,
|
||||
hasResultDisplay: !!t.resultDisplay,
|
||||
parentCallId: t.parentCallId,
|
||||
})
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We HIDE tools that are still in pre-execution states (Confirming, Pending)
|
||||
// from the History log. They live in the Global Queue or wait for their turn.
|
||||
// Only show tools that are actually running or finished.
|
||||
const displayStatus = mapCoreStatusToDisplayStatus(t.status);
|
||||
|
||||
// We hide Confirming tools from the history log because they are
|
||||
// currently being rendered in the interactive ToolConfirmationQueue.
|
||||
// We show everything else, including Pending (waiting to run) and
|
||||
// Canceled (rejected by user), to ensure the history is complete
|
||||
// and to avoid tools "vanishing" after approval.
|
||||
return displayStatus !== ToolCallStatus.Confirming;
|
||||
}),
|
||||
allToolCalls.filter((t) =>
|
||||
// Use the unified visibility utility
|
||||
isVisibleInToolGroup(
|
||||
buildToolVisibilityContextFromDisplay(t),
|
||||
isLowErrorVerbosity ? 'low' : 'full',
|
||||
),
|
||||
),
|
||||
[allToolCalls, isLowErrorVerbosity],
|
||||
);
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ import {
|
||||
isBackgroundExecutionData,
|
||||
Kind,
|
||||
ACTIVATE_SKILL_TOOL_NAME,
|
||||
shouldHideToolCall,
|
||||
isRenderedInHistory,
|
||||
buildToolVisibilityContext,
|
||||
UPDATE_TOPIC_TOOL_NAME,
|
||||
UPDATE_TOPIC_DISPLAY_NAME,
|
||||
} from '@google/gemini-cli-core';
|
||||
@@ -647,29 +648,8 @@ export const useGeminiStream = (
|
||||
toolCalls.every((tc) => pushedToolCallIds.has(tc.request.callId));
|
||||
|
||||
const isToolVisible = (tc: TrackedToolCall) => {
|
||||
const displayName = tc.tool?.displayName ?? tc.request.name;
|
||||
|
||||
let hasResultDisplay = false;
|
||||
if (
|
||||
tc.status === CoreToolCallStatus.Success ||
|
||||
tc.status === CoreToolCallStatus.Error ||
|
||||
tc.status === CoreToolCallStatus.Cancelled
|
||||
) {
|
||||
hasResultDisplay = !!tc.response?.resultDisplay;
|
||||
} else if (tc.status === CoreToolCallStatus.Executing) {
|
||||
hasResultDisplay = !!tc.liveOutput;
|
||||
}
|
||||
|
||||
// AskUser tools and Plan Mode write/edit are handled by this logic
|
||||
if (
|
||||
shouldHideToolCall({
|
||||
displayName,
|
||||
status: tc.status,
|
||||
approvalMode: tc.approvalMode,
|
||||
hasResultDisplay,
|
||||
parentCallId: tc.request.parentCallId,
|
||||
})
|
||||
) {
|
||||
if (!isRenderedInHistory(buildToolVisibilityContext(tc))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,18 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { CoreToolCallStatus } from '@google/gemini-cli-core';
|
||||
import {
|
||||
CoreToolCallStatus,
|
||||
belongsInConfirmationQueue,
|
||||
} from '@google/gemini-cli-core';
|
||||
import {
|
||||
type HistoryItemWithoutId,
|
||||
type IndividualToolCallDisplay,
|
||||
} from '../types.js';
|
||||
import { getAllToolCalls } from './historyUtils.js';
|
||||
import {
|
||||
getAllToolCalls,
|
||||
buildToolVisibilityContextFromDisplay,
|
||||
} from './historyUtils.js';
|
||||
|
||||
export interface ConfirmingToolState {
|
||||
tool: IndividualToolCallDisplay;
|
||||
@@ -33,14 +39,18 @@ export function getConfirmingToolState(
|
||||
return null;
|
||||
}
|
||||
|
||||
const actionablePendingTools = allPendingTools.filter((tool) =>
|
||||
belongsInConfirmationQueue(buildToolVisibilityContextFromDisplay(tool)),
|
||||
);
|
||||
|
||||
const head = confirmingTools[0];
|
||||
const headIndexInFullList = allPendingTools.findIndex(
|
||||
const headIndexInFullList = actionablePendingTools.findIndex(
|
||||
(tool) => tool.callId === head.callId,
|
||||
);
|
||||
|
||||
return {
|
||||
tool: head,
|
||||
index: headIndexInFullList + 1,
|
||||
total: allPendingTools.length,
|
||||
total: actionablePendingTools.length,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { type ToolVisibilityContext } from '@google/gemini-cli-core';
|
||||
import { CoreToolCallStatus } from '../types.js';
|
||||
import type {
|
||||
HistoryItem,
|
||||
@@ -12,6 +13,23 @@ import type {
|
||||
IndividualToolCallDisplay,
|
||||
} from '../types.js';
|
||||
|
||||
/**
|
||||
* Maps an IndividualToolCallDisplay from the CLI to a ToolVisibilityContext for core logic.
|
||||
*/
|
||||
export function buildToolVisibilityContextFromDisplay(
|
||||
tool: IndividualToolCallDisplay,
|
||||
): ToolVisibilityContext {
|
||||
return {
|
||||
name: tool.originalRequestName ?? tool.name,
|
||||
displayName: tool.name, // In CLI, 'name' is usually the resolved display name
|
||||
status: tool.status,
|
||||
hasResult: !!tool.resultDisplay,
|
||||
approvalMode: tool.approvalMode,
|
||||
isClientInitiated: tool.isClientInitiated,
|
||||
parentCallId: tool.parentCallId,
|
||||
};
|
||||
}
|
||||
|
||||
export function getLastTurnToolCallIds(
|
||||
history: HistoryItem[],
|
||||
pendingHistoryItems: HistoryItemWithoutId[],
|
||||
|
||||
@@ -294,7 +294,7 @@ describe('validateNonInterActiveAuth', () => {
|
||||
expect(processExitSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('succeeds if effectiveAuthType matches enforcedAuthType', async () => {
|
||||
it('succeeds if effectiveAuthType matches enforcedType', async () => {
|
||||
mockSettings.merged.security.auth.enforcedType = AuthType.USE_GEMINI;
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
const nonInteractiveConfig = createLocalMockConfig({});
|
||||
@@ -308,7 +308,7 @@ describe('validateNonInterActiveAuth', () => {
|
||||
expect(debugLoggerErrorSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('exits if configuredAuthType does not match enforcedAuthType', async () => {
|
||||
it('exits if configuredAuthType does not match enforcedType', async () => {
|
||||
mockSettings.merged.security.auth.enforcedType = AuthType.LOGIN_WITH_GOOGLE;
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.TEXT),
|
||||
@@ -334,7 +334,7 @@ describe('validateNonInterActiveAuth', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('exits if auth from env var does not match enforcedAuthType', async () => {
|
||||
it('exits if auth from env var does not match enforcedType', async () => {
|
||||
mockSettings.merged.security.auth.enforcedType = AuthType.LOGIN_WITH_GOOGLE;
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
|
||||
Reference in New Issue
Block a user