fix: update task tracker storage location in system prompt (#24034)

This commit is contained in:
anj-s
2026-04-01 11:29:09 -07:00
committed by GitHub
parent bda4491616
commit 43cf63e189
7 changed files with 77 additions and 17 deletions

View File

@@ -113,4 +113,21 @@ describe('tracker_mode', () => {
assertModelHasOutput(result);
},
});
evalTest('USUALLY_PASSES', {
name: 'should correctly identify the task tracker storage location from the system prompt',
params: {
settings: { experimental: { taskTracker: true } },
},
prompt:
'Where is my task tracker storage located? Please provide the absolute path in your response.',
assert: async (rig, result) => {
// The rig sets GEMINI_CLI_HOME to rig.homeDir
const homeDir = rig.homeDir!;
// The response should contain the dynamic path which includes the home directory
// and follows the .gemini/tmp/.../tracker structure.
expect(result).toContain(homeDir);
expect(result).toMatch(/\.gemini\/tmp\/.*\/tracker/);
},
});
});

View File

@@ -2899,7 +2899,7 @@ Use 'read_file' to understand context and validate any assumptions you may have.
6. **Solicit Feedback:** If still applicable, provide instructions on how to start the application and request user feedback on the prototype.
# TASK MANAGEMENT PROTOCOL
You are operating with a persistent file-based task tracking system located at \`.tracker/tasks/\`. You must adhere to the following rules:
You are operating with a persistent file-based task tracking system located at \`/mock/.gemini/tmp/session/tracker\`. You must adhere to the following rules:
1. **NO IN-MEMORY LISTS**: Do not maintain a mental list of tasks or write markdown checkboxes in the chat. Use the provided tools (\`tracker_create_task\`, \`tracker_list_tasks\`, \`tracker_update_task\`) for all state management.
2. **IMMEDIATE DECOMPOSITION**: Upon receiving a task, evaluate its functional complexity and scope. If the request involves more than a single atomic modification, or necessitates research before execution, you MUST immediately decompose it into discrete entries using \`tracker_create_task\`.
@@ -3079,7 +3079,7 @@ Operate using a **Research -> Strategy -> Execution** lifecycle. For the Executi
5. **Solicit Feedback:** Provide instructions on how to start the application and request user feedback on the prototype.
# TASK MANAGEMENT PROTOCOL
You are operating with a persistent file-based task tracking system located at \`.tracker/tasks/\`. You must adhere to the following rules:
You are operating with a persistent file-based task tracking system located at \`/mock/.gemini/tmp/session/tracker\`. You must adhere to the following rules:
1. **NO IN-MEMORY LISTS**: Do not maintain a mental list of tasks or write markdown checkboxes in the chat. Use the provided tools (\`tracker_create_task\`, \`tracker_list_tasks\`, \`tracker_update_task\`) for all state management.
2. **IMMEDIATE DECOMPOSITION**: Upon receiving a task, evaluate its functional complexity and scope. If the request involves more than a single atomic modification, or necessitates research before execution, you MUST immediately decompose it into discrete entries using \`tracker_create_task\`.

View File

@@ -93,6 +93,9 @@ describe('Core System Prompt (prompts.ts)', () => {
storage: {
getProjectTempDir: vi.fn().mockReturnValue('/tmp/project-temp'),
getPlansDir: vi.fn().mockReturnValue('/tmp/project-temp/plans'),
getProjectTempTrackerDir: vi
.fn()
.mockReturnValue('/mock/.gemini/tmp/session/tracker'),
},
isInteractive: vi.fn().mockReturnValue(true),
isInteractiveShellEnabled: vi.fn().mockReturnValue(true),

View File

@@ -64,6 +64,9 @@ describe('PromptProvider', () => {
storage: {
getProjectTempDir: vi.fn().mockReturnValue('/tmp/project-temp'),
getPlansDir: vi.fn().mockReturnValue('/tmp/project-temp/plans'),
getProjectTempTrackerDir: vi
.fn()
.mockReturnValue('/tmp/project-temp/tracker'),
},
isInteractive: vi.fn().mockReturnValue(true),
isInteractiveShellEnabled: vi.fn().mockReturnValue(true),
@@ -104,6 +107,36 @@ describe('PromptProvider', () => {
);
});
it('should include the task tracker storage location in the system prompt', () => {
vi.mocked(mockConfig.isTrackerEnabled).mockReturnValue(true);
const mockTrackerDir = '/mock/tracker/path';
vi.mocked(mockConfig.storage.getProjectTempTrackerDir).mockReturnValue(
mockTrackerDir,
);
const provider = new PromptProvider();
const prompt = provider.getCoreSystemPrompt(mockConfig);
expect(prompt).toContain('# TASK MANAGEMENT PROTOCOL');
expect(prompt).toContain(`located at \`${mockTrackerDir}\``);
});
it('should sanitize the task tracker storage location in the system prompt', () => {
vi.mocked(mockConfig.isTrackerEnabled).mockReturnValue(true);
const mockTrackerDir = '/mock/tracker/path\nwith-newline]and-bracket';
vi.mocked(mockConfig.storage.getProjectTempTrackerDir).mockReturnValue(
mockTrackerDir,
);
const provider = new PromptProvider();
const prompt = provider.getCoreSystemPrompt(mockConfig);
expect(prompt).toContain('# TASK MANAGEMENT PROTOCOL');
expect(prompt).toContain(
'located at `/mock/tracker/path with-newlineand-bracket`',
);
});
it('should handle multiple context filenames in user memory section', () => {
vi.mocked(getAllGeminiMdFilenames).mockReturnValue([
DEFAULT_CONTEXT_FILENAME,

View File

@@ -72,6 +72,16 @@ export class PromptProvider {
const activeSnippets = isModernModel ? snippets : legacySnippets;
const contextFilenames = getAllGeminiMdFilenames();
let trackerDir = context.config.isTrackerEnabled()
? context.config.storage.getProjectTempTrackerDir()
: undefined;
if (trackerDir) {
// Sanitize path to prevent prompt injection
trackerDir = trackerDir.replace(/\n/g, ' ').replace(/\]/g, '');
}
// --- Context Gathering ---
let planModeToolsList = '';
if (isPlanMode) {
const allTools = context.toolRegistry.getAllTools();
@@ -149,7 +159,7 @@ export class PromptProvider {
})),
skills.length > 0,
),
taskTracker: context.config.isTrackerEnabled(),
taskTracker: trackerDir,
hookContext: isSectionEnabled('hookContext') || undefined,
primaryWorkflows: this.withSection(
'primaryWorkflows',
@@ -167,7 +177,7 @@ export class PromptProvider {
approvedPlan: approvedPlanPath
? { path: approvedPlanPath }
: undefined,
taskTracker: context.config.isTrackerEnabled(),
taskTracker: trackerDir,
topicUpdateNarration:
context.config.isTopicUpdateNarrationEnabled(),
}),
@@ -180,7 +190,6 @@ export class PromptProvider {
planModeToolsList,
plansDir: context.config.storage.getPlansDir(),
approvedPlanPath: context.config.getApprovedPlanPath(),
taskTracker: context.config.isTrackerEnabled(),
}),
isPlanMode,
),

