@theia/ai-chat 1.55.0-next.4 → 1.55.0
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 +25 -2
- package/lib/browser/ai-chat-frontend-module.js.map +1 -1
- package/lib/browser/custom-agent-factory.d.ts +4 -0
- package/lib/browser/custom-agent-factory.d.ts.map +1 -0
- package/lib/browser/custom-agent-factory.js +20 -0
- package/lib/browser/custom-agent-factory.js.map +1 -0
- package/lib/browser/custom-agent-frontend-application-contribution.d.ts +13 -0
- package/lib/browser/custom-agent-frontend-application-contribution.d.ts.map +1 -0
- package/lib/browser/custom-agent-frontend-application-contribution.js +82 -0
- package/lib/browser/custom-agent-frontend-application-contribution.js.map +1 -0
- package/lib/common/chat-agent-service.d.ts +11 -0
- package/lib/common/chat-agent-service.d.ts.map +1 -1
- package/lib/common/chat-agent-service.js +3 -0
- package/lib/common/chat-agent-service.js.map +1 -1
- package/lib/common/chat-agents-variable-contribution.d.ts +1 -1
- package/lib/common/chat-agents-variable-contribution.d.ts.map +1 -1
- package/lib/common/chat-agents.d.ts +8 -1
- package/lib/common/chat-agents.d.ts.map +1 -1
- package/lib/common/chat-agents.js +48 -31
- package/lib/common/chat-agents.js.map +1 -1
- package/lib/common/chat-model.d.ts +14 -1
- package/lib/common/chat-model.d.ts.map +1 -1
- package/lib/common/chat-model.js +11 -1
- package/lib/common/chat-model.js.map +1 -1
- package/lib/common/custom-chat-agent.d.ts +14 -0
- package/lib/common/custom-chat-agent.d.ts.map +1 -0
- package/lib/common/custom-chat-agent.js +43 -0
- package/lib/common/custom-chat-agent.js.map +1 -0
- package/lib/common/index.d.ts +4 -3
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +4 -3
- package/lib/common/index.js.map +1 -1
- package/lib/common/o1-chat-agent.d.ts +13 -0
- package/lib/common/o1-chat-agent.d.ts.map +1 -0
- package/lib/common/o1-chat-agent.js +45 -0
- package/lib/common/o1-chat-agent.js.map +1 -0
- package/lib/common/orchestrator-chat-agent.d.ts.map +1 -1
- package/lib/common/orchestrator-chat-agent.js +28 -3
- package/lib/common/orchestrator-chat-agent.js.map +1 -1
- package/package.json +8 -8
- package/src/browser/ai-chat-frontend-module.ts +30 -4
- package/src/browser/custom-agent-factory.ts +20 -0
- package/src/browser/custom-agent-frontend-application-contribution.ts +73 -0
- package/src/common/chat-agent-service.ts +15 -0
- package/src/common/chat-agents-variable-contribution.ts +1 -1
- package/src/common/chat-agents.ts +49 -30
- package/src/common/chat-model.ts +17 -1
- package/src/common/custom-chat-agent.ts +44 -0
- package/src/common/index.ts +4 -3
- package/src/common/o1-chat-agent.ts +51 -0
- package/src/common/orchestrator-chat-agent.ts +29 -4
|
@@ -137,7 +137,8 @@ export abstract class AbstractChatAgent {
|
|
|
137
137
|
protected defaultLanguageModelPurpose: string,
|
|
138
138
|
public iconClass: string = 'codicon codicon-copilot',
|
|
139
139
|
public locations: ChatAgentLocation[] = ChatAgentLocation.ALL,
|
|
140
|
-
public tags: String[] = ['Chat']
|
|
140
|
+
public tags: String[] = ['Chat'],
|
|
141
|
+
public defaultLogging: boolean = true) {
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
@postConstruct()
|
|
@@ -152,14 +153,16 @@ export abstract class AbstractChatAgent {
|
|
|
152
153
|
throw new Error('Couldn\'t find a matching language model. Please check your setup!');
|
|
153
154
|
}
|
|
154
155
|
const messages = await this.getMessages(request.session);
|
|
155
|
-
this.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
if (this.defaultLogging) {
|
|
157
|
+
this.recordingService.recordRequest({
|
|
158
|
+
agentId: this.id,
|
|
159
|
+
sessionId: request.session.id,
|
|
160
|
+
timestamp: Date.now(),
|
|
161
|
+
requestId: request.id,
|
|
162
|
+
request: request.request.text,
|
|
163
|
+
messages
|
|
164
|
+
});
|
|
165
|
+
}
|
|
163
166
|
|
|
164
167
|
const systemMessageDescription = await this.getSystemMessageDescription();
|
|
165
168
|
const tools: Map<string, ToolRequest> = new Map();
|
|
@@ -192,13 +195,15 @@ export abstract class AbstractChatAgent {
|
|
|
192
195
|
);
|
|
193
196
|
await this.addContentsToResponse(languageModelResponse, request);
|
|
194
197
|
request.response.complete();
|
|
195
|
-
this.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
if (this.defaultLogging) {
|
|
199
|
+
this.recordingService.recordResponse({
|
|
200
|
+
agentId: this.id,
|
|
201
|
+
sessionId: request.session.id,
|
|
202
|
+
timestamp: Date.now(),
|
|
203
|
+
requestId: request.response.requestId,
|
|
204
|
+
response: request.response.response.asString()
|
|
205
|
+
});
|
|
206
|
+
}
|
|
202
207
|
} catch (e) {
|
|
203
208
|
this.handleError(request, e);
|
|
204
209
|
}
|
|
@@ -274,13 +279,22 @@ export abstract class AbstractChatAgent {
|
|
|
274
279
|
tools: ToolRequest[] | undefined,
|
|
275
280
|
token: CancellationToken
|
|
276
281
|
): Promise<LanguageModelResponse> {
|
|
282
|
+
const settings = this.getLlmSettings();
|
|
277
283
|
const languageModelResponse = languageModel.request({
|
|
278
284
|
messages,
|
|
279
285
|
tools,
|
|
286
|
+
settings,
|
|
280
287
|
}, token);
|
|
281
288
|
return languageModelResponse;
|
|
282
289
|
}
|
|
283
290
|
|
|
291
|
+
/**
|
|
292
|
+
* @returns the settings, such as `temperature`, to be used in all language model requests. Returns `undefined` by default.
|
|
293
|
+
*/
|
|
294
|
+
protected getLlmSettings(): { [key: string]: unknown; } | undefined {
|
|
295
|
+
return undefined;
|
|
296
|
+
}
|
|
297
|
+
|
|
284
298
|
protected abstract addContentsToResponse(languageModelResponse: LanguageModelResponse, request: ChatRequestModelImpl): Promise<void>;
|
|
285
299
|
}
|
|
286
300
|
|
|
@@ -307,25 +321,30 @@ export abstract class AbstractStreamParsingChatAgent extends AbstractChatAgent {
|
|
|
307
321
|
const contents = this.parseContents(languageModelResponse.text);
|
|
308
322
|
request.response.response.addContents(contents);
|
|
309
323
|
request.response.complete();
|
|
310
|
-
this.
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
324
|
+
if (this.defaultLogging) {
|
|
325
|
+
this.recordingService.recordResponse({
|
|
326
|
+
agentId: this.id,
|
|
327
|
+
sessionId: request.session.id,
|
|
328
|
+
timestamp: Date.now(),
|
|
329
|
+
requestId: request.response.requestId,
|
|
330
|
+
response: request.response.response.asString()
|
|
331
|
+
|
|
332
|
+
});
|
|
333
|
+
}
|
|
317
334
|
return;
|
|
318
335
|
}
|
|
319
336
|
if (isLanguageModelStreamResponse(languageModelResponse)) {
|
|
320
337
|
await this.addStreamResponse(languageModelResponse, request);
|
|
321
338
|
request.response.complete();
|
|
322
|
-
this.
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
339
|
+
if (this.defaultLogging) {
|
|
340
|
+
this.recordingService.recordResponse({
|
|
341
|
+
agentId: this.id,
|
|
342
|
+
sessionId: request.session.id,
|
|
343
|
+
timestamp: Date.now(),
|
|
344
|
+
requestId: request.response.requestId,
|
|
345
|
+
response: request.response.response.asString()
|
|
346
|
+
});
|
|
347
|
+
}
|
|
329
348
|
return;
|
|
330
349
|
}
|
|
331
350
|
this.logger.error(
|
package/src/common/chat-model.ts
CHANGED
|
@@ -73,6 +73,7 @@ export interface ChatRequestModel {
|
|
|
73
73
|
readonly response: ChatResponseModel;
|
|
74
74
|
readonly message: ParsedChatRequest;
|
|
75
75
|
readonly agentId?: string;
|
|
76
|
+
readonly data?: { [key: string]: unknown };
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export interface ChatProgressMessage {
|
|
@@ -342,14 +343,29 @@ export class ChatRequestModelImpl implements ChatRequestModel {
|
|
|
342
343
|
protected _request: ChatRequest;
|
|
343
344
|
protected _response: ChatResponseModelImpl;
|
|
344
345
|
protected _agentId?: string;
|
|
346
|
+
protected _data: { [key: string]: unknown };
|
|
345
347
|
|
|
346
|
-
constructor(session: ChatModel, public readonly message: ParsedChatRequest, agentId?: string
|
|
348
|
+
constructor(session: ChatModel, public readonly message: ParsedChatRequest, agentId?: string,
|
|
349
|
+
data: { [key: string]: unknown } = {}) {
|
|
347
350
|
// TODO accept serialized data as a parameter to restore a previously saved ChatRequestModel
|
|
348
351
|
this._request = message.request;
|
|
349
352
|
this._id = generateUuid();
|
|
350
353
|
this._session = session;
|
|
351
354
|
this._response = new ChatResponseModelImpl(this._id, agentId);
|
|
352
355
|
this._agentId = agentId;
|
|
356
|
+
this._data = data;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
get data(): { [key: string]: unknown } | undefined {
|
|
360
|
+
return this._data;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
addData(key: string, value: unknown): void {
|
|
364
|
+
this._data[key] = value;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
getDataByKey(key: string): unknown {
|
|
368
|
+
return this._data[key];
|
|
353
369
|
}
|
|
354
370
|
|
|
355
371
|
get id(): string {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 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 { AgentSpecificVariables, PromptTemplate } from '@theia/ai-core';
|
|
18
|
+
import { AbstractStreamParsingChatAgent, ChatAgent, SystemMessageDescription } from './chat-agents';
|
|
19
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
20
|
+
|
|
21
|
+
@injectable()
|
|
22
|
+
export class CustomChatAgent
|
|
23
|
+
extends AbstractStreamParsingChatAgent
|
|
24
|
+
implements ChatAgent {
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
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
|
+
}
|
|
40
|
+
|
|
41
|
+
set prompt(prompt: string) {
|
|
42
|
+
this.promptTemplates.push({ id: `${this.name}_prompt`, template: prompt });
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/common/index.ts
CHANGED
|
@@ -13,12 +13,13 @@
|
|
|
13
13
|
//
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
|
-
export * from './chat-agent-service';
|
|
17
16
|
export * from './chat-agents';
|
|
17
|
+
export * from './chat-agent-service';
|
|
18
18
|
export * from './chat-model';
|
|
19
|
-
export * from './parsed-chat-request';
|
|
20
19
|
export * from './chat-request-parser';
|
|
21
20
|
export * from './chat-service';
|
|
22
21
|
export * from './command-chat-agents';
|
|
23
|
-
export * from './
|
|
22
|
+
export * from './custom-chat-agent';
|
|
23
|
+
export * from './parsed-chat-request';
|
|
24
24
|
export * from './orchestrator-chat-agent';
|
|
25
|
+
export * from './universal-chat-agent';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 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 {
|
|
18
|
+
ChatAgent,
|
|
19
|
+
AbstractStreamParsingChatAgent,
|
|
20
|
+
SystemMessageDescription
|
|
21
|
+
} from './chat-agents';
|
|
22
|
+
|
|
23
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
24
|
+
import { AgentSpecificVariables, PromptTemplate } from '@theia/ai-core';
|
|
25
|
+
|
|
26
|
+
@injectable()
|
|
27
|
+
export class O1ChatAgent extends AbstractStreamParsingChatAgent implements ChatAgent {
|
|
28
|
+
|
|
29
|
+
public name = 'O1-Preview';
|
|
30
|
+
public description = 'An agent for interacting with ChatGPT o1-preview';
|
|
31
|
+
public promptTemplates: PromptTemplate[] = [];
|
|
32
|
+
readonly agentSpecificVariables: AgentSpecificVariables[] = [];
|
|
33
|
+
readonly variables: string[] = [];
|
|
34
|
+
readonly functions: string[] = [];
|
|
35
|
+
|
|
36
|
+
constructor() {
|
|
37
|
+
super(
|
|
38
|
+
'o1-preview',
|
|
39
|
+
[{
|
|
40
|
+
purpose: 'chat',
|
|
41
|
+
identifier: 'openai/o1-preview',
|
|
42
|
+
}],
|
|
43
|
+
'chat'
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected async getSystemMessageDescription(): Promise<SystemMessageDescription | undefined> {
|
|
48
|
+
// O1 currently does not support system prompts
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { AgentSpecificVariables,
|
|
17
|
+
import { AgentSpecificVariables, getJsonOfText, getTextOfResponse, LanguageModelResponse } from '@theia/ai-core';
|
|
18
18
|
import {
|
|
19
19
|
PromptTemplate
|
|
20
20
|
} from '@theia/ai-core/lib/common';
|
|
@@ -22,6 +22,7 @@ import { inject, injectable } from '@theia/core/shared/inversify';
|
|
|
22
22
|
import { ChatAgentService } from './chat-agent-service';
|
|
23
23
|
import { AbstractStreamParsingChatAgent, ChatAgent, SystemMessageDescription } from './chat-agents';
|
|
24
24
|
import { ChatRequestModelImpl, InformationalChatResponseContentImpl } from './chat-model';
|
|
25
|
+
import { generateUuid } from '@theia/core';
|
|
25
26
|
|
|
26
27
|
export const orchestratorTemplate: PromptTemplate = {
|
|
27
28
|
id: 'orchestrator-system',
|
|
@@ -59,6 +60,7 @@ You must only use the \`id\` attribute of the agent, never the name.
|
|
|
59
60
|
`};
|
|
60
61
|
|
|
61
62
|
export const OrchestratorChatAgentId = 'Orchestrator';
|
|
63
|
+
const OrchestatorRequestIdKey = 'orchestatorRequestIdKey';
|
|
62
64
|
|
|
63
65
|
@injectable()
|
|
64
66
|
export class OrchestratorChatAgent extends AbstractStreamParsingChatAgent implements ChatAgent {
|
|
@@ -74,7 +76,7 @@ export class OrchestratorChatAgent extends AbstractStreamParsingChatAgent implem
|
|
|
74
76
|
super(OrchestratorChatAgentId, [{
|
|
75
77
|
purpose: 'agent-selection',
|
|
76
78
|
identifier: 'openai/gpt-4o',
|
|
77
|
-
}], 'agent-selection', 'codicon codicon-symbol-boolean');
|
|
79
|
+
}], 'agent-selection', 'codicon codicon-symbol-boolean', undefined, undefined, false);
|
|
78
80
|
this.name = OrchestratorChatAgentId;
|
|
79
81
|
this.description = 'This agent analyzes the user request against the description of all available chat agents and selects the best fitting agent to answer the request \
|
|
80
82
|
(by using AI).The user\'s request will be directly delegated to the selected agent without further confirmation.';
|
|
@@ -88,8 +90,19 @@ export class OrchestratorChatAgent extends AbstractStreamParsingChatAgent implem
|
|
|
88
90
|
@inject(ChatAgentService)
|
|
89
91
|
protected chatAgentService: ChatAgentService;
|
|
90
92
|
|
|
91
|
-
override invoke(request: ChatRequestModelImpl): Promise<void> {
|
|
93
|
+
override async invoke(request: ChatRequestModelImpl): Promise<void> {
|
|
92
94
|
request.response.addProgressMessage({ content: 'Determining the most appropriate agent', status: 'inProgress' });
|
|
95
|
+
// We generate a dedicated ID for recording the orchestrator request/response, as we will forward the original request to another agent
|
|
96
|
+
const orchestartorRequestId = generateUuid();
|
|
97
|
+
request.addData(OrchestatorRequestIdKey, orchestartorRequestId);
|
|
98
|
+
const userPrompt = request.request.text;
|
|
99
|
+
this.recordingService.recordRequest({
|
|
100
|
+
agentId: this.id,
|
|
101
|
+
sessionId: request.session.id,
|
|
102
|
+
timestamp: Date.now(),
|
|
103
|
+
requestId: orchestartorRequestId,
|
|
104
|
+
request: userPrompt,
|
|
105
|
+
});
|
|
93
106
|
return super.invoke(request);
|
|
94
107
|
}
|
|
95
108
|
|
|
@@ -100,8 +113,20 @@ export class OrchestratorChatAgent extends AbstractStreamParsingChatAgent implem
|
|
|
100
113
|
|
|
101
114
|
protected override async addContentsToResponse(response: LanguageModelResponse, request: ChatRequestModelImpl): Promise<void> {
|
|
102
115
|
let agentIds: string[] = [];
|
|
116
|
+
const responseText = await getTextOfResponse(response);
|
|
117
|
+
// We use the previously generated, dedicated ID to log the orchestrator response before we forward the original request
|
|
118
|
+
const orchestratorRequestId = request.getDataByKey(OrchestatorRequestIdKey);
|
|
119
|
+
if (typeof orchestratorRequestId === 'string') {
|
|
120
|
+
this.recordingService.recordResponse({
|
|
121
|
+
agentId: this.id,
|
|
122
|
+
sessionId: request.session.id,
|
|
123
|
+
timestamp: Date.now(),
|
|
124
|
+
requestId: orchestratorRequestId,
|
|
125
|
+
response: responseText,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
103
128
|
try {
|
|
104
|
-
const jsonResponse = await
|
|
129
|
+
const jsonResponse = await getJsonOfText(responseText);
|
|
105
130
|
if (Array.isArray(jsonResponse)) {
|
|
106
131
|
agentIds = jsonResponse.filter((id: string) => id !== this.id);
|
|
107
132
|
}
|