@theia/ai-chat 1.60.0-next.47 → 1.60.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.
Files changed (38) hide show
  1. package/lib/browser/ai-chat-frontend-module.d.ts.map +1 -1
  2. package/lib/browser/ai-chat-frontend-module.js +4 -0
  3. package/lib/browser/ai-chat-frontend-module.js.map +1 -1
  4. package/lib/browser/file-chat-variable-contribution.d.ts +1 -1
  5. package/lib/browser/file-chat-variable-contribution.d.ts.map +1 -1
  6. package/lib/browser/file-chat-variable-contribution.js +4 -3
  7. package/lib/browser/file-chat-variable-contribution.js.map +1 -1
  8. package/lib/common/chat-agents.d.ts +8 -19
  9. package/lib/common/chat-agents.d.ts.map +1 -1
  10. package/lib/common/chat-agents.js +59 -35
  11. package/lib/common/chat-agents.js.map +1 -1
  12. package/lib/common/chat-model.d.ts +41 -4
  13. package/lib/common/chat-model.d.ts.map +1 -1
  14. package/lib/common/chat-model.js +89 -1
  15. package/lib/common/chat-model.js.map +1 -1
  16. package/lib/common/chat-request-parser.spec.js +10 -2
  17. package/lib/common/chat-request-parser.spec.js.map +1 -1
  18. package/lib/common/chat-service.d.ts +20 -4
  19. package/lib/common/chat-service.d.ts.map +1 -1
  20. package/lib/common/chat-service.js +52 -5
  21. package/lib/common/chat-service.js.map +1 -1
  22. package/lib/common/chat-session-naming-service.d.ts +26 -0
  23. package/lib/common/chat-session-naming-service.d.ts.map +1 -0
  24. package/lib/common/chat-session-naming-service.js +132 -0
  25. package/lib/common/chat-session-naming-service.js.map +1 -0
  26. package/package.json +11 -11
  27. package/src/browser/ai-chat-frontend-module.ts +5 -0
  28. package/src/browser/file-chat-variable-contribution.ts +5 -3
  29. package/src/common/chat-agents.ts +85 -69
  30. package/src/common/chat-model.ts +115 -5
  31. package/src/common/chat-request-parser.spec.ts +10 -2
  32. package/src/common/chat-service.ts +63 -5
  33. package/src/common/chat-session-naming-service.ts +135 -0
  34. package/lib/common/chat-history-entry.d.ts +0 -7
  35. package/lib/common/chat-history-entry.d.ts.map +0 -1
  36. package/lib/common/chat-history-entry.js +0 -42
  37. package/lib/common/chat-history-entry.js.map +0 -1
  38. package/src/common/chat-history-entry.ts +0 -47
@@ -24,7 +24,7 @@ import { MarkdownString, MarkdownStringImpl } from '@theia/core/lib/common/markd
24
24
  import { Position } from '@theia/core/shared/vscode-languageserver-protocol';
25
25
  import { ChatAgentLocation } from './chat-agents';
26
26
  import { ParsedChatRequest } from './parsed-chat-request';
27
- import { AIVariableResolutionRequest, ResolvedAIContextVariable } from '@theia/ai-core';
27
+ import { AIVariableResolutionRequest, LanguageModelMessage, ResolvedAIContextVariable, TextMessage, ThinkingMessage, ToolResultMessage, ToolUseMessage } from '@theia/ai-core';
28
28
 
