mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-22 11:04:42 -07:00
feat(core): scope subagent workspace directories via AsyncLocalStorage (#24445)
This commit is contained in:
@@ -198,6 +198,27 @@ vi.mock('../utils/promptIdContext.js', async (importOriginal) => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../config/scoped-config.js', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('../config/scoped-config.js')>();
|
||||
return {
|
||||
...actual,
|
||||
runWithScopedWorkspaceContext: vi.fn(actual.runWithScopedWorkspaceContext),
|
||||
createScopedWorkspaceContext: vi.fn(actual.createScopedWorkspaceContext),
|
||||
};
|
||||
});
|
||||
|
||||
import {
|
||||
runWithScopedWorkspaceContext,
|
||||
createScopedWorkspaceContext,
|
||||
} from '../config/scoped-config.js';
|
||||
const mockedRunWithScopedWorkspaceContext = vi.mocked(
|
||||
runWithScopedWorkspaceContext,
|
||||
);
|
||||
const mockedCreateScopedWorkspaceContext = vi.mocked(
|
||||
createScopedWorkspaceContext,
|
||||
);
|
||||
|
||||
const MockedGeminiChat = vi.mocked(GeminiChat);
|
||||
const mockedGetDirectoryContextString = vi.mocked(getDirectoryContextString);
|
||||
const mockedPromptIdContext = vi.mocked(promptIdContext);
|
||||
@@ -396,6 +417,8 @@ describe('LocalAgentExecutor', () => {
|
||||
);
|
||||
mockedLogAgentStart.mockReset();
|
||||
mockedLogAgentFinish.mockReset();
|
||||
mockedRunWithScopedWorkspaceContext.mockClear();
|
||||
mockedCreateScopedWorkspaceContext.mockClear();
|
||||
mockedPromptIdContext.getStore.mockReset();
|
||||
mockedPromptIdContext.run.mockImplementation((_id, fn) => fn());
|
||||
|
||||
@@ -885,6 +908,55 @@ describe('LocalAgentExecutor', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('run (Workspace Scoping)', () => {
|
||||
it('should use runWithScopedWorkspaceContext when workspaceDirectories is set', async () => {
|
||||
const definition = createTestDefinition();
|
||||
definition.workspaceDirectories = ['/tmp/extra-dir'];
|
||||
const executor = await LocalAgentExecutor.create(
|
||||
definition,
|
||||
mockConfig,
|
||||
onActivity,
|
||||
);
|
||||
|
||||
// Mock a simple complete_task response so run() terminates
|
||||
mockModelResponse([
|
||||
{
|
||||
name: COMPLETE_TASK_TOOL_NAME,
|
||||
args: { finalResult: 'done' },
|
||||
id: 'c1',
|
||||
},
|
||||
]);
|
||||
|
||||
await executor.run({ goal: 'test' }, signal);
|
||||
|
||||
expect(mockedCreateScopedWorkspaceContext).toHaveBeenCalledOnce();
|
||||
expect(mockedRunWithScopedWorkspaceContext).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('should not use runWithScopedWorkspaceContext when workspaceDirectories is not set', async () => {
|
||||
const definition = createTestDefinition();
|
||||
const executor = await LocalAgentExecutor.create(
|
||||
definition,
|
||||
mockConfig,
|
||||
onActivity,
|
||||
);
|
||||
|
||||
// Mock a simple complete_task response so run() terminates
|
||||
mockModelResponse([
|
||||
{
|
||||
name: COMPLETE_TASK_TOOL_NAME,
|
||||
args: { finalResult: 'done' },
|
||||
id: 'c1',
|
||||
},
|
||||
]);
|
||||
|
||||
await executor.run({ goal: 'test' }, signal);
|
||||
|
||||
expect(mockedCreateScopedWorkspaceContext).not.toHaveBeenCalled();
|
||||
expect(mockedRunWithScopedWorkspaceContext).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('run (Execution Loop and Logic)', () => {
|
||||
it('should log AgentFinish with error if run throws', async () => {
|
||||
const definition = createTestDefinition();
|
||||
|
||||
Reference in New Issue
Block a user