3
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
+ import { coalesce } from 'vs/base/common/arrays' ;
6
7
import { DeferredPromise , raceCancellation } from 'vs/base/common/async' ;
7
8
import { CancellationToken } from 'vs/base/common/cancellation' ;
8
9
import { toErrorMessage } from 'vs/base/common/errorMessage' ;
@@ -14,12 +15,11 @@ import { localize } from 'vs/nls';
14
15
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' ;
15
16
import { ILogService } from 'vs/platform/log/common/log' ;
16
17
import { Progress } from 'vs/platform/progress/common/progress' ;
17
- import { ExtHostChatAgentsShape2 , IChatAgentCompletionItem , IMainContext , MainContext , MainThreadChatAgentsShape2 } from 'vs/workbench/api/common/extHost.protocol' ;
18
+ import { ExtHostChatAgentsShape2 , IChatAgentCompletionItem , IChatAgentHistoryEntryDto , IMainContext , MainContext , MainThreadChatAgentsShape2 } from 'vs/workbench/api/common/extHost.protocol' ;
18
19
import { ExtHostChatProvider } from 'vs/workbench/api/common/extHostChatProvider' ;
19
20
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters' ;
20
21
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes' ;
21
22
import { IChatAgentCommand , IChatAgentRequest , IChatAgentResult } from 'vs/workbench/contrib/chat/common/chatAgents' ;
22
- import { IChatMessage } from 'vs/workbench/contrib/chat/common/chatProvider' ;
23
23
import { IChatFollowup , IChatUserActionEvent , InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService' ;
24
24
import { checkProposedApiEnabled , isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions' ;
25
25
import type * as vscode from 'vscode' ;
@@ -51,10 +51,10 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
51
51
return agent . apiAgent ;
52
52
}
53
53
54
- async $invokeAgent ( handle : number , sessionId : string , requestId : string , request : IChatAgentRequest , context : { history : IChatMessage [ ] } , token : CancellationToken ) : Promise < IChatAgentResult | undefined > {
54
+ async $invokeAgent ( handle : number , request : IChatAgentRequest , context : { history : IChatAgentHistoryEntryDto [ ] } , token : CancellationToken ) : Promise < IChatAgentResult | undefined > {
55
55
// Clear the previous result so that $acceptFeedback or $acceptAction during a request will be ignored.
56
56
// We may want to support sending those during a request.
57
- this . _previousResultMap . delete ( sessionId ) ;
57
+ this . _previousResultMap . delete ( request . sessionId ) ;
58
58
59
59
const agent = this . _agents . get ( handle ) ;
60
60
if ( ! agent ) {
@@ -79,13 +79,10 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
79
79
const stopWatch = StopWatch . create ( false ) ;
80
80
let firstProgress : number | undefined ;
81
81
try {
82
+ const convertedHistory = await this . prepareHistory ( agent , request , context ) ;
82
83
const task = agent . invoke (
83
- {
84
- prompt : request . message ,
85
- variables : typeConvert . ChatVariable . objectTo ( request . variables ) ,
86
- slashCommand
87
- } ,
88
- { history : context . history . map ( typeConvert . ChatMessage . to ) } ,
84
+ typeConvert . ChatAgentRequest . to ( request , slashCommand ) ,
85
+ { history : convertedHistory } ,
89
86
new Progress < vscode . ChatAgentExtendedProgress > ( progress => {
90
87
throwIfDone ( ) ;
91
88
@@ -101,7 +98,7 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
101
98
}
102
99
103
100
if ( 'placeholder' in progress && 'resolvedContent' in progress ) {
104
- const resolvedContent = Promise . all ( [ this . _proxy . $handleProgressChunk ( requestId , convertedProgress ) , progress . resolvedContent ] ) ;
101
+ const resolvedContent = Promise . all ( [ this . _proxy . $handleProgressChunk ( request . requestId , convertedProgress ) , progress . resolvedContent ] ) ;
105
102
raceCancellation ( resolvedContent , token ) . then ( res => {
106
103
if ( ! res ) {
107
104
return ; /* Cancelled */
@@ -113,29 +110,29 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
113
110
return ;
114
111
}
115
112
116
- this . _proxy . $handleProgressChunk ( requestId , convertedContent , progressHandle ?? undefined ) ;
113
+ this . _proxy . $handleProgressChunk ( request . requestId , convertedContent , progressHandle ?? undefined ) ;
117
114
} ) ;
118
115
} else {
119
- this . _proxy . $handleProgressChunk ( requestId , convertedProgress ) ;
116
+ this . _proxy . $handleProgressChunk ( request . requestId , convertedProgress ) ;
120
117
}
121
118
} ) ,
122
119
token
123
120
) ;
124
121
125
122
return await raceCancellation ( Promise . resolve ( task ) . then ( ( result ) => {
126
123
if ( result ) {
127
- this . _previousResultMap . set ( sessionId , result ) ;
128
- let sessionResults = this . _resultsBySessionAndRequestId . get ( sessionId ) ;
124
+ this . _previousResultMap . set ( request . sessionId , result ) ;
125
+ let sessionResults = this . _resultsBySessionAndRequestId . get ( request . sessionId ) ;
129
126
if ( ! sessionResults ) {
130
127
sessionResults = new Map ( ) ;
131
- this . _resultsBySessionAndRequestId . set ( sessionId , sessionResults ) ;
128
+ this . _resultsBySessionAndRequestId . set ( request . sessionId , sessionResults ) ;
132
129
}
133
- sessionResults . set ( requestId , result ) ;
130
+ sessionResults . set ( request . requestId , result ) ;
134
131
135
132
const timings = { firstProgress : firstProgress , totalElapsed : stopWatch . elapsed ( ) } ;
136
133
return { errorDetails : result . errorDetails , timings } ;
137
134
} else {
138
- this . _previousResultMap . delete ( sessionId ) ;
135
+ this . _previousResultMap . delete ( request . sessionId ) ;
139
136
}
140
137
141
138
return undefined ;
@@ -151,6 +148,19 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
151
148
}
152
149
}
153
150
151
+ private async prepareHistory < T extends vscode . ChatAgentResult2 > ( agent : ExtHostChatAgent < T > , request : IChatAgentRequest , context : { history : IChatAgentHistoryEntryDto [ ] } ) : Promise < vscode . ChatAgentHistoryEntry [ ] > {
152
+ return coalesce ( await Promise . all ( context . history
153
+ . map ( async h => {
154
+ const result = request . agentId === h . request . agentId && this . _resultsBySessionAndRequestId . get ( request . sessionId ) ?. get ( h . request . requestId )
155
+ || h . result ;
156
+ return {
157
+ request : typeConvert . ChatAgentRequest . to ( h . request , undefined ) ,
158
+ response : coalesce ( h . response . map ( r => typeConvert . ChatResponseProgress . toProgressContent ( r ) ) ) ,
159
+ result
160
+ } satisfies vscode . ChatAgentHistoryEntry ;
161
+ } ) ) ) ;
162
+ }
163
+
154
164
$releaseSession ( sessionId : string ) : void {
155
165
this . _previousResultMap . delete ( sessionId ) ;
156
166
this . _resultsBySessionAndRequestId . delete ( sessionId ) ;
@@ -248,7 +258,7 @@ class ExtHostChatAgent<TResult extends vscode.ChatAgentResult2> {
248
258
249
259
constructor (
250
260
public readonly extension : IExtensionDescription ,
251
- private readonly _id : string ,
261
+ public readonly id : string ,
252
262
private readonly _proxy : MainThreadChatAgentsShape2 ,
253
263
private readonly _handle : number ,
254
264
private readonly _callback : vscode . ChatAgentExtendedHandler ,
@@ -352,7 +362,7 @@ class ExtHostChatAgent<TResult extends vscode.ChatAgentResult2> {
352
362
const that = this ;
353
363
return {
354
364
get name ( ) {
355
- return that . _id ;
365
+ return that . id ;
356
366
} ,
357
367
get description ( ) {
358
368
return that . _description ?? '' ;
0 commit comments