29
29
  /**********************
30
30
  * INTERFACES AND TYPE GUARDS
@@ -95,6 +95,7 @@ export interface ChatModel {
95
95
  readonly location: ChatAgentLocation;
96
96
  readonly changeSet?: ChangeSet;
97
97
  readonly context: ChatContextManager;
98
+ readonly settings?: { [key: string]: unknown };
98
99
  getRequests(): ChatRequestModel[];
99
100
  isEmpty(): boolean;
100
101
  }
@@ -197,6 +198,7 @@ export interface ChatResponseContent {
197
198
  asString?(): string | undefined;
198
199
  asDisplayString?(): string | undefined;
199
200
  merge?(nextChatResponseContent: ChatResponseContent): boolean;
201
+ toLanguageModelMessage?(): LanguageModelMessage | LanguageModelMessage[];
200
202
  }
201
203
 
202
204
  export namespace ChatResponseContent {
@@ -223,6 +225,11 @@ export namespace ChatResponseContent {
223
225
  ): obj is Required<Pick<ChatResponseContent, 'merge'>> & ChatResponseContent {
224
226
  return typeof obj.merge === 'function';
225
227
  }
228
+ export function hasToLanguageModelMessage(
229
+ obj: ChatResponseContent
230
+ ): obj is Required<Pick<ChatResponseContent, 'toLanguageModelMessage'>> & ChatResponseContent {
231
+ return typeof obj.toLanguageModelMessage === 'function';
232
+ }
226
233
  }
227
234
 
228
235
  export interface TextChatResponseContent
@@ -250,7 +257,7 @@ export interface CodeChatResponseContent
250
257
  location?: Location;
251
258
  }
252
259
 
253
- export interface HorizontalLayoutChatResponseContent extends Required<ChatResponseContent> {
260
+ export interface HorizontalLayoutChatResponseContent extends ChatResponseContent {
254
261
  kind: 'horizontal';
255
262
  content: ChatResponseContent[];
256
263
  }
@@ -264,6 +271,13 @@ export interface ToolCallChatResponseContent extends Required<ChatResponseConten
264
271
  result?: string;
265
272
  }
266
273
 
274
+ export interface ThinkingChatResponseContent
275
+ extends Required<ChatResponseContent> {
276
+ kind: 'thinking';
277
+ content: string;
278
+ signature: string;
279
+ }
280
+
267
281
  export interface Location {
268
282
  uri: URI;
269
283
  position: Position;
@@ -389,6 +403,17 @@ export namespace ErrorChatResponseContent {
389
403
  }
390
404
  }
391
405
 
406
+ export namespace ThinkingChatResponseContent {
407
+ export function is(obj: unknown): obj is ThinkingChatResponseContent {
408
+ return (
409
+ ChatResponseContent.is(obj) &&
410
+ obj.kind === 'thinking' &&
411
+ 'content' in obj &&
412
+ typeof obj.content === 'string'
413
+ );
414
+ }
415
+ }
416
+
392
417
  export type QuestionResponseHandler = (
393
418
  selectedOption: { text: string, value?: string },
394
419
  ) => void;
@@ -498,6 +523,7 @@ export class MutableChatModel implements ChatModel, Disposable {
498
523
  protected _id: string;
499
524
  protected _changeSet?: ChangeSetImpl;
500
525
  protected readonly _contextManager = new ChatContextManagerImpl();
526
+ protected _settings: { [key: string]: unknown };
501
527
 
502
528
  constructor(public readonly location = ChatAgentLocation.Panel) {
503
529
  // TODO accept serialized data as a parameter to restore a previously saved ChatModel
@@ -526,6 +552,14 @@ export class MutableChatModel implements ChatModel, Disposable {
526
552
  return this._contextManager;
527
553
  }
528
554
 
555
+ get settings(): { [key: string]: unknown } {
556
+ return this._settings;
557
+ }
558
+
559
+ setSettings(settings: { [key: string]: unknown }): void {
560
+ this._settings = settings;
561
+ }
562
+
529
563
  setChangeSet(changeSet: ChangeSetImpl | undefined): void {
530
564
  if (!changeSet) {
531
565
  return this.removeChangeSet();
@@ -714,8 +748,8 @@ export class MutableChatRequestModel implements ChatRequestModel {
714
748
  this._data[key] = value;
715
749
  }
716
750
 
717
- getDataByKey(key: string): unknown {
718
- return this._data[key];
751
+ getDataByKey<T = unknown>(key: string): T {
752
+ return this._data[key] as T;
719
753
  }
720
754
 
721
755
  get id(): string {
@@ -785,6 +819,57 @@ export class TextChatResponseContentImpl implements TextChatResponseContent {
785
819
  this._content += nextChatResponseContent.content;
786
820
  return true;
787
821
  }
822
+ toLanguageModelMessage(): TextMessage {
823
+ return {
824
+ actor: 'ai',
825
+ type: 'text',
826
+ text: this.content
827
+ };
828
+ }
829
+ }
830
+ export class ThinkingChatResponseContentImpl implements ThinkingChatResponseContent {
831
+ readonly kind = 'thinking';
832
+ protected _content: string;
833
+ protected _signature: string;
834
+
835
+ constructor(content: string, signature: string) {
836
+ this._content = content;
837
+ this._signature = signature;
838
+ }
839
+
840
+ get content(): string {
841
+ return this._content;
842
+ }
843
+ get signature(): string {
844
+ return this._signature;
845
+ }
846
+
847
+ asString(): string {
848
+ return JSON.stringify({
849
+ type: 'thinking',
850
+ thinking: this.content,
851
+ signature: this.signature
852
+ });
853
+ }
854
+
855
+ asDisplayString(): string | undefined {
856
+ return `<Thinking>${this.content}</Thinking>`;
857
+ }
858
+
859
+ merge(nextChatResponseContent: ThinkingChatResponseContent): boolean {
860
+ this._content += nextChatResponseContent.content;
861
+ this._signature += nextChatResponseContent.signature;
862
+ return true;
863
+ }
864
+
865
+ toLanguageModelMessage(): ThinkingMessage {
866
+ return {
867
+ actor: 'ai',
868
+ type: 'thinking',
869
+ thinking: this.content,
870
+ signature: this.signature
871
+ };
872
+ }
788
873
  }
789
874
 
790
875
  export class MarkdownChatResponseContentImpl implements MarkdownChatResponseContent {
@@ -811,6 +896,14 @@ export class MarkdownChatResponseContentImpl implements MarkdownChatResponseCont
811
896
  this._content.appendMarkdown(nextChatResponseContent.content.value);
812
897
  return true;
813
898
  }
899
+
900
+ toLanguageModelMessage(): TextMessage {
901
+ return {
902
+ actor: 'ai',
903
+ type: 'text',
904
+ text: this.content.value
905
+ };
906
+ }
814
907
  }
815
908
 
816
909
  export class InformationalChatResponseContentImpl implements InformationalChatResponseContent {
@@ -911,6 +1004,7 @@ export class ToolCallChatResponseContentImpl implements ToolCallChatResponseCont
911
1004
  asDisplayString(): string {
912
1005
  return `Tool call: ${this._name}(${this._arguments ?? ''})`;
913
1006
  }
1007
+
914
1008
  merge(nextChatResponseContent: ToolCallChatResponseContent): boolean {
915
1009
  if (nextChatResponseContent.id === this.id) {
916
1010
  this._finished = nextChatResponseContent.finished;
@@ -926,6 +1020,22 @@ export class ToolCallChatResponseContentImpl implements ToolCallChatResponseCont
926
1020
  this._arguments += `${nextChatResponseContent.arguments}`;
927
1021
  return true;
928
1022
  }
1023
+
1024
+ toLanguageModelMessage(): [ToolUseMessage, ToolResultMessage] {
1025
+ return [{
1026
+ actor: 'ai',
1027
+ type: 'tool_use',
1028
+ id: this.id ?? '',
1029
+ input: (this.arguments && JSON.parse(this.arguments)) ?? undefined,
1030
+ name: this.name ?? ''
1031
+ }, {
1032
+ actor: 'user',
1033
+ type: 'tool_result',
1034
+ tool_use_id: this.id ?? '',
1035
+ content: this.result,
1036
+ name: this.name ?? ''
1037
+ }];
1038
+ }
929
1039
  }
930
1040
 
931
1041
  export const COMMAND_CHAT_RESPONSE_COMMAND: Command = {
@@ -1097,7 +1207,7 @@ class ChatResponseImpl implements ChatResponse {
1097
1207
  }
1098
1208
  }
1099
1209
 
1100
- class MutableChatResponseModel implements ChatResponseModel {
1210
+ export class MutableChatResponseModel implements ChatResponseModel {
1101
1211
  protected readonly _onDidChangeEmitter = new Emitter<void>();
1102
1212
  onDidChange: Event<void> = this._onDidChangeEmitter.event;
1103
1213
 
@@ -137,12 +137,20 @@ describe('ChatRequestParserImpl', () => {
137
137
  const testTool1: ToolRequest = {
138
138
  id: 'testTool1',
139
139
  name: 'Test Tool 1',
140
- handler: async () => undefined
140
+ handler: async () => undefined,
141
+ parameters: {
142
+ type: 'object',
143
+ properties: {}
144
+ },
141
145
  };
142
146
  const testTool2: ToolRequest = {
143
147
  id: 'testTool2',
144
148
  name: 'Test Tool 2',
145
- handler: async () => undefined
149
+ handler: async () => undefined,
150
+ parameters: {
151
+ type: 'object',
152
+ properties: {}
153
+ },
146
154
  };
147
155
  // Configure the tool registry to return our test tools
148
156
  toolInvocationRegistry.getFunction.withArgs(testTool1.id).returns(testTool1);
@@ -33,9 +33,11 @@ import {
33
33
  ChatResponseModel,
34
34
  ErrorChatResponseModel,
35
35
  ChatContext,
36
+ MutableChatRequestModel,
36
37
  } from './chat-model';
37
38
  import { ChatRequestParser } from './chat-request-parser';
38
39
  import { ParsedChatRequest, ParsedChatRequestAgentPart } from './parsed-chat-request';
40
+ import { ChatSessionNamingService } from './chat-session-naming-service';
39
41
 
40
42
  export interface ChatRequestInvocation {
41
43
  /**
@@ -55,16 +57,43 @@ export interface ChatRequestInvocation {
55
57
  export interface ChatSession {
56
58
  id: string;
57
59
  title?: string;
60
+ lastInteraction?: Date;
58
61
  model: ChatModel;
59
62
  isActive: boolean;
60
63
  pinnedAgent?: ChatAgent;
61
64
  }
62
65
 
63
66
  export interface ActiveSessionChangedEvent {
67
+ type: 'activeChange';
64
68
  sessionId: string | undefined;
65
69
  focus?: boolean;
66
70
  }
67
71
 
72
+ export function isActiveSessionChangedEvent(obj: unknown): obj is ActiveSessionChangedEvent {
73
+ // eslint-disable-next-line no-null/no-null
74
+ return typeof obj === 'object' && obj !== null && 'type' in obj && obj.type === 'activeChange';
75
+ }
76
+
77
+ export interface SessionCreatedEvent {
78
+ type: 'created';
79
+ sessionId: string;
80
+ }
81
+
82
+ export function isSessionCreatedEvent(obj: unknown): obj is SessionCreatedEvent {
83
+ // eslint-disable-next-line no-null/no-null
84
+ return typeof obj === 'object' && obj !== null && 'type' in obj && obj.type === 'created';
85
+ }
86
+
87
+ export interface SessionDeletedEvent {
88
+ type: 'deleted';
89
+ sessionId: string;
90
+ }
91
+
92
+ export function isSessionDeletedEvent(obj: unknown): obj is SessionDeletedEvent {
93
+ // eslint-disable-next-line no-null/no-null
94
+ return typeof obj === 'object' && obj !== null && 'type' in obj && obj.type === 'deleted';
95
+ }
96
+
68
97
  export interface SessionOptions {
69
98
  focus?: boolean;
70
99
  }
@@ -90,7 +119,7 @@ export type PinChatAgent = boolean;
90
119
 
91
120
  export const ChatService = Symbol('ChatService');
92
121
  export interface ChatService {
93
- onActiveSessionChanged: Event<ActiveSessionChangedEvent>
122
+ onSessionEvent: Event<ActiveSessionChangedEvent | SessionCreatedEvent | SessionDeletedEvent>
94
123
 
95
124
  getSession(id: string): ChatSession | undefined;
96
125
  getSessions(): ChatSession[];
@@ -115,8 +144,8 @@ interface ChatSessionInternal extends ChatSession {
115
144
 
116
145
  @injectable()
117
146
  export class ChatServiceImpl implements ChatService {
118
- protected readonly onActiveSessionChangedEmitter = new Emitter<ActiveSessionChangedEvent>();
119
- onActiveSessionChanged = this.onActiveSessionChangedEmitter.event;
147
+ protected readonly onSessionEventEmitter = new Emitter<ActiveSessionChangedEvent | SessionCreatedEvent | SessionDeletedEvent>();
148
+ onSessionEvent = this.onSessionEventEmitter.event;
120
149
 
121
150
  @inject(ChatAgentService)
122
151
  protected chatAgentService: ChatAgentService;
@@ -127,6 +156,9 @@ export class ChatServiceImpl implements ChatService {
127
156
  @inject(FallbackChatAgentId) @optional()
128
157
  protected fallbackChatAgentId: FallbackChatAgentId | undefined;
129
158
 
159
+ @inject(ChatSessionNamingService) @optional()
160
+ protected chatSessionNamingService: ChatSessionNamingService | undefined;
161
+
130
162
  @inject(PinChatAgent) @optional()
131
163
  protected pinChatAgent: boolean | undefined;
132
164
 
@@ -159,6 +191,7 @@ export class ChatServiceImpl implements ChatService {
159
191
  };
160
192
  this._sessions.push(session);
161
193
  this.setActiveSession(session.id, options);
194
+ this.onSessionEventEmitter.fire({ type: 'created', sessionId: session.id });
162
195
  return session;
163
196
  }
164
197
 
@@ -172,13 +205,14 @@ export class ChatServiceImpl implements ChatService {
172
205
  }
173
206
  session.model.dispose();
174
207
  this._sessions.splice(sessionIndex, 1);
208
+ this.onSessionEventEmitter.fire({ type: 'deleted', sessionId: sessionId });
175
209
  }
176
210
 
177
211
  setActiveSession(sessionId: string | undefined, options?: SessionOptions): void {
178
212
  this._sessions.forEach(session => {
179
213
  session.isActive = session.id === sessionId;
180
214
  });
181
- this.onActiveSessionChangedEmitter.fire({ sessionId: sessionId, ...options });
215
+ this.onSessionEventEmitter.fire({ type: 'activeChange', sessionId: sessionId, ...options });
182
216
  }
183
217
 
184
218
  async sendRequest(
@@ -189,7 +223,6 @@ export class ChatServiceImpl implements ChatService {
189
223
  if (!session) {
190
224
  return undefined;
191
225
  }
192
- session.title = request.text;
193
226
 
194
227
  const resolutionContext: ChatSessionContext = { model: session.model };
195
228
  const resolvedContext = await this.resolveChatContext(session.model.context.getVariables(), resolutionContext);
@@ -208,6 +241,7 @@ export class ChatServiceImpl implements ChatService {
208
241
  }
209
242
 
210
243
  const requestModel = session.model.addRequest(parsedRequest, agent?.id, resolvedContext);
244
+ this.updateSessionMetadata(session, requestModel);
211
245
  resolutionContext.request = requestModel;
212
246
 
213
247
  let resolveResponseCreated: (responseModel: ChatResponseModel) => void;
@@ -241,6 +275,30 @@ export class ChatServiceImpl implements ChatService {
241
275
  return invocation;
242
276
  }
243
277
 
278
+ protected updateSessionMetadata(session: ChatSessionInternal, request: MutableChatRequestModel): void {
279
+ session.lastInteraction = new Date();
280
+ if (session.title) {
281
+ return;
282
+ }
283
+ const requestText = request.request.displayText ?? request.request.text;
284
+ session.title = requestText;
285
+ if (this.chatSessionNamingService) {
286
+ const otherSessionNames = this._sessions.map(s => s.title).filter((title): title is string => title !== undefined);
287
+ const namingService = this.chatSessionNamingService;
288
+ let didGenerateName = false;
289
+ request.response.onDidChange(() => {
290
+ if (request.response.isComplete && !didGenerateName) {
291
+ namingService.generateChatSessionName(session, otherSessionNames).then(name => {
292
+ if (name && session.title === requestText) {
293
+ session.title = name;
294
+ }
295
+ didGenerateName = true;
296
+ }).catch(error => this.logger.error('Failed to generate chat session name', error));
297
+ }
298
+ });
299
+ }
300
+ }
301
+
244
302
  protected async resolveChatContext(
245
303
  resolutionRequests: readonly AIVariableResolutionRequest[],
246
304
  context: ChatSessionContext,
@@ -0,0 +1,135 @@
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 {
18
+ Agent,
19
+ AgentService,
20
+ CommunicationRecordingService,
21
+ getTextOfResponse,
22
+ LanguageModelRegistry,
23
+ LanguageModelRequest,
24
+ LanguageModelRequirement,
25
+ PromptService,
26
+ PromptTemplate
27
+ } from '@theia/ai-core';
28
+ import { inject, injectable } from '@theia/core/shared/inversify';
29
+ import { ChatSession } from './chat-service';
30
+ import { generateUuid } from '@theia/core';
31
+
32
+ const CHAT_SESSION_NAMING_PROMPT = {
33
+ id: 'chat-session-naming-prompt',
34
+ template: '{{!-- Made improvements or adaptations to this prompt template? We\'d love for you to share it with the community! Contribute back here: ' +
35
+ 'https://github.com/eclipse-theia/theia/discussions/new?category=prompt-template-contribution --}}\n\n' +
36
+ 'Provide a short and descriptive name for the given AI chat conversation of an AI-powered tool based on the conversation below.\n\n' +
37
+ 'The purpose of the name is for users to recognize the chat conversation easily in a list of conversations. ' +
38
+ 'Use the same language for the chat conversation name as used in the provided conversation, if in doubt default to English. ' +
39
+ 'Start the chat conversation name with an upper-case letter. ' +
40
+ 'Below we also provide the already existing other conversation names, make sure your suggestion for a name is unique with respect to the existing ones.\n\n' +
41
+ 'IMPORTANT: Your answer MUST ONLY CONTAIN THE PROPOSED NAME and must not be preceded or succeeded with any other text.' +
42
+ '\n\nOther session names:\n{{listOfSessionNames}}' +
43
+ '\n\nConversation:\n{{conversation}}',
44
+ };
45
+
46
+ @injectable()
47
+ export class ChatSessionNamingService {
48
+ @inject(AgentService) protected agentService: AgentService;
49
+ async generateChatSessionName(chatSession: ChatSession, otherNames: string[]): Promise<string | undefined> {
50
+ const chatSessionNamingAgent = this.agentService.getAgents().find(agent => ChatSessionNamingAgent.ID === agent.id);
51
+ if (!(chatSessionNamingAgent instanceof ChatSessionNamingAgent)) {
52
+ return undefined;
53
+ }
54
+ return chatSessionNamingAgent.generateChatSessionName(chatSession, otherNames);
55
+ }
56
+ }
57
+
58
+ @injectable()
59
+ export class ChatSessionNamingAgent implements Agent {
60
+ static ID = 'chat-session-naming-agent';
61
+ id = ChatSessionNamingAgent.ID;
62
+ name = 'Chat Session Naming';
63
+ description = 'Agent for generating chat session names';
64
+ variables = [];
65
+ promptTemplates: PromptTemplate[] = [CHAT_SESSION_NAMING_PROMPT];
66
+ languageModelRequirements: LanguageModelRequirement[] = [{
67
+ purpose: 'chat-session-naming',
68
+ identifier: 'openai/gpt-4o-mini',
69
+ }];
70
+ agentSpecificVariables = [
71
+ { name: 'conversation', usedInPrompt: true, description: 'The content of the chat conversation.' },
72
+ { name: 'listOfSessionNames', usedInPrompt: true, description: 'The list of existing session names.' }
73
+ ];
74
+ functions = [];
75
+
76
+ @inject(LanguageModelRegistry)
77
+ protected readonly lmRegistry: LanguageModelRegistry;
78
+
79
+ @inject(CommunicationRecordingService)
80
+ protected recordingService: CommunicationRecordingService;
81
+
82
+ @inject(PromptService)
83
+ protected promptService: PromptService;
84
+
85
+ async generateChatSessionName(chatSession: ChatSession, otherNames: string[]): Promise<string> {
86
+ const lm = await this.lmRegistry.selectLanguageModel({ agent: this.id, ...this.languageModelRequirements[0] });
87
+ if (!lm) {
88
+ throw new Error('No language model found for chat session naming');
89
+ }
90
+ if (chatSession.model.getRequests().length < 1) {
91
+ throw new Error('No chat request available to generate chat session name');
92
+ }
93
+
94
+ const conversation = chatSession.model.getRequests()
95
+ .map(req => `<user>${req.request.text}</user>` +
96
+ (req.response.response ? `<assistant>${req.response.response.asString()}</assistant>` : ''))
97
+ .join('\n\n');
98
+ const listOfSessionNames = otherNames.map(name => name).join(', ');
99
+
100
+ const prompt = await this.promptService.getPrompt(CHAT_SESSION_NAMING_PROMPT.id, { conversation, listOfSessionNames });
101
+ const message = prompt?.text;
102
+ if (!message) {
103
+ throw new Error('Unable to create prompt message for generating chat session name');
104
+ }
105
+
106
+ const request: LanguageModelRequest = {
107
+ messages: [{
108
+ actor: 'user',
109
+ text: message,
110
+ type: 'text'
111
+ }]
112
+ };
113
+
114
+ const sessionId = generateUuid();
115
+ const requestId = generateUuid();
116
+ this.recordingService.recordRequest({
117
+ agentId: this.id,
118
+ sessionId,
119
+ requestId,
120
+ ...request
121
+ });
122
+
123
+ const result = await lm.request(request);
124
+ const response = await getTextOfResponse(result);
125
+ this.recordingService.recordResponse({
126
+ agentId: this.id,
127
+ sessionId,
128
+ requestId,
129
+ response: [{ actor: 'ai', text: response, type: 'text' }]
130
+ });
131
+
132
+ return response.replace(/\s+/g, ' ').substring(0, 100);
133
+ }
134
+
135
+ }
@@ -1,7 +0,0 @@
1
- import { CommunicationRequestEntryParam, CommunicationResponseEntryParam } from '@theia/ai-core/lib/common/communication-recording-service';
2
- import { ChatRequestModel } from './chat-model';
3
- export declare namespace ChatHistoryEntry {
4
- function fromRequest(agentId: string, request: ChatRequestModel, args?: Partial<CommunicationRequestEntryParam>): CommunicationRequestEntryParam;
5
- function fromResponse(agentId: string, request: ChatRequestModel, args?: Partial<CommunicationResponseEntryParam>): CommunicationResponseEntryParam;
6
- }
7
- //# sourceMappingURL=chat-history-entry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-history-entry.d.ts","sourceRoot":"","sources":["../../src/common/chat-history-entry.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,MAAM,2DAA2D,CAAC;AAC5I,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,yBAAiB,gBAAgB,CAAC;IAC9B,SAAgB,WAAW,CACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,EACzB,IAAI,GAAE,OAAO,CAAC,8BAA8B,CAAM,GACnD,8BAA8B,CAQhC;IACD,SAAgB,YAAY,CACxB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,EACzB,IAAI,GAAE,OAAO,CAAC,+BAA+B,CAAM,GACpD,+BAA+B,CAQjC;CACJ"}
@@ -1,42 +0,0 @@
1
- "use strict";
2
- // *****************************************************************************
3
- // Copyright (C) 2024 EclipseSource GmbH.
4
- //
5
- // This program and the accompanying materials are made available under the
6
- // terms of the Eclipse Public License v. 2.0 which is available at
7
- // http://www.eclipse.org/legal/epl-2.0.
8
- //
9
- // This Source Code may also be made available under the following Secondary
10
- // Licenses when the conditions for such availability set forth in the Eclipse
11
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
- // with the GNU Classpath Exception which is available at
13
- // https://www.gnu.org/software/classpath/license.html.
14
- //
15
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
- // *****************************************************************************
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.ChatHistoryEntry = void 0;
19
- var ChatHistoryEntry;
20
- (function (ChatHistoryEntry) {
21
- function fromRequest(agentId, request, args = {}) {
22
- return {
23
- agentId: agentId,
24
- sessionId: request.session.id,
25
- requestId: request.id,
26
- request: request.request.text,
27
- ...args,
28
- };
29
- }
30
- ChatHistoryEntry.fromRequest = fromRequest;
31
- function fromResponse(agentId, request, args = {}) {
32
- return {
33
- agentId: agentId,
34
- sessionId: request.session.id,
35
- requestId: request.id,
36
- response: request.response.response.asDisplayString(),
37
- ...args,
38
- };
39
- }
40
- ChatHistoryEntry.fromResponse = fromResponse;
41
- })(ChatHistoryEntry || (exports.ChatHistoryEntry = ChatHistoryEntry = {}));
42
- //# sourceMappingURL=chat-history-entry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-history-entry.js","sourceRoot":"","sources":["../../src/common/chat-history-entry.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AAKhF,IAAiB,gBAAgB,CA2BhC;AA3BD,WAAiB,gBAAgB;IAC7B,SAAgB,WAAW,CACvB,OAAe,EACf,OAAyB,EACzB,OAAgD,EAAE;QAElD,OAAO;YACH,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;YAC7B,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI;YAC7B,GAAG,IAAI;SACV,CAAC;IACN,CAAC;IAZe,4BAAW,cAY1B,CAAA;IACD,SAAgB,YAAY,CACxB,OAAe,EACf,OAAyB,EACzB,OAAiD,EAAE;QAEnD,OAAO;YACH,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;YAC7B,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE;YACrD,GAAG,IAAI;SACV,CAAC;IACN,CAAC;IAZe,6BAAY,eAY3B,CAAA;AACL,CAAC,EA3BgB,gBAAgB,gCAAhB,gBAAgB,QA2BhC"}
@@ -1,47 +0,0 @@
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 { CommunicationRequestEntryParam, CommunicationResponseEntryParam } from '@theia/ai-core/lib/common/communication-recording-service';
18
- import { ChatRequestModel } from './chat-model';
19
-
20
- export namespace ChatHistoryEntry {
21
- export function fromRequest(
22
- agentId: string,
23
- request: ChatRequestModel,
24
- args: Partial<CommunicationRequestEntryParam> = {}
25
- ): CommunicationRequestEntryParam {
26
- return {
27
- agentId: agentId,
28
- sessionId: request.session.id,
29
- requestId: request.id,
30
- request: request.request.text,
31
- ...args,
32
- };
33
- }
34
- export function fromResponse(
35
- agentId: string,
36
- request: ChatRequestModel,
37
- args: Partial<CommunicationResponseEntryParam> = {}
38
- ): CommunicationResponseEntryParam {
39
- return {
40
- agentId: agentId,
41
- sessionId: request.session.id,
42
- requestId: request.id,
43
- response: request.response.response.asDisplayString(),
44
- ...args,
45
- };
46
- }
47
- }