Skip to content

Commit ce6cc6f

Browse files
authored
Adjust the read_file prompt based on whether partial reads are enabled (#3995)
1 parent 61a381a commit ce6cc6f

File tree

9 files changed

+615
-334
lines changed

9 files changed

+615
-334
lines changed

src/core/prompts/__tests__/__snapshots__/system.test.ts.snap

Lines changed: 485 additions & 324 deletions
Large diffs are not rendered by default.

src/core/prompts/__tests__/custom-system-prompt.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ describe("File-Based Custom System Prompt", () => {
7676
undefined, // diffEnabled
7777
undefined, // experiments
7878
true, // enableMcpServerCreation
79+
undefined, // language
80+
undefined, // rooIgnoreInstructions
81+
undefined, // partialReadsEnabled
7982
)
8083

8184
// Should contain default sections
@@ -110,6 +113,9 @@ describe("File-Based Custom System Prompt", () => {
110113
undefined, // diffEnabled
111114
undefined, // experiments
112115
true, // enableMcpServerCreation
116+
undefined, // language
117+
undefined, // rooIgnoreInstructions
118+
undefined, // partialReadsEnabled
113119
)
114120

115121
// Should contain role definition and file-based system prompt
@@ -153,6 +159,9 @@ describe("File-Based Custom System Prompt", () => {
153159
undefined, // diffEnabled
154160
undefined, // experiments
155161
true, // enableMcpServerCreation
162+
undefined, // language
163+
undefined, // rooIgnoreInstructions
164+
undefined, // partialReadsEnabled
156165
)
157166

158167
// Should contain custom role definition and file-based system prompt

src/core/prompts/__tests__/system.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ describe("SYSTEM_PROMPT", () => {
211211
undefined, // diffEnabled
212212
experiments,
213213
true, // enableMcpServerCreation
214+
undefined, // language
215+
undefined, // rooIgnoreInstructions
216+
undefined, // partialReadsEnabled
214217
)
215218

216219
expect(prompt).toMatchSnapshot()
@@ -231,6 +234,9 @@ describe("SYSTEM_PROMPT", () => {
231234
undefined, // diffEnabled
232235
experiments,
233236
true, // enableMcpServerCreation
237+
undefined, // language
238+
undefined, // rooIgnoreInstructions
239+
undefined, // partialReadsEnabled
234240
)
235241

236242
expect(prompt).toMatchSnapshot()
@@ -253,6 +259,9 @@ describe("SYSTEM_PROMPT", () => {
253259
undefined, // diffEnabled
254260
experiments,
255261
true, // enableMcpServerCreation
262+
undefined, // language
263+
undefined, // rooIgnoreInstructions
264+
undefined, // partialReadsEnabled
256265
)
257266

258267
expect(prompt).toMatchSnapshot()
@@ -273,6 +282,9 @@ describe("SYSTEM_PROMPT", () => {
273282
undefined, // diffEnabled
274283
experiments,
275284
true, // enableMcpServerCreation
285+
undefined, // language
286+
undefined, // rooIgnoreInstructions
287+
undefined, // partialReadsEnabled
276288
)
277289

278290
expect(prompt).toMatchSnapshot()
@@ -293,6 +305,9 @@ describe("SYSTEM_PROMPT", () => {
293305
undefined, // diffEnabled
294306
experiments,
295307
true, // enableMcpServerCreation
308+
undefined, // language
309+
undefined, // rooIgnoreInstructions
310+
undefined, // partialReadsEnabled
296311
)
297312

298313
expect(prompt).toMatchSnapshot()
@@ -313,6 +328,9 @@ describe("SYSTEM_PROMPT", () => {
313328
true, // diffEnabled
314329
experiments,
315330
true, // enableMcpServerCreation
331+
undefined, // language
332+
undefined, // rooIgnoreInstructions
333+
undefined, // partialReadsEnabled
316334
)
317335

318336
expect(prompt).toContain("apply_diff")
@@ -334,6 +352,9 @@ describe("SYSTEM_PROMPT", () => {
334352
false, // diffEnabled
335353
experiments,
336354
true, // enableMcpServerCreation
355+
undefined, // language
356+
undefined, // rooIgnoreInstructions
357+
undefined, // partialReadsEnabled
337358
)
338359

339360
expect(prompt).not.toContain("apply_diff")
@@ -355,6 +376,9 @@ describe("SYSTEM_PROMPT", () => {
355376
undefined, // diffEnabled
356377
experiments,
357378
true, // enableMcpServerCreation
379+
undefined, // language
380+
undefined, // rooIgnoreInstructions
381+
undefined, // partialReadsEnabled
358382
)
359383

360384
expect(prompt).not.toContain("apply_diff")
@@ -403,6 +427,9 @@ describe("SYSTEM_PROMPT", () => {
403427
undefined, // diffEnabled
404428
undefined, // experiments
405429
true, // enableMcpServerCreation
430+
undefined, // language
431+
undefined, // rooIgnoreInstructions
432+
undefined, // partialReadsEnabled
406433
)
407434

408435
expect(prompt).toContain("Language Preference:")
@@ -461,6 +488,9 @@ describe("SYSTEM_PROMPT", () => {
461488
undefined, // diffEnabled
462489
experiments,
463490
true, // enableMcpServerCreation
491+
undefined, // language
492+
undefined, // rooIgnoreInstructions
493+
undefined, // partialReadsEnabled
464494
)
465495

466496
// Role definition should be at the top
@@ -496,6 +526,9 @@ describe("SYSTEM_PROMPT", () => {
496526
undefined, // diffEnabled
497527
undefined, // experiments
498528
false, // enableMcpServerCreation
529+
undefined, // language
530+
undefined, // rooIgnoreInstructions
531+
undefined, // partialReadsEnabled
499532
)
500533

501534
// Role definition from promptComponent should be at the top
@@ -526,6 +559,9 @@ describe("SYSTEM_PROMPT", () => {
526559
undefined, // diffEnabled
527560
undefined, // experiments
528561
false, // enableMcpServerCreation
562+
undefined, // language
563+
undefined, // rooIgnoreInstructions
564+
undefined, // partialReadsEnabled
529565
)
530566

531567
// Should use the default mode's role definition
@@ -570,6 +606,9 @@ describe("addCustomInstructions", () => {
570606
undefined, // diffEnabled
571607
undefined, // experiments
572608
true, // enableMcpServerCreation
609+
undefined, // language
610+
undefined, // rooIgnoreInstructions
611+
undefined, // partialReadsEnabled
573612
)
574613

575614
expect(prompt).toMatchSnapshot()
@@ -590,6 +629,9 @@ describe("addCustomInstructions", () => {
590629
undefined, // diffEnabled
591630
undefined, // experiments
592631
true, // enableMcpServerCreation
632+
undefined, // language
633+
undefined, // rooIgnoreInstructions
634+
undefined, // partialReadsEnabled
593635
)
594636

595637
expect(prompt).toMatchSnapshot()
@@ -612,6 +654,9 @@ describe("addCustomInstructions", () => {
612654
undefined, // diffEnabled
613655
undefined, // experiments
614656
true, // enableMcpServerCreation
657+
undefined, // language
658+
undefined, // rooIgnoreInstructions
659+
undefined, // partialReadsEnabled
615660
)
616661

617662
expect(prompt).toContain("Creating an MCP Server")
@@ -635,12 +680,38 @@ describe("addCustomInstructions", () => {
635680
undefined, // diffEnabled
636681
undefined, // experiments
637682
false, // enableMcpServerCreation
683+
undefined, // language
684+
undefined, // rooIgnoreInstructions
685+
undefined, // partialReadsEnabled
638686
)
639687

640688
expect(prompt).not.toContain("Creating an MCP Server")
641689
expect(prompt).toMatchSnapshot()
642690
})
643691

692+
it("should include partial read instructions when partialReadsEnabled is true", async () => {
693+
const prompt = await SYSTEM_PROMPT(
694+
mockContext,
695+
"/test/path",
696+
false, // supportsComputerUse
697+
undefined, // mcpHub
698+
undefined, // diffStrategy
699+
undefined, // browserViewportSize
700+
defaultModeSlug, // mode
701+
undefined, // customModePrompts
702+
undefined, // customModes,
703+
undefined, // globalCustomInstructions
704+
undefined, // diffEnabled
705+
undefined, // experiments
706+
true, // enableMcpServerCreation
707+
undefined, // language
708+
undefined, // rooIgnoreInstructions
709+
true, // partialReadsEnabled
710+
)
711+
712+
expect(prompt).toMatchSnapshot()
713+
})
714+
644715
it("should prioritize mode-specific rules for code mode", async () => {
645716
const instructions = await addCustomInstructions("", "", "/test/path", defaultModeSlug)
646717
expect(instructions).toMatchSnapshot()

src/core/prompts/system.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ async function generatePrompt(
4545
enableMcpServerCreation?: boolean,
4646
language?: string,
4747
rooIgnoreInstructions?: string,
48+
partialReadsEnabled?: boolean,
4849
): Promise<string> {
4950
if (!context) {
5051
throw new Error("Extension context is required for generating system prompt")
@@ -82,6 +83,7 @@ ${getToolDescriptionsForMode(
8283
mcpHub,
8384
customModeConfigs,
8485
experiments,
86+
partialReadsEnabled,
8587
)}
8688
8789
${getToolUseGuidelinesSection()}
@@ -119,6 +121,7 @@ export const SYSTEM_PROMPT = async (
119121
enableMcpServerCreation?: boolean,
120122
language?: string,
121123
rooIgnoreInstructions?: string,
124+
partialReadsEnabled?: boolean,
122125
): Promise<string> => {
123126
if (!context) {
124127
throw new Error("Extension context is required for generating system prompt")
@@ -185,5 +188,6 @@ ${customInstructions}`
185188
enableMcpServerCreation,
186189
language,
187190
rooIgnoreInstructions,
191+
partialReadsEnabled,
188192
)
189193
}

src/core/prompts/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function getToolDescriptionsForMode(
5656
mcpHub?: McpHub,
5757
customModes?: ModeConfig[],
5858
experiments?: Record<string, boolean>,
59+
partialReadsEnabled?: boolean,
5960
): string {
6061
const config = getModeConfig(mode, customModes)
6162
const args: ToolArgs = {
@@ -64,6 +65,7 @@ export function getToolDescriptionsForMode(
6465
diffStrategy,
6566
browserViewportSize,
6667
mcpHub,
68+
partialReadsEnabled,
6769
}
6870

6971
const tools = new Set<string>()

src/core/prompts/tools/read-file.ts

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,51 @@
11
import { ToolArgs } from "./types"
22

33
export function getReadFileDescription(args: ToolArgs): string {
4-
return `## read_file
5-
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.
4+
// Base description without partial read instructions
5+
let description = `## read_file
6+
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.`
7+
8+
// Add partial read instructions only when partial reads are active
9+
if (args.partialReadsEnabled) {
10+
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.`
11+
}
12+
13+
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.
614
Parameters:
7-
- path: (required) The path of the file to read (relative to the current workspace directory ${args.cwd})
15+
- path: (required) The path of the file to read (relative to the current workspace directory ${args.cwd})`
16+
17+
// Add start_line and end_line parameters only when partial reads are active
18+
if (args.partialReadsEnabled) {
19+
description += `
820
- start_line: (optional) The starting line number to read from (1-based). If not provided, it starts from the beginning of the file.
9-
- end_line: (optional) The ending line number to read to (1-based, inclusive). If not provided, it reads to the end of the file.
21+
- end_line: (optional) The ending line number to read to (1-based, inclusive). If not provided, it reads to the end of the file.`
22+
}
23+
24+
description += `
1025
Usage:
1126
<read_file>
12-
<path>File path here</path>
27+
<path>File path here</path>`
28+
29+
// Add start_line and end_line in usage only when partial reads are active
30+
if (args.partialReadsEnabled) {
31+
description += `
1332
<start_line>Starting line number (optional)</start_line>
14-
<end_line>Ending line number (optional)</end_line>
33+
<end_line>Ending line number (optional)</end_line>`
34+
}
35+
36+
description += `
1537
</read_file>
1638
1739
Examples:
1840
1941
1. Reading an entire file:
2042
<read_file>
2143
<path>frontend-config.json</path>
22-
</read_file>
44+
</read_file>`
45+
46+
// Add partial read examples only when partial reads are active
47+
if (args.partialReadsEnabled) {
48+
description += `
2349
2450
2. Reading the first 1000 lines of a large log file:
2551
<read_file>
@@ -42,4 +68,7 @@ Examples:
4268
</read_file>
4369
4470
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.`
71+
}
72+
73+
return description
4574
}

src/core/prompts/tools/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ export type ToolArgs = {
88
browserViewportSize?: string
99
mcpHub?: McpHub
1010
toolOptions?: any
11+
partialReadsEnabled?: boolean
1112
}

src/core/task/Task.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,18 +1451,19 @@ export class Task extends EventEmitter<ClineEvents> {
14511451

14521452
const rooIgnoreInstructions = this.rooIgnoreController?.getInstructions()
14531453

1454+
const state = await this.providerRef.deref()?.getState()
14541455
const {
14551456
browserViewportSize,
14561457
mode,
1458+
customModes,
14571459
customModePrompts,
14581460
customInstructions,
14591461
experiments,
14601462
enableMcpServerCreation,
14611463
browserToolEnabled,
14621464
language,
1463-
} = (await this.providerRef.deref()?.getState()) ?? {}
1464-
1465-
const { customModes } = (await this.providerRef.deref()?.getState()) ?? {}
1465+
maxReadFileLine,
1466+
} = state ?? {}
14661467

14671468
return await (async () => {
14681469
const provider = this.providerRef.deref()
@@ -1487,6 +1488,7 @@ export class Task extends EventEmitter<ClineEvents> {
14871488
enableMcpServerCreation,
14881489
language,
14891490
rooIgnoreInstructions,
1491+
maxReadFileLine !== -1,
14901492
)
14911493
})()
14921494
}

src/core/webview/generateSystemPrompt.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const generateSystemPrompt = async (provider: ClineProvider, message: Web
2020
enableMcpServerCreation,
2121
browserToolEnabled,
2222
language,
23+
maxReadFileLine,
2324
} = await provider.getState()
2425

2526
const diffStrategy = new MultiSearchReplaceDiffStrategy(fuzzyMatchThreshold)
@@ -67,6 +68,7 @@ export const generateSystemPrompt = async (provider: ClineProvider, message: Web
6768
enableMcpServerCreation,
6869
language,
6970
rooIgnoreInstructions,
71+
maxReadFileLine !== -1,
7072
)
7173

7274
return systemPrompt

0 commit comments

Comments
 (0)