@@ -62,6 +62,7 @@ export interface StrReplaceEditorToolData {
6262 filePath ?: string ;
6363 fileLabel ?: string ;
6464 parsedContent ?: { content : string ; fileA : string | undefined ; fileB : string | undefined ; } ;
65+ viewRange ?: { start : number , end : number }
6566}
6667
6768export namespace StrReplaceEditorToolData {
@@ -110,6 +111,32 @@ export function parseDiff(content: string): { content: string; fileA: string | u
110111 } ;
111112}
112113
114+ export function parseRange ( view_range : unknown ) : { start : number , end : number } | undefined {
115+ if ( ! view_range ) {
116+ return undefined ;
117+ }
118+
119+ if ( ! Array . isArray ( view_range ) ) {
120+ return undefined ;
121+ }
122+
123+ if ( view_range . length !== 2 ) {
124+ return undefined ;
125+ }
126+
127+ const start = view_range [ 0 ] ;
128+ const end = view_range [ 1 ] ;
129+
130+ if ( typeof start !== 'number' || typeof end !== 'number' ) {
131+ return undefined ;
132+ }
133+
134+ return {
135+ start,
136+ end
137+ } ;
138+ }
139+
113140
114141
115142/**
@@ -133,7 +160,7 @@ export function parseToolCallDetails(
133160 } ,
134161 content : string
135162) : ParsedToolCallDetails {
136- let args : { command ?: string , path ?: string , prDescription ?: string , commitMessage ?: string } = { } ;
163+ let args : { command ?: string , path ?: string , prDescription ?: string , commitMessage ?: string , view_range ?: unknown } = { } ;
137164 try {
138165 args = toolCall . function . arguments ? JSON . parse ( toolCall . function . arguments ) : { } ;
139166 } catch {
@@ -145,18 +172,20 @@ export function parseToolCallDetails(
145172 if ( name === 'str_replace_editor' ) {
146173 if ( args . command === 'view' ) {
147174 const parsedContent = parseDiff ( content ) ;
175+ const parsedRange = parseRange ( args . view_range ) ;
148176 if ( parsedContent ) {
149177 const file = parsedContent . fileA ?? parsedContent . fileB ;
150178 const fileLabel = file && toFileLabel ( file ) ;
151179 return {
152180 toolName : fileLabel === '' ? 'Read repository' : 'Read' ,
153- invocationMessage : fileLabel ? `Read [](${ fileLabel } )` : 'Read repository' ,
154- pastTenseMessage : fileLabel ? `Read [](${ fileLabel } )` : 'Read repository' ,
181+ invocationMessage : fileLabel ? ( `Read [](${ fileLabel } )` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Read repository' ,
182+ pastTenseMessage : fileLabel ? ( `Read [](${ fileLabel } )` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Read repository' ,
155183 toolSpecificData : fileLabel ? {
156184 command : 'view' ,
157185 filePath : file ,
158186 fileLabel : fileLabel ,
159- parsedContent : parsedContent
187+ parsedContent : parsedContent ,
188+ viewRange : parsedRange
160189 } : undefined
161190 } ;
162191 } else {
@@ -167,9 +196,9 @@ export function parseToolCallDetails(
167196 fileLabel = filePath ;
168197
169198 return {
170- toolName : fileLabel ? `Read ${ fileLabel } ` : 'Read repository' ,
171- invocationMessage : fileLabel ? `Read ${ fileLabel } ` : 'Read repository' ,
172- pastTenseMessage : fileLabel ? `Read ${ fileLabel } ` : 'Read repository' ,
199+ toolName : fileLabel ? ( `Read ${ fileLabel } ` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Read repository' ,
200+ invocationMessage : fileLabel ? ( `Read ${ fileLabel } ` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Read repository' ,
201+ pastTenseMessage : fileLabel ? ( `Read ${ fileLabel } ` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Read repository' ,
173202 } ;
174203 } else if ( fileLabel === '' ) {
175204 return {
@@ -180,41 +209,48 @@ export function parseToolCallDetails(
180209 } else {
181210 return {
182211 toolName : `Read` ,
183- invocationMessage : `Read ${ fileLabel } ` ,
184- pastTenseMessage : `Read ${ fileLabel } ` ,
212+ invocationMessage : ( `Read ${ fileLabel } ` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) ,
213+ pastTenseMessage : ( `Read ${ fileLabel } ` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) ,
185214 toolSpecificData : {
186215 command : 'view' ,
187216 filePath : filePath ,
188- fileLabel : fileLabel
217+ fileLabel : fileLabel ,
218+ viewRange : parsedRange
189219 }
190220 } ;
191221 }
192222 }
193223 } else {
194224 const filePath = args . path ;
195225 const fileLabel = filePath && toFileLabel ( filePath ) ;
226+ const parsedRange = parseRange ( args . view_range ) ;
227+
196228 return {
197229 toolName : 'Edit' ,
198- invocationMessage : fileLabel ? `Edit [](${ fileLabel } )` : 'Edit' ,
199- pastTenseMessage : fileLabel ? `Edit [](${ fileLabel } )` : 'Edit' ,
230+ invocationMessage : fileLabel ? ( `Edit [](${ fileLabel } )` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Edit' ,
231+ pastTenseMessage : fileLabel ? ( `Edit [](${ fileLabel } )` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Edit' ,
200232 toolSpecificData : fileLabel ? {
201233 command : args . command || 'edit' ,
202234 filePath : filePath ,
203- fileLabel : fileLabel
235+ fileLabel : fileLabel ,
236+ viewRange : parsedRange
204237 } : undefined
205238 } ;
206239 }
207240 } else if ( name === 'view' ) {
208241 const filePath = args . path ;
209242 const fileLabel = filePath && toFileLabel ( filePath ) ;
243+ const parsedRange = parseRange ( args . view_range ) ;
244+
210245 return {
211246 toolName : fileLabel === '' ? 'Read repository' : 'Read' ,
212- invocationMessage : fileLabel ? `Read [](${ fileLabel } )` : 'Read repository' ,
213- pastTenseMessage : fileLabel ? `Read [](${ fileLabel } )` : 'Read repository' ,
247+ invocationMessage : fileLabel ? ( `Read [](${ fileLabel } )` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Read repository' ,
248+ pastTenseMessage : fileLabel ? ( `Read [](${ fileLabel } )` + ( parsedRange ? `, lines ${ parsedRange . start } to ${ parsedRange . end } ` : '' ) ) : 'Read repository' ,
214249 toolSpecificData : fileLabel ? {
215250 command : 'view' ,
216251 filePath : filePath ,
217- fileLabel : fileLabel
252+ fileLabel : fileLabel ,
253+ viewRange : parsedRange
218254 } : undefined
219255 } ;
220256 } else if ( name === 'think' ) {
@@ -250,6 +286,16 @@ export function parseToolCallDetails(
250286 details . toolSpecificData = bashToolData ;
251287 }
252288 return details ;
289+ } else if ( name === 'read_bash' ) {
290+ return {
291+ toolName : 'read_bash' ,
292+ invocationMessage : 'Read logs from Bash session'
293+ }
294+ } else if ( name === 'stop_bash' ) {
295+ return {
296+ toolName : 'stop_bash' ,
297+ invocationMessage : 'Stop Bash session'
298+ }
253299 } else {
254300 // Unknown tool type
255301 return {
0 commit comments