mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 12:54:07 -07:00
feat(cli): core logic for dense tool output and history merging
- Update useGeminiStream to detect dense tool batches (non-verbose, non-shell). - Update useHistoryManager to merge consecutive tool_group items into a single history entry. - Add unit tests for history manager merging logic.
This commit is contained in:
@@ -80,6 +80,8 @@ import { useSessionStats } from '../contexts/SessionContext.js';
|
|||||||
import { useKeypress } from './useKeypress.js';
|
import { useKeypress } from './useKeypress.js';
|
||||||
import type { LoadedSettings } from '../../config/settings.js';
|
import type { LoadedSettings } from '../../config/settings.js';
|
||||||
|
|
||||||
|
import { isShellTool } from '../components/messages/ToolShared.js';
|
||||||
|
|
||||||
type ToolResponseWithParts = ToolCallResponseInfo & {
|
type ToolResponseWithParts = ToolCallResponseInfo & {
|
||||||
llmContent?: PartListUnion;
|
llmContent?: PartListUnion;
|
||||||
};
|
};
|
||||||
@@ -356,6 +358,8 @@ export const useGeminiStream = (
|
|||||||
addItem,
|
addItem,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const isVerboseMode = settings.merged.output?.verbosity === 'verbose';
|
||||||
|
|
||||||
const pendingToolGroupItems = useMemo((): HistoryItemWithoutId[] => {
|
const pendingToolGroupItems = useMemo((): HistoryItemWithoutId[] => {
|
||||||
const remainingTools = toolCalls.filter(
|
const remainingTools = toolCalls.filter(
|
||||||
(tc) => !pushedToolCallIds.has(tc.request.callId),
|
(tc) => !pushedToolCallIds.has(tc.request.callId),
|
||||||
@@ -375,6 +379,14 @@ export const useGeminiStream = (
|
|||||||
// Always show a bottom border slice if we have ANY tools in the batch
|
// Always show a bottom border slice if we have ANY tools in the batch
|
||||||
// and we haven't finished pushing the whole batch to history yet.
|
// and we haven't finished pushing the whole batch to history yet.
|
||||||
// Once all tools are terminal and pushed, the last history item handles the closing border.
|
// Once all tools are terminal and pushed, the last history item handles the closing border.
|
||||||
|
// NOTE: In dense mode, we skip this if there are no shell tools (which require boxes).
|
||||||
|
const requiresBoxLayout =
|
||||||
|
isVerboseMode || toolCalls.some((tc) => isShellTool(tc.request.name));
|
||||||
|
|
||||||
|
if (!requiresBoxLayout) {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
const allTerminal =
|
const allTerminal =
|
||||||
toolCalls.length > 0 &&
|
toolCalls.length > 0 &&
|
||||||
toolCalls.every(
|
toolCalls.every(
|
||||||
@@ -419,7 +431,7 @@ export const useGeminiStream = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
}, [toolCalls, pushedToolCallIds]);
|
}, [toolCalls, pushedToolCallIds, isVerboseMode]);
|
||||||
|
|
||||||
const activeToolPtyId = useMemo(() => {
|
const activeToolPtyId = useMemo(() => {
|
||||||
const executingShellTool = toolCalls.find(
|
const executingShellTool = toolCalls.find(
|
||||||
|
|||||||
@@ -323,4 +323,29 @@ describe('useHistoryManager', () => {
|
|||||||
expect(thirdItem.type).toBe('tool_group');
|
expect(thirdItem.type).toBe('tool_group');
|
||||||
expect(thirdItem.tools).toHaveLength(1);
|
expect(thirdItem.tools).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should update borderBottom when merging tool groups', () => {
|
||||||
|
const { result } = renderHook(() => useHistory());
|
||||||
|
const timestamp = Date.now();
|
||||||
|
const toolGroup1: HistoryItemWithoutId = {
|
||||||
|
type: 'tool_group',
|
||||||
|
tools: [{ callId: '1', name: 'tool-a' } as IndividualToolCallDisplay],
|
||||||
|
borderBottom: false,
|
||||||
|
};
|
||||||
|
const toolGroup2: HistoryItemWithoutId = {
|
||||||
|
type: 'tool_group',
|
||||||
|
tools: [{ callId: '2', name: 'tool-b' } as IndividualToolCallDisplay],
|
||||||
|
borderBottom: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.addItem(toolGroup1, timestamp);
|
||||||
|
result.current.addItem(toolGroup2, timestamp + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.history).toHaveLength(1);
|
||||||
|
const mergedItem = result.current.history[0] as HistoryItemToolGroup;
|
||||||
|
expect(mergedItem.tools).toHaveLength(2);
|
||||||
|
expect(mergedItem.borderBottom).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export function useHistory({
|
|||||||
const updatedLastItem: HistoryItem = {
|
const updatedLastItem: HistoryItem = {
|
||||||
...lastItem,
|
...lastItem,
|
||||||
tools: [...lastItem.tools, ...newItem.tools],
|
tools: [...lastItem.tools, ...newItem.tools],
|
||||||
|
borderBottom: newItem.borderBottom,
|
||||||
};
|
};
|
||||||
return [...prevHistory.slice(0, -1), updatedLastItem];
|
return [...prevHistory.slice(0, -1), updatedLastItem];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user