feat(core): enable topic update narration for legacy models (#24241)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Abhijit Balaji
2026-03-30 17:57:46 -07:00
committed by GitHub
parent 35efdfc409
commit 80929c48c5
2 changed files with 53 additions and 3 deletions

View File

@@ -11,7 +11,10 @@ import {
getAllGeminiMdFilenames,
DEFAULT_CONTEXT_FILENAME,
} from '../tools/memoryTool.js';
import { PREVIEW_GEMINI_MODEL } from '../config/models.js';
import {
PREVIEW_GEMINI_MODEL,
DEFAULT_GEMINI_MODEL,
} from '../config/models.js';
import { ApprovalMode } from '../policy/types.js';
import { DiscoveredMCPTool } from '../tools/mcp-tool.js';
import { MockTool } from '../test-utils/mock-tool.js';
@@ -301,5 +304,20 @@ describe('PromptProvider', () => {
expect(prompt).toContain(`<tool>\`${UPDATE_TOPIC_TOOL_NAME}\`</tool>`);
});
it('should include topic update instructions in legacy model prompt when enabled', () => {
vi.mocked(mockConfig.getActiveModel).mockReturnValue(
DEFAULT_GEMINI_MODEL,
);
vi.mocked(mockConfig.isTopicUpdateNarrationEnabled).mockReturnValue(true);
const provider = new PromptProvider();
const prompt = provider.getCoreSystemPrompt(mockConfig);
expect(prompt).toContain('## Topic Updates');
expect(prompt).toContain(UPDATE_TOPIC_TOOL_NAME);
expect(prompt).toContain('No Chitchat');
expect(prompt).toContain('Topic Model');
});
});
});

View File

