@@ -4,6 +4,7 @@ import * as path from "path"
44
55import { countFileLines } from "../../../integrations/misc/line-counter"
66import { readLines } from "../../../integrations/misc/read-lines"
7+ import { readPartialContent } from "../../../integrations/misc/read-partial-content"
78import { extractTextFromFile , addLineNumbers , getSupportedBinaryFormats } from "../../../integrations/misc/extract-text"
89import { parseSourceCodeDefinitionsForFile } from "../../../services/tree-sitter"
910import { isBinaryFile } from "isbinaryfile"
@@ -36,6 +37,14 @@ vi.mock("../../../integrations/misc/read-lines", () => ({
3637} ) )
3738vi . mock ( "../../../integrations/misc/read-partial-content" , ( ) => ( {
3839 readPartialSingleLineContent : vi . fn ( ) . mockResolvedValue ( "mocked partial content" ) ,
40+ readPartialContent : vi . fn ( ) . mockResolvedValue ( {
41+ content : "mocked partial content" ,
42+ charactersRead : 100 ,
43+ totalCharacters : 1000 ,
44+ linesRead : 5 ,
45+ totalLines : 50 ,
46+ lastLineRead : 5 ,
47+ } ) ,
3948} ) )
4049vi . mock ( "../contextValidator" )
4150
@@ -1367,21 +1376,29 @@ describe("read_file tool XML output structure", () => {
13671376 vi . mocked ( contextValidatorModule . validateFileSizeForContext ) . mockResolvedValue ( {
13681377 shouldLimit : true ,
13691378 safeContentLimit : 2000 ,
1370- reason : "File exceeds available context space" ,
1379+ reason : "File exceeds available context space. Can read 2000 of 500000 characters (40%). Context usage: 10000/100000 tokens (10%). " ,
13711380 } )
13721381
1373- // Mock readLines to return truncated content
1374- vi . mocked ( readLines ) . mockResolvedValue ( "Line 1\nLine 2\n...truncated..." )
1382+ // Mock readPartialContent to return truncated content
1383+ vi . mocked ( readPartialContent ) . mockResolvedValue ( {
1384+ content : "Line 1\nLine 2\n...truncated..." ,
1385+ charactersRead : 2000 ,
1386+ totalCharacters : 500000 ,
1387+ linesRead : 100 ,
1388+ totalLines : 10000 ,
1389+ lastLineRead : 100 ,
1390+ } )
13751391
13761392 const result = await executeReadFileTool (
13771393 { args : `<file><path>large-file.ts</path></file>` } ,
13781394 { totalLines : 10000 , maxReadFileLine : - 1 } ,
13791395 )
13801396
1381- // Verify the result contains the inline instructions
1397+ // Verify the result contains the partial read notice for multi-line files
13821398 expect ( result ) . toContain ( "<notice>" )
1383- expect ( result ) . toContain ( "File exceeds available context space" )
1384- expect ( result ) . toContain ( "tools:readFile.contextLimitInstructions</notice>" )
1399+ expect ( result ) . toContain ( "tools:readFile.partialReadMultiLine" )
1400+ // The current implementation doesn't include contextLimitInstructions
1401+ expect ( result ) . not . toContain ( "tools:readFile.contextLimitInstructions" )
13851402 } )
13861403
13871404 it ( "should not show any special notice when file fits in context" , async ( ) => {
@@ -1409,12 +1426,19 @@ describe("read_file tool XML output structure", () => {
14091426 // Mock contextValidator to return shouldLimit true with single-line file message
14101427 vi . mocked ( contextValidatorModule . validateFileSizeForContext ) . mockResolvedValue ( {
14111428 shouldLimit : true ,
1412- safeContentLimit : 1 ,
1429+ safeContentLimit : 5000 ,
14131430 reason : "Large single-line file (likely minified) exceeds available context space. Only the first 50% (5000 of 10000 characters) can be loaded. This is a hard limit - no additional content from this file can be accessed." ,
14141431 } )
14151432
1416- // Mock extractTextFromFile to return truncated content
1417- vi . mocked ( extractTextFromFile ) . mockResolvedValue ( "1 | const a=1;const b=2;...truncated" )
1433+ // Mock readPartialContent to return truncated content for single-line file
1434+ vi . mocked ( readPartialContent ) . mockResolvedValue ( {
1435+ content : "const a=1;const b=2;...truncated" ,
1436+ charactersRead : 5000 ,
1437+ totalCharacters : 10000 ,
1438+ linesRead : 1 ,
1439+ totalLines : 1 ,
1440+ lastLineRead : 1 ,
1441+ } )
14181442
14191443 const result = await executeReadFileTool (
14201444 { args : `<file><path>minified.js</path></file>` } ,
@@ -1423,8 +1447,7 @@ describe("read_file tool XML output structure", () => {
14231447
14241448 // Verify the result contains the notice but NOT the line_range instructions
14251449 expect ( result ) . toContain ( "<notice>" )
1426- expect ( result ) . toContain ( "Large single-line file" )
1427- expect ( result ) . toContain ( "This is a hard limit" )
1450+ expect ( result ) . toContain ( "tools:readFile.partialReadSingleLine" )
14281451 expect ( result ) . not . toContain ( "tools:readFile.contextLimitInstructions" )
14291452 expect ( result ) . not . toContain ( "Use line_range" )
14301453 } )
@@ -1436,22 +1459,30 @@ describe("read_file tool XML output structure", () => {
14361459 // Mock contextValidator to return shouldLimit true with multi-line file message
14371460 vi . mocked ( contextValidatorModule . validateFileSizeForContext ) . mockResolvedValue ( {
14381461 shouldLimit : true ,
1439- safeContentLimit : 1000 ,
1440- reason : "File exceeds available context space. Safely read 1000 lines out of 5000 total lines ." ,
1462+ safeContentLimit : 50000 ,
1463+ reason : "File exceeds available context space. Can read 50000 of 250000 characters (20%). Context usage: 50000/100000 tokens (50%) ." ,
14411464 } )
14421465
1443- // Mock readLines to return truncated content
1444- vi . mocked ( readLines ) . mockResolvedValue ( "Line 1\nLine 2\n...truncated..." )
1466+ // Mock readPartialContent to return truncated content
1467+ vi . mocked ( readPartialContent ) . mockResolvedValue ( {
1468+ content : "Line 1\nLine 2\n...truncated..." ,
1469+ charactersRead : 50000 ,
1470+ totalCharacters : 250000 ,
1471+ linesRead : 1000 ,
1472+ totalLines : 5000 ,
1473+ lastLineRead : 1000 ,
1474+ } )
14451475
14461476 const result = await executeReadFileTool (
14471477 { args : `<file><path>large-file.ts</path></file>` } ,
14481478 { totalLines : 5000 , maxReadFileLine : - 1 } ,
14491479 )
14501480
1451- // Verify the result contains both the notice AND the line_range instructions
1481+ // Verify the result contains the partial read notice for multi-line files
14521482 expect ( result ) . toContain ( "<notice>" )
1453- expect ( result ) . toContain ( "File exceeds available context space" )
1454- expect ( result ) . toContain ( "tools:readFile.contextLimitInstructions</notice>" )
1483+ expect ( result ) . toContain ( "tools:readFile.partialReadMultiLine" )
1484+ // The current implementation doesn't include contextLimitInstructions
1485+ expect ( result ) . not . toContain ( "tools:readFile.contextLimitInstructions" )
14551486 } )
14561487
14571488 it ( "should handle normal file read section for single-line files with validation notice" , async ( ) => {
@@ -1461,12 +1492,19 @@ describe("read_file tool XML output structure", () => {
14611492 // Mock contextValidator to return shouldLimit true with a single-line file notice
14621493 vi . mocked ( contextValidatorModule . validateFileSizeForContext ) . mockResolvedValue ( {
14631494 shouldLimit : true ,
1464- safeContentLimit : 1 ,
1465- reason : "Large single-line file (likely minified) exceeds available context space. Only the first 80% can be loaded." ,
1495+ safeContentLimit : 8000 ,
1496+ reason : "Large single-line file (likely minified) exceeds available context space. Only the first 80% (8000 of 10000 characters) can be loaded." ,
14661497 } )
14671498
1468- // Mock extractTextFromFile
1469- vi . mocked ( extractTextFromFile ) . mockResolvedValue ( "1 | const a=1;const b=2;const c=3;" )
1499+ // Mock readPartialContent for single-line file
1500+ vi . mocked ( readPartialContent ) . mockResolvedValue ( {
1501+ content : "const a=1;const b=2;const c=3;" ,
1502+ charactersRead : 8000 ,
1503+ totalCharacters : 10000 ,
1504+ linesRead : 1 ,
1505+ totalLines : 1 ,
1506+ lastLineRead : 1 ,
1507+ } )
14701508
14711509 const result = await executeReadFileTool (
14721510 { args : `<file><path>semi-large.js</path></file>` } ,
@@ -1475,7 +1513,7 @@ describe("read_file tool XML output structure", () => {
14751513
14761514 // Verify single-line file notice doesn't include line_range instructions
14771515 expect ( result ) . toContain ( "<notice>" )
1478- expect ( result ) . toContain ( "Large single-line file " )
1516+ expect ( result ) . toContain ( "tools:readFile.partialReadSingleLine " )
14791517 expect ( result ) . not . toContain ( "tools:readFile.contextLimitInstructions" )
14801518 } )
14811519 } )
0 commit comments