33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6- import { SweCustomAgent } from '@github/copilot/sdk' ;
6+ import { Attachment , SweCustomAgent } from '@github/copilot/sdk' ;
77import * as l10n from '@vscode/l10n' ;
88import * as vscode from 'vscode' ;
99import { ChatExtendedRequestHandler , Uri } from 'vscode' ;
@@ -434,6 +434,7 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
434434 }
435435
436436 private readonly previousReferences = new Map < string , vscode . ChatPromptReference [ ] > ( ) ;
437+ private readonly attachmentsForRequest = new Map < string , Attachment [ ] > ( ) ;
437438 private async handleRequest ( request : vscode . ChatRequest , context : vscode . ChatContext , stream : vscode . ChatResponseStream , token : vscode . CancellationToken ) : Promise < vscode . ChatResult | void > {
438439 const { chatSessionContext } = context ;
439440 const disposables = new DisposableStore ( ) ;
@@ -493,6 +494,11 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
493494
494495 if ( request . prompt . startsWith ( '/delegate' ) ) {
495496 await this . handleDelegateCommand ( session . object , request , context , stream , token ) ;
497+ } else if ( this . attachmentsForRequest . has ( session . object . sessionId ) ) {
498+ // This is a request that was created in createCLISessionAndSubmitRequest with attachments already resolved.
499+ const attachments = this . attachmentsForRequest . get ( session . object . sessionId ) ! ;
500+ this . attachmentsForRequest . delete ( session . object . sessionId ) ;
501+ await session . object . handleRequest ( request . id , request . prompt , attachments , modelId , token ) ;
496502 } else {
497503 // Construct the full prompt with references to be sent to CLI.
498504 const { prompt, attachments } = await this . promptResolver . resolvePrompt ( request , undefined , additionalReferences , session . object . options . isolationEnabled , token ) ;
@@ -811,31 +817,37 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
811817 token : vscode . CancellationToken
812818 ) : Promise < vscode . ChatResult > {
813819 let history : string | undefined ;
820+ const requestPromptPromise = ( async ( ) => {
821+ if ( this . hasHistoryToSummarize ( context . history ) ) {
822+ stream . progress ( vscode . l10n . t ( 'Analyzing chat history' ) ) ;
823+ history = await this . chatDelegationSummaryService . summarize ( context , token ) ;
824+ history = history ? `**Summary**\n${ history } ` : undefined ;
825+ }
814826
815- if ( this . hasHistoryToSummarize ( context . history ) ) {
816- stream . progress ( vscode . l10n . t ( 'Analyzing chat history' ) ) ;
817- history = await this . chatDelegationSummaryService . summarize ( context , token ) ;
818- history = history ? `**Summary**\n${ history } ` : undefined ;
819- }
827+ // Give priority to userPrompt if provided (e.g., from confirmation metadata)
828+ userPrompt = userPrompt || request . prompt ;
829+ return history ? `${ userPrompt } \n${ history } ` : userPrompt ;
830+ } ) ( ) ;
820831
821- // Give priority to userPrompt if provided (e.g., from confirmation metadata)
822- userPrompt = userPrompt || request . prompt ;
823- const requestPrompt = history ? `${ userPrompt } \n${ history } ` : userPrompt ;
832+ const getWorkingDirectory = async ( ) => {
833+ // Create worktree if isolation is enabled and we don't have one yet
834+ if ( isolationEnabled && ! workingDirectory ) {
835+ const workTreePath = await this . worktreeManager . createWorktree ( stream ) ;
836+ workingDirectory = workTreePath ? URI . file ( workTreePath ) : undefined ;
837+ }
824838
825- // Create worktree if isolation is enabled and we don't have one yet
826- if ( isolationEnabled && ! workingDirectory ) {
827- const workTreePath = await this . worktreeManager . createWorktree ( stream ) ;
828- workingDirectory = workTreePath ? URI . file ( workTreePath ) : undefined ;
829- }
839+ // Fallback to default directory if worktree creation failed
840+ if ( ! isolationEnabled && ! workingDirectory ) {
841+ workingDirectory = await this . copilotCLISDK . getDefaultWorkingDirectory ( ) ;
842+ }
843+ } ;
830844
831- // Fallback to default directory if worktree creation failed
832- if ( ! workingDirectory && ! isolationEnabled ) {
833- workingDirectory = await this . copilotCLISDK . getDefaultWorkingDirectory ( ) ;
834- }
835- const [ { prompt, attachments } , model , agent ] = await Promise . all ( [
836- this . promptResolver . resolvePrompt ( request , requestPrompt , ( references || [ ] ) . concat ( [ ] ) , isolationEnabled , token ) ,
845+ const [ requestPrompt , { prompt, attachments } , model , agent ] = await Promise . all ( [
846+ requestPromptPromise ,
847+ requestPromptPromise . then ( prompt => this . promptResolver . resolvePrompt ( request , prompt , ( references || [ ] ) . concat ( [ ] ) , isolationEnabled , token ) ) ,
837848 this . getModelId ( undefined , undefined , token ) ,
838849 this . getAgent ( undefined , undefined , token ) ,
850+ getWorkingDirectory ( )
839851 ] ) ;
840852
841853 const session = await this . sessionService . createSession ( { workingDirectory, isolationEnabled, agent, model } , token ) ;
@@ -849,12 +861,14 @@ export class CopilotCLIChatSessionParticipant extends Disposable {
849861 }
850862
851863 try {
864+ this . attachmentsForRequest . set ( session . object . sessionId , attachments ) ;
852865 this . sessionItemProvider . notifySessionsChange ( ) ;
853866 await vscode . commands . executeCommand ( 'workbench.action.chat.openSessionWithPrompt.copilotcli' , {
854867 resource : SessionIdForCLI . getResource ( session . object . sessionId ) ,
855868 prompt : requestPrompt
856869 } ) ;
857870 } catch {
871+ this . attachmentsForRequest . delete ( session . object . sessionId ) ;
858872 // TODO@rebornix : handle potential missing command
859873 // We don't want to block the caller anymore.
860874 // The caller is most likely a chat editor or the like.
0 commit comments