fix(cli): exclude update_topic from confirmation queue count (#24945)

This commit is contained in:
Abhijit Balaji
2026-04-10 16:04:59 -07:00
committed by GitHub
parent 773567c6ca
commit 0957f7d3e2
9 changed files with 385 additions and 234 deletions

View File

@@ -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],
);

View File

@@ -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;
}

View File

@@ -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,
};
}

View File

@@ -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[],