@@ -9,7 +9,7 @@ import type { ChatPromptReference, ChatTerminalToolInvocationData, ExtendedChatR
99import { isLocation } from '../../../../util/common/types' ;
1010import { ResourceSet } from '../../../../util/vs/base/common/map' ;
1111import { URI } from '../../../../util/vs/base/common/uri' ;
12- import { ChatRequestTurn2 , ChatResponseMarkdownPart , ChatResponsePullRequestPart , ChatResponseThinkingProgressPart , ChatResponseTurn2 , ChatToolInvocationPart , MarkdownString , Uri } from '../../../../vscodeTypes' ;
12+ import { ChatRequestTurn2 , ChatResponseCodeblockUriPart , ChatResponseMarkdownPart , ChatResponsePullRequestPart , ChatResponseTextEditPart , ChatResponseThinkingProgressPart , ChatResponseTurn2 , ChatToolInvocationPart , MarkdownString , Uri } from '../../../../vscodeTypes' ;
1313import { formatUriForFileWidget } from '../../../tools/common/toolUtils' ;
1414import { extractChatPromptReferences , getFolderAttachmentPath } from './copilotCLIPrompt' ;
1515
@@ -283,12 +283,14 @@ function extractPRMetadata(content: string): { cleanedContent: string; prPart?:
283283 * Build chat history from SDK events for VS Code chat session
284284 * Converts SDKEvents into ChatRequestTurn2 and ChatResponseTurn2 objects
285285 */
286- export function buildChatHistoryFromEvents ( events : readonly SessionEvent [ ] ) : ( ChatRequestTurn2 | ChatResponseTurn2 ) [ ] {
286+ export function buildChatHistoryFromEvents ( events : readonly SessionEvent [ ] , getVSCodeRequestId ?: ( sdkRequestId : string ) => { requestId : string ; toolIdEditMap : Record < string , string > } | undefined ) : ( ChatRequestTurn2 | ChatResponseTurn2 ) [ ] {
287287 const turns : ( ChatRequestTurn2 | ChatResponseTurn2 ) [ ] = [ ] ;
288288 let currentResponseParts : ExtendedChatResponsePart [ ] = [ ] ;
289- const pendingToolInvocations = new Map < string , ChatToolInvocationPart > ( ) ;
289+ const pendingToolInvocations = new Map < string , [ ChatToolInvocationPart , toolData : ToolCall ] > ( ) ;
290290
291+ let details : { requestId : string ; toolIdEditMap : Record < string , string > } | undefined ;
291292 for ( const event of events ) {
293+ details = getVSCodeRequestId ?.( event . id ) ?? details ;
292294 switch ( event . type ) {
293295 case 'user.message' : {
294296 // Flush any pending response parts before adding user message
@@ -338,7 +340,7 @@ export function buildChatHistoryFromEvents(events: readonly SessionEvent[]): (Ch
338340 range
339341 } ) ;
340342 } ) ;
341- turns . push ( new ChatRequestTurn2 ( stripReminders ( event . data . content || '' ) , undefined , references , '' , [ ] , undefined ) ) ;
343+ turns . push ( new ChatRequestTurn2 ( stripReminders ( event . data . content || '' ) , undefined , references , '' , [ ] , undefined , details ?. requestId ) ) ;
342344 break ;
343345 }
344346 case 'assistant.message' : {
@@ -367,9 +369,21 @@ export function buildChatHistoryFromEvents(events: readonly SessionEvent[]): (Ch
367369 break ;
368370 }
369371 case 'tool.execution_complete' : {
370- const responsePart = processToolExecutionComplete ( event , pendingToolInvocations ) ;
371- if ( responsePart && ! ( responsePart instanceof ChatResponseThinkingProgressPart ) ) {
372- currentResponseParts . push ( responsePart ) ;
372+ const [ responsePart , toolCall ] = processToolExecutionComplete ( event , pendingToolInvocations ) ?? [ undefined , undefined ] ;
373+ if ( responsePart && toolCall && ! ( responsePart instanceof ChatResponseThinkingProgressPart ) ) {
374+ const editId = details ?. toolIdEditMap ? details . toolIdEditMap [ toolCall . toolCallId ] : undefined ;
375+ const editedUris = getAffectedUrisForEditTool ( toolCall ) ;
376+ if ( isCopilotCliEditToolCall ( toolCall ) && editId && editedUris . length > 0 ) {
377+ for ( const uri of editedUris ) {
378+ currentResponseParts . push ( new ChatResponseMarkdownPart ( '\n````\n' ) ) ;
379+ currentResponseParts . push ( new ChatResponseCodeblockUriPart ( uri , true , editId ) ) ;
380+ currentResponseParts . push ( new ChatResponseMarkdownPart ( '\n````\n' ) ) ;
381+ currentResponseParts . push ( new ChatResponseTextEditPart ( uri , [ ] ) ) ;
382+ currentResponseParts . push ( new ChatResponseTextEditPart ( uri , true ) ) ;
383+ }
384+ } else {
385+ currentResponseParts . push ( responsePart ) ;
386+ }
373387 }
374388 break ;
375389 }
@@ -393,27 +407,27 @@ function getRangeInPrompt(prompt: string, referencedName: string): [number, numb
393407 return undefined ;
394408}
395409
396- export function processToolExecutionStart ( event : ToolExecutionStartEvent , pendingToolInvocations : Map < string , ChatToolInvocationPart | ChatResponseThinkingProgressPart > ) : ChatToolInvocationPart | ChatResponseThinkingProgressPart | undefined {
410+ export function processToolExecutionStart ( event : ToolExecutionStartEvent , pendingToolInvocations : Map < string , [ ChatToolInvocationPart | ChatResponseThinkingProgressPart , toolData : ToolCall ] > ) : ChatToolInvocationPart | ChatResponseThinkingProgressPart | undefined {
397411 const toolInvocation = createCopilotCLIToolInvocation ( event . data as ToolCall ) ;
398412 if ( toolInvocation ) {
399413 // Store pending invocation to update with result later
400- pendingToolInvocations . set ( event . data . toolCallId , toolInvocation ) ;
414+ pendingToolInvocations . set ( event . data . toolCallId , [ toolInvocation , event . data as ToolCall ] ) ;
401415 }
402416 return toolInvocation ;
403417}
404418
405- export function processToolExecutionComplete ( event : ToolExecutionCompleteEvent , pendingToolInvocations : Map < string , ChatToolInvocationPart | ChatResponseThinkingProgressPart > ) : ChatToolInvocationPart | ChatResponseThinkingProgressPart | undefined {
419+ export function processToolExecutionComplete ( event : ToolExecutionCompleteEvent , pendingToolInvocations : Map < string , [ ChatToolInvocationPart | ChatResponseThinkingProgressPart , toolData : ToolCall ] > ) : [ ChatToolInvocationPart | ChatResponseThinkingProgressPart , toolData : ToolCall ] | undefined {
406420 const invocation = pendingToolInvocations . get ( event . data . toolCallId ) ;
407421 pendingToolInvocations . delete ( event . data . toolCallId ) ;
408422
409- if ( invocation && invocation instanceof ChatToolInvocationPart ) {
410- invocation . isComplete = true ;
411- invocation . isError = ! ! event . data . error ;
412- invocation . invocationMessage = event . data . error ?. message || invocation . invocationMessage ;
423+ if ( invocation && invocation [ 0 ] instanceof ChatToolInvocationPart ) {
424+ invocation [ 0 ] . isComplete = true ;
425+ invocation [ 0 ] . isError = ! ! event . data . error ;
426+ invocation [ 0 ] . invocationMessage = event . data . error ?. message || invocation [ 0 ] . invocationMessage ;
413427 if ( ! event . data . success && ( event . data . error ?. code === 'rejected' || event . data . error ?. code === 'denied' ) ) {
414- invocation . isConfirmed = false ;
428+ invocation [ 0 ] . isConfirmed = false ;
415429 } else {
416- invocation . isConfirmed = true ;
430+ invocation [ 0 ] . isConfirmed = true ;
417431 }
418432 }
419433
@@ -423,7 +437,7 @@ export function processToolExecutionComplete(event: ToolExecutionCompleteEvent,
423437/**
424438 * Creates a formatted tool invocation part for CopilotCLI tools
425439 */
426- export function createCopilotCLIToolInvocation ( data : { toolCallId : string ; toolName : string ; arguments ?: unknown } ) : ChatToolInvocationPart | ChatResponseThinkingProgressPart | undefined {
440+ export function createCopilotCLIToolInvocation ( data : { toolCallId : string ; toolName : string ; arguments ?: unknown } , editId ?: string ) : ChatToolInvocationPart | ChatResponseThinkingProgressPart | undefined {
427441 if ( ! Object . hasOwn ( ToolFriendlyNameAndHandlers , data . toolName ) ) {
428442 const invocation = new ChatToolInvocationPart ( data . toolName ?? 'unknown' , data . toolCallId ?? '' , false ) ;
429443 invocation . isConfirmed = false ;
@@ -450,11 +464,11 @@ export function createCopilotCLIToolInvocation(data: { toolCallId: string; toolN
450464 invocation . isConfirmed = false ;
451465 invocation . isComplete = false ;
452466
453- ( formatter as Formatter ) ( invocation , toolCall ) ;
467+ ( formatter as Formatter ) ( invocation , toolCall , editId ) ;
454468 return invocation ;
455469}
456470
457- type Formatter = ( invocation : ChatToolInvocationPart , toolCall : ToolCall ) => void ;
471+ type Formatter = ( invocation : ChatToolInvocationPart , toolCall : ToolCall , editId ?: string ) => void ;
458472type ToolCallFor < T extends ToolCall [ 'toolName' ] > = Extract < ToolCall , { toolName : T } > ;
459473
460474const ToolFriendlyNameAndHandlers : { [ K in ToolCall [ 'toolName' ] ] : [ string , ( invocation : ChatToolInvocationPart , toolCall : ToolCallFor < K > ) => void ] } = {
@@ -513,7 +527,7 @@ function formatViewToolInvocation(invocation: ChatToolInvocationPart, toolCall:
513527 }
514528}
515529
516- function formatStrReplaceEditorInvocation ( invocation : ChatToolInvocationPart , toolCall : StringReplaceEditorTool ) : void {
530+ function formatStrReplaceEditorInvocation ( invocation : ChatToolInvocationPart , toolCall : StringReplaceEditorTool , editId ?: string ) : void {
517531 if ( ! toolCall . arguments . path ) {
518532 return ;
519533 }
@@ -554,7 +568,7 @@ function formatUndoEdit(invocation: ChatToolInvocationPart, toolCall: UndoEditTo
554568 }
555569}
556570
557- function formatEditToolInvocation ( invocation : ChatToolInvocationPart , toolCall : EditTool ) : void {
571+ function formatEditToolInvocation ( invocation : ChatToolInvocationPart , toolCall : EditTool , editId ?: string ) : void {
558572 const args = toolCall . arguments ;
559573 const display = args . path ? formatUriForFileWidget ( Uri . file ( args . path ) ) : '' ;
560574
@@ -564,7 +578,7 @@ function formatEditToolInvocation(invocation: ChatToolInvocationPart, toolCall:
564578}
565579
566580
567- function formatCreateToolInvocation ( invocation : ChatToolInvocationPart , toolCall : CreateTool ) : void {
581+ function formatCreateToolInvocation ( invocation : ChatToolInvocationPart , toolCall : CreateTool , editId ?: string ) : void {
568582 const args = toolCall . arguments ;
569583 const display = args . path ? formatUriForFileWidget ( Uri . file ( args . path ) ) : '' ;
570584
0 commit comments