@@ -18,10 +18,13 @@ export const ReadTool = Tool.define("read", {
1818 description : DESCRIPTION ,
1919 parameters : z . object ( {
2020 filePath : z . string ( ) . describe ( "The absolute path to the file or directory to read" ) ,
21- offset : z . coerce . number ( ) . describe ( "The 0-based line offset to start reading from" ) . optional ( ) ,
21+ offset : z . coerce . number ( ) . describe ( "The line number to start reading from (1-indexed) " ) . optional ( ) ,
2222 limit : z . coerce . number ( ) . describe ( "The maximum number of lines to read (defaults to 2000)" ) . optional ( ) ,
2323 } ) ,
2424 async execute ( params , ctx ) {
25+ if ( params . offset !== undefined && params . offset < 1 ) {
26+ throw new Error ( "offset must be greater than or equal to 1" )
27+ }
2528 let filepath = params . filePath
2629 if ( ! path . isAbsolute ( filepath ) ) {
2730 filepath = path . resolve ( Instance . directory , filepath )
@@ -78,9 +81,10 @@ export const ReadTool = Tool.define("read", {
7881 entries . sort ( ( a , b ) => a . localeCompare ( b ) )
7982
8083 const limit = params . limit ?? DEFAULT_READ_LIMIT
81- const offset = params . offset || 0
82- const sliced = entries . slice ( offset , offset + limit )
83- const truncated = offset + sliced . length < entries . length
84+ const offset = params . offset ?? 1
85+ const start = offset - 1
86+ const sliced = entries . slice ( start , start + limit )
87+ const truncated = start + sliced . length < entries . length
8488
8589 const output = [
8690 `<path>${ filepath } </path>` ,
@@ -138,13 +142,15 @@ export const ReadTool = Tool.define("read", {
138142 if ( isBinary ) throw new Error ( `Cannot read binary file: ${ filepath } ` )
139143
140144 const limit = params . limit ?? DEFAULT_READ_LIMIT
141- const offset = params . offset || 0
145+ const offset = params . offset ?? 1
146+ const start = offset - 1
142147 const lines = await file . text ( ) . then ( ( text ) => text . split ( "\n" ) )
148+ if ( start >= lines . length ) throw new Error ( `Offset ${ offset } is out of range for this file (${ lines . length } lines)` )
143149
144150 const raw : string [ ] = [ ]
145151 let bytes = 0
146152 let truncatedByBytes = false
147- for ( let i = offset ; i < Math . min ( lines . length , offset + limit ) ; i ++ ) {
153+ for ( let i = start ; i < Math . min ( lines . length , start + limit ) ; i ++ ) {
148154 const line = lines [ i ] . length > MAX_LINE_LENGTH ? lines [ i ] . substring ( 0 , MAX_LINE_LENGTH ) + "..." : lines [ i ]
149155 const size = Buffer . byteLength ( line , "utf-8" ) + ( raw . length > 0 ? 1 : 0 )
150156 if ( bytes + size > MAX_BYTES ) {
@@ -156,15 +162,15 @@ export const ReadTool = Tool.define("read", {
156162 }
157163
158164 const content = raw . map ( ( line , index ) => {
159- return `${ index + offset + 1 } : ${ line } `
165+ return `${ index + offset } : ${ line } `
160166 } )
161167 const preview = raw . slice ( 0 , 20 ) . join ( "\n" )
162168
163169 let output = [ `<path>${ filepath } </path>` , `<type>file</type>` , "<content>" ] . join ( "\n" )
164170 output += content . join ( "\n" )
165171
166172 const totalLines = lines . length
167- const lastReadLine = offset + raw . length
173+ const lastReadLine = offset + raw . length - 1
168174 const hasMoreLines = totalLines > lastReadLine
169175 const truncated = hasMoreLines || truncatedByBytes
170176
0 commit comments