feat(plan): refresh system prompt when approval mode changes (Shift+Tab) (#17585)

This commit is contained in:
Jerop Kipruto
2026-01-26 18:45:24 -05:00
committed by GitHub
parent b5fe372b5b
commit 49c26b4801
5 changed files with 49 additions and 9 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ export async function refreshMemory(
fileCount = result.fileCount; fileCount = result.fileCount;
} }
await config.updateSystemInstructionIfInitialized(); config.updateSystemInstructionIfInitialized();
let content: string; let content: string;
if (memoryContent.length > 0) { if (memoryContent.length > 0) {
+33
View File
@@ -1269,6 +1269,39 @@ describe('setApprovalMode with folder trust', () => {
expect(() => config.setApprovalMode(ApprovalMode.DEFAULT)).not.toThrow(); expect(() => config.setApprovalMode(ApprovalMode.DEFAULT)).not.toThrow();
}); });
it('should update system instruction when entering Plan mode', () => {
const config = new Config(baseParams);
vi.spyOn(config, 'isTrustedFolder').mockReturnValue(true);
const updateSpy = vi.spyOn(config, 'updateSystemInstructionIfInitialized');
config.setApprovalMode(ApprovalMode.PLAN);
expect(updateSpy).toHaveBeenCalled();
});
it('should update system instruction when leaving Plan mode', () => {
const config = new Config({
...baseParams,
approvalMode: ApprovalMode.PLAN,
});
vi.spyOn(config, 'isTrustedFolder').mockReturnValue(true);
const updateSpy = vi.spyOn(config, 'updateSystemInstructionIfInitialized');
config.setApprovalMode(ApprovalMode.DEFAULT);
expect(updateSpy).toHaveBeenCalled();
});
it('should not update system instruction when switching between non-Plan modes', () => {
const config = new Config(baseParams);
vi.spyOn(config, 'isTrustedFolder').mockReturnValue(true);
const updateSpy = vi.spyOn(config, 'updateSystemInstructionIfInitialized');
config.setApprovalMode(ApprovalMode.AUTO_EDIT);
expect(updateSpy).not.toHaveBeenCalled();
});
describe('registerCoreTools', () => { describe('registerCoreTools', () => {
beforeEach(() => { beforeEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
+12 -5
View File
@@ -1341,7 +1341,7 @@ export class Config {
} }
if (this.geminiClient?.isInitialized()) { if (this.geminiClient?.isInitialized()) {
await this.geminiClient.setTools(); await this.geminiClient.setTools();
await this.geminiClient.updateSystemInstruction(); this.geminiClient.updateSystemInstruction();
} }
} }
@@ -1409,6 +1409,13 @@ export class Config {
} }
this.policyEngine.setApprovalMode(mode); this.policyEngine.setApprovalMode(mode);
const isPlanModeTransition =
currentMode !== mode &&
(currentMode === ApprovalMode.PLAN || mode === ApprovalMode.PLAN);
if (isPlanModeTransition) {
this.updateSystemInstructionIfInitialized();
}
} }
/** /**
@@ -1491,10 +1498,10 @@ export class Config {
* Updates the system instruction with the latest user memory. * Updates the system instruction with the latest user memory.
* Whenever the user memory (GEMINI.md files) is updated. * Whenever the user memory (GEMINI.md files) is updated.
*/ */
async updateSystemInstructionIfInitialized(): Promise<void> { updateSystemInstructionIfInitialized(): void {
const geminiClient = this.getGeminiClient(); const geminiClient = this.getGeminiClient();
if (geminiClient?.isInitialized()) { if (geminiClient?.isInitialized()) {
await geminiClient.updateSystemInstruction(); geminiClient.updateSystemInstruction();
} }
} }
@@ -1803,7 +1810,7 @@ export class Config {
} }
// Notify the client that system instructions might need updating // Notify the client that system instructions might need updating
await this.updateSystemInstructionIfInitialized(); this.updateSystemInstructionIfInitialized();
} }
/** /**
@@ -2142,7 +2149,7 @@ export class Config {
const client = this.getGeminiClient(); const client = this.getGeminiClient();
if (client?.isInitialized()) { if (client?.isInitialized()) {
await client.setTools(); await client.setTools();
await client.updateSystemInstruction(); client.updateSystemInstruction();
} else { } else {
debugLogger.debug( debugLogger.debug(
'[Config] GeminiClient not initialized; skipping live prompt/tool refresh.', '[Config] GeminiClient not initialized; skipping live prompt/tool refresh.',
+2 -2
View File
@@ -1842,7 +1842,7 @@ ${JSON.stringify(
const { getCoreSystemPrompt } = await import('./prompts.js'); const { getCoreSystemPrompt } = await import('./prompts.js');
const mockGetCoreSystemPrompt = vi.mocked(getCoreSystemPrompt); const mockGetCoreSystemPrompt = vi.mocked(getCoreSystemPrompt);
await client.updateSystemInstruction(); client.updateSystemInstruction();
expect(mockGetCoreSystemPrompt).toHaveBeenCalledWith( expect(mockGetCoreSystemPrompt).toHaveBeenCalledWith(
mockConfig, mockConfig,
@@ -1857,7 +1857,7 @@ ${JSON.stringify(
const { getCoreSystemPrompt } = await import('./prompts.js'); const { getCoreSystemPrompt } = await import('./prompts.js');
const mockGetCoreSystemPrompt = vi.mocked(getCoreSystemPrompt); const mockGetCoreSystemPrompt = vi.mocked(getCoreSystemPrompt);
await client.updateSystemInstruction(); client.updateSystemInstruction();
expect(mockGetCoreSystemPrompt).toHaveBeenCalledWith( expect(mockGetCoreSystemPrompt).toHaveBeenCalledWith(
mockConfig, mockConfig,
+1 -1
View File
@@ -300,7 +300,7 @@ export class GeminiClient {
}); });
} }
async updateSystemInstruction(): Promise<void> { updateSystemInstruction(): void {
if (!this.isInitialized()) { if (!this.isInitialized()) {
return; return;
} }