fix(core): resolve subagent chat recording gaps and directory inheritance (#24368)

This commit is contained in:
Abhi
2026-04-01 11:29:38 -04:00
committed by GitHub
parent 9f76f34049
commit dcf5afafda
4 changed files with 144 additions and 18 deletions
+41 -12
View File
@@ -18,6 +18,8 @@ const {
mockSendMessageStream,
mockScheduleAgentTools,
mockSetSystemInstruction,
mockRecordCompletedToolCalls,
mockSaveSummary,
mockCompress,
mockMaybeDiscoverMcpServer,
mockStopMcp,
@@ -32,6 +34,8 @@ const {
}),
mockScheduleAgentTools: vi.fn(),
mockSetSystemInstruction: vi.fn(),
mockRecordCompletedToolCalls: vi.fn(),
mockSaveSummary: vi.fn(),
mockCompress: vi.fn(),
mockMaybeDiscoverMcpServer: vi.fn().mockResolvedValue(undefined),
mockStopMcp: vi.fn().mockResolvedValue(undefined),
@@ -127,18 +131,21 @@ vi.mock('../context/chatCompressionService.js', () => ({
})),
}));
vi.mock('../core/geminiChat.js', async (importOriginal) => {
const actual = await importOriginal<typeof import('../core/geminiChat.js')>();
return {
...actual,
GeminiChat: vi.fn().mockImplementation(() => ({
sendMessageStream: mockSendMessageStream,
getHistory: vi.fn((_curated?: boolean) => [...mockChatHistory]),
setHistory: mockSetHistory,
setSystemInstruction: mockSetSystemInstruction,
})),
};
});
vi.mock('../core/geminiChat.js', () => ({
StreamEventType: {
CHUNK: 'chunk',
},
GeminiChat: vi.fn().mockImplementation(() => ({
sendMessageStream: mockSendMessageStream,
getHistory: vi.fn((_curated?: boolean) => [...mockChatHistory]),
setHistory: mockSetHistory,
setSystemInstruction: mockSetSystemInstruction,
recordCompletedToolCalls: mockRecordCompletedToolCalls,
getChatRecordingService: vi.fn().mockReturnValue({
saveSummary: mockSaveSummary,
}),
})),
}));
vi.mock('./agent-scheduler.js', () => ({
scheduleAgentTools: mockScheduleAgentTools,
@@ -337,6 +344,10 @@ describe('LocalAgentExecutor', () => {
getHistory: vi.fn((_curated?: boolean) => [...mockChatHistory]),
getLastPromptTokenCount: vi.fn(() => 100),
setHistory: mockSetHistory,
recordCompletedToolCalls: mockRecordCompletedToolCalls,
getChatRecordingService: vi.fn().mockReturnValue({
saveSummary: mockSaveSummary,
}),
}) as unknown as GeminiChat,
);
@@ -942,6 +953,20 @@ describe('LocalAgentExecutor', () => {
// Context checks
expect(mockedPromptIdContext.run).toHaveBeenCalledTimes(2); // Two turns
// Recording checks
expect(mockRecordCompletedToolCalls).toHaveBeenCalledTimes(1);
expect(mockRecordCompletedToolCalls).toHaveBeenCalledWith(
expect.any(String), // model
expect.arrayContaining([
expect.objectContaining({
status: 'success',
request: expect.objectContaining({ name: LS_TOOL_NAME }),
}),
]),
);
expect(mockSaveSummary).toHaveBeenCalledTimes(1);
expect(mockSaveSummary).toHaveBeenCalledWith('Found file1.txt');
const agentId = executor['agentId'];
expect(mockedPromptIdContext.run).toHaveBeenNthCalledWith(
1,
@@ -2450,6 +2475,10 @@ describe('LocalAgentExecutor', () => {
expect(recoveryEvent).toBeInstanceOf(RecoveryAttemptEvent);
expect(recoveryEvent.success).toBe(true);
expect(recoveryEvent.reason).toBe(AgentTerminateMode.MAX_TURNS);
// Verify that the summary is saved upon successful recovery
expect(mockSaveSummary).toHaveBeenCalledTimes(1);
expect(mockSaveSummary).toHaveBeenCalledWith('Recovered!');
});
describe('Model Steering', () => {