@@ -42,6 +42,7 @@ const CONTINUE_WITHOUT_PUSHING = vscode.l10n.t('Ignore changes');
4242const CONTINUE_AND_DO_NOT_ASK_AGAIN = vscode . l10n . t ( 'Continue and don\'t ask again' ) ;
4343
4444const CONTINUE_TRUNCATION = vscode . l10n . t ( 'Continue with truncation' ) ;
45+ const DELEGATE_MODAL_DETAILS = vscode . l10n . t ( 'The agent will work asynchronously to create a pull request with your requested changes.' ) ;
4546
4647const COPILOT = '@copilot' ;
4748
@@ -72,23 +73,25 @@ export namespace SessionIdForPr {
7273
7374export class CopilotRemoteAgentManager extends Disposable {
7475 async chatParticipantImpl ( request : vscode . ChatRequest , context : vscode . ChatContext , stream : vscode . ChatResponseStream , token : vscode . CancellationToken ) {
75- const startSession = async ( prompt : string , history : ReadonlyArray < vscode . ChatRequestTurn | vscode . ChatResponseTurn > , source : string , chatSummary ?: { prompt ?: string ; history ?: string } ) => {
76+ const startSession = async ( source : string ) => {
7677 /* __GDPR__
7778 "copilot.remoteagent.editor.invoke" : {
7879 "promptLength" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
7980 "historyLength" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
80- "hasPromptSummary " : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
81- "hasHistorySummary " : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
81+ "promptSummaryLength " : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
82+ "historySummaryLength " : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
8283 "source" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
8384 }
8485 */
85- const promptSummary = chatSummary ?. prompt ;
86- const historySummary = chatSummary ?. history ;
86+ const prompt = request . prompt ;
87+ const history = context . history ;
88+ const promptSummary = context . chatSummary ?. prompt ;
89+ const historySummary = context . chatSummary ?. history ;
8790 this . telemetry . sendTelemetryEvent ( 'copilot.remoteagent.editor.invoke' , {
8891 promptLength : prompt . length . toString ( ) ,
8992 historyLength : history ?. length . toString ( ) ,
90- hasPromptSummary : String ( ! ! promptSummary ) ,
91- hasHistorySummary : String ( ! ! historySummary ) ,
93+ promptSummaryLength : promptSummary ?. length . toString ( ) || '0' ,
94+ historySummaryLength : historySummary ?. length . toString ( ) || '0' ,
9295 source,
9396 } ) ;
9497 stream . progress ( vscode . l10n . t ( 'Delegating to coding agent' ) ) ;
@@ -109,9 +112,48 @@ export class CopilotRemoteAgentManager extends Disposable {
109112 return result . number ;
110113 } ;
111114
115+ const handleConfirmationData = async ( ) => {
116+ const results : Array < { step : string ; accepted : boolean } > = [ ] ;
117+ results . push ( ...( request . acceptedConfirmationData ?. map ( data => ( { step : data . step , accepted : true } ) ) ?? [ ] ) ) ;
118+ results . push ( ...( ( request . rejectedConfirmationData ?? [ ] ) . filter ( data => ! results . some ( r => r . step === data . step ) ) . map ( data => ( { step : data . step , accepted : false } ) ) ) ) ;
119+ for ( const data of results ) {
120+ switch ( data . step ) {
121+ case 'create' :
122+ if ( ! data . accepted ) {
123+ stream . markdown ( vscode . l10n . t ( 'Coding agent request cancelled.' ) ) ;
124+ return { } ;
125+ }
126+ const number = await startSession ( 'chat' ) ;
127+ if ( ! number ) {
128+ return { } ;
129+ }
130+ const pullRequest = await this . findPullRequestById ( number , true ) ;
131+ if ( ! pullRequest ) {
132+ stream . warning ( vscode . l10n . t ( 'Could not find the associated pull request {0} for this chat session.' , number ) ) ;
133+ return { } ;
134+ }
135+ const uri = await toOpenPullRequestWebviewUri ( { owner : pullRequest . remote . owner , repo : pullRequest . remote . repositoryName , pullRequestNumber : pullRequest . number } ) ;
136+ const plaintextBody = marked . parse ( pullRequest . body , { renderer : new PlainTextRenderer ( true ) , smartypants : true } ) . trim ( ) ;
137+ const card = new vscode . ChatResponsePullRequestPart ( uri , pullRequest . title , plaintextBody , pullRequest . author . specialDisplayName ?? pullRequest . author . login , `#${ pullRequest . number } ` ) ;
138+ stream . push ( card ) ;
139+ stream . markdown ( vscode . l10n . t ( 'GitHub Copilot coding agent has begun working on your request. Follow its progress in the associated chat and pull request.' ) ) ;
140+ vscode . window . showChatSession ( COPILOT_SWE_AGENT , String ( number ) , { viewColumn : vscode . ViewColumn . Active } ) ;
141+ break ;
142+ default :
143+ stream . warning ( `Unknown confirmation step: ${ data . step } \n\n` ) ;
144+ break ;
145+ }
146+ }
147+ return { } ;
148+ } ;
149+
150+ if ( request . acceptedConfirmationData || request . rejectedConfirmationData ) {
151+ return await handleConfirmationData ( ) ;
152+ }
153+
112154 if ( context . chatSessionContext ?. isUntitled ) {
113155 /* Generate new coding agent session from an 'untitled' session */
114- const number = await startSession ( request . prompt , context . history , 'untitledChatSession' ) ;
156+ const number = await startSession ( 'untitledChatSession' ) ;
115157 if ( ! number ) {
116158 return { } ;
117159 }
@@ -175,25 +217,13 @@ export class CopilotRemoteAgentManager extends Disposable {
175217 } else {
176218 /* @copilot invoked from a 'normal' chat */
177219
178- // TODO(jospicer): Use confirmations to guide users
179-
180- const number = await startSession ( request . prompt , context . history , 'chat' , context . chatSummary ) ; // TODO(jospicer): 'All of the chat messages so far in the current chat session. Currently, only chat messages for the current participant are included'
181- if ( ! number ) {
182- return { } ;
183- }
184- const pullRequest = await this . findPullRequestById ( number , true ) ;
185- if ( ! pullRequest ) {
186- stream . warning ( vscode . l10n . t ( 'Could not find the associated pull request {0} for this chat session.' , number ) ) ;
187- return { } ;
188- }
189-
190- const uri = await toOpenPullRequestWebviewUri ( { owner : pullRequest . remote . owner , repo : pullRequest . remote . repositoryName , pullRequestNumber : pullRequest . number } ) ;
191- const plaintextBody = marked . parse ( pullRequest . body , { renderer : new PlainTextRenderer ( true ) , smartypants : true } ) . trim ( ) ;
220+ stream . confirmation (
221+ vscode . l10n . t ( 'Delegate to coding agent' ) ,
222+ DELEGATE_MODAL_DETAILS ,
223+ { step : 'create' } ,
224+ [ 'Delegate' , 'Cancel' ]
225+ ) ;
192226
193- const card = new vscode . ChatResponsePullRequestPart ( uri , pullRequest . title , plaintextBody , pullRequest . author . specialDisplayName ?? pullRequest . author . login , `#${ pullRequest . number } ` ) ;
194- stream . push ( card ) ;
195- stream . markdown ( vscode . l10n . t ( 'GitHub Copilot coding agent has begun working on your request. Follow its progress in the associated chat and pull request.' ) ) ;
196- vscode . window . showChatSession ( COPILOT_SWE_AGENT , String ( number ) , { viewColumn : vscode . ViewColumn . Active } ) ;
197227 }
198228 }
199229
@@ -549,7 +579,7 @@ export class CopilotRemoteAgentManager extends Disposable {
549579
550580 let autoPushAndCommit = false ;
551581 const message = vscode . l10n . t ( 'Copilot coding agent will continue your work in \'{0}\'.' , repoName ) ;
552- const detail = vscode . l10n . t ( 'Your chat context will be used to continue work in a new pull request.' ) ;
582+ const detail = DELEGATE_MODAL_DETAILS ;
553583 if ( source !== 'prompt' && hasChanges && CopilotRemoteAgentConfig . getAutoCommitAndPushEnabled ( ) ) {
554584 // Pending changes modal
555585 const modalResult = await vscode . window . showInformationMessage (
0 commit comments