@@ -20,6 +20,9 @@ import {
TRACKER_CREATE_TASK_TOOL_NAME,
TRACKER_LIST_TASKS_TOOL_NAME,
TRACKER_UPDATE_TASK_TOOL_NAME,
UPDATE_TOPIC_TOOL_NAME,
TOPIC_PARAM_TITLE,
TOPIC_PARAM_SUMMARY,
WRITE_FILE_TOOL_NAME,
WRITE_TODOS_TOOL_NAME,
} from '../tools/tool-names.js';
@@ -51,6 +54,7 @@ export interface CoreMandatesOptions {
isGemini3: boolean;
hasSkills: boolean;
hasHierarchicalMemory: boolean;
topicUpdateNarration?: boolean;
}
export interface PrimaryWorkflowsOptions {
@@ -60,6 +64,7 @@ export interface PrimaryWorkflowsOptions {
enableEnterPlanModeTool: boolean;
approvedPlan?: { path: string };
taskTracker?: boolean;
topicUpdateNarration?: boolean;
}
export interface OperationalGuidelinesOptions {
@@ -67,6 +72,7 @@ export interface OperationalGuidelinesOptions {
isGemini3: boolean;
enableShellEfficiency: boolean;
interactiveShellEnabled: boolean;
topicUpdateNarration?: boolean;
memoryManagerEnabled: boolean;
}
@@ -177,7 +183,11 @@ export function renderCoreMandates(options?: CoreMandatesOptions): string {
- **User Hints:** During execution, the user may provide real-time hints (marked as "User hint:" or "User hints:"). Treat these as high-priority but scope-preserving course corrections: apply the minimal plan change needed, keep unaffected user tasks active, and never cancel/skip tasks unless cancellation is explicit for those tasks. Hints may add new tasks, modify one or more tasks, cancel specific tasks, or provide extra context only. If scope is ambiguous, ask for clarification before dropping work.
- ${mandateConfirm(options.interactive)}
- **Explaining Changes:** After completing a code modification or file operation *do not* provide summaries unless asked.
- **Do Not revert changes:** Do not revert changes to the codebase unless asked to do so by the user. Only revert changes made by you if they have resulted in an error or if the user has explicitly asked you to revert the changes.${mandateSkillGuidance(options.hasSkills)}${mandateExplainBeforeActing(options.isGemini3)}${mandateContinueWork(options.interactive)}
- **Do Not revert changes:** Do not revert changes to the codebase unless asked to do so by the user. Only revert changes made by you if they have resulted in an error or if the user has explicitly asked you to revert the changes.${mandateSkillGuidance(options.hasSkills)}${
options.topicUpdateNarration
? mandateTopicUpdateModel()
: mandateExplainBeforeActing(options.isGemini3)
}${mandateContinueWork(options.interactive)}
`.trim();
}
@@ -272,7 +282,12 @@ ${shellEfficiencyGuidelines(options.enableShellEfficiency)}
## Tone and Style (CLI Interaction)
- **Concise & Direct:** Adopt a professional, direct, and concise tone suitable for a CLI environment.
- **Minimal Output:** Aim for fewer than 3 lines of text output (excluding tool use/code generation) per response whenever practical. Focus strictly on the user's query.
- **Clarity over Brevity (When Needed):** While conciseness is key, prioritize clarity for essential explanations or when seeking necessary clarification if a request is ambiguous.${toneAndStyleNoChitchat(options.isGemini3)}
- **Clarity over Brevity (When Needed):** While conciseness is key, prioritize clarity for essential explanations or when seeking necessary clarification if a request is ambiguous.${
options.topicUpdateNarration
? `
- **No Chitchat:** Avoid conversational filler, preambles ("Okay, I will now..."), or postambles ("I have finished the changes...") unless they are part of the **Topic Model**.`
: toneAndStyleNoChitchat(options.isGemini3)
}
- **Formatting:** Use GitHub-flavored Markdown. Responses will be rendered in monospace.
- **Tools vs. Text:** Use tools for actions, text output *only* for communication. Do not add explanatory comments within tool calls or code blocks unless specifically part of the required code/command itself.
- **Handling Inability:** If unable/unwilling to fulfill a request, state so briefly (1-2 sentences) without excessive justification. Offer alternatives if appropriate.
@@ -493,6 +508,23 @@ function mandateConfirm(interactive: boolean): string {
: '**Handle Ambiguity/Expansion:** Do not take significant actions beyond the clear scope of the request. If the user implies a change (e.g., reports a bug) without explicitly asking for a fix, do not perform it automatically.';
}
function mandateTopicUpdateModel(): string {
return `
## Topic Updates
As you work, the user follows along by reading topic updates that you publish with ${UPDATE_TOPIC_TOOL_NAME}. Keep them informed by doing the following:
- Always call ${UPDATE_TOPIC_TOOL_NAME} in your first and last turn. The final turn should always recap what was done.
- Each topic update should give a concise description of what you are doing for the next few turns in the \`${TOPIC_PARAM_SUMMARY}\` parameter.
- Provide topic updates whenever you change "topics". A topic is typically a discrete subgoal and will be every 3 to 10 turns. Do not use ${UPDATE_TOPIC_TOOL_NAME} on every turn.
- The typical user message should call ${UPDATE_TOPIC_TOOL_NAME} 3 or more times. Each corresponds to a distinct phase of the task, such as "Researching X", "Researching Y", "Implementing Z with X", and "Testing Z".
- Remember to call ${UPDATE_TOPIC_TOOL_NAME} when you experience an unexpected event (e.g., a test failure, compilation error, environment issue, or unexpected learning) that requires a strategic detour.
- **Examples:**
- ${UPDATE_TOPIC_TOOL_NAME}(${TOPIC_PARAM_TITLE}="Researching Parser", ${TOPIC_PARAM_SUMMARY}="I am starting an investigation into the parser timeout bug. My goal is to first understand the current test coverage and then attempt to reproduce the failure. This phase will focus on identifying the bottleneck in the main loop before we move to implementation.")
- ${UPDATE_TOPIC_TOOL_NAME}(${TOPIC_PARAM_TITLE}="Implementing Buffer Fix", ${TOPIC_PARAM_SUMMARY}="I have completed the research phase and identified a race condition in the tokenizer's buffer management. I am now transitioning to implementation. This new chapter will focus on refactoring the buffer logic to handle async chunks safely, followed by unit testing the fix.")
`;
}
function mandateSkillGuidance(hasSkills: boolean): string {
if (!hasSkills) return '';
return `