View File

@@ -37,7 +37,7 @@ export interface SystemPromptOptions {
hookContext?: boolean;
primaryWorkflows?: PrimaryWorkflowsOptions;
planningWorkflow?: PlanningWorkflowOptions;
taskTracker?: boolean;
taskTracker?: string;
operationalGuidelines?: OperationalGuidelinesOptions;
sandbox?: SandboxOptions;
interactiveYoloMode?: boolean;
@@ -63,7 +63,7 @@ export interface PrimaryWorkflowsOptions {
enableWriteTodosTool: boolean;
enableEnterPlanModeTool: boolean;
approvedPlan?: { path: string };
taskTracker?: boolean;
taskTracker?: string;
topicUpdateNarration?: boolean;
}
@@ -95,7 +95,6 @@ export interface PlanningWorkflowOptions {
planModeToolsList: string;
plansDir: string;
approvedPlanPath?: string;
taskTracker?: boolean;
}
export interface AgentSkillOptions {
@@ -132,7 +131,7 @@ ${
: renderPrimaryWorkflows(options.primaryWorkflows)
}
${options.taskTracker ? renderTaskTracker() : ''}
${options.taskTracker ? renderTaskTracker(options.taskTracker) : ''}
${renderOperationalGuidelines(options.operationalGuidelines)}
@@ -491,10 +490,10 @@ An approved plan is available for this task.
`;
}
export function renderTaskTracker(): string {
export function renderTaskTracker(trackerDir: string): string {
return `
# TASK MANAGEMENT PROTOCOL
You are operating with a persistent file-based task tracking system located at \`.tracker/tasks/\`. You must adhere to the following rules:
You are operating with a persistent file-based task tracking system located at \`${trackerDir}\`. You must adhere to the following rules:
1. **NO IN-MEMORY LISTS**: Do not maintain a mental list of tasks or write markdown checkboxes in the chat. Use the provided tools (\`${TRACKER_CREATE_TASK_TOOL_NAME}\`, \`${TRACKER_LIST_TASKS_TOOL_NAME}\`, \`${TRACKER_UPDATE_TASK_TOOL_NAME}\`) for all state management.
2. **IMMEDIATE DECOMPOSITION**: Upon receiving a task, evaluate its functional complexity and scope. If the request involves more than a single atomic modification, or necessitates research before execution, you MUST immediately decompose it into discrete entries using \`${TRACKER_CREATE_TASK_TOOL_NAME}\`.

View File

@@ -47,7 +47,7 @@ export interface SystemPromptOptions {
hookContext?: boolean;
primaryWorkflows?: PrimaryWorkflowsOptions;
planningWorkflow?: PlanningWorkflowOptions;
taskTracker?: boolean;
taskTracker?: string;
operationalGuidelines?: OperationalGuidelinesOptions;
sandbox?: SandboxOptions;
interactiveYoloMode?: boolean;
@@ -74,7 +74,7 @@ export interface PrimaryWorkflowsOptions {
enableGrep: boolean;
enableGlob: boolean;
approvedPlan?: { path: string };
taskTracker?: boolean;
taskTracker?: string;
topicUpdateNarration: boolean;
}
@@ -101,7 +101,6 @@ export interface PlanningWorkflowOptions {
planModeToolsList: string;
plansDir: string;
approvedPlanPath?: string;
taskTracker?: boolean;
}
export interface AgentSkillOptions {
@@ -139,7 +138,7 @@ ${
: renderPrimaryWorkflows(options.primaryWorkflows)
}
${options.taskTracker ? renderTaskTracker() : ''}
${options.taskTracker ? renderTaskTracker(options.taskTracker) : ''}
${renderOperationalGuidelines(options.operationalGuidelines)}
@@ -537,14 +536,14 @@ ${trimmed}
return `\n---\n\n<loaded_context>\n${sections.join('\n')}\n</loaded_context>`;
}
export function renderTaskTracker(): string {
export function renderTaskTracker(trackerDir: string): string {
const trackerCreate = formatToolName(TRACKER_CREATE_TASK_TOOL_NAME);
const trackerList = formatToolName(TRACKER_LIST_TASKS_TOOL_NAME);
const trackerUpdate = formatToolName(TRACKER_UPDATE_TASK_TOOL_NAME);
return `
# TASK MANAGEMENT PROTOCOL
You are operating with a persistent file-based task tracking system located at \`.tracker/tasks/\`. You must adhere to the following rules:
You are operating with a persistent file-based task tracking system located at \`${trackerDir}\`. You must adhere to the following rules:
1. **NO IN-MEMORY LISTS**: Do not maintain a mental list of tasks or write markdown checkboxes in the chat. Use the provided tools (${trackerCreate}, ${trackerList}, ${trackerUpdate}) for all state management.
2. **IMMEDIATE DECOMPOSITION**: Upon receiving a task, evaluate its functional complexity and scope. If the request involves more than a single atomic modification, or necessitates research before execution, you MUST immediately decompose it into discrete entries using ${trackerCreate}.