@theia/ai-chat 1.58.3 → 1.59.0-next.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/ai-chat-frontend-module.d.ts.map +1 -1
- package/lib/browser/ai-chat-frontend-module.js +16 -13
- package/lib/browser/ai-chat-frontend-module.js.map +1 -1
- package/lib/browser/ai-chat-preferences.d.ts +1 -0
- package/lib/browser/ai-chat-preferences.d.ts.map +1 -1
- package/lib/browser/ai-chat-preferences.js +12 -3
- package/lib/browser/ai-chat-preferences.js.map +1 -1
- package/lib/browser/change-set-file-element.d.ts +31 -6
- package/lib/browser/change-set-file-element.d.ts.map +1 -1
- package/lib/browser/change-set-file-element.js +108 -15
- package/lib/browser/change-set-file-element.js.map +1 -1
- package/lib/browser/change-set-file-resource.d.ts +40 -8
- package/lib/browser/change-set-file-resource.d.ts.map +1 -1
- package/lib/browser/change-set-file-resource.js +123 -37
- package/lib/browser/change-set-file-resource.js.map +1 -1
- package/lib/browser/change-set-file-service.d.ts +9 -3
- package/lib/browser/change-set-file-service.d.ts.map +1 -1
- package/lib/browser/change-set-file-service.js +35 -13
- package/lib/browser/change-set-file-service.js.map +1 -1
- package/lib/browser/change-set-variable.d.ts +11 -0
- package/lib/browser/change-set-variable.d.ts.map +1 -0
- package/lib/browser/change-set-variable.js +56 -0
- package/lib/browser/change-set-variable.js.map +1 -0
- package/lib/browser/context-file-variable-label-provider.d.ts +14 -0
- package/lib/browser/context-file-variable-label-provider.d.ts.map +1 -0
- package/lib/browser/context-file-variable-label-provider.js +63 -0
- package/lib/browser/context-file-variable-label-provider.js.map +1 -0
- package/lib/browser/context-variable-label-provider.d.ts +9 -0
- package/lib/browser/context-variable-label-provider.d.ts.map +1 -0
- package/lib/browser/context-variable-label-provider.js +55 -0
- package/lib/browser/context-variable-label-provider.js.map +1 -0
- package/lib/browser/file-chat-variable-contribution.d.ts +18 -0
- package/lib/browser/file-chat-variable-contribution.d.ts.map +1 -0
- package/lib/browser/file-chat-variable-contribution.js +135 -0
- package/lib/browser/file-chat-variable-contribution.js.map +1 -0
- package/lib/browser/frontend-chat-service.d.ts +10 -3
- package/lib/browser/frontend-chat-service.d.ts.map +1 -1
- package/lib/browser/frontend-chat-service.js +39 -19
- package/lib/browser/frontend-chat-service.js.map +1 -1
- package/lib/common/chat-agents.d.ts +54 -24
- package/lib/common/chat-agents.d.ts.map +1 -1
- package/lib/common/chat-agents.js +58 -20
- package/lib/common/chat-agents.js.map +1 -1
- package/lib/common/chat-history-entry.js +1 -1
- package/lib/common/chat-history-entry.js.map +1 -1
- package/lib/common/chat-model.d.ts +84 -36
- package/lib/common/chat-model.d.ts.map +1 -1
- package/lib/common/chat-model.js +142 -51
- package/lib/common/chat-model.js.map +1 -1
- package/lib/common/chat-service.d.ts +27 -10
- package/lib/common/chat-service.d.ts.map +1 -1
- package/lib/common/chat-service.js +80 -20
- package/lib/common/chat-service.js.map +1 -1
- package/lib/common/chat-string-utils.d.ts +3 -0
- package/lib/common/chat-string-utils.d.ts.map +1 -0
- package/lib/common/chat-string-utils.js +27 -0
- package/lib/common/chat-string-utils.js.map +1 -0
- package/lib/common/chat-tool-request-service.d.ts +5 -5
- package/lib/common/chat-tool-request-service.d.ts.map +1 -1
- package/lib/common/chat-tool-request-service.js.map +1 -1
- package/lib/common/context-details-variable.d.ts +9 -0
- package/lib/common/context-details-variable.d.ts.map +1 -0
- package/lib/common/context-details-variable.js +57 -0
- package/lib/common/context-details-variable.js.map +1 -0
- package/lib/common/context-summary-variable.d.ts +9 -0
- package/lib/common/context-summary-variable.d.ts.map +1 -0
- package/lib/common/context-summary-variable.js +57 -0
- package/lib/common/context-summary-variable.js.map +1 -0
- package/lib/common/context-variables.d.ts +4 -0
- package/lib/common/context-variables.d.ts.map +1 -0
- package/lib/common/context-variables.js +22 -0
- package/lib/common/context-variables.js.map +1 -0
- package/lib/common/custom-chat-agent.d.ts +6 -10
- package/lib/common/custom-chat-agent.d.ts.map +1 -1
- package/lib/common/custom-chat-agent.js +8 -11
- package/lib/common/custom-chat-agent.js.map +1 -1
- package/lib/common/index.d.ts +1 -3
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +1 -3
- package/lib/common/index.js.map +1 -1
- package/lib/common/parse-contents.d.ts +2 -2
- package/lib/common/parse-contents.d.ts.map +1 -1
- package/lib/common/parse-contents.js.map +1 -1
- package/lib/common/parse-contents.spec.d.ts.map +1 -1
- package/lib/common/parse-contents.spec.js.map +1 -1
- package/lib/common/response-content-matcher.d.ts +3 -3
- package/lib/common/response-content-matcher.d.ts.map +1 -1
- package/lib/common/response-content-matcher.js.map +1 -1
- package/package.json +12 -10
- package/src/browser/ai-chat-frontend-module.ts +20 -18
- package/src/browser/ai-chat-preferences.ts +13 -2
- package/src/browser/change-set-file-element.ts +109 -20
- package/src/browser/change-set-file-resource.ts +125 -39
- package/src/browser/change-set-file-service.ts +38 -16
- package/src/browser/change-set-variable.ts +54 -0
- package/src/browser/context-file-variable-label-provider.ts +62 -0
- package/src/browser/context-variable-label-provider.ts +56 -0
- package/src/browser/file-chat-variable-contribution.ts +143 -0
- package/src/browser/frontend-chat-service.ts +40 -26
- package/src/common/chat-agents.ts +87 -30
- package/src/common/chat-history-entry.ts +1 -1
- package/src/common/chat-model.ts +204 -70
- package/src/common/chat-service.ts +92 -24
- package/src/common/chat-string-utils.ts +23 -0
- package/src/common/chat-tool-request-service.ts +5 -5
- package/src/common/context-details-variable.ts +53 -0
- package/src/common/context-summary-variable.ts +53 -0
- package/src/common/context-variables.ts +19 -0
- package/src/common/custom-chat-agent.ts +9 -20
- package/src/common/index.ts +1 -3
- package/src/common/parse-contents.spec.ts +2 -2
- package/src/common/parse-contents.ts +2 -2
- package/src/common/response-content-matcher.ts +3 -3
- package/lib/common/command-chat-agents.d.ts +0 -33
- package/lib/common/command-chat-agents.d.ts.map +0 -1
- package/lib/common/command-chat-agents.js +0 -329
- package/lib/common/command-chat-agents.js.map +0 -1
- package/lib/common/orchestrator-chat-agent.d.ts +0 -22
- package/lib/common/orchestrator-chat-agent.d.ts.map +0 -1
- package/lib/common/orchestrator-chat-agent.js +0 -167
- package/lib/common/orchestrator-chat-agent.js.map +0 -1
- package/lib/common/universal-chat-agent.d.ts +0 -16
- package/lib/common/universal-chat-agent.d.ts.map +0 -1
- package/lib/common/universal-chat-agent.js +0 -109
- package/lib/common/universal-chat-agent.js.map +0 -1
- package/src/common/command-chat-agents.ts +0 -354
- package/src/common/orchestrator-chat-agent.ts +0 -179
- package/src/common/universal-chat-agent.ts +0 -117
|
@@ -19,22 +19,23 @@
|
|
|
19
19
|
*--------------------------------------------------------------------------------------------*/
|
|
20
20
|
// Partially copied from https://github.com/microsoft/vscode/blob/a2cab7255c0df424027be05d58e1b7b941f4ea60/src/vs/workbench/contrib/chat/common/chatService.ts
|
|
21
21
|
|
|
22
|
+
import { AIVariableResolutionRequest, AIVariableService, ResolvedAIContextVariable } from '@theia/ai-core';
|
|
23
|
+
import { Emitter, ILogger, generateUuid } from '@theia/core';
|
|
22
24
|
import { inject, injectable, optional } from '@theia/core/shared/inversify';
|
|
25
|
+
import { Event } from '@theia/core/shared/vscode-languageserver-protocol';
|
|
26
|
+
import { ChatAgentService } from './chat-agent-service';
|
|
27
|
+
import { ChatAgent, ChatAgentLocation, ChatSessionContext } from './chat-agents';
|
|
23
28
|
import {
|
|
24
29
|
ChatModel,
|
|
25
|
-
|
|
30
|
+
MutableChatModel,
|
|
26
31
|
ChatRequest,
|
|
27
32
|
ChatRequestModel,
|
|
28
33
|
ChatResponseModel,
|
|
29
|
-
|
|
34
|
+
ErrorChatResponseModel,
|
|
35
|
+
ChatContext,
|
|
30
36
|
} from './chat-model';
|
|
31
|
-
import { ChatAgentService } from './chat-agent-service';
|
|
32
|
-
import { Emitter, ILogger, generateUuid } from '@theia/core';
|
|
33
37
|
import { ChatRequestParser } from './chat-request-parser';
|
|
34
|
-
import {
|
|
35
|
-
import { ParsedChatRequestAgentPart, ParsedChatRequestVariablePart, ParsedChatRequest } from './parsed-chat-request';
|
|
36
|
-
import { AIVariableService } from '@theia/ai-core';
|
|
37
|
-
import { Event } from '@theia/core/shared/vscode-languageserver-protocol';
|
|
38
|
+
import { ParsedChatRequest, ParsedChatRequestAgentPart, ParsedChatRequestVariablePart } from './parsed-chat-request';
|
|
38
39
|
|
|
39
40
|
export interface ChatRequestInvocation {
|
|
40
41
|
/**
|
|
@@ -56,6 +57,7 @@ export interface ChatSession {
|
|
|
56
57
|
title?: string;
|
|
57
58
|
model: ChatModel;
|
|
58
59
|
isActive: boolean;
|
|
60
|
+
pinnedAgent?: ChatAgent;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
export interface ActiveSessionChangedEvent {
|
|
@@ -67,18 +69,32 @@ export interface SessionOptions {
|
|
|
67
69
|
focus?: boolean;
|
|
68
70
|
}
|
|
69
71
|
|
|
72
|
+
/**
|
|
73
|
+
* The default chat agent to invoke
|
|
74
|
+
*/
|
|
70
75
|
export const DefaultChatAgentId = Symbol('DefaultChatAgentId');
|
|
71
76
|
export interface DefaultChatAgentId {
|
|
72
77
|
id: string;
|
|
73
78
|
}
|
|
74
79
|
|
|
80
|
+
/**
|
|
81
|
+
* In case no fitting chat agent is available, this one will be used (if it is itself available)
|
|
82
|
+
*/
|
|
83
|
+
export const FallbackChatAgentId = Symbol('FallbackChatAgentId');
|
|
84
|
+
export interface FallbackChatAgentId {
|
|
85
|
+
id: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const PinChatAgent = Symbol('PinChatAgent');
|
|
89
|
+
export type PinChatAgent = boolean;
|
|
90
|
+
|
|
75
91
|
export const ChatService = Symbol('ChatService');
|
|
76
92
|
export interface ChatService {
|
|
77
93
|
onActiveSessionChanged: Event<ActiveSessionChangedEvent>
|
|
78
94
|
|
|
79
95
|
getSession(id: string): ChatSession | undefined;
|
|
80
96
|
getSessions(): ChatSession[];
|
|
81
|
-
createSession(location?: ChatAgentLocation, options?: SessionOptions): ChatSession;
|
|
97
|
+
createSession(location?: ChatAgentLocation, options?: SessionOptions, pinnedAgent?: ChatAgent): ChatSession;
|
|
82
98
|
deleteSession(sessionId: string): void;
|
|
83
99
|
setActiveSession(sessionId: string, options?: SessionOptions): void;
|
|
84
100
|
|
|
@@ -94,7 +110,7 @@ export interface ChatService {
|
|
|
94
110
|
}
|
|
95
111
|
|
|
96
112
|
interface ChatSessionInternal extends ChatSession {
|
|
97
|
-
model:
|
|
113
|
+
model: MutableChatModel;
|
|
98
114
|
}
|
|
99
115
|
|
|
100
116
|
@injectable()
|
|
@@ -108,6 +124,12 @@ export class ChatServiceImpl implements ChatService {
|
|
|
108
124
|
@inject(DefaultChatAgentId) @optional()
|
|
109
125
|
protected defaultChatAgentId: DefaultChatAgentId | undefined;
|
|
110
126
|
|
|
127
|
+
@inject(FallbackChatAgentId) @optional()
|
|
128
|
+
protected fallbackChatAgentId: FallbackChatAgentId | undefined;
|
|
129
|
+
|
|
130
|
+
@inject(PinChatAgent) @optional()
|
|
131
|
+
protected pinChatAgent: boolean | undefined;
|
|
132
|
+
|
|
111
133
|
@inject(ChatRequestParser)
|
|
112
134
|
protected chatRequestParser: ChatRequestParser;
|
|
113
135
|
|
|
@@ -127,12 +149,13 @@ export class ChatServiceImpl implements ChatService {
|
|
|
127
149
|
return this._sessions.find(session => session.id === id);
|
|
128
150
|
}
|
|
129
151
|
|
|
130
|
-
createSession(location = ChatAgentLocation.Panel, options?: SessionOptions): ChatSession {
|
|
131
|
-
const model = new
|
|
152
|
+
createSession(location = ChatAgentLocation.Panel, options?: SessionOptions, pinnedAgent?: ChatAgent): ChatSession {
|
|
153
|
+
const model = new MutableChatModel(location);
|
|
132
154
|
const session: ChatSessionInternal = {
|
|
133
155
|
id: model.id,
|
|
134
156
|
model,
|
|
135
|
-
isActive: true
|
|
157
|
+
isActive: true,
|
|
158
|
+
pinnedAgent
|
|
136
159
|
};
|
|
137
160
|
this._sessions.push(session);
|
|
138
161
|
this.setActiveSession(session.id, options);
|
|
@@ -140,11 +163,15 @@ export class ChatServiceImpl implements ChatService {
|
|
|
140
163
|
}
|
|
141
164
|
|
|
142
165
|
deleteSession(sessionId: string): void {
|
|
166
|
+
const sessionIndex = this._sessions.findIndex(candidate => candidate.id === sessionId);
|
|
167
|
+
if (sessionIndex === -1) { return; }
|
|
168
|
+
const session = this._sessions[sessionIndex];
|
|
143
169
|
// If the removed session is the active one, set the newest one as active
|
|
144
|
-
if (
|
|
170
|
+
if (session.isActive) {
|
|
145
171
|
this.setActiveSession(this._sessions[this._sessions.length - 1]?.id);
|
|
146
172
|
}
|
|
147
|
-
|
|
173
|
+
session.model.dispose();
|
|
174
|
+
this._sessions.splice(sessionIndex, 1);
|
|
148
175
|
}
|
|
149
176
|
|
|
150
177
|
setActiveSession(sessionId: string | undefined, options?: SessionOptions): void {
|
|
@@ -156,7 +183,7 @@ export class ChatServiceImpl implements ChatService {
|
|
|
156
183
|
|
|
157
184
|
async sendRequest(
|
|
158
185
|
sessionId: string,
|
|
159
|
-
request: ChatRequest
|
|
186
|
+
request: ChatRequest,
|
|
160
187
|
): Promise<ChatRequestInvocation | undefined> {
|
|
161
188
|
const session = this.getSession(sessionId);
|
|
162
189
|
if (!session) {
|
|
@@ -165,25 +192,29 @@ export class ChatServiceImpl implements ChatService {
|
|
|
165
192
|
session.title = request.text;
|
|
166
193
|
|
|
167
194
|
const parsedRequest = this.chatRequestParser.parseChatRequest(request, session.model.location);
|
|
195
|
+
const agent = this.getAgent(parsedRequest, session);
|
|
168
196
|
|
|
169
|
-
const agent = this.getAgent(parsedRequest);
|
|
170
197
|
if (agent === undefined) {
|
|
171
198
|
const error = 'No ChatAgents available to handle request!';
|
|
172
199
|
this.logger.error(error);
|
|
173
|
-
const chatResponseModel = new
|
|
200
|
+
const chatResponseModel = new ErrorChatResponseModel(generateUuid(), new Error(error));
|
|
174
201
|
return {
|
|
175
202
|
requestCompleted: Promise.reject(error),
|
|
176
203
|
responseCreated: Promise.reject(error),
|
|
177
204
|
responseCompleted: Promise.resolve(chatResponseModel),
|
|
178
205
|
};
|
|
179
206
|
}
|
|
180
|
-
|
|
207
|
+
|
|
208
|
+
const resolutionContext: ChatSessionContext = { model: session.model };
|
|
209
|
+
const resolvedContext = await this.resolveChatContext(session.model.context.getVariables(), resolutionContext);
|
|
210
|
+
const requestModel = session.model.addRequest(parsedRequest, agent?.id, resolvedContext);
|
|
211
|
+
resolutionContext.request = requestModel;
|
|
181
212
|
|
|
182
213
|
for (const part of parsedRequest.parts) {
|
|
183
214
|
if (part instanceof ParsedChatRequestVariablePart) {
|
|
184
215
|
const resolvedVariable = await this.variableService.resolveVariable(
|
|
185
216
|
{ variable: part.variableName, arg: part.variableArg },
|
|
186
|
-
|
|
217
|
+
resolutionContext
|
|
187
218
|
);
|
|
188
219
|
if (resolvedVariable) {
|
|
189
220
|
part.resolution = resolvedVariable;
|
|
@@ -224,18 +255,55 @@ export class ChatServiceImpl implements ChatService {
|
|
|
224
255
|
return invocation;
|
|
225
256
|
}
|
|
226
257
|
|
|
258
|
+
protected async resolveChatContext(
|
|
259
|
+
resolutionRequests: readonly AIVariableResolutionRequest[],
|
|
260
|
+
context: ChatSessionContext,
|
|
261
|
+
): Promise<ChatContext> {
|
|
262
|
+
const resolvedVariables = await Promise.all(
|
|
263
|
+
resolutionRequests.map(async contextVariable => {
|
|
264
|
+
const resolvedVariable = await this.variableService.resolveVariable(contextVariable, context);
|
|
265
|
+
if (ResolvedAIContextVariable.is(resolvedVariable)) {
|
|
266
|
+
return resolvedVariable;
|
|
267
|
+
}
|
|
268
|
+
return undefined;
|
|
269
|
+
})
|
|
270
|
+
).then(results => results.filter((result): result is ResolvedAIContextVariable => result !== undefined));
|
|
271
|
+
return { variables: resolvedVariables };
|
|
272
|
+
}
|
|
273
|
+
|
|
227
274
|
async cancelRequest(sessionId: string, requestId: string): Promise<void> {
|
|
228
275
|
return this.getSession(sessionId)?.model.getRequest(requestId)?.response.cancel();
|
|
229
276
|
}
|
|
230
277
|
|
|
231
|
-
protected getAgent(parsedRequest: ParsedChatRequest): ChatAgent | undefined {
|
|
278
|
+
protected getAgent(parsedRequest: ParsedChatRequest, session: ChatSession): ChatAgent | undefined {
|
|
279
|
+
let agent = this.initialAgentSelection(parsedRequest);
|
|
280
|
+
if (this.pinChatAgent === false) {
|
|
281
|
+
return agent;
|
|
282
|
+
}
|
|
283
|
+
if (!session.pinnedAgent && agent && agent.id !== this.defaultChatAgentId?.id) {
|
|
284
|
+
session.pinnedAgent = agent;
|
|
285
|
+
} else if (session.pinnedAgent && this.getMentionedAgent(parsedRequest) === undefined) {
|
|
286
|
+
agent = session.pinnedAgent;
|
|
287
|
+
}
|
|
288
|
+
return agent;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
protected initialAgentSelection(parsedRequest: ParsedChatRequest): ChatAgent | undefined {
|
|
232
292
|
const agentPart = this.getMentionedAgent(parsedRequest);
|
|
233
293
|
if (agentPart) {
|
|
234
294
|
return this.chatAgentService.getAgent(agentPart.agentId);
|
|
235
295
|
}
|
|
296
|
+
let chatAgent = undefined;
|
|
236
297
|
if (this.defaultChatAgentId) {
|
|
237
|
-
|
|
298
|
+
chatAgent = this.chatAgentService.getAgent(this.defaultChatAgentId.id);
|
|
299
|
+
}
|
|
300
|
+
if (!chatAgent && this.fallbackChatAgentId) {
|
|
301
|
+
chatAgent = this.chatAgentService.getAgent(this.fallbackChatAgentId.id);
|
|
302
|
+
}
|
|
303
|
+
if (chatAgent) {
|
|
304
|
+
return chatAgent;
|
|
238
305
|
}
|
|
306
|
+
this.logger.warn('Neither the default chat agent nor the fallback chat agent are configured or available. Falling back to the first registered agent');
|
|
239
307
|
return this.chatAgentService.getAgents()[0] ?? undefined;
|
|
240
308
|
}
|
|
241
309
|
|
|
@@ -244,10 +312,10 @@ export class ChatServiceImpl implements ChatService {
|
|
|
244
312
|
}
|
|
245
313
|
|
|
246
314
|
deleteChangeSet(sessionId: string): void {
|
|
247
|
-
this.getSession(sessionId)?.model.
|
|
315
|
+
this.getSession(sessionId)?.model.removeChangeSet();
|
|
248
316
|
}
|
|
249
317
|
|
|
250
318
|
deleteChangeSetElement(sessionId: string, index: number): void {
|
|
251
|
-
this.getSession(sessionId)?.model.changeSet?.
|
|
319
|
+
this.getSession(sessionId)?.model.changeSet?.removeElements(index);
|
|
252
320
|
}
|
|
253
321
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
export function stringJsonCodeBlock(input: string): string {
|
|
18
|
+
return `\`\`\`json\n${input}\n\`\`\``;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function dataToJsonCodeBlock(input: unknown): string {
|
|
22
|
+
return stringJsonCodeBlock(JSON.stringify(input, undefined, 2));
|
|
23
|
+
}
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
|
|
17
17
|
import { ToolRequest } from '@theia/ai-core';
|
|
18
18
|
import { injectable } from '@theia/core/shared/inversify';
|
|
19
|
-
import {
|
|
19
|
+
import { MutableChatRequestModel } from './chat-model';
|
|
20
20
|
|
|
21
21
|
export interface ChatToolRequest extends ToolRequest {
|
|
22
22
|
handler: (
|
|
23
23
|
arg_string: string,
|
|
24
|
-
context:
|
|
24
|
+
context: MutableChatRequestModel,
|
|
25
25
|
) => Promise<unknown>;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -34,7 +34,7 @@ export interface ChatToolRequest extends ToolRequest {
|
|
|
34
34
|
@injectable()
|
|
35
35
|
export class ChatToolRequestService {
|
|
36
36
|
|
|
37
|
-
getChatToolRequests(request:
|
|
37
|
+
getChatToolRequests(request: MutableChatRequestModel): ChatToolRequest[] {
|
|
38
38
|
const toolRequests = request.message.toolRequests.size > 0 ? [...request.message.toolRequests.values()] : undefined;
|
|
39
39
|
if (!toolRequests) {
|
|
40
40
|
return [];
|
|
@@ -42,14 +42,14 @@ export class ChatToolRequestService {
|
|
|
42
42
|
return this.toChatToolRequests(toolRequests, request);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
toChatToolRequests(toolRequests: ToolRequest[] | undefined, request:
|
|
45
|
+
toChatToolRequests(toolRequests: ToolRequest[] | undefined, request: MutableChatRequestModel): ChatToolRequest[] {
|
|
46
46
|
if (!toolRequests) {
|
|
47
47
|
return [];
|
|
48
48
|
}
|
|
49
49
|
return toolRequests.map(toolRequest => this.toChatToolRequest(toolRequest, request));
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
protected toChatToolRequest(toolRequest: ToolRequest, request:
|
|
52
|
+
protected toChatToolRequest(toolRequest: ToolRequest, request: MutableChatRequestModel): ChatToolRequest {
|
|
53
53
|
return {
|
|
54
54
|
...toolRequest,
|
|
55
55
|
handler: async (arg_string: string) => toolRequest.handler(arg_string, request)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { MaybePromise, nls } from '@theia/core';
|
|
18
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { AIVariable, ResolvedAIVariable, AIVariableContribution, AIVariableResolver, AIVariableService, AIVariableResolutionRequest, AIVariableContext } from '@theia/ai-core';
|
|
20
|
+
import { dataToJsonCodeBlock } from './chat-string-utils';
|
|
21
|
+
import { ChatSessionContext } from './chat-agents';
|
|
22
|
+
import { CHAT_CONTEXT_DETAILS_VARIABLE_ID } from './context-variables';
|
|
23
|
+
|
|
24
|
+
export const CONTEXT_DETAILS_VARIABLE: AIVariable = {
|
|
25
|
+
id: CHAT_CONTEXT_DETAILS_VARIABLE_ID,
|
|
26
|
+
description: nls.localize('theia/ai/core/contextDetailsVariable/description', 'Provides full text values and descriptions for all context elements.'),
|
|
27
|
+
name: CHAT_CONTEXT_DETAILS_VARIABLE_ID,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
@injectable()
|
|
31
|
+
export class ContextDetailsVariableContribution implements AIVariableContribution, AIVariableResolver {
|
|
32
|
+
registerVariables(service: AIVariableService): void {
|
|
33
|
+
service.registerResolver(CONTEXT_DETAILS_VARIABLE, this);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
canResolve(request: AIVariableResolutionRequest, context: AIVariableContext): MaybePromise<number> {
|
|
37
|
+
return request.variable.name === CONTEXT_DETAILS_VARIABLE.name ? 50 : 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async resolve(request: AIVariableResolutionRequest, context: AIVariableContext): Promise<ResolvedAIVariable | undefined> {
|
|
41
|
+
/** By expecting context.request, we're assuming that this variable will not be resolved until the context has been resolved. */
|
|
42
|
+
if (!ChatSessionContext.is(context) || request.variable.name !== CONTEXT_DETAILS_VARIABLE.name || !context.request) { return undefined; }
|
|
43
|
+
const data = context.request.context.variables.map(variable => ({
|
|
44
|
+
type: variable.variable.name,
|
|
45
|
+
ref: variable.value,
|
|
46
|
+
content: variable.contextValue
|
|
47
|
+
}));
|
|
48
|
+
return {
|
|
49
|
+
variable: CONTEXT_DETAILS_VARIABLE,
|
|
50
|
+
value: dataToJsonCodeBlock(data)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { MaybePromise, nls } from '@theia/core';
|
|
18
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { AIVariable, ResolvedAIVariable, AIVariableContribution, AIVariableResolver, AIVariableService, AIVariableResolutionRequest, AIVariableContext } from '@theia/ai-core';
|
|
20
|
+
import { dataToJsonCodeBlock } from './chat-string-utils';
|
|
21
|
+
import { ChatSessionContext } from './chat-agents';
|
|
22
|
+
|
|
23
|
+
export const CONTEXT_SUMMARY_VARIABLE: AIVariable = {
|
|
24
|
+
id: 'contextSummary',
|
|
25
|
+
description: nls.localize('theia/ai/core/contextSummaryVariable/description', 'Describes files in the context for a given session.'),
|
|
26
|
+
name: 'contextSummary',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
@injectable()
|
|
30
|
+
export class ContextSummaryVariableContribution implements AIVariableContribution, AIVariableResolver {
|
|
31
|
+
registerVariables(service: AIVariableService): void {
|
|
32
|
+
service.registerResolver(CONTEXT_SUMMARY_VARIABLE, this);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
canResolve(request: AIVariableResolutionRequest, context: AIVariableContext): MaybePromise<number> {
|
|
36
|
+
return request.variable.name === CONTEXT_SUMMARY_VARIABLE.name ? 50 : 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async resolve(request: AIVariableResolutionRequest, context: AIVariableContext): Promise<ResolvedAIVariable | undefined> {
|
|
40
|
+
if (!ChatSessionContext.is(context) || request.variable.name !== CONTEXT_SUMMARY_VARIABLE.name) { return undefined; }
|
|
41
|
+
const data = context.model.context.getVariables().filter(variable => variable.variable.isContextVariable)
|
|
42
|
+
.map(variable => ({
|
|
43
|
+
type: variable.variable.name,
|
|
44
|
+
// eslint-disable-next-line no-null/no-null
|
|
45
|
+
instanceData: variable.arg || null,
|
|
46
|
+
contextElementId: variable.variable.id + variable.arg
|
|
47
|
+
}));
|
|
48
|
+
return {
|
|
49
|
+
variable: CONTEXT_SUMMARY_VARIABLE,
|
|
50
|
+
value: dataToJsonCodeBlock(data)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
export const CHAT_CONTEXT_VARIABLE_ID = 'contextSummary';
|
|
18
|
+
export const CHAT_CONTEXT_DETAILS_VARIABLE_ID = 'contextDetails';
|
|
19
|
+
export const CHANGE_SET_SUMMARY_VARIABLE_ID = 'changeSetSummary';
|
|
@@ -14,31 +14,20 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
import { AbstractStreamParsingChatAgent
|
|
17
|
+
import { LanguageModelRequirement } from '@theia/ai-core';
|
|
18
|
+
import { AbstractStreamParsingChatAgent } from './chat-agents';
|
|
19
19
|
import { injectable } from '@theia/core/shared/inversify';
|
|
20
20
|
|
|
21
21
|
@injectable()
|
|
22
|
-
export class CustomChatAgent
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
readonly variables: string[] = [];
|
|
28
|
-
readonly functions: string[] = [];
|
|
29
|
-
readonly promptTemplates: PromptTemplate[] = [];
|
|
30
|
-
readonly agentSpecificVariables: AgentSpecificVariables[] = [];
|
|
31
|
-
|
|
32
|
-
constructor(
|
|
33
|
-
) {
|
|
34
|
-
super('CustomChatAgent', [{ purpose: 'chat' }], 'chat');
|
|
35
|
-
}
|
|
36
|
-
protected override async getSystemMessageDescription(): Promise<SystemMessageDescription | undefined> {
|
|
37
|
-
const resolvedPrompt = await this.promptService.getPrompt(`${this.name}_prompt`);
|
|
38
|
-
return resolvedPrompt ? SystemMessageDescription.fromResolvedPromptTemplate(resolvedPrompt) : undefined;
|
|
39
|
-
}
|
|
22
|
+
export class CustomChatAgent extends AbstractStreamParsingChatAgent {
|
|
23
|
+
id: string = 'CustomChatAgent';
|
|
24
|
+
name: string = 'CustomChatAgent';
|
|
25
|
+
languageModelRequirements: LanguageModelRequirement[] = [{ purpose: 'chat' }];
|
|
26
|
+
protected defaultLanguageModelPurpose: string = 'chat';
|
|
40
27
|
|
|
41
28
|
set prompt(prompt: string) {
|
|
29
|
+
// the name is dynamic, so we set the propmptId here
|
|
30
|
+
this.systemPromptId = `${this.name}_prompt`;
|
|
42
31
|
this.promptTemplates.push({ id: `${this.name}_prompt`, template: prompt });
|
|
43
32
|
}
|
|
44
33
|
}
|
package/src/common/index.ts
CHANGED
|
@@ -19,8 +19,6 @@ export * from './chat-model';
|
|
|
19
19
|
export * from './chat-model-util';
|
|
20
20
|
export * from './chat-request-parser';
|
|
21
21
|
export * from './chat-service';
|
|
22
|
-
export * from './command-chat-agents';
|
|
23
22
|
export * from './custom-chat-agent';
|
|
24
23
|
export * from './parsed-chat-request';
|
|
25
|
-
export * from './
|
|
26
|
-
export * from './universal-chat-agent';
|
|
24
|
+
export * from './context-variables';
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { expect } from 'chai';
|
|
18
|
-
import {
|
|
18
|
+
import { MutableChatRequestModel, ChatResponseContent, CodeChatResponseContentImpl, MarkdownChatResponseContentImpl } from './chat-model';
|
|
19
19
|
import { parseContents } from './parse-contents';
|
|
20
20
|
import { CodeContentMatcher, ResponseContentMatcher } from './response-content-matcher';
|
|
21
21
|
|
|
@@ -33,7 +33,7 @@ export const CommandContentMatcher: ResponseContentMatcher = {
|
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
const fakeRequest = {} as
|
|
36
|
+
const fakeRequest = {} as MutableChatRequestModel;
|
|
37
37
|
|
|
38
38
|
describe('parseContents', () => {
|
|
39
39
|
it('should parse code content', () => {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
16
|
+
import { MutableChatRequestModel, ChatResponseContent } from './chat-model';
|
|
17
17
|
import { CodeContentMatcher, MarkdownContentFactory, ResponseContentFactory, ResponseContentMatcher } from './response-content-matcher';
|
|
18
18
|
|
|
19
19
|
interface Match {
|
|
@@ -24,7 +24,7 @@ interface Match {
|
|
|
24
24
|
|
|
25
25
|
export function parseContents(
|
|
26
26
|
text: string,
|
|
27
|
-
request:
|
|
27
|
+
request: MutableChatRequestModel,
|
|
28
28
|
contentMatchers: ResponseContentMatcher[] = [CodeContentMatcher],
|
|
29
29
|
defaultContentFactory: ResponseContentFactory = MarkdownContentFactory
|
|
30
30
|
): ChatResponseContent[] {
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
*/
|
|
16
16
|
import {
|
|
17
|
-
|
|
17
|
+
MutableChatRequestModel,
|
|
18
18
|
ChatResponseContent,
|
|
19
19
|
CodeChatResponseContentImpl,
|
|
20
20
|
MarkdownChatResponseContentImpl
|
|
21
21
|
} from './chat-model';
|
|
22
22
|
import { injectable } from '@theia/core/shared/inversify';
|
|
23
23
|
|
|
24
|
-
export type ResponseContentFactory = (content: string, request:
|
|
24
|
+
export type ResponseContentFactory = (content: string, request: MutableChatRequestModel) => ChatResponseContent;
|
|
25
25
|
|
|
26
26
|
export const MarkdownContentFactory: ResponseContentFactory = (content: string) =>
|
|
27
27
|
new MarkdownChatResponseContentImpl(content);
|
|
@@ -34,7 +34,7 @@ export const MarkdownContentFactory: ResponseContentFactory = (content: string)
|
|
|
34
34
|
*/
|
|
35
35
|
@injectable()
|
|
36
36
|
export class DefaultResponseContentFactory {
|
|
37
|
-
create(content: string, request:
|
|
37
|
+
create(content: string, request: MutableChatRequestModel): ChatResponseContent {
|
|
38
38
|
return MarkdownContentFactory(content, request);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { AbstractTextToModelParsingChatAgent, ChatAgent, SystemMessageDescription } from './chat-agents';
|
|
2
|
-
import { PromptTemplate, AgentSpecificVariables } from '@theia/ai-core';
|
|
3
|
-
import { ChatRequestModelImpl, ChatResponseContent } from './chat-model';
|
|
4
|
-
import { CommandRegistry, MessageService } from '@theia/core';
|
|
5
|
-
export declare const commandTemplate: PromptTemplate;
|
|
6
|
-
interface ParsedCommand {
|
|
7
|
-
type: 'theia-command' | 'custom-handler' | 'no-command';
|
|
8
|
-
commandId: string;
|
|
9
|
-
arguments?: string[];
|
|
10
|
-
message?: string;
|
|
11
|
-
}
|
|
12
|
-
export declare class CommandChatAgent extends AbstractTextToModelParsingChatAgent<ParsedCommand> implements ChatAgent {
|
|
13
|
-
protected commandRegistry: CommandRegistry;
|
|
14
|
-
protected messageService: MessageService;
|
|
15
|
-
readonly name: string;
|
|
16
|
-
readonly description: string;
|
|
17
|
-
readonly variables: string[];
|
|
18
|
-
readonly promptTemplates: PromptTemplate[];
|
|
19
|
-
readonly functions: string[];
|
|
20
|
-
readonly agentSpecificVariables: AgentSpecificVariables[];
|
|
21
|
-
constructor();
|
|
22
|
-
protected getSystemMessageDescription(): Promise<SystemMessageDescription | undefined>;
|
|
23
|
-
/**
|
|
24
|
-
* @param text the text received from the language model
|
|
25
|
-
* @returns the parsed command if the text contained a valid command.
|
|
26
|
-
* If there was no json in the text, return a no-command response.
|
|
27
|
-
*/
|
|
28
|
-
protected parseTextResponse(text: string): Promise<ParsedCommand>;
|
|
29
|
-
protected createResponseContent(parsedCommand: ParsedCommand, request: ChatRequestModelImpl): ChatResponseContent;
|
|
30
|
-
protected commandCallback(...commandArgs: unknown[]): Promise<void>;
|
|
31
|
-
}
|
|
32
|
-
export {};
|
|
33
|
-
//# sourceMappingURL=command-chat-agents.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"command-chat-agents.d.ts","sourceRoot":"","sources":["../../src/common/command-chat-agents.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,mCAAmC,EAAE,SAAS,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EACH,cAAc,EACd,sBAAsB,EACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACH,oBAAoB,EACpB,mBAAmB,EAKtB,MAAM,cAAc,CAAC;AACtB,OAAO,EACH,eAAe,EACf,cAAc,EAEjB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,eAAe,EAAE,cA8M5B,CAAC;AAEH,UAAU,aAAa;IACnB,IAAI,EAAE,eAAe,GAAG,gBAAgB,GAAG,YAAY,CAAA;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBACa,gBAAiB,SAAQ,mCAAmC,CAAC,aAAa,CAAE,YAAW,SAAS;IAEzG,SAAS,CAAC,eAAe,EAAE,eAAe,CAAC;IAE3C,SAAS,CAAC,cAAc,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,EAAE,CAAC;;cAqB1C,2BAA2B,IAAI,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC;IAc5F;;;;OAIG;cACa,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAUvE,SAAS,CAAC,qBAAqB,CAAC,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,oBAAoB,GAAG,mBAAmB;cAqCjG,eAAe,CAAC,GAAG,WAAW,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAI5E"}
|