mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
fix(patch): cherry-pick cfdc4cf to release/v0.24.0-pr-16759 to patch version v0.24.0 and create version 0.24.1 (#16865)
Co-authored-by: christine betts <chrstn@uw.edu> Co-authored-by: Tommaso Sciortino <sciortino@gmail.com>
This commit is contained in:
@@ -444,7 +444,7 @@ export const useGeminiStream = (
|
|||||||
isClientInitiated: true,
|
isClientInitiated: true,
|
||||||
prompt_id,
|
prompt_id,
|
||||||
};
|
};
|
||||||
scheduleToolCalls([toolCallRequest], abortSignal);
|
await scheduleToolCalls([toolCallRequest], abortSignal);
|
||||||
return { queryToSend: null, shouldProceed: false };
|
return { queryToSend: null, shouldProceed: false };
|
||||||
}
|
}
|
||||||
case 'submit_prompt': {
|
case 'submit_prompt': {
|
||||||
@@ -911,7 +911,7 @@ export const useGeminiStream = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (toolCallRequests.length > 0) {
|
if (toolCallRequests.length > 0) {
|
||||||
scheduleToolCalls(toolCallRequests, signal);
|
await scheduleToolCalls(toolCallRequests, signal);
|
||||||
}
|
}
|
||||||
return StreamProcessingStatus.Completed;
|
return StreamProcessingStatus.Completed;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import { ToolCallStatus } from '../types.js';
|
|||||||
export type ScheduleFn = (
|
export type ScheduleFn = (
|
||||||
request: ToolCallRequestInfo | ToolCallRequestInfo[],
|
request: ToolCallRequestInfo | ToolCallRequestInfo[],
|
||||||
signal: AbortSignal,
|
signal: AbortSignal,
|
||||||
) => void;
|
) => Promise<void>;
|
||||||
export type MarkToolsAsSubmittedFn = (callIds: string[]) => void;
|
export type MarkToolsAsSubmittedFn = (callIds: string[]) => void;
|
||||||
|
|
||||||
export type TrackedScheduledToolCall = ScheduledToolCall & {
|
export type TrackedScheduledToolCall = ScheduledToolCall & {
|
||||||
@@ -180,7 +180,7 @@ export function useReactToolScheduler(
|
|||||||
signal: AbortSignal,
|
signal: AbortSignal,
|
||||||
) => {
|
) => {
|
||||||
setToolCallsForDisplay([]);
|
setToolCallsForDisplay([]);
|
||||||
void scheduler.schedule(request, signal);
|
return scheduler.schedule(request, signal);
|
||||||
},
|
},
|
||||||
[scheduler, setToolCallsForDisplay],
|
[scheduler, setToolCallsForDisplay],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -163,8 +163,8 @@ describe('useReactToolScheduler in YOLO Mode', () => {
|
|||||||
args: { data: 'any data' },
|
args: { data: 'any data' },
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
act(() => {
|
await act(async () => {
|
||||||
schedule(request, new AbortController().signal);
|
await schedule(request, new AbortController().signal);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
@@ -220,11 +220,11 @@ describe('useReactToolScheduler', () => {
|
|||||||
schedule: (
|
schedule: (
|
||||||
req: ToolCallRequestInfo | ToolCallRequestInfo[],
|
req: ToolCallRequestInfo | ToolCallRequestInfo[],
|
||||||
signal: AbortSignal,
|
signal: AbortSignal,
|
||||||
) => void,
|
) => Promise<void>,
|
||||||
request: ToolCallRequestInfo | ToolCallRequestInfo[],
|
request: ToolCallRequestInfo | ToolCallRequestInfo[],
|
||||||
) => {
|
) => {
|
||||||
act(() => {
|
await act(async () => {
|
||||||
schedule(request, new AbortController().signal);
|
await schedule(request, new AbortController().signal);
|
||||||
});
|
});
|
||||||
|
|
||||||
await advanceAndSettle();
|
await advanceAndSettle();
|
||||||
@@ -313,10 +313,13 @@ describe('useReactToolScheduler', () => {
|
|||||||
|
|
||||||
it('should clear previous tool calls when scheduling new ones', async () => {
|
it('should clear previous tool calls when scheduling new ones', async () => {
|
||||||
mockToolRegistry.getTool.mockReturnValue(mockTool);
|
mockToolRegistry.getTool.mockReturnValue(mockTool);
|
||||||
(mockTool.execute as Mock).mockResolvedValue({
|
(mockTool.execute as Mock).mockImplementation(async () => {
|
||||||
|
await new Promise((r) => setTimeout(r, 10));
|
||||||
|
return {
|
||||||
llmContent: 'Tool output',
|
llmContent: 'Tool output',
|
||||||
returnDisplay: 'Formatted tool output',
|
returnDisplay: 'Formatted tool output',
|
||||||
} as ToolResult);
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const { result } = renderScheduler();
|
const { result } = renderScheduler();
|
||||||
const schedule = result.current[1];
|
const schedule = result.current[1];
|
||||||
@@ -337,10 +340,13 @@ describe('useReactToolScheduler', () => {
|
|||||||
name: 'mockTool',
|
name: 'mockTool',
|
||||||
args: {},
|
args: {},
|
||||||
} as any;
|
} as any;
|
||||||
act(() => {
|
let schedulePromise: Promise<void>;
|
||||||
schedule(newRequest, new AbortController().signal);
|
await act(async () => {
|
||||||
|
schedulePromise = schedule(newRequest, new AbortController().signal);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await advanceAndSettle();
|
||||||
|
|
||||||
// After scheduling, the old call should be gone,
|
// After scheduling, the old call should be gone,
|
||||||
// and the new one should be in the display in its initial state.
|
// and the new one should be in the display in its initial state.
|
||||||
expect(result.current[0].length).toBe(1);
|
expect(result.current[0].length).toBe(1);
|
||||||
@@ -349,14 +355,13 @@ describe('useReactToolScheduler', () => {
|
|||||||
|
|
||||||
// Let the new call finish.
|
// Let the new call finish.
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
await vi.advanceTimersByTimeAsync(20);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
await schedulePromise;
|
||||||
});
|
|
||||||
await act(async () => {
|
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(onComplete).toHaveBeenCalled();
|
expect(onComplete).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -379,16 +384,14 @@ describe('useReactToolScheduler', () => {
|
|||||||
args: {},
|
args: {},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
act(() => {
|
let schedulePromise: Promise<void>;
|
||||||
schedule(request, new AbortController().signal);
|
|
||||||
});
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
schedulePromise = schedule(request, new AbortController().signal);
|
||||||
}); // validation
|
|
||||||
await act(async () => {
|
|
||||||
await vi.advanceTimersByTimeAsync(0); // Process scheduling
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await advanceAndSettle(); // validation
|
||||||
|
await advanceAndSettle(); // Process scheduling
|
||||||
|
|
||||||
// At this point, the tool is 'executing' and waiting on the promise.
|
// At this point, the tool is 'executing' and waiting on the promise.
|
||||||
expect(result.current[0][0].status).toBe('executing');
|
expect(result.current[0][0].status).toBe('executing');
|
||||||
|
|
||||||
@@ -397,9 +400,7 @@ describe('useReactToolScheduler', () => {
|
|||||||
cancelAllToolCalls(cancelController.signal);
|
cancelAllToolCalls(cancelController.signal);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await advanceAndSettle();
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(onComplete).toHaveBeenCalledWith([
|
expect(onComplete).toHaveBeenCalledWith([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@@ -412,6 +413,11 @@ describe('useReactToolScheduler', () => {
|
|||||||
await act(async () => {
|
await act(async () => {
|
||||||
resolveExecute({ llmContent: 'output', returnDisplay: 'display' });
|
resolveExecute({ llmContent: 'output', returnDisplay: 'display' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Now await the schedule promise
|
||||||
|
await act(async () => {
|
||||||
|
await schedulePromise;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
@@ -511,8 +517,9 @@ describe('useReactToolScheduler', () => {
|
|||||||
args: { data: 'sensitive' },
|
args: { data: 'sensitive' },
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
act(() => {
|
let schedulePromise: Promise<void>;
|
||||||
schedule(request, new AbortController().signal);
|
await act(async () => {
|
||||||
|
schedulePromise = schedule(request, new AbortController().signal);
|
||||||
});
|
});
|
||||||
await advanceAndSettle();
|
await advanceAndSettle();
|
||||||
|
|
||||||
@@ -526,8 +533,11 @@ describe('useReactToolScheduler', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await advanceAndSettle();
|
await advanceAndSettle();
|
||||||
await advanceAndSettle();
|
|
||||||
await advanceAndSettle();
|
// Now await the schedule promise as it should complete
|
||||||
|
await act(async () => {
|
||||||
|
await schedulePromise;
|
||||||
|
});
|
||||||
|
|
||||||
expect(mockOnUserConfirmForToolConfirmation).toHaveBeenCalledWith(
|
expect(mockOnUserConfirmForToolConfirmation).toHaveBeenCalledWith(
|
||||||
ToolConfirmationOutcome.ProceedOnce,
|
ToolConfirmationOutcome.ProceedOnce,
|
||||||
@@ -558,8 +568,9 @@ describe('useReactToolScheduler', () => {
|
|||||||
args: {},
|
args: {},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
act(() => {
|
let schedulePromise: Promise<void>;
|
||||||
schedule(request, new AbortController().signal);
|
await act(async () => {
|
||||||
|
schedulePromise = schedule(request, new AbortController().signal);
|
||||||
});
|
});
|
||||||
await advanceAndSettle();
|
await advanceAndSettle();
|
||||||
|
|
||||||
@@ -571,8 +582,13 @@ describe('useReactToolScheduler', () => {
|
|||||||
await act(async () => {
|
await act(async () => {
|
||||||
await capturedOnConfirmForTest?.(ToolConfirmationOutcome.Cancel);
|
await capturedOnConfirmForTest?.(ToolConfirmationOutcome.Cancel);
|
||||||
});
|
});
|
||||||
|
|
||||||
await advanceAndSettle();
|
await advanceAndSettle();
|
||||||
await advanceAndSettle();
|
|
||||||
|
// Now await the schedule promise
|
||||||
|
await act(async () => {
|
||||||
|
await schedulePromise;
|
||||||
|
});
|
||||||
|
|
||||||
expect(mockOnUserConfirmForToolConfirmation).toHaveBeenCalledWith(
|
expect(mockOnUserConfirmForToolConfirmation).toHaveBeenCalledWith(
|
||||||
ToolConfirmationOutcome.Cancel,
|
ToolConfirmationOutcome.Cancel,
|
||||||
@@ -619,8 +635,12 @@ describe('useReactToolScheduler', () => {
|
|||||||
args: {},
|
args: {},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
act(() => {
|
let schedulePromise: Promise<void>;
|
||||||
result.current[1](request, new AbortController().signal);
|
await act(async () => {
|
||||||
|
schedulePromise = result.current[1](
|
||||||
|
request,
|
||||||
|
new AbortController().signal,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
await advanceAndSettle();
|
await advanceAndSettle();
|
||||||
|
|
||||||
@@ -644,7 +664,11 @@ describe('useReactToolScheduler', () => {
|
|||||||
} as ToolResult);
|
} as ToolResult);
|
||||||
});
|
});
|
||||||
await advanceAndSettle();
|
await advanceAndSettle();
|
||||||
await advanceAndSettle();
|
|
||||||
|
// Now await schedule
|
||||||
|
await act(async () => {
|
||||||
|
await schedulePromise;
|
||||||
|
});
|
||||||
|
|
||||||
const completedCalls = onComplete.mock.calls[0][0] as ToolCall[];
|
const completedCalls = onComplete.mock.calls[0][0] as ToolCall[];
|
||||||
expect(completedCalls[0].status).toBe('success');
|
expect(completedCalls[0].status).toBe('success');
|
||||||
@@ -690,8 +714,8 @@ describe('useReactToolScheduler', () => {
|
|||||||
{ callId: 'multi2', name: 'tool2', args: { p: 2 } } as any,
|
{ callId: 'multi2', name: 'tool2', args: { p: 2 } } as any,
|
||||||
];
|
];
|
||||||
|
|
||||||
act(() => {
|
await act(async () => {
|
||||||
schedule(requests, new AbortController().signal);
|
await schedule(requests, new AbortController().signal);
|
||||||
});
|
});
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
await vi.advanceTimersByTimeAsync(0);
|
||||||
@@ -782,24 +806,30 @@ describe('useReactToolScheduler', () => {
|
|||||||
args: {},
|
args: {},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
act(() => {
|
let schedulePromise1: Promise<void>;
|
||||||
schedule(request1, new AbortController().signal);
|
let schedulePromise2: Promise<void>;
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
schedulePromise1 = schedule(request1, new AbortController().signal);
|
||||||
});
|
});
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
await vi.advanceTimersByTimeAsync(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
act(() => {
|
await act(async () => {
|
||||||
schedule(request2, new AbortController().signal);
|
schedulePromise2 = schedule(request2, new AbortController().signal);
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(50);
|
await vi.advanceTimersByTimeAsync(50);
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
await vi.advanceTimersByTimeAsync(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for first to complete
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
await schedulePromise1;
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(onComplete).toHaveBeenCalledWith([
|
expect(onComplete).toHaveBeenCalledWith([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
@@ -807,13 +837,17 @@ describe('useReactToolScheduler', () => {
|
|||||||
response: expect.objectContaining({ resultDisplay: 'done display' }),
|
response: expect.objectContaining({ resultDisplay: 'done display' }),
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(50);
|
await vi.advanceTimersByTimeAsync(50);
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
await vi.advanceTimersByTimeAsync(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for second to complete
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await vi.advanceTimersByTimeAsync(0);
|
await schedulePromise2;
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(onComplete).toHaveBeenCalledWith([
|
expect(onComplete).toHaveBeenCalledWith([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
|
|||||||
Reference in New Issue
Block a user