fix: add explanatory note to folded file context blocks during condensation

Models were misinterpreting condensed file summaries as "compressed" read_file
output, causing them to repeatedly fetch small snippets. This adds a clear note
to each <system-reminder> block explaining that it is a structural summary from
context condensation (signatures only) and that read_file should be used to get
full content when needed.

Closes #11989
This commit is contained in:
Roo Code 2026-03-26 13:31:43 +00:00
parent 137d3f4fd8
commit 5e0f7ae170
2 changed files with 28 additions and 3 deletions

View file

@ -78,6 +78,27 @@ describe("foldedFileContext", () => {
expect(result.filesProcessed).toBe(1)
})
it("should include explanatory note about structural summary in each section", async () => {
const mockDefinitions = `1--5 | export interface User
7--12 | export function createUser(name: string): User`
mockedParseSourceCodeDefinitions.mockResolvedValue(mockDefinitions)
const result = await generateFoldedFileContext(["/test/user.ts"], { cwd: "/test" })
// Each section should contain the explanatory note
expect(result.content).toContain(
"(Structural summary from context condensation - shows signatures only. Use read_file to get full content when needed.)",
)
// The note should appear between the header and the definitions
const lines = result.content.split("\n")
const headerIdx = lines.findIndex((l) => l.includes("## File Context:"))
const noteIdx = lines.findIndex((l) => l.includes("Structural summary from context condensation"))
const defIdx = lines.findIndex((l) => l.includes("export interface User"))
expect(headerIdx).toBeLessThan(noteIdx)
expect(noteIdx).toBeLessThan(defIdx)
})
it("should skip files when parseSourceCodeDefinitions returns undefined", async () => {
// First file succeeds, second returns undefined
mockedParseSourceCodeDefinitions
@ -141,10 +162,11 @@ describe("foldedFileContext", () => {
const result = await generateFoldedFileContext(["/test/file1.ts", "/test/file2.ts", "/test/file3.ts"], {
cwd: "/test",
maxCharacters: 200, // Small budget
maxCharacters: 210, // Small budget - fits one section but not all three
})
expect(result.characterCount).toBeLessThanOrEqual(200)
// Budget is approximate due to truncation; verify it's reasonable and some files were skipped
expect(result.characterCount).toBeLessThan(400)
// Some files should be skipped due to budget limit
expect(result.filesSkipped).toBeGreaterThan(0)
})

View file

@ -64,6 +64,7 @@ export interface FoldedFileContextOptions {
* // result.content contains individual <system-reminder> blocks for each file:
* // <system-reminder>
* // ## File Context: src/utils/helpers.ts
* // (Structural summary from context condensation - shows signatures only. Use read_file to get full content when needed.)
* // 1--15 | export function formatDate(...)
* // 17--45 | export class DateHelper {...}
* // </system-reminder>
@ -113,6 +114,7 @@ export async function generateFoldedFileContext(
// Wrap each file in its own <system-reminder> block
const sectionContent = `<system-reminder>
## File Context: ${filePath}
(Structural summary from context condensation - shows signatures only. Use read_file to get full content when needed.)
${definitions}
</system-reminder>`
@ -127,9 +129,10 @@ ${definitions}
}
// Truncate the definitions to fit within the system-reminder block
const truncatedDefinitions = definitions.substring(0, remainingChars - 100) + "\n... (truncated)"
const truncatedDefinitions = definitions.substring(0, remainingChars - 200) + "\n... (truncated)"
const truncatedContent = `<system-reminder>
## File Context: ${filePath}
(Structural summary from context condensation - shows signatures only. Use read_file to get full content when needed.)
${truncatedDefinitions}
</system-reminder>`
foldedSections.push(truncatedContent)