Add low/full CLI error verbosity mode for cleaner UI (#20399)

This commit is contained in:
Dmitry Lyalin
2026-02-27 14:15:10 -05:00
committed by GitHub
parent 1c8951334a
commit 7f8ce8657c
25 changed files with 689 additions and 32 deletions
@@ -335,7 +335,10 @@ describe('useGeminiStream', () => {
});
const mockLoadedSettings: LoadedSettings = {
merged: { preferredEditor: 'vscode' },
merged: {
preferredEditor: 'vscode',
ui: { errorVerbosity: 'full' },
},
user: { path: '/user/settings.json', settings: {} },
workspace: { path: '/workspace/.gemini/settings.json', settings: {} },
errors: [],
@@ -346,6 +349,7 @@ describe('useGeminiStream', () => {
const renderTestHook = (
initialToolCalls: TrackedToolCall[] = [],
geminiClient?: any,
loadedSettings: LoadedSettings = mockLoadedSettings,
) => {
const client = geminiClient || mockConfig.getGeminiClient();
let lastToolCalls = initialToolCalls;
@@ -360,7 +364,7 @@ describe('useGeminiStream', () => {
cmd: PartListUnion,
) => Promise<SlashCommandProcessorResult | false>,
shellModeActive: false,
loadedSettings: mockLoadedSettings,
loadedSettings,
toolCalls: initialToolCalls,
};
@@ -969,6 +973,93 @@ describe('useGeminiStream', () => {
// Streaming state should be Idle
expect(result.current.streamingState).toBe(StreamingState.Idle);
});
const infoTexts = mockAddItem.mock.calls.map(
([item]) => (item as { text?: string }).text ?? '',
);
expect(
infoTexts.some((text) =>
text.includes(
'Some internal tool attempts failed before this final error',
),
),
).toBe(false);
expect(
infoTexts.some((text) =>
text.includes('This request failed. Press F12 for diagnostics'),
),
).toBe(false);
});
it('should add a compact suppressed-error note before STOP_EXECUTION terminal info in low verbosity mode', async () => {
const stopExecutionToolCalls: TrackedToolCall[] = [
{
request: {
callId: 'stop-call',
name: 'stopTool',
args: {},
isClientInitiated: false,
prompt_id: 'prompt-id-stop',
},
status: CoreToolCallStatus.Error,
response: {
callId: 'stop-call',
responseParts: [{ text: 'error occurred' }],
errorType: ToolErrorType.STOP_EXECUTION,
error: new Error('Stop reason from hook'),
resultDisplay: undefined,
},
responseSubmittedToGemini: false,
tool: {
displayName: 'stop tool',
},
invocation: {
getDescription: () => `Mock description`,
} as unknown as AnyToolInvocation,
} as unknown as TrackedCompletedToolCall,
];
const lowVerbositySettings = {
...mockLoadedSettings,
merged: {
...mockLoadedSettings.merged,
ui: { errorVerbosity: 'low' },
},
} as LoadedSettings;
const client = new MockedGeminiClientClass(mockConfig);
const { result } = renderTestHook([], client, lowVerbositySettings);
await act(async () => {
if (capturedOnComplete) {
await capturedOnComplete(stopExecutionToolCalls);
}
});
await waitFor(() => {
expect(mockMarkToolsAsSubmitted).toHaveBeenCalledWith(['stop-call']);
expect(mockSendMessageStream).not.toHaveBeenCalled();
expect(result.current.streamingState).toBe(StreamingState.Idle);
});
const infoTexts = mockAddItem.mock.calls.map(
([item]) => (item as { text?: string }).text ?? '',
);
const noteIndex = infoTexts.findIndex((text) =>
text.includes(
'Some internal tool attempts failed before this final error',
),
);
const stopIndex = infoTexts.findIndex((text) =>
text.includes('Agent execution stopped: Stop reason from hook'),
);
const failureHintIndex = infoTexts.findIndex((text) =>
text.includes('This request failed. Press F12 for diagnostics'),
);
expect(noteIndex).toBeGreaterThanOrEqual(0);
expect(stopIndex).toBeGreaterThanOrEqual(0);
expect(failureHintIndex).toBeGreaterThanOrEqual(0);
expect(noteIndex).toBeLessThan(stopIndex);
expect(stopIndex).toBeLessThan(failureHintIndex);
});
it('should group multiple cancelled tool call responses into a single history entry', async () => {