@theia/ai-ide 1.64.0-next.35 → 1.65.0-next.1
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-configuration/agent-configuration-widget.d.ts +5 -2
- package/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.js +15 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/ai-configuration-service.d.ts +6 -1
- package/lib/browser/ai-configuration/ai-configuration-service.d.ts.map +1 -1
- package/lib/browser/ai-configuration/ai-configuration-service.js +10 -1
- package/lib/browser/ai-configuration/ai-configuration-service.js.map +1 -1
- package/lib/browser/ai-configuration/ai-configuration-widget.d.ts +2 -0
- package/lib/browser/ai-configuration/ai-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/ai-configuration-widget.js +7 -1
- package/lib/browser/ai-configuration/ai-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/language-model-renderer.d.ts +4 -2
- package/lib/browser/ai-configuration/language-model-renderer.d.ts.map +1 -1
- package/lib/browser/ai-configuration/language-model-renderer.js +49 -71
- package/lib/browser/ai-configuration/language-model-renderer.js.map +1 -1
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts +41 -0
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.d.ts.map +1 -0
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.js +225 -0
- package/lib/browser/ai-configuration/model-aliases-configuration-widget.js.map +1 -0
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts +7 -3
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js +35 -13
- package/lib/browser/ai-configuration/prompt-fragments-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +1 -1
- package/lib/browser/ai-configuration/template-settings-renderer.js +11 -6
- package/lib/browser/ai-configuration/template-settings-renderer.js.map +1 -1
- package/lib/browser/ai-ide-activation-service.d.ts +18 -0
- package/lib/browser/ai-ide-activation-service.d.ts.map +1 -0
- package/lib/browser/ai-ide-activation-service.js +72 -0
- package/lib/browser/ai-ide-activation-service.js.map +1 -0
- package/lib/browser/ai-ide-preferences.d.ts +4 -0
- package/lib/browser/ai-ide-preferences.d.ts.map +1 -0
- package/lib/browser/ai-ide-preferences.js +43 -0
- package/lib/browser/ai-ide-preferences.js.map +1 -0
- package/lib/browser/app-tester-chat-agent.js +1 -1
- package/lib/browser/app-tester-chat-agent.js.map +1 -1
- package/lib/browser/architect-agent.js +1 -1
- package/lib/browser/architect-agent.js.map +1 -1
- package/lib/browser/coder-agent.js +1 -1
- package/lib/browser/coder-agent.js.map +1 -1
- package/lib/browser/context-functions.d.ts.map +1 -1
- package/lib/browser/context-functions.js +12 -0
- package/lib/browser/context-functions.js.map +1 -1
- package/lib/browser/context-functions.spec.d.ts +2 -0
- package/lib/browser/context-functions.spec.d.ts.map +1 -0
- package/lib/browser/context-functions.spec.js +93 -0
- package/lib/browser/context-functions.spec.js.map +1 -0
- package/lib/browser/file-changeset-function.spec.d.ts +2 -0
- package/lib/browser/file-changeset-function.spec.d.ts.map +1 -0
- package/lib/browser/file-changeset-function.spec.js +45 -0
- package/lib/browser/file-changeset-function.spec.js.map +1 -0
- package/lib/browser/file-changeset-functions.d.ts +13 -3
- package/lib/browser/file-changeset-functions.d.ts.map +1 -1
- package/lib/browser/file-changeset-functions.js +100 -29
- package/lib/browser/file-changeset-functions.js.map +1 -1
- package/lib/browser/file-changeset-functions.spec.d.ts +2 -0
- package/lib/browser/file-changeset-functions.spec.d.ts.map +1 -0
- package/lib/browser/file-changeset-functions.spec.js +161 -0
- package/lib/browser/file-changeset-functions.spec.js.map +1 -0
- package/lib/browser/frontend-module.d.ts.map +1 -1
- package/lib/browser/frontend-module.js +20 -0
- package/lib/browser/frontend-module.js.map +1 -1
- package/lib/browser/ide-chat-welcome-message-provider.js +2 -2
- package/lib/browser/ide-chat-welcome-message-provider.js.map +1 -1
- package/lib/browser/test/tool-provider-cancellation-test-util.spec.d.ts +2 -0
- package/lib/browser/test/tool-provider-cancellation-test-util.spec.d.ts.map +1 -0
- package/lib/browser/test/tool-provider-cancellation-test-util.spec.js +52 -0
- package/lib/browser/test/tool-provider-cancellation-test-util.spec.js.map +1 -0
- package/lib/browser/workspace-functions.d.ts +3 -3
- package/lib/browser/workspace-functions.d.ts.map +1 -1
- package/lib/browser/workspace-functions.js +79 -28
- package/lib/browser/workspace-functions.js.map +1 -1
- package/lib/browser/workspace-functions.spec.d.ts +2 -0
- package/lib/browser/workspace-functions.spec.d.ts.map +1 -0
- package/lib/browser/workspace-functions.spec.js +161 -0
- package/lib/browser/workspace-functions.spec.js.map +1 -0
- package/lib/browser/workspace-launch-provider.d.ts +24 -0
- package/lib/browser/workspace-launch-provider.d.ts.map +1 -0
- package/lib/browser/workspace-launch-provider.js +216 -0
- package/lib/browser/workspace-launch-provider.js.map +1 -0
- package/lib/browser/workspace-launch-provider.spec.d.ts +2 -0
- package/lib/browser/workspace-launch-provider.spec.d.ts.map +1 -0
- package/lib/browser/workspace-launch-provider.spec.js +245 -0
- package/lib/browser/workspace-launch-provider.spec.js.map +1 -0
- package/lib/browser/workspace-search-provider.d.ts.map +1 -1
- package/lib/browser/workspace-search-provider.js +9 -0
- package/lib/browser/workspace-search-provider.js.map +1 -1
- package/lib/browser/workspace-search-provider.spec.js +59 -203
- package/lib/browser/workspace-search-provider.spec.js.map +1 -1
- package/lib/browser/workspace-task-provider.d.ts.map +1 -1
- package/lib/browser/workspace-task-provider.js +8 -1
- package/lib/browser/workspace-task-provider.js.map +1 -1
- package/lib/browser/workspace-task-provider.spec.d.ts +2 -0
- package/lib/browser/workspace-task-provider.spec.d.ts.map +1 -0
- package/lib/browser/workspace-task-provider.spec.js +109 -0
- package/lib/browser/workspace-task-provider.spec.js.map +1 -0
- package/lib/common/architect-prompt-template.d.ts.map +1 -1
- package/lib/common/architect-prompt-template.js +11 -0
- package/lib/common/architect-prompt-template.js.map +1 -1
- package/lib/common/command-chat-agents.js +1 -1
- package/lib/common/command-chat-agents.js.map +1 -1
- package/lib/common/orchestrator-chat-agent.js +1 -1
- package/lib/common/orchestrator-chat-agent.js.map +1 -1
- package/lib/common/universal-chat-agent.js +1 -1
- package/lib/common/universal-chat-agent.js.map +1 -1
- package/lib/common/workspace-functions.d.ts +3 -0
- package/lib/common/workspace-functions.d.ts.map +1 -1
- package/lib/common/workspace-functions.js +4 -1
- package/lib/common/workspace-functions.js.map +1 -1
- package/package.json +18 -17
- package/src/browser/ai-configuration/agent-configuration-widget.tsx +18 -2
- package/src/browser/ai-configuration/ai-configuration-service.ts +14 -1
- package/src/browser/ai-configuration/ai-configuration-widget.tsx +7 -1
- package/src/browser/ai-configuration/language-model-renderer.tsx +87 -59
- package/src/browser/ai-configuration/model-aliases-configuration-widget.tsx +279 -0
- package/src/browser/ai-configuration/prompt-fragments-configuration-widget.tsx +43 -13
- package/src/browser/ai-configuration/template-settings-renderer.tsx +11 -7
- package/src/browser/ai-ide-activation-service.ts +65 -0
- package/src/browser/ai-ide-preferences.ts +44 -0
- package/src/browser/app-tester-chat-agent.ts +1 -1
- package/src/browser/architect-agent.ts +1 -1
- package/src/browser/coder-agent.ts +1 -1
- package/src/browser/context-functions.spec.ts +102 -0
- package/src/browser/context-functions.ts +11 -0
- package/src/browser/file-changeset-function.spec.ts +52 -0
- package/src/browser/file-changeset-functions.spec.ts +212 -0
- package/src/browser/file-changeset-functions.ts +102 -25
- package/src/browser/frontend-module.ts +29 -1
- package/src/browser/ide-chat-welcome-message-provider.tsx +4 -4
- package/src/browser/style/index.css +111 -6
- package/src/browser/test/tool-provider-cancellation-test-util.spec.ts +60 -0
- package/src/browser/workspace-functions.spec.ts +199 -0
- package/src/browser/workspace-functions.ts +105 -32
- package/src/browser/workspace-launch-provider.spec.ts +320 -0
- package/src/browser/workspace-launch-provider.ts +231 -0
- package/src/browser/workspace-search-provider.spec.ts +79 -229
- package/src/browser/workspace-search-provider.ts +10 -1
- package/src/browser/workspace-task-provider.spec.ts +125 -0
- package/src/browser/workspace-task-provider.ts +7 -2
- package/src/common/architect-prompt-template.ts +11 -0
- package/src/common/command-chat-agents.ts +1 -1
- package/src/common/orchestrator-chat-agent.ts +1 -1
- package/src/common/universal-chat-agent.ts +1 -1
- package/src/common/workspace-functions.ts +3 -0
|
@@ -13,24 +13,31 @@
|
|
|
13
13
|
//
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
|
-
import { injectable, inject } from '@theia/core/shared/inversify';
|
|
17
|
-
import { ToolProvider, ToolRequest, ToolRequestParameters, ToolRequestParametersProperties } from '@theia/ai-core';
|
|
18
|
-
import { WorkspaceFunctionScope } from './workspace-functions';
|
|
19
|
-
import { ChangeSetElementArgs, ChangeSetFileElement, ChangeSetFileElementFactory } from '@theia/ai-chat/lib/browser/change-set-file-element';
|
|
20
16
|
import { ChangeSet, MutableChatRequestModel } from '@theia/ai-chat';
|
|
21
|
-
import {
|
|
17
|
+
import { ChangeSetElementArgs, ChangeSetFileElement, ChangeSetFileElementFactory } from '@theia/ai-chat/lib/browser/change-set-file-element';
|
|
18
|
+
import { ToolProvider, ToolRequest, ToolRequestParameters, ToolRequestParametersProperties } from '@theia/ai-core';
|
|
22
19
|
import { ContentReplacer, Replacement } from '@theia/core/lib/common/content-replacer';
|
|
23
20
|
import { URI } from '@theia/core/lib/common/uri';
|
|
21
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
22
|
+
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
|
23
|
+
import { WorkspaceFunctionScope } from './workspace-functions';
|
|
24
24
|
|
|
25
|
+
import { nls } from '@theia/core';
|
|
25
26
|
import {
|
|
27
|
+
CLEAR_FILE_CHANGES_ID,
|
|
28
|
+
GET_PROPOSED_CHANGES_ID,
|
|
26
29
|
SUGGEST_FILE_CONTENT_ID,
|
|
27
|
-
WRITE_FILE_CONTENT_ID,
|
|
28
30
|
SUGGEST_FILE_REPLACEMENTS_ID,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
GET_PROPOSED_CHANGES_ID
|
|
31
|
+
WRITE_FILE_CONTENT_ID,
|
|
32
|
+
WRITE_FILE_REPLACEMENTS_ID
|
|
32
33
|
} from '../common/file-changeset-function-ids';
|
|
33
34
|
|
|
35
|
+
export const FileChangeSetTitleProvider = Symbol('FileChangeSetTitleProvider');
|
|
36
|
+
|
|
37
|
+
export interface FileChangeSetTitleProvider {
|
|
38
|
+
getChangeSetTitle(ctx: MutableChatRequestModel): string;
|
|
39
|
+
}
|
|
40
|
+
|
|
34
41
|
@injectable()
|
|
35
42
|
export class SuggestFileContent implements ToolProvider {
|
|
36
43
|
static ID = SUGGEST_FILE_CONTENT_ID;
|
|
@@ -44,6 +51,9 @@ export class SuggestFileContent implements ToolProvider {
|
|
|
44
51
|
@inject(ChangeSetFileElementFactory)
|
|
45
52
|
protected readonly fileChangeFactory: ChangeSetFileElementFactory;
|
|
46
53
|
|
|
54
|
+
@inject(FileChangeSetTitleProvider)
|
|
55
|
+
protected readonly fileChangeSetTitleProvider: FileChangeSetTitleProvider;
|
|
56
|
+
|
|
47
57
|
getTool(): ToolRequest {
|
|
48
58
|
return {
|
|
49
59
|
id: SuggestFileContent.ID,
|
|
@@ -68,6 +78,9 @@ export class SuggestFileContent implements ToolProvider {
|
|
|
68
78
|
required: ['path', 'content']
|
|
69
79
|
},
|
|
70
80
|
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
|
|
81
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
82
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
83
|
+
}
|
|
71
84
|
const { path, content } = JSON.parse(args);
|
|
72
85
|
const chatSessionId = ctx.session.id;
|
|
73
86
|
const uri = await this.workspaceFunctionScope.resolveRelativePath(path);
|
|
@@ -75,7 +88,7 @@ export class SuggestFileContent implements ToolProvider {
|
|
|
75
88
|
if (content === '') {
|
|
76
89
|
type = 'delete';
|
|
77
90
|
}
|
|
78
|
-
if (!await this.fileService.exists(uri)) {
|
|
91
|
+
if (!(await this.fileService.exists(uri))) {
|
|
79
92
|
type = 'add';
|
|
80
93
|
}
|
|
81
94
|
ctx.session.changeSet.addElements(
|
|
@@ -88,7 +101,8 @@ export class SuggestFileContent implements ToolProvider {
|
|
|
88
101
|
chatSessionId
|
|
89
102
|
})
|
|
90
103
|
);
|
|
91
|
-
|
|
104
|
+
|
|
105
|
+
ctx.session.changeSet.setTitle(this.fileChangeSetTitleProvider.getChangeSetTitle(ctx));
|
|
92
106
|
return `Proposed writing to file ${path}. The user will review and potentially apply the changes`;
|
|
93
107
|
}
|
|
94
108
|
};
|
|
@@ -108,6 +122,9 @@ export class WriteFileContent implements ToolProvider {
|
|
|
108
122
|
@inject(ChangeSetFileElementFactory)
|
|
109
123
|
protected readonly fileChangeFactory: ChangeSetFileElementFactory;
|
|
110
124
|
|
|
125
|
+
@inject(FileChangeSetTitleProvider)
|
|
126
|
+
protected readonly fileChangeSetTitleProvider: FileChangeSetTitleProvider;
|
|
127
|
+
|
|
111
128
|
getTool(): ToolRequest {
|
|
112
129
|
return {
|
|
113
130
|
id: WriteFileContent.ID,
|
|
@@ -132,6 +149,9 @@ export class WriteFileContent implements ToolProvider {
|
|
|
132
149
|
required: ['path', 'content']
|
|
133
150
|
},
|
|
134
151
|
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
|
|
152
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
153
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
154
|
+
}
|
|
135
155
|
const { path, content } = JSON.parse(args);
|
|
136
156
|
const chatSessionId = ctx.session.id;
|
|
137
157
|
const uri = await this.workspaceFunctionScope.resolveRelativePath(path);
|
|
@@ -139,7 +159,7 @@ export class WriteFileContent implements ToolProvider {
|
|
|
139
159
|
if (content === '') {
|
|
140
160
|
type = 'delete';
|
|
141
161
|
}
|
|
142
|
-
if (!await this.fileService.exists(uri)) {
|
|
162
|
+
if (!(await this.fileService.exists(uri))) {
|
|
143
163
|
type = 'add';
|
|
144
164
|
}
|
|
145
165
|
|
|
@@ -153,7 +173,7 @@ export class WriteFileContent implements ToolProvider {
|
|
|
153
173
|
chatSessionId
|
|
154
174
|
});
|
|
155
175
|
|
|
156
|
-
ctx.session.changeSet.setTitle(
|
|
176
|
+
ctx.session.changeSet.setTitle(this.fileChangeSetTitleProvider.getChangeSetTitle(ctx));
|
|
157
177
|
// Add the element to the change set
|
|
158
178
|
ctx.session.changeSet.addElements(fileElement);
|
|
159
179
|
|
|
@@ -180,6 +200,9 @@ export class ReplaceContentInFileFunctionHelper {
|
|
|
180
200
|
@inject(ChangeSetFileElementFactory)
|
|
181
201
|
protected readonly fileChangeFactory: ChangeSetFileElementFactory;
|
|
182
202
|
|
|
203
|
+
@inject(FileChangeSetTitleProvider)
|
|
204
|
+
protected readonly fileChangeSetTitleProvider: FileChangeSetTitleProvider;
|
|
205
|
+
|
|
183
206
|
private replacer: ContentReplacer;
|
|
184
207
|
|
|
185
208
|
constructor() {
|
|
@@ -249,12 +272,15 @@ export class ReplaceContentInFileFunctionHelper {
|
|
|
249
272
|
description: replacementDescription,
|
|
250
273
|
parameters: replacementParameters
|
|
251
274
|
};
|
|
252
|
-
|
|
253
275
|
}
|
|
254
276
|
|
|
255
277
|
async createChangesetFromToolCall(toolCallString: string, ctx: MutableChatRequestModel): Promise<string> {
|
|
256
278
|
try {
|
|
257
|
-
|
|
279
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
280
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const result = await this.processReplacementsCommon(toolCallString, ctx, this.fileChangeSetTitleProvider.getChangeSetTitle(ctx));
|
|
258
284
|
|
|
259
285
|
if (result.errors.length > 0) {
|
|
260
286
|
return `Errors encountered: ${result.errors.join('; ')}`;
|
|
@@ -274,7 +300,11 @@ export class ReplaceContentInFileFunctionHelper {
|
|
|
274
300
|
|
|
275
301
|
async writeChangesetFromToolCall(toolCallString: string, ctx: MutableChatRequestModel): Promise<string> {
|
|
276
302
|
try {
|
|
277
|
-
|
|
303
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
304
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const result = await this.processReplacementsCommon(toolCallString, ctx, this.fileChangeSetTitleProvider.getChangeSetTitle(ctx));
|
|
278
308
|
|
|
279
309
|
if (result.errors.length > 0) {
|
|
280
310
|
return `Errors encountered: ${result.errors.join('; ')}`;
|
|
@@ -300,6 +330,10 @@ export class ReplaceContentInFileFunctionHelper {
|
|
|
300
330
|
ctx: MutableChatRequestModel,
|
|
301
331
|
changeSetTitle: string
|
|
302
332
|
): Promise<{ fileElement: ChangeSetFileElement | undefined, path: string, reset: boolean, errors: string[] }> {
|
|
333
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
334
|
+
throw new Error('Operation cancelled by user');
|
|
335
|
+
}
|
|
336
|
+
|
|
303
337
|
const { path, replacements, reset } = JSON.parse(toolCallString) as { path: string, replacements: Replacement[], reset?: boolean };
|
|
304
338
|
const fileUri = await this.workspaceFunctionScope.resolveRelativePath(path);
|
|
305
339
|
|
|
@@ -318,6 +352,10 @@ export class ReplaceContentInFileFunctionHelper {
|
|
|
318
352
|
}
|
|
319
353
|
}
|
|
320
354
|
|
|
355
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
356
|
+
throw new Error('Operation cancelled by user');
|
|
357
|
+
}
|
|
358
|
+
|
|
321
359
|
const { updatedContent, errors } = this.replacer.applyReplacements(startingContent, replacements);
|
|
322
360
|
|
|
323
361
|
if (errors.length > 0) {
|
|
@@ -348,11 +386,17 @@ export class ReplaceContentInFileFunctionHelper {
|
|
|
348
386
|
|
|
349
387
|
private findExistingChangeElement(changeSet: ChangeSet, fileUri: URI): ChangeSetFileElement | undefined {
|
|
350
388
|
const element = changeSet.getElementByURI(fileUri);
|
|
351
|
-
if (element instanceof ChangeSetFileElement) {
|
|
389
|
+
if (element instanceof ChangeSetFileElement) {
|
|
390
|
+
return element;
|
|
391
|
+
}
|
|
352
392
|
}
|
|
353
393
|
|
|
354
394
|
async clearFileChanges(path: string, ctx: MutableChatRequestModel): Promise<string> {
|
|
355
395
|
try {
|
|
396
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
397
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
398
|
+
}
|
|
399
|
+
|
|
356
400
|
const fileUri = await this.workspaceFunctionScope.resolveRelativePath(path);
|
|
357
401
|
if (ctx.session.changeSet.removeElements(fileUri)) {
|
|
358
402
|
return `Cleared pending change(s) for file ${path}.`;
|
|
@@ -367,6 +411,10 @@ export class ReplaceContentInFileFunctionHelper {
|
|
|
367
411
|
|
|
368
412
|
async getProposedFileState(path: string, ctx: MutableChatRequestModel): Promise<string> {
|
|
369
413
|
try {
|
|
414
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
415
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
416
|
+
}
|
|
417
|
+
|
|
370
418
|
const fileUri = await this.workspaceFunctionScope.resolveRelativePath(path);
|
|
371
419
|
|
|
372
420
|
if (!ctx.session.changeSet) {
|
|
@@ -403,8 +451,12 @@ export class SimpleSuggestFileReplacements implements ToolProvider {
|
|
|
403
451
|
name: SimpleSuggestFileReplacements.ID,
|
|
404
452
|
description: metadata.description,
|
|
405
453
|
parameters: metadata.parameters,
|
|
406
|
-
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> =>
|
|
407
|
-
|
|
454
|
+
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
|
|
455
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
456
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
457
|
+
}
|
|
458
|
+
return this.replaceContentInFileFunctionHelper.createChangesetFromToolCall(args, ctx);
|
|
459
|
+
}
|
|
408
460
|
};
|
|
409
461
|
}
|
|
410
462
|
}
|
|
@@ -422,8 +474,12 @@ export class SimpleWriteFileReplacements implements ToolProvider {
|
|
|
422
474
|
name: SimpleWriteFileReplacements.ID,
|
|
423
475
|
description: metadata.description,
|
|
424
476
|
parameters: metadata.parameters,
|
|
425
|
-
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> =>
|
|
426
|
-
|
|
477
|
+
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
|
|
478
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
479
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
480
|
+
}
|
|
481
|
+
return this.replaceContentInFileFunctionHelper.writeChangesetFromToolCall(args, ctx);
|
|
482
|
+
}
|
|
427
483
|
};
|
|
428
484
|
}
|
|
429
485
|
}
|
|
@@ -441,8 +497,12 @@ export class SuggestFileReplacements implements ToolProvider {
|
|
|
441
497
|
name: SuggestFileReplacements.ID,
|
|
442
498
|
description: metadata.description,
|
|
443
499
|
parameters: metadata.parameters,
|
|
444
|
-
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> =>
|
|
445
|
-
|
|
500
|
+
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
|
|
501
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
502
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
503
|
+
}
|
|
504
|
+
return this.replaceContentInFileFunctionHelper.createChangesetFromToolCall(args, ctx);
|
|
505
|
+
}
|
|
446
506
|
};
|
|
447
507
|
}
|
|
448
508
|
}
|
|
@@ -460,8 +520,12 @@ export class WriteFileReplacements implements ToolProvider {
|
|
|
460
520
|
name: WriteFileReplacements.ID,
|
|
461
521
|
description: metadata.description,
|
|
462
522
|
parameters: metadata.parameters,
|
|
463
|
-
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> =>
|
|
464
|
-
|
|
523
|
+
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
|
|
524
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
525
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
526
|
+
}
|
|
527
|
+
return this.replaceContentInFileFunctionHelper.writeChangesetFromToolCall(args, ctx);
|
|
528
|
+
}
|
|
465
529
|
};
|
|
466
530
|
}
|
|
467
531
|
}
|
|
@@ -488,6 +552,9 @@ export class ClearFileChanges implements ToolProvider {
|
|
|
488
552
|
required: ['path']
|
|
489
553
|
},
|
|
490
554
|
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
|
|
555
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
556
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
557
|
+
}
|
|
491
558
|
const { path } = JSON.parse(args);
|
|
492
559
|
return this.replaceContentInFileFunctionHelper.clearFileChanges(path, ctx);
|
|
493
560
|
}
|
|
@@ -518,9 +585,19 @@ export class GetProposedFileState implements ToolProvider {
|
|
|
518
585
|
required: ['path']
|
|
519
586
|
},
|
|
520
587
|
handler: async (args: string, ctx: MutableChatRequestModel): Promise<string> => {
|
|
588
|
+
if (ctx?.response?.cancellationToken?.isCancellationRequested) {
|
|
589
|
+
return JSON.stringify({ error: 'Operation cancelled by user' });
|
|
590
|
+
}
|
|
521
591
|
const { path } = JSON.parse(args);
|
|
522
592
|
return this.replaceContentInFileFunctionHelper.getProposedFileState(path, ctx);
|
|
523
593
|
}
|
|
524
594
|
};
|
|
525
595
|
}
|
|
526
596
|
}
|
|
597
|
+
|
|
598
|
+
@injectable()
|
|
599
|
+
export class DefaultFileChangeSetTitleProvider implements FileChangeSetTitleProvider {
|
|
600
|
+
getChangeSetTitle(ctx: MutableChatRequestModel): string {
|
|
601
|
+
return nls.localize('theia/ai-chat/fileChangeSetTitle', 'Changes proposed');
|
|
602
|
+
}
|
|
603
|
+
}
|
|
@@ -33,6 +33,11 @@ import {
|
|
|
33
33
|
ServiceConnectionProvider
|
|
34
34
|
} from '@theia/core/lib/browser';
|
|
35
35
|
import { TaskListProvider, TaskRunnerProvider } from './workspace-task-provider';
|
|
36
|
+
import {
|
|
37
|
+
LaunchListProvider,
|
|
38
|
+
LaunchRunnerProvider,
|
|
39
|
+
LaunchStopProvider,
|
|
40
|
+
} from './workspace-launch-provider';
|
|
36
41
|
import { WorkspacePreferencesSchema } from './workspace-preferences';
|
|
37
42
|
import {
|
|
38
43
|
ClearFileChanges,
|
|
@@ -43,7 +48,9 @@ import {
|
|
|
43
48
|
SuggestFileContent,
|
|
44
49
|
WriteFileContent,
|
|
45
50
|
WriteFileReplacements,
|
|
46
|
-
SimpleWriteFileReplacements
|
|
51
|
+
SimpleWriteFileReplacements,
|
|
52
|
+
FileChangeSetTitleProvider,
|
|
53
|
+
DefaultFileChangeSetTitleProvider
|
|
47
54
|
} from './file-changeset-functions';
|
|
48
55
|
import { OrchestratorChatAgent, OrchestratorChatAgentId } from '../common/orchestrator-chat-agent';
|
|
49
56
|
import { UniversalChatAgent, UniversalChatAgentId } from '../common/universal-chat-agent';
|
|
@@ -71,10 +78,19 @@ import { CommandContribution } from '@theia/core';
|
|
|
71
78
|
import { AIPromptFragmentsConfigurationWidget } from './ai-configuration/prompt-fragments-configuration-widget';
|
|
72
79
|
import { BrowserAutomation, browserAutomationPath } from '../common/browser-automation-protocol';
|
|
73
80
|
import { CloseBrowserProvider, IsBrowserRunningProvider, LaunchBrowserProvider, QueryDomProvider } from './app-tester-chat-functions';
|
|
81
|
+
import { ModelAliasesConfigurationWidget } from './ai-configuration/model-aliases-configuration-widget';
|
|
82
|
+
import { aiIdePreferenceSchema } from './ai-ide-preferences';
|
|
83
|
+
import { AIActivationService } from '@theia/ai-core/lib/browser';
|
|
84
|
+
import { AIIdeActivationServiceImpl } from './ai-ide-activation-service';
|
|
74
85
|
|
|
75
86
|
export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
|
|
87
|
+
bind(PreferenceContribution).toConstantValue({ schema: aiIdePreferenceSchema });
|
|
76
88
|
bind(PreferenceContribution).toConstantValue({ schema: WorkspacePreferencesSchema });
|
|
77
89
|
|
|
90
|
+
bind(AIIdeActivationServiceImpl).toSelf().inSingletonScope();
|
|
91
|
+
// rebinds the default implementation of '@theia/ai-core'
|
|
92
|
+
rebind(AIActivationService).toService(AIIdeActivationServiceImpl);
|
|
93
|
+
|
|
78
94
|
bind(ArchitectAgent).toSelf().inSingletonScope();
|
|
79
95
|
bind(Agent).toService(ArchitectAgent);
|
|
80
96
|
bind(ChatAgent).toService(ArchitectAgent);
|
|
@@ -119,7 +135,11 @@ export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
|
|
|
119
135
|
bindToolProvider(WriteFileContent, bind);
|
|
120
136
|
bindToolProvider(TaskListProvider, bind);
|
|
121
137
|
bindToolProvider(TaskRunnerProvider, bind);
|
|
138
|
+
bindToolProvider(LaunchListProvider, bind);
|
|
139
|
+
bindToolProvider(LaunchRunnerProvider, bind);
|
|
140
|
+
bindToolProvider(LaunchStopProvider, bind);
|
|
122
141
|
bind(ReplaceContentInFileFunctionHelper).toSelf().inSingletonScope();
|
|
142
|
+
bind(FileChangeSetTitleProvider).to(DefaultFileChangeSetTitleProvider).inSingletonScope();
|
|
123
143
|
bindToolProvider(SuggestFileReplacements, bind);
|
|
124
144
|
bindToolProvider(WriteFileReplacements, bind);
|
|
125
145
|
bindToolProvider(ListChatContext, bind);
|
|
@@ -157,6 +177,14 @@ export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
|
|
|
157
177
|
}))
|
|
158
178
|
.inSingletonScope();
|
|
159
179
|
|
|
180
|
+
bind(ModelAliasesConfigurationWidget).toSelf();
|
|
181
|
+
bind(WidgetFactory)
|
|
182
|
+
.toDynamicValue(ctx => ({
|
|
183
|
+
id: ModelAliasesConfigurationWidget.ID,
|
|
184
|
+
createWidget: () => ctx.container.get(ModelAliasesConfigurationWidget)
|
|
185
|
+
}))
|
|
186
|
+
.inSingletonScope();
|
|
187
|
+
|
|
160
188
|
bindToolProvider(SimpleSuggestFileReplacements, bind);
|
|
161
189
|
bindToolProvider(SimpleWriteFileReplacements, bind);
|
|
162
190
|
bindToolProvider(ClearFileChanges, bind);
|
|
@@ -85,7 +85,7 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
|
|
|
85
85
|
<div className='theia-ResponseNode-Content' key={'disabled-message'}>
|
|
86
86
|
<div className="disable-message">
|
|
87
87
|
<span className="section-header">{
|
|
88
|
-
nls.localize('theia/ai/chat-ui/chat-view-tree-widget/aiFeatureHeader', '🚀 AI Features Available (
|
|
88
|
+
nls.localize('theia/ai/chat-ui/chat-view-tree-widget/aiFeatureHeader', '🚀 AI Features Available (Beta Version)!')}
|
|
89
89
|
</span>
|
|
90
90
|
<div className="section-title">
|
|
91
91
|
<p><code>{nls.localize('theia/ai/chat-ui/chat-view-tree-widget/featuresDisabled', 'Currently, all AI Features are disabled!')}</code></p>
|
|
@@ -96,14 +96,14 @@ export class IdeChatWelcomeMessageProvider implements ChatWelcomeMessageProvider
|
|
|
96
96
|
<div className="section-content">
|
|
97
97
|
<p>To enable the AI features, please go to the AI features section of the
|
|
98
98
|
{this.renderLinkButton(nls.localize('theia/ai/chat-ui/chat-view-tree-widget/settingsMenu', 'the settings menu'),
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
CommonCommands.OPEN_PREFERENCES.id, 'ai-features')} and
|
|
100
|
+
</p>
|
|
101
101
|
<ol>
|
|
102
102
|
<li>Toggle the switch for <strong>{nls.localize('theia/ai/chat-ui/chat-view-tree-widget/aiFeaturesEnable', 'Ai-features: Enable')}</strong>.</li>
|
|
103
103
|
<li>Provide at least one LLM provider (e.g. OpenAI). See <a href="https://theia-ide.org/docs/user_ai/" target="_blank">the documentation</a>
|
|
104
104
|
for more information.</li>
|
|
105
105
|
</ol>
|
|
106
|
-
<p>This will activate the AI capabilities in the app. Please remember, these features are <strong>in
|
|
106
|
+
<p>This will activate the AI capabilities in the app. Please remember, these features are <strong>in a beta state</strong>,
|
|
107
107
|
so they may change and we are working on improving them 🚧.<br></br>
|
|
108
108
|
Please support us by <a href="https://github.com/eclipse-theia/theia">providing feedback
|
|
109
109
|
</a>!</p>
|
|
@@ -64,7 +64,8 @@
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
#ai-variable-configuration-container-widget,
|
|
67
|
-
#ai-agent-configuration-container-widget
|
|
67
|
+
#ai-agent-configuration-container-widget,
|
|
68
|
+
#ai-model-aliases-configuration-widget {
|
|
68
69
|
margin-top: 5px;
|
|
69
70
|
}
|
|
70
71
|
|
|
@@ -86,21 +87,24 @@
|
|
|
86
87
|
grid-template-columns: 1fr 2fr;
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
/* Agent Settings */
|
|
90
|
-
#ai-agent-configuration-container-widget ul
|
|
90
|
+
/* Agent and Model Alias Settings */
|
|
91
|
+
#ai-agent-configuration-container-widget ul,
|
|
92
|
+
#ai-model-aliases-configuration-widget .model-alias-configuration-list ul {
|
|
91
93
|
list-style: none;
|
|
92
94
|
padding: 0;
|
|
93
95
|
margin: 0;
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
.ai-agent-configuration-main
|
|
98
|
+
.ai-agent-configuration-main,
|
|
99
|
+
.model-alias-configuration-main {
|
|
97
100
|
display: flex;
|
|
98
101
|
flex-direction: row;
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
#ai-agent-configuration-container-widget
|
|
102
105
|
.ai-agent-configuration-main
|
|
103
|
-
.configuration-agents-list
|
|
106
|
+
.configuration-agents-list,
|
|
107
|
+
#ai-model-aliases-configuration-widget .model-alias-configuration-list {
|
|
104
108
|
min-width: 160px;
|
|
105
109
|
overflow: hidden;
|
|
106
110
|
white-space: nowrap;
|
|
@@ -109,7 +113,8 @@
|
|
|
109
113
|
padding: var(--theia-ui-padding);
|
|
110
114
|
}
|
|
111
115
|
|
|
112
|
-
.configuration-agent-panel
|
|
116
|
+
.configuration-agent-panel,
|
|
117
|
+
.model-alias-configuration-panel {
|
|
113
118
|
flex: 1;
|
|
114
119
|
}
|
|
115
120
|
|
|
@@ -337,6 +342,32 @@
|
|
|
337
342
|
font-style: italic;
|
|
338
343
|
}
|
|
339
344
|
|
|
345
|
+
.prompt-variant-warning {
|
|
346
|
+
color: var(--theia-warningForeground);
|
|
347
|
+
background: var(--theia-warningBackground);
|
|
348
|
+
border-left: 4px solid var(--theia-warningBorder);
|
|
349
|
+
padding: 6px 12px;
|
|
350
|
+
margin-bottom: 8px;
|
|
351
|
+
display: flex;
|
|
352
|
+
align-items: center;
|
|
353
|
+
gap: 8px;
|
|
354
|
+
border-radius: 3px;
|
|
355
|
+
font-size: 0.95em;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.prompt-variant-error {
|
|
359
|
+
color: var(--theia-errorForeground);
|
|
360
|
+
background: var(--theia-errorBackground);
|
|
361
|
+
border-left: 4px solid var(--theia-errorBorder);
|
|
362
|
+
padding: 6px 12px;
|
|
363
|
+
margin-bottom: 8px;
|
|
364
|
+
display: flex;
|
|
365
|
+
align-items: center;
|
|
366
|
+
gap: 8px;
|
|
367
|
+
border-radius: 3px;
|
|
368
|
+
font-size: 0.95em;
|
|
369
|
+
}
|
|
370
|
+
|
|
340
371
|
/* Template content collapsable styles */
|
|
341
372
|
.template-content-container {
|
|
342
373
|
padding: 10px;
|
|
@@ -746,6 +777,80 @@ h4 {
|
|
|
746
777
|
|
|
747
778
|
/* End AI Tools Configuration Widget Styles */
|
|
748
779
|
|
|
780
|
+
/* AI Model Aliases and Language Model Renderer extracted styles */
|
|
781
|
+
.ai-model-alias-list {
|
|
782
|
+
width: 25%;
|
|
783
|
+
}
|
|
784
|
+
.ai-alias-detail-title {
|
|
785
|
+
padding-left: 0;
|
|
786
|
+
padding-bottom: 10px;
|
|
787
|
+
}
|
|
788
|
+
.ai-alias-detail-description {
|
|
789
|
+
padding-bottom: 10px;
|
|
790
|
+
}
|
|
791
|
+
.ai-alias-detail-selected-model {
|
|
792
|
+
margin-bottom: 20px;
|
|
793
|
+
}
|
|
794
|
+
.ai-language-model-item-ready {
|
|
795
|
+
font-style: normal;
|
|
796
|
+
}
|
|
797
|
+
.ai-language-model-item-not-ready {
|
|
798
|
+
font-style: italic;
|
|
799
|
+
}
|
|
800
|
+
.ai-alias-priority-item-resolved {
|
|
801
|
+
font-weight: bold;
|
|
802
|
+
}
|
|
803
|
+
.ai-alias-priority-item-ready {
|
|
804
|
+
font-style: inherit;
|
|
805
|
+
}
|
|
806
|
+
.ai-alias-priority-item-not-ready {
|
|
807
|
+
font-style: italic;
|
|
808
|
+
}
|
|
809
|
+
.ai-alias-detail-defaults {
|
|
810
|
+
margin-bottom: 10px;
|
|
811
|
+
}
|
|
812
|
+
.ai-model-default-not-ready {
|
|
813
|
+
font-style: italic;
|
|
814
|
+
color: var(--theia-descriptionForeground);
|
|
815
|
+
}
|
|
816
|
+
.ai-alias-defaults-hint {
|
|
817
|
+
color: var(--theia-descriptionForeground);
|
|
818
|
+
margin-top: 8px;
|
|
819
|
+
}
|
|
820
|
+
.ai-alias-evaluates-to-container {
|
|
821
|
+
margin-top: 8px;
|
|
822
|
+
margin-bottom: 8px;
|
|
823
|
+
}
|
|
824
|
+
.ai-alias-evaluates-to-label {
|
|
825
|
+
font-weight: 600;
|
|
826
|
+
}
|
|
827
|
+
.ai-alias-evaluates-to-value {
|
|
828
|
+
margin-left: 8px;
|
|
829
|
+
}
|
|
830
|
+
.ai-model-status-ready {
|
|
831
|
+
color: green;
|
|
832
|
+
margin-left: 6px;
|
|
833
|
+
}
|
|
834
|
+
.ai-model-status-not-ready {
|
|
835
|
+
color: red;
|
|
836
|
+
margin-left: 6px;
|
|
837
|
+
}
|
|
838
|
+
.ai-alias-evaluates-to-unresolved {
|
|
839
|
+
margin-left: 8px;
|
|
840
|
+
color: var(--theia-descriptionForeground);
|
|
841
|
+
}
|
|
842
|
+
.ai-alias-detail-agents {
|
|
843
|
+
margin-bottom: 10px;
|
|
844
|
+
}
|
|
845
|
+
.ai-alias-agent-id {
|
|
846
|
+
color: var(--theia-descriptionForeground);
|
|
847
|
+
margin-left: 8px;
|
|
848
|
+
}
|
|
849
|
+
.ai-alias-no-agents {
|
|
850
|
+
color: var(--theia-descriptionForeground);
|
|
851
|
+
}
|
|
852
|
+
/* End AI Model Aliases and Language Model Renderer extracted styles */
|
|
853
|
+
|
|
749
854
|
/* Token Usage Configuration Styles */
|
|
750
855
|
.token-usage-configuration-title {
|
|
751
856
|
margin: 0 0 16px 0;
|
|
@@ -0,0 +1,60 @@
|
|
|
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 { CancellationTokenSource } from '@theia/core';
|
|
18
|
+
import { expect } from 'chai';
|
|
19
|
+
|
|
20
|
+
// Simple test for cancellation handling
|
|
21
|
+
describe('Tool Provider Cancellation Tests', () => {
|
|
22
|
+
it('should verify basic cancellation token functionality', () => {
|
|
23
|
+
// Create a cancellation token source
|
|
24
|
+
const cts = new CancellationTokenSource();
|
|
25
|
+
|
|
26
|
+
// Initially the token should not be cancelled
|
|
27
|
+
expect(cts.token.isCancellationRequested).to.be.false;
|
|
28
|
+
|
|
29
|
+
// After cancellation, the token should report as cancelled
|
|
30
|
+
cts.cancel();
|
|
31
|
+
expect(cts.token.isCancellationRequested).to.be.true;
|
|
32
|
+
|
|
33
|
+
// Cleanup
|
|
34
|
+
cts.dispose();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should trigger cancellation callback when cancelled', async () => {
|
|
38
|
+
// Create a cancellation token source
|
|
39
|
+
const cts = new CancellationTokenSource();
|
|
40
|
+
|
|
41
|
+
// Create a flag to track if the callback was called
|
|
42
|
+
let callbackCalled = false;
|
|
43
|
+
|
|
44
|
+
// Register a cancellation callback
|
|
45
|
+
const disposable = cts.token.onCancellationRequested(() => {
|
|
46
|
+
callbackCalled = true;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Initially the callback should not have been called
|
|
50
|
+
expect(callbackCalled).to.be.false;
|
|
51
|
+
|
|
52
|
+
// After cancellation, the callback should be called
|
|
53
|
+
cts.cancel();
|
|
54
|
+
expect(callbackCalled).to.be.true;
|
|
55
|
+
|
|
56
|
+
// Cleanup
|
|
57
|
+
disposable.dispose();
|
|
58
|
+
cts.dispose();
|
|
59
|
+
});
|
|
60
|
+
});
|