Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
809 changes: 485 additions & 324 deletions src/core/prompts/__tests__/__snapshots__/system.test.ts.snap

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/core/prompts/__tests__/custom-system-prompt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ describe("File-Based Custom System Prompt", () => {
undefined, // diffEnabled
undefined, // experiments
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

// Should contain default sections
Expand Down Expand Up @@ -110,6 +113,9 @@ describe("File-Based Custom System Prompt", () => {
undefined, // diffEnabled
undefined, // experiments
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

// Should contain role definition and file-based system prompt
Expand Down Expand Up @@ -153,6 +159,9 @@ describe("File-Based Custom System Prompt", () => {
undefined, // diffEnabled
undefined, // experiments
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

// Should contain custom role definition and file-based system prompt
Expand Down
71 changes: 71 additions & 0 deletions src/core/prompts/__tests__/system.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toMatchSnapshot()
Expand All @@ -231,6 +234,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toMatchSnapshot()
Expand All @@ -253,6 +259,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toMatchSnapshot()
Expand All @@ -273,6 +282,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toMatchSnapshot()
Expand All @@ -293,6 +305,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toMatchSnapshot()
Expand All @@ -313,6 +328,9 @@ describe("SYSTEM_PROMPT", () => {
true, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toContain("apply_diff")
Expand All @@ -334,6 +352,9 @@ describe("SYSTEM_PROMPT", () => {
false, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).not.toContain("apply_diff")
Expand All @@ -355,6 +376,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).not.toContain("apply_diff")
Expand Down Expand Up @@ -403,6 +427,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
undefined, // experiments
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toContain("Language Preference:")
Expand Down Expand Up @@ -461,6 +488,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
experiments,
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

// Role definition should be at the top
Expand Down Expand Up @@ -496,6 +526,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
undefined, // experiments
false, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

// Role definition from promptComponent should be at the top
Expand Down Expand Up @@ -526,6 +559,9 @@ describe("SYSTEM_PROMPT", () => {
undefined, // diffEnabled
undefined, // experiments
false, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

// Should use the default mode's role definition
Expand Down Expand Up @@ -570,6 +606,9 @@ describe("addCustomInstructions", () => {
undefined, // diffEnabled
undefined, // experiments
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toMatchSnapshot()
Expand All @@ -590,6 +629,9 @@ describe("addCustomInstructions", () => {
undefined, // diffEnabled
undefined, // experiments
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toMatchSnapshot()
Expand All @@ -612,6 +654,9 @@ describe("addCustomInstructions", () => {
undefined, // diffEnabled
undefined, // experiments
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).toContain("Creating an MCP Server")
Expand All @@ -635,12 +680,38 @@ describe("addCustomInstructions", () => {
undefined, // diffEnabled
undefined, // experiments
false, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
undefined, // partialReadsEnabled
)

expect(prompt).not.toContain("Creating an MCP Server")
expect(prompt).toMatchSnapshot()
})

it("should include partial read instructions when partialReadsEnabled is true", async () => {
const prompt = await SYSTEM_PROMPT(
mockContext,
"/test/path",
false, // supportsComputerUse
undefined, // mcpHub
undefined, // diffStrategy
undefined, // browserViewportSize
defaultModeSlug, // mode
undefined, // customModePrompts
undefined, // customModes,
undefined, // globalCustomInstructions
undefined, // diffEnabled
undefined, // experiments
true, // enableMcpServerCreation
undefined, // language
undefined, // rooIgnoreInstructions
true, // partialReadsEnabled
)

expect(prompt).toMatchSnapshot()
})

it("should prioritize mode-specific rules for code mode", async () => {
const instructions = await addCustomInstructions("", "", "/test/path", defaultModeSlug)
expect(instructions).toMatchSnapshot()
Expand Down
4 changes: 4 additions & 0 deletions src/core/prompts/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ async function generatePrompt(
enableMcpServerCreation?: boolean,
language?: string,
rooIgnoreInstructions?: string,
partialReadsEnabled?: boolean,
): Promise<string> {
if (!context) {
throw new Error("Extension context is required for generating system prompt")
Expand Down Expand Up @@ -82,6 +83,7 @@ ${getToolDescriptionsForMode(
mcpHub,
customModeConfigs,
experiments,
partialReadsEnabled,
)}

${getToolUseGuidelinesSection()}
Expand Down Expand Up @@ -119,6 +121,7 @@ export const SYSTEM_PROMPT = async (
enableMcpServerCreation?: boolean,
language?: string,
rooIgnoreInstructions?: string,
partialReadsEnabled?: boolean,
): Promise<string> => {
if (!context) {
throw new Error("Extension context is required for generating system prompt")
Expand Down Expand Up @@ -185,5 +188,6 @@ ${customInstructions}`
enableMcpServerCreation,
language,
rooIgnoreInstructions,
partialReadsEnabled,
)
}
2 changes: 2 additions & 0 deletions src/core/prompts/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export function getToolDescriptionsForMode(
mcpHub?: McpHub,
customModes?: ModeConfig[],
experiments?: Record<string, boolean>,
partialReadsEnabled?: boolean,
): string {
const config = getModeConfig(mode, customModes)
const args: ToolArgs = {
Expand All @@ -64,6 +65,7 @@ export function getToolDescriptionsForMode(
diffStrategy,
browserViewportSize,
mcpHub,
partialReadsEnabled,
}

const tools = new Set<string>()
Expand Down
43 changes: 36 additions & 7 deletions src/core/prompts/tools/read-file.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
import { ToolArgs } from "./types"

export function getReadFileDescription(args: ToolArgs): string {
return `## read_file
Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. The output includes line numbers prefixed to each line (e.g. "1 | const x = 1"), making it easier to reference specific lines when creating diffs or discussing code. By specifying start_line and end_line parameters, you can efficiently read specific portions of large files without loading the entire file into memory. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string.
// Base description without partial read instructions
let description = `## read_file
Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. The output includes line numbers prefixed to each line (e.g. "1 | const x = 1"), making it easier to reference specific lines when creating diffs or discussing code.`

// Add partial read instructions only when partial reads are active
if (args.partialReadsEnabled) {
description += ` By specifying start_line and end_line parameters, you can efficiently read specific portions of large files without loading the entire file into memory.`
}

description += ` Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string.
Parameters:
- path: (required) The path of the file to read (relative to the current workspace directory ${args.cwd})
- path: (required) The path of the file to read (relative to the current workspace directory ${args.cwd})`

// Add start_line and end_line parameters only when partial reads are active
if (args.partialReadsEnabled) {
description += `
- start_line: (optional) The starting line number to read from (1-based). If not provided, it starts from the beginning of the file.
- end_line: (optional) The ending line number to read to (1-based, inclusive). If not provided, it reads to the end of the file.
- end_line: (optional) The ending line number to read to (1-based, inclusive). If not provided, it reads to the end of the file.`
}

description += `
Usage:
<read_file>
<path>File path here</path>
<path>File path here</path>`

// Add start_line and end_line in usage only when partial reads are active
if (args.partialReadsEnabled) {
description += `
<start_line>Starting line number (optional)</start_line>
<end_line>Ending line number (optional)</end_line>
<end_line>Ending line number (optional)</end_line>`
}

description += `
</read_file>

Examples:

1. Reading an entire file:
<read_file>
<path>frontend-config.json</path>
</read_file>
</read_file>`

// Add partial read examples only when partial reads are active
if (args.partialReadsEnabled) {
description += `

2. Reading the first 1000 lines of a large log file:
<read_file>
Expand All @@ -42,4 +68,7 @@ Examples:
</read_file>

Note: When both start_line and end_line are provided, this tool efficiently streams only the requested lines, making it suitable for processing large files like logs, CSV files, and other large datasets without memory issues.`
}

return description
}
1 change: 1 addition & 0 deletions src/core/prompts/tools/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export type ToolArgs = {
browserViewportSize?: string
mcpHub?: McpHub
toolOptions?: any
partialReadsEnabled?: boolean
}
8 changes: 5 additions & 3 deletions src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1451,18 +1451,19 @@ export class Task extends EventEmitter<ClineEvents> {

const rooIgnoreInstructions = this.rooIgnoreController?.getInstructions()

const state = await this.providerRef.deref()?.getState()
const {
browserViewportSize,
mode,
customModes,
customModePrompts,
customInstructions,
experiments,
enableMcpServerCreation,
browserToolEnabled,
language,
} = (await this.providerRef.deref()?.getState()) ?? {}

const { customModes } = (await this.providerRef.deref()?.getState()) ?? {}
maxReadFileLine,
} = state ?? {}

return await (async () => {
const provider = this.providerRef.deref()
Expand All @@ -1487,6 +1488,7 @@ export class Task extends EventEmitter<ClineEvents> {
enableMcpServerCreation,
language,
rooIgnoreInstructions,
maxReadFileLine !== -1,
)
})()
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/webview/generateSystemPrompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const generateSystemPrompt = async (provider: ClineProvider, message: Web
enableMcpServerCreation,
browserToolEnabled,
language,
maxReadFileLine,
} = await provider.getState()

const diffStrategy = new MultiSearchReplaceDiffStrategy(fuzzyMatchThreshold)
Expand Down Expand Up @@ -67,6 +68,7 @@ export const generateSystemPrompt = async (provider: ClineProvider, message: Web
enableMcpServerCreation,
language,
rooIgnoreInstructions,
maxReadFileLine !== -1,
)

return systemPrompt
Expand Down