mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
fix(cli): prevent sub-agent tool calls from leaking into UI (#20580)
This commit is contained in:
@@ -359,14 +359,10 @@ describe('useToolScheduler', () => {
|
|||||||
} as ToolCallsUpdateMessage);
|
} as ToolCallsUpdateMessage);
|
||||||
});
|
});
|
||||||
|
|
||||||
let [toolCalls] = result.current;
|
const [toolCalls] = result.current;
|
||||||
expect(toolCalls).toHaveLength(2);
|
expect(toolCalls).toHaveLength(1);
|
||||||
expect(
|
expect(toolCalls[0].request.callId).toBe('call-root');
|
||||||
toolCalls.find((t) => t.request.callId === 'call-root')?.schedulerId,
|
expect(toolCalls[0].schedulerId).toBe(ROOT_SCHEDULER_ID);
|
||||||
).toBe(ROOT_SCHEDULER_ID);
|
|
||||||
expect(
|
|
||||||
toolCalls.find((t) => t.request.callId === 'call-sub')?.schedulerId,
|
|
||||||
).toBe('subagent-1');
|
|
||||||
|
|
||||||
// 2. Call setToolCallsForDisplay (e.g., simulate a manual update or clear)
|
// 2. Call setToolCallsForDisplay (e.g., simulate a manual update or clear)
|
||||||
act(() => {
|
act(() => {
|
||||||
@@ -377,34 +373,45 @@ describe('useToolScheduler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 3. Verify that tools are still present and maintain their scheduler IDs
|
// 3. Verify that tools are still present and maintain their scheduler IDs
|
||||||
// The internal map should have been re-grouped.
|
const [toolCalls2] = result.current;
|
||||||
[toolCalls] = result.current;
|
expect(toolCalls2).toHaveLength(1);
|
||||||
expect(toolCalls).toHaveLength(2);
|
expect(toolCalls2[0].responseSubmittedToGemini).toBe(true);
|
||||||
expect(toolCalls.every((t) => t.responseSubmittedToGemini)).toBe(true);
|
expect(toolCalls2[0].schedulerId).toBe(ROOT_SCHEDULER_ID);
|
||||||
|
});
|
||||||
|
|
||||||
const updatedRoot = toolCalls.find((t) => t.request.callId === 'call-root');
|
it('ignores TOOL_CALLS_UPDATE from non-root schedulers', () => {
|
||||||
const updatedSub = toolCalls.find((t) => t.request.callId === 'call-sub');
|
const { result } = renderHook(() =>
|
||||||
|
useToolScheduler(
|
||||||
|
vi.fn().mockResolvedValue(undefined),
|
||||||
|
mockConfig,
|
||||||
|
() => undefined,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
expect(updatedRoot?.schedulerId).toBe(ROOT_SCHEDULER_ID);
|
const subagentCall = {
|
||||||
expect(updatedSub?.schedulerId).toBe('subagent-1');
|
status: CoreToolCallStatus.Executing as const,
|
||||||
|
request: {
|
||||||
|
callId: 'call-sub',
|
||||||
|
name: 'test',
|
||||||
|
args: {},
|
||||||
|
isClientInitiated: false,
|
||||||
|
prompt_id: 'p1',
|
||||||
|
},
|
||||||
|
tool: createMockTool(),
|
||||||
|
invocation: createMockInvocation(),
|
||||||
|
schedulerId: 'subagent-1',
|
||||||
|
};
|
||||||
|
|
||||||
// 4. Verify that a subsequent update to ONE scheduler doesn't wipe the other
|
|
||||||
act(() => {
|
act(() => {
|
||||||
void mockMessageBus.publish({
|
void mockMessageBus.publish({
|
||||||
type: MessageBusType.TOOL_CALLS_UPDATE,
|
type: MessageBusType.TOOL_CALLS_UPDATE,
|
||||||
toolCalls: [{ ...callRoot, status: CoreToolCallStatus.Executing }],
|
toolCalls: [subagentCall],
|
||||||
schedulerId: ROOT_SCHEDULER_ID,
|
schedulerId: 'subagent-1',
|
||||||
} as ToolCallsUpdateMessage);
|
} as ToolCallsUpdateMessage);
|
||||||
});
|
});
|
||||||
|
|
||||||
[toolCalls] = result.current;
|
const [toolCalls] = result.current;
|
||||||
expect(toolCalls).toHaveLength(2);
|
expect(toolCalls).toHaveLength(0);
|
||||||
expect(
|
|
||||||
toolCalls.find((t) => t.request.callId === 'call-root')?.status,
|
|
||||||
).toBe(CoreToolCallStatus.Executing);
|
|
||||||
expect(
|
|
||||||
toolCalls.find((t) => t.request.callId === 'call-sub')?.schedulerId,
|
|
||||||
).toBe('subagent-1');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adapts success/error status to executing when a tail call is present', () => {
|
it('adapts success/error status to executing when a tail call is present', () => {
|
||||||
|
|||||||
@@ -115,6 +115,12 @@ export function useToolScheduler(
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handler = (event: ToolCallsUpdateMessage) => {
|
const handler = (event: ToolCallsUpdateMessage) => {
|
||||||
|
// Only process updates for the root scheduler.
|
||||||
|
// Subagent internal tools should not be displayed in the main tool list.
|
||||||
|
if (event.schedulerId !== ROOT_SCHEDULER_ID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update output timer for UI spinners (Side Effect)
|
// Update output timer for UI spinners (Side Effect)
|
||||||
const hasExecuting = event.toolCalls.some(
|
const hasExecuting = event.toolCalls.some(
|
||||||
(tc) =>
|
(tc) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user