Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion packages/core/src/core/prompts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { getCoreSystemPrompt, resolvePathFromEnv } from './prompts.js';
import { isGitRepository } from '../utils/gitUtils.js';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import process from 'node:process';
import type { Config } from '../config/config.js';
import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js';
import { GEMINI_DIR } from '../utils/paths.js';
Expand Down Expand Up @@ -52,10 +53,12 @@ vi.mock('../config/models.js', async (importOriginal) => {

describe('Core System Prompt (prompts.ts)', () => {
let mockConfig: Config;

beforeEach(() => {
vi.resetAllMocks();
vi.stubEnv('GEMINI_SYSTEM_MD', undefined);
vi.stubEnv('GEMINI_WRITE_SYSTEM_MD', undefined);
vi.spyOn(process, 'platform', 'get').mockReturnValue('linux');
mockConfig = {
getToolRegistry: vi.fn().mockReturnValue({
getAllToolNames: vi.fn().mockReturnValue([]),
Expand All @@ -78,6 +81,30 @@ describe('Core System Prompt (prompts.ts)', () => {
} as unknown as Config;
});

afterEach(() => {
vi.restoreAllMocks();
});

it('should use Windows-specific commands when platform is win32', () => {
vi.spyOn(process, 'platform', 'get').mockReturnValue('win32');
vi.mocked(isGitRepository).mockReturnValue(true);
const prompt = getCoreSystemPrompt(mockConfig);
expect(prompt).toContain("'Select-String'");
expect(prompt).toContain("'Get-Content -Tail 10'");
expect(prompt).toContain("'Get-Content -TotalCount 10'");
Comment on lines +93 to +94
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

To align with the suggested change in prompts.ts, this test should check for the command and parameter without the hardcoded line count.

Suggested change
expect(prompt).toContain("'Get-Content -Tail 10'");
expect(prompt).toContain("'Get-Content -TotalCount 10'");
expect(prompt).toContain("'Get-Content -Tail'");
expect(prompt).toContain("'Get-Content -TotalCount'");

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

expect(prompt).toContain('git status ; git diff HEAD ; git log -n 3');
});

it('should use Linux-specific commands when platform is linux', () => {
vi.spyOn(process, 'platform', 'get').mockReturnValue('linux');
vi.mocked(isGitRepository).mockReturnValue(true);
const prompt = getCoreSystemPrompt(mockConfig);
expect(prompt).toContain("'grep'");
expect(prompt).toContain("'tail'");
expect(prompt).toContain("'head'");
expect(prompt).toContain('git status && git diff HEAD && git log -n 3');
});

it('should include available_skills when provided in config', () => {
const skills = [
{
Expand Down
10 changes: 8 additions & 2 deletions packages/core/src/core/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ export function getCoreSystemPrompt(

const interactiveMode = config.isInteractive();

const isWindows = process.platform === 'win32';
const commandSeparator = isWindows ? ';' : '&&';
const grepCommand = isWindows ? 'Select-String' : 'grep';
const tailCommand = isWindows ? 'Get-Content -Tail 10' : 'tail';
const headCommand = isWindows ? 'Get-Content -TotalCount 10' : 'head';
Comment on lines +136 to +137
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Hardcoding the line count to 10 for tail and head equivalents on Windows limits the agent's flexibility. The agent might need to inspect more or fewer lines depending on the context. A better approach would be to provide the command and parameter, allowing the agent to specify the number of lines itself. This would be more consistent with how the tail and head commands are used on Linux, where the agent can add flags like -n 20.

Suggested change
const tailCommand = isWindows ? 'Get-Content -Tail 10' : 'tail';
const headCommand = isWindows ? 'Get-Content -TotalCount 10' : 'head';
const tailCommand = isWindows ? 'Get-Content -Tail' : 'tail';
const headCommand = isWindows ? 'Get-Content -TotalCount' : 'head';

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10 is the default for tail and head so I think this is fine


const skills = config.getSkillManager().getSkills();
let skillsPrompt = '';
if (skills.length > 0) {
Expand Down Expand Up @@ -260,7 +266,7 @@ IT IS CRITICAL TO FOLLOW THESE GUIDELINES TO AVOID EXCESSIVE TOKEN CONSUMPTION.
- If a command is expected to produce a lot of output, use quiet or silent flags where available and appropriate.
- Always consider the trade-off between output verbosity and the need for information. If a command's full output is essential for understanding the result, avoid overly aggressive quieting that might obscure important details.
- If a command does not have quiet/silent flags or for commands with potentially long output that may not be useful, redirect stdout and stderr to temp files in the project's temporary directory. For example: 'command > <temp_dir>/out.log 2> <temp_dir>/err.log'.
- After the command runs, inspect the temp files (e.g. '<temp_dir>/out.log' and '<temp_dir>/err.log') using commands like 'grep', 'tail', 'head', ... (or platform equivalents). Remove the temp files when done.
- After the command runs, inspect the temp files (e.g. '<temp_dir>/out.log' and '<temp_dir>/err.log') using commands like '${grepCommand}', '${tailCommand}', '${headCommand}', ... (or platform equivalents). Remove the temp files when done.
`;
}
return '';
Expand Down Expand Up @@ -337,7 +343,7 @@ ${(function () {
- \`git diff HEAD\` to review all changes (including unstaged changes) to tracked files in work tree since last commit.
- \`git diff --staged\` to review only staged changes when a partial commit makes sense or was requested by the user.
- \`git log -n 3\` to review recent commit messages and match their style (verbosity, formatting, signature line, etc.)
- Combine shell commands whenever possible to save time/steps, e.g. \`git status && git diff HEAD && git log -n 3\`.
- Combine shell commands whenever possible to save time/steps, e.g. \`git status ${commandSeparator} git diff HEAD ${commandSeparator} git log -n 3\`.
- Always propose a draft commit message. Never just ask the user to give you the full commit message.
- Prefer commit messages that are clear, concise, and focused more on "why" and less on "what".${
interactiveMode
Expand Down
Loading