@theia/ai-chat-ui 1.59.0-next.62 → 1.59.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 (57) hide show
  1. package/lib/browser/ai-chat-ui-frontend-module.d.ts +1 -1
  2. package/lib/browser/ai-chat-ui-frontend-module.d.ts.map +1 -1
  3. package/lib/browser/ai-chat-ui-frontend-module.js +12 -11
  4. package/lib/browser/ai-chat-ui-frontend-module.js.map +1 -1
  5. package/lib/browser/change-set-actions/change-set-accept-action.d.ts +10 -0
  6. package/lib/browser/change-set-actions/change-set-accept-action.d.ts.map +1 -0
  7. package/lib/browser/change-set-actions/change-set-accept-action.js +47 -0
  8. package/lib/browser/change-set-actions/change-set-accept-action.js.map +1 -0
  9. package/lib/browser/change-set-actions/change-set-action-service.d.ts +31 -0
  10. package/lib/browser/change-set-actions/change-set-action-service.d.ts.map +1 -0
  11. package/lib/browser/change-set-actions/change-set-action-service.js +57 -0
  12. package/lib/browser/change-set-actions/change-set-action-service.js.map +1 -0
  13. package/lib/browser/chat-input-widget.d.ts +6 -4
  14. package/lib/browser/chat-input-widget.d.ts.map +1 -1
  15. package/lib/browser/chat-input-widget.js +57 -43
  16. package/lib/browser/chat-input-widget.js.map +1 -1
  17. package/lib/browser/chat-response-renderer/ai-selection-resolver.d.ts +23 -0
  18. package/lib/browser/chat-response-renderer/ai-selection-resolver.d.ts.map +1 -0
  19. package/lib/browser/chat-response-renderer/{ai-editor-manager.js → ai-selection-resolver.js} +2 -38
  20. package/lib/browser/chat-response-renderer/ai-selection-resolver.js.map +1 -0
  21. package/lib/browser/chat-response-renderer/code-part-renderer.d.ts.map +1 -1
  22. package/lib/browser/chat-response-renderer/code-part-renderer.js +3 -2
  23. package/lib/browser/chat-response-renderer/code-part-renderer.js.map +1 -1
  24. package/lib/browser/chat-response-renderer/index.d.ts +1 -1
  25. package/lib/browser/chat-response-renderer/index.d.ts.map +1 -1
  26. package/lib/browser/chat-response-renderer/index.js +1 -1
  27. package/lib/browser/chat-response-renderer/index.js.map +1 -1
  28. package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts.map +1 -1
  29. package/lib/browser/chat-tree-view/chat-view-tree-widget.js +2 -1
  30. package/lib/browser/chat-tree-view/chat-view-tree-widget.js.map +1 -1
  31. package/lib/browser/chat-view-contribution.d.ts.map +1 -1
  32. package/lib/browser/chat-view-contribution.js +2 -2
  33. package/lib/browser/chat-view-contribution.js.map +1 -1
  34. package/lib/browser/chat-view-language-contribution.d.ts +1 -0
  35. package/lib/browser/chat-view-language-contribution.d.ts.map +1 -1
  36. package/lib/browser/chat-view-language-contribution.js +19 -9
  37. package/lib/browser/chat-view-language-contribution.js.map +1 -1
  38. package/lib/browser/chat-view-widget.d.ts +1 -1
  39. package/lib/browser/chat-view-widget.d.ts.map +1 -1
  40. package/lib/browser/chat-view-widget.js +2 -3
  41. package/lib/browser/chat-view-widget.js.map +1 -1
  42. package/package.json +11 -11
  43. package/src/browser/ai-chat-ui-frontend-module.ts +12 -14
  44. package/src/browser/change-set-actions/change-set-accept-action.tsx +52 -0
  45. package/src/browser/change-set-actions/change-set-action-service.ts +65 -0
  46. package/src/browser/chat-input-widget.tsx +88 -61
  47. package/src/browser/chat-response-renderer/{ai-editor-manager.ts → ai-selection-resolver.ts} +6 -45
  48. package/src/browser/chat-response-renderer/code-part-renderer.tsx +3 -2
  49. package/src/browser/chat-response-renderer/index.ts +1 -1
  50. package/src/browser/chat-tree-view/chat-view-tree-widget.tsx +2 -1
  51. package/src/browser/chat-view-contribution.ts +2 -2
  52. package/src/browser/chat-view-language-contribution.ts +22 -10
  53. package/src/browser/chat-view-widget.tsx +2 -3
  54. package/src/browser/style/index.css +20 -4
  55. package/lib/browser/chat-response-renderer/ai-editor-manager.d.ts +0 -36
  56. package/lib/browser/chat-response-renderer/ai-editor-manager.d.ts.map +0 -1
  57. package/lib/browser/chat-response-renderer/ai-editor-manager.js.map +0 -1
@@ -114,13 +114,12 @@ let ChatViewWidget = ChatViewWidget_1 = class ChatViewWidget extends browser_1.B
114
114
  get onStateChanged() {
115
115
  return this.onStateChangedEmitter.event;
116
116
  }
117
- async onQuery(query, contextVariableRequests) {
117
+ async onQuery(query) {
118
118
  if (query.length === 0) {
119
119
  return;
120
120
  }
121
121
  const chatRequest = { text: query };
122
- const context = { variableRequests: contextVariableRequests !== null && contextVariableRequests !== void 0 ? contextVariableRequests : [] };
123
- const requestProgress = await this.chatService.sendRequest(this.chatSession.id, chatRequest, context);
122
+ const requestProgress = await this.chatService.sendRequest(this.chatSession.id, chatRequest);
124
123
  requestProgress === null || requestProgress === void 0 ? void 0 : requestProgress.responseCompleted.then(responseModel => {
125
124
  var _a, _b;
126
125
  if (responseModel.isError) {
@@ -1 +1 @@
1
- {"version":3,"file":"chat-view-widget.js","sourceRoot":"","sources":["../../src/browser/chat-view-widget.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-view-widget.js","sourceRoot":"","sources":["../../src/browser/chat-view-widget.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@theia/ai-chat-ui",
3
- "version": "1.59.0-next.62+9e43c93ad",
3
+ "version": "1.59.0",
4
4
  "description": "Theia - AI Chat UI Extension",
5
5
  "dependencies": {
6
- "@theia/ai-chat": "1.59.0-next.62+9e43c93ad",
7
- "@theia/ai-core": "1.59.0-next.62+9e43c93ad",
8
- "@theia/core": "1.59.0-next.62+9e43c93ad",
9
- "@theia/editor": "1.59.0-next.62+9e43c93ad",
10
- "@theia/editor-preview": "1.59.0-next.62+9e43c93ad",
11
- "@theia/filesystem": "1.59.0-next.62+9e43c93ad",
12
- "@theia/monaco": "1.59.0-next.62+9e43c93ad",
6
+ "@theia/ai-chat": "1.59.0",
7
+ "@theia/ai-core": "1.59.0",
8
+ "@theia/core": "1.59.0",
9
+ "@theia/editor": "1.59.0",
10
+ "@theia/editor-preview": "1.59.0",
11
+ "@theia/filesystem": "1.59.0",
12
+ "@theia/monaco": "1.59.0",
13
13
  "@theia/monaco-editor-core": "1.96.302",
14
- "@theia/workspace": "1.59.0-next.62+9e43c93ad",
14
+ "@theia/workspace": "1.59.0",
15
15
  "minimatch": "^5.1.0",
16
16
  "tslib": "^2.6.2",
17
17
  "uuid": "^9.0.1"
@@ -50,10 +50,10 @@
50
50
  "watch": "theiaext watch"
51
51
  },
52
52
  "devDependencies": {
53
- "@theia/ext-scripts": "1.58.0"
53
+ "@theia/ext-scripts": "1.59.0"
54
54
  },
55
55
  "nyc": {
56
56
  "extends": "../../configs/nyc.json"
57
57
  },
58
- "gitHead": "9e43c93ad61ea977db3974207bac5d7c1fd3ccd6"
58
+ "gitHead": "ce21dd18b5aceee41d5265066f8bb1a69b3710e6"
59
59
  }
@@ -14,13 +14,12 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
 
17
+ import '../../src/browser/style/index.css';
17
18
  import { bindContributionProvider, CommandContribution, MenuContribution } from '@theia/core';
18
19
  import { bindViewContribution, FrontendApplicationContribution, WidgetFactory } from '@theia/core/lib/browser';
19
20
  import { TabBarToolbarContribution } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
20
21
  import { ContainerModule, interfaces } from '@theia/core/shared/inversify';
21
- import { EditorPreviewManager } from '@theia/editor-preview/lib/browser/editor-preview-manager';
22
- import { EditorManager } from '@theia/editor/lib/browser';
23
- import '../../src/browser/style/index.css';
22
+ import { EditorSelectionResolver } from '@theia/editor/lib/browser/editor-manager';
24
23
  import { AIChatContribution } from './ai-chat-ui-contribution';
25
24
  import { AIChatInputConfiguration, AIChatInputWidget } from './chat-input-widget';
26
25
  import { ChatNodeToolbarActionContribution } from './chat-node-toolbar-action-contribution';
@@ -37,12 +36,10 @@ import {
37
36
  ToolCallPartRenderer,
38
37
  } from './chat-response-renderer';
39
38
  import {
40
- AIEditorManager,
41
- AIEditorSelectionResolver,
42
39
  GitHubSelectionResolver,
43
40
  TextFragmentSelectionResolver,
44
41
  TypeDocSymbolSelectionResolver,
45
- } from './chat-response-renderer/ai-editor-manager';
42
+ } from './chat-response-renderer/ai-selection-resolver';
46
43
  import { QuestionPartRenderer } from './chat-response-renderer/question-part-renderer';
47
44
  import { createChatViewTreeWidget } from './chat-tree-view';
48
45
  import { ChatViewTreeWidget } from './chat-tree-view/chat-view-tree-widget';
@@ -51,6 +48,8 @@ import { ChatViewLanguageContribution } from './chat-view-language-contribution'
51
48
  import { ChatViewWidget } from './chat-view-widget';
52
49
  import { ChatViewWidgetToolbarContribution } from './chat-view-widget-toolbar-contribution';
53
50
  import { ContextVariablePicker } from './context-variable-picker';
51
+ import { ChangeSetActionRenderer, ChangeSetActionService } from './change-set-actions/change-set-action-service';
52
+ import { ChangeSetAcceptAction } from './change-set-actions/change-set-accept-action';
54
53
 
55
54
  export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
56
55
  bindViewContribution(bind, AIChatContribution);
@@ -93,24 +92,23 @@ export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
93
92
  );
94
93
 
95
94
  bindContributionProvider(bind, CodePartRendererAction);
95
+ bindContributionProvider(bind, ChangeSetActionRenderer);
96
96
  bind(CopyToClipboardButtonAction).toSelf().inSingletonScope();
97
97
  bind(CodePartRendererAction).toService(CopyToClipboardButtonAction);
98
98
  bind(InsertCodeAtCursorButtonAction).toSelf().inSingletonScope();
99
99
  bind(CodePartRendererAction).toService(InsertCodeAtCursorButtonAction);
100
100
 
101
- bind(AIEditorManager).toSelf().inSingletonScope();
102
- rebind(EditorManager).toService(AIEditorManager);
103
- rebind(EditorPreviewManager).toService(AIEditorManager);
104
-
105
- bindContributionProvider(bind, AIEditorSelectionResolver);
106
- bind(AIEditorSelectionResolver).to(GitHubSelectionResolver).inSingletonScope();
107
- bind(AIEditorSelectionResolver).to(TypeDocSymbolSelectionResolver).inSingletonScope();
108
- bind(AIEditorSelectionResolver).to(TextFragmentSelectionResolver).inSingletonScope();
101
+ bind(EditorSelectionResolver).to(GitHubSelectionResolver).inSingletonScope();
102
+ bind(EditorSelectionResolver).to(TypeDocSymbolSelectionResolver).inSingletonScope();
103
+ bind(EditorSelectionResolver).to(TextFragmentSelectionResolver).inSingletonScope();
109
104
 
110
105
  bind(ChatViewWidgetToolbarContribution).toSelf().inSingletonScope();
111
106
  bind(TabBarToolbarContribution).toService(ChatViewWidgetToolbarContribution);
112
107
 
113
108
  bind(FrontendApplicationContribution).to(ChatViewLanguageContribution).inSingletonScope();
109
+ bind(ChangeSetActionService).toSelf().inSingletonScope();
110
+ bind(ChangeSetAcceptAction).toSelf().inSingletonScope();
111
+ bind(ChangeSetActionRenderer).toService(ChangeSetAcceptAction);
114
112
 
115
113
  bindContributionProvider(bind, ChatNodeToolbarActionContribution);
116
114
  });
@@ -0,0 +1,52 @@
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
+ import * as React from '@theia/core/shared/react';
18
+ import { injectable } from '@theia/core/shared/inversify';
19
+ import { ChangeSetActionRenderer } from './change-set-action-service';
20
+ import { ChangeSet, ChangeSetElement } from '@theia/ai-chat';
21
+ import { nls } from '@theia/core';
22
+
23
+ @injectable()
24
+ export class ChangeSetAcceptAction implements ChangeSetActionRenderer {
25
+ readonly id = 'change-set-accept-action';
26
+ canRender(changeSet: ChangeSet): boolean {
27
+ return changeSet.getElements().length > 0;
28
+ }
29
+
30
+ render(changeSet: ChangeSet): React.ReactNode {
31
+ return <button
32
+ className='theia-button'
33
+ disabled={!hasPendingElementsToAccept(changeSet)}
34
+ title={nls.localize('theia/ai/chat-ui/applyAllTitle', 'Apply all pending changes')}
35
+ onClick={() => acceptAllPendingElements(changeSet)}
36
+ >
37
+ {nls.localize('theia/ai/chat-ui/applyAll', 'Apply All')}
38
+ </button>;
39
+ }
40
+ }
41
+
42
+ function acceptAllPendingElements(changeSet: ChangeSet): void {
43
+ acceptablePendingElements(changeSet).forEach(e => e.apply!());
44
+ }
45
+
46
+ function hasPendingElementsToAccept(changeSet: ChangeSet): boolean | undefined {
47
+ return acceptablePendingElements(changeSet).length > 0;
48
+ }
49
+
50
+ function acceptablePendingElements(changeSet: ChangeSet): ChangeSetElement[] {
51
+ return changeSet.getElements().filter(e => e.apply && (e.state === undefined || e.state === 'pending'));
52
+ }
@@ -0,0 +1,65 @@
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 { ContributionProvider, Event, Emitter } from '@theia/core';
18
+ import { ChangeSet } from '@theia/ai-chat';
19
+ import { inject, injectable, named, postConstruct } from '@theia/core/shared/inversify';
20
+
21
+ export const ChangeSetActionRenderer = Symbol('ChangeSetActionRenderer');
22
+ /**
23
+ * The CodePartRenderer offers to contribute arbitrary React nodes to the rendered code part.
24
+ * Technically anything can be rendered, however it is intended to be used for actions, like
25
+ * "Copy to Clipboard" or "Insert at Cursor".
26
+ */
27
+ export interface ChangeSetActionRenderer {
28
+ readonly id: string;
29
+ onDidChange?: Event<void>;
30
+ render(changeSet: ChangeSet): React.ReactNode;
31
+ /**
32
+ * Determines if the action should be rendered for the given response.
33
+ */
34
+ canRender?(changeSet: ChangeSet): boolean;
35
+ /**
36
+ * Actions are ordered by descending priority. (Highest on left).
37
+ */
38
+ readonly priority?: number;
39
+ }
40
+
41
+ @injectable()
42
+ export class ChangeSetActionService {
43
+ protected readonly onDidChangeEmitter = new Emitter<void>();
44
+ get onDidChange(): Event<void> {
45
+ return this.onDidChangeEmitter.event;
46
+ }
47
+
48
+ @inject(ContributionProvider) @named(ChangeSetActionRenderer)
49
+ protected readonly contributions: ContributionProvider<ChangeSetActionRenderer>;
50
+
51
+ @postConstruct()
52
+ protected init(): void {
53
+ const actions = this.contributions.getContributions();
54
+ actions.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
55
+ actions.forEach(contribution => contribution.onDidChange?.(this.onDidChangeEmitter.fire, this.onDidChangeEmitter));
56
+ }
57
+
58
+ getActions(): readonly ChangeSetActionRenderer[] {
59
+ return this.contributions.getContributions();
60
+ }
61
+
62
+ getActionsForChangeset(changeSet: ChangeSet): ChangeSetActionRenderer[] {
63
+ return this.getActions().filter(candidate => !candidate.canRender || candidate.canRender(changeSet));
64
+ }
65
+ }
@@ -13,8 +13,8 @@
13
13
  //
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
- import { ChangeSet, ChangeSetElement, ChatAgent, ChatChangeEvent, ChatModel, ChatRequestModel } from '@theia/ai-chat';
17
- import { Disposable, InMemoryResources, URI, nls } from '@theia/core';
16
+ import { ChangeSet, ChatAgent, ChatChangeEvent, ChatModel, ChatRequestModel } from '@theia/ai-chat';
17
+ import { Disposable, DisposableCollection, InMemoryResources, URI, nls } from '@theia/core';
18
18
  import { ContextMenuRenderer, LabelProvider, Message, ReactWidget } from '@theia/core/lib/browser';
19
19
  import { Deferred } from '@theia/core/lib/common/promise-util';
20
20
  import { inject, injectable, optional, postConstruct } from '@theia/core/shared/inversify';
@@ -26,8 +26,9 @@ import { CHAT_VIEW_LANGUAGE_EXTENSION } from './chat-view-language-contribution'
26
26
  import { AIVariableResolutionRequest } from '@theia/ai-core';
27
27
  import { FrontendVariableService } from '@theia/ai-core/lib/browser';
28
28
  import { ContextVariablePicker } from './context-variable-picker';
29
+ import { ChangeSetActionRenderer, ChangeSetActionService } from './change-set-actions/change-set-action-service';
29
30
 
30
- type Query = (query: string, context?: AIVariableResolutionRequest[]) => Promise<void>;
31
+ type Query = (query: string) => Promise<void>;
31
32
  type Unpin = () => void;
32
33
  type Cancel = (requestModel: ChatRequestModel) => void;
33
34
  type DeleteChangeSet = (requestModel: ChatRequestModel) => void;
@@ -65,13 +66,14 @@ export class AIChatInputWidget extends ReactWidget {
65
66
  @inject(ContextVariablePicker)
66
67
  protected readonly contextVariablePicker: ContextVariablePicker;
67
68
 
69
+ @inject(ChangeSetActionService)
70
+ protected readonly changeSetActionService: ChangeSetActionService;
71
+
68
72
  protected editorRef: MonacoEditor | undefined = undefined;
69
73
  private editorReady = new Deferred<void>();
70
74
 
71
75
  protected isEnabled = false;
72
76
 
73
- protected context: AIVariableResolutionRequest[] = [];
74
-
75
77
  private _onQuery: Query;
76
78
  set onQuery(query: Query) {
77
79
  this._onQuery = query;
@@ -93,8 +95,16 @@ export class AIChatInputWidget extends ReactWidget {
93
95
  this._onDeleteChangeSetElement = deleteChangeSetElement;
94
96
  }
95
97
 
98
+ protected onDisposeForChatModel = new DisposableCollection();
96
99
  private _chatModel: ChatModel;
97
100
  set chatModel(chatModel: ChatModel) {
101
+ this.onDisposeForChatModel.dispose();
102
+ this.onDisposeForChatModel = new DisposableCollection();
103
+ this.onDisposeForChatModel.push(chatModel.onDidChange(event => {
104
+ if (event.kind === 'addVariable' || event.kind === 'removeVariable') {
105
+ this.update();
106
+ }
107
+ }));
98
108
  this._chatModel = chatModel;
99
109
  this.update();
100
110
  }
@@ -132,7 +142,7 @@ export class AIChatInputWidget extends ReactWidget {
132
142
  onDeleteChangeSetElement={this._onDeleteChangeSetElement.bind(this)}
133
143
  onAddContextElement={this.addContextElement.bind(this)}
134
144
  onDeleteContextElement={this.deleteContextElement.bind(this)}
135
- context={this.context}
145
+ context={this._chatModel.context.getVariables()}
136
146
  chatModel={this._chatModel}
137
147
  pinnedAgent={this._pinnedAgent}
138
148
  editorProvider={this.editorProvider}
@@ -146,6 +156,7 @@ export class AIChatInputWidget extends ReactWidget {
146
156
  showContext={this.configuration?.showContext}
147
157
  showPinnedAgent={this.configuration?.showPinnedAgent}
148
158
  labelProvider={this.labelProvider}
159
+ actionService={this.changeSetActionService}
149
160
  />
150
161
  );
151
162
  }
@@ -192,36 +203,32 @@ export class AIChatInputWidget extends ReactWidget {
192
203
  protected addContextElement(): void {
193
204
  this.contextVariablePicker.pickContextVariable().then(contextElement => {
194
205
  if (contextElement) {
195
- this.addContext(contextElement);
206
+ this._chatModel.context.addVariables(contextElement);
196
207
  }
197
208
  });
198
209
  }
199
210
 
200
211
  protected deleteContextElement(index: number): void {
201
- this.context.splice(index, 1);
202
- this.update();
212
+ this._chatModel.context.deleteVariables(index);
203
213
  }
204
214
 
205
215
  protected handleContextMenu(event: IMouseEvent): void {
206
216
  this.contextMenuRenderer.render({
207
217
  menuPath: AIChatInputWidget.CONTEXT_MENU,
208
218
  anchor: { x: event.posx, y: event.posy },
219
+ context: event.target
209
220
  });
210
221
  event.preventDefault();
211
222
  }
212
223
 
213
- addContext(variableRequest: AIVariableResolutionRequest): void {
214
- if (this.context.some(existing => existing.variable.id === variableRequest.variable.id && existing.arg === variableRequest.arg)) {
215
- return;
216
- }
217
- this.context.push(variableRequest);
218
- this.update();
224
+ addContext(variable: AIVariableResolutionRequest): void {
225
+ this._chatModel.context.addVariables(variable);
219
226
  }
220
227
  }
221
228
 
222
229
  interface ChatInputProperties {
223
230
  onCancel: (requestModel: ChatRequestModel) => void;
224
- onQuery: (query: string, context?: AIVariableResolutionRequest[]) => void;
231
+ onQuery: (query: string) => void;
225
232
  onUnpin: () => void;
226
233
  onDragOver: (event: React.DragEvent) => void;
227
234
  onDrop: (event: React.DragEvent) => void;
@@ -229,7 +236,7 @@ interface ChatInputProperties {
229
236
  onDeleteChangeSetElement: (sessionId: string, index: number) => void;
230
237
  onAddContextElement: () => void;
231
238
  onDeleteContextElement: (index: number) => void;
232
- context?: AIVariableResolutionRequest[];
239
+ context?: readonly AIVariableResolutionRequest[];
233
240
  isEnabled?: boolean;
234
241
  chatModel: ChatModel;
235
242
  pinnedAgent?: ChatAgent;
@@ -240,6 +247,7 @@ interface ChatInputProperties {
240
247
  showContext?: boolean;
241
248
  showPinnedAgent?: boolean;
242
249
  labelProvider: LabelProvider;
250
+ actionService: ChangeSetActionService;
243
251
  }
244
252
 
245
253
  const ChatInput: React.FunctionComponent<ChatInputProperties> = (props: ChatInputProperties) => {
@@ -249,7 +257,15 @@ const ChatInput: React.FunctionComponent<ChatInputProperties> = (props: ChatInpu
249
257
  const [inProgress, setInProgress] = React.useState(false);
250
258
  const [isInputEmpty, setIsInputEmpty] = React.useState(true);
251
259
  const [changeSetUI, setChangeSetUI] = React.useState(
252
- () => props.chatModel.changeSet ? buildChangeSetUI(props.chatModel.changeSet, props.labelProvider, onDeleteChangeSet, onDeleteChangeSetElement) : undefined
260
+ () => props.chatModel.changeSet
261
+ ? buildChangeSetUI(
262
+ props.chatModel.changeSet,
263
+ props.labelProvider,
264
+ props.actionService.getActionsForChangeset(props.chatModel.changeSet),
265
+ onDeleteChangeSet,
266
+ onDeleteChangeSetElement
267
+ )
268
+ : undefined
253
269
  );
254
270
 
255
271
  // eslint-disable-next-line no-null/no-null
@@ -353,14 +369,28 @@ const ChatInput: React.FunctionComponent<ChatInputProperties> = (props: ChatInpu
353
369
  setInProgress(ChatRequestModel.isInProgress(event.request))
354
370
  );
355
371
  } else if (ChatChangeEvent.isChangeSetEvent(event)) {
356
- if (event.changeSet) {
357
- setChangeSetUI(buildChangeSetUI(event.changeSet, props.labelProvider, onDeleteChangeSet, onDeleteChangeSetElement));
358
- } else {
372
+ if (event.kind === 'removeChangeSet') {
359
373
  setChangeSetUI(undefined);
374
+ } else if (event.kind === 'setChangeSet' || 'updateChangeSet') {
375
+ setChangeSetUI(buildChangeSetUI(
376
+ event.changeSet,
377
+ props.labelProvider,
378
+ props.actionService.getActionsForChangeset(event.changeSet),
379
+ onDeleteChangeSet,
380
+ onDeleteChangeSetElement
381
+ ));
360
382
  }
361
383
  }
362
384
  });
363
- setChangeSetUI(props.chatModel.changeSet ? buildChangeSetUI(props.chatModel.changeSet, props.labelProvider, onDeleteChangeSet, onDeleteChangeSetElement) : undefined);
385
+ setChangeSetUI(props.chatModel.changeSet
386
+ ? buildChangeSetUI(
387
+ props.chatModel.changeSet,
388
+ props.labelProvider,
389
+ props.actionService.getActionsForChangeset(props.chatModel.changeSet),
390
+ onDeleteChangeSet,
391
+ onDeleteChangeSetElement
392
+ )
393
+ : undefined);
364
394
  return () => {
365
395
  listener?.dispose();
366
396
  responseListenerRef.current?.dispose();
@@ -368,16 +398,25 @@ const ChatInput: React.FunctionComponent<ChatInputProperties> = (props: ChatInpu
368
398
  };
369
399
  }, [props.chatModel]);
370
400
 
371
- function submit(value: string): void {
401
+ React.useEffect(() => {
402
+ const disposable = props.actionService.onDidChange(() => {
403
+ if (!props.chatModel.changeSet) { return; }
404
+ const newActions = props.actionService.getActionsForChangeset(props.chatModel.changeSet);
405
+ setChangeSetUI(current => !current ? current : { ...current, actions: newActions });
406
+ });
407
+ return () => disposable.dispose();
408
+ });
409
+
410
+ const submit = React.useCallback(function submit(value: string): void {
372
411
  if (!value || value.trim().length === 0) {
373
412
  return;
374
413
  }
375
414
  setInProgress(true);
376
- props.onQuery(value, props.context);
415
+ props.onQuery(value);
377
416
  if (editorRef.current) {
378
417
  editorRef.current.document.textEditorModel.setValue('');
379
418
  }
380
- }
419
+ }, [props.context, props.onQuery, editorRef]);
381
420
 
382
421
  const onKeyDown = React.useCallback((event: React.KeyboardEvent) => {
383
422
  if (!props.isEnabled) {
@@ -387,7 +426,7 @@ const ChatInput: React.FunctionComponent<ChatInputProperties> = (props: ChatInpu
387
426
  event.preventDefault();
388
427
  submit(editorRef.current?.document.textEditorModel.getValue() || '');
389
428
  }
390
- }, [props.isEnabled]);
429
+ }, [props.isEnabled, submit]);
391
430
 
392
431
  const handleInputFocus = () => {
393
432
  hidePlaceholderIfEditorFilled();
@@ -498,13 +537,18 @@ const noPropagation = (handler: () => void) => (e: React.MouseEvent) => {
498
537
  e.stopPropagation();
499
538
  };
500
539
 
501
- const buildChangeSetUI = (changeSet: ChangeSet, labelProvider: LabelProvider, onDeleteChangeSet: () => void, onDeleteChangeSetElement: (index: number) => void): ChangeSetUI => ({
540
+ const buildChangeSetUI = (
541
+ changeSet: ChangeSet,
542
+ labelProvider: LabelProvider,
543
+ actions: ChangeSetActionRenderer[],
544
+ onDeleteChangeSet: () => void,
545
+ onDeleteChangeSetElement: (index: number) => void
546
+ ): ChangeSetUI => ({
502
547
  title: changeSet.title,
503
- disabled: !hasPendingElementsToAccept(changeSet),
504
- applyAllPendingElements: () => applyAllPendingElements(changeSet),
505
- delete: () => onDeleteChangeSet(),
548
+ changeSet,
549
+ deleteChangeSet: onDeleteChangeSet,
506
550
  elements: changeSet.getElements().map(element => ({
507
- open: element?.open?.bind(element),
551
+ open: element.open?.bind(element),
508
552
  iconClass: element.icon ?? labelProvider.getIcon(element.uri) ?? labelProvider.fileIcon,
509
553
  nameClass: `${element.type} ${element.state}`,
510
554
  name: element.name ?? labelProvider.getName(element.uri),
@@ -513,7 +557,8 @@ const buildChangeSetUI = (changeSet: ChangeSet, labelProvider: LabelProvider, on
513
557
  apply: element.state !== 'applied' ? element?.apply?.bind(element) : undefined,
514
558
  revert: element.state === 'applied' || element.state === 'stale' ? element?.revert?.bind(element) : undefined,
515
559
  delete: () => onDeleteChangeSetElement(changeSet.getElements().indexOf(element))
516
- }))
560
+ })),
561
+ actions
517
562
  });
518
563
 
519
564
  interface ChangeSetUIElement {
@@ -529,32 +574,26 @@ interface ChangeSetUIElement {
529
574
  }
530
575
 
531
576
  interface ChangeSetUI {
577
+ changeSet: ChangeSet;
532
578
  title: string;
533
- disabled: boolean;
534
- applyAllPendingElements: () => void;
535
- delete: () => void;
579
+ deleteChangeSet: () => void;
536
580
  elements: ChangeSetUIElement[];
581
+ actions: ChangeSetActionRenderer[];
537
582
  }
538
583
 
539
- const ChangeSetBox: React.FunctionComponent<{ changeSet: ChangeSetUI }> = ({ changeSet }) => (
584
+ /** Memo because the parent element rerenders on every key press in the chat widget. */
585
+ const ChangeSetBox: React.FunctionComponent<{ changeSet: ChangeSetUI }> = React.memo(({ changeSet: { changeSet, title, deleteChangeSet, elements, actions } }) => (
540
586
  <div className='theia-ChatInput-ChangeSet-Box'>
541
587
  <div className='theia-ChatInput-ChangeSet-Header'>
542
- <h3>{changeSet.title}</h3>
588
+ <h3>{title}</h3>
543
589
  <div className='theia-ChatInput-ChangeSet-Header-Actions'>
544
- <button
545
- className='theia-button'
546
- disabled={changeSet.disabled}
547
- title={nls.localize('theia/ai/chat-ui/applyAllTitle', 'Apply all pending suggestions')}
548
- onClick={() => changeSet.applyAllPendingElements()}
549
- >
550
- {nls.localize('theia/ai/chat-ui/acceptAll', 'Apply All')}
551
- </button>
552
- <span className='codicon codicon-close action' title={nls.localize('theia/ai/chat-ui/deleteChangeSet', 'Delete Change Set')} onClick={() => changeSet.delete()} />
590
+ {actions.map(action => <div key={action.id} className='theia-changeSet-Action'>{action.render(changeSet)}</div>)}
591
+ <span className='codicon codicon-close action' title={nls.localize('theia/ai/chat-ui/deleteChangeSet', 'Delete Change Set')} onClick={() => deleteChangeSet()} />
553
592
  </div>
554
593
  </div>
555
594
  <div className='theia-ChatInput-ChangeSet-List'>
556
595
  <ul>
557
- {changeSet.elements.map((element, index) => (
596
+ {elements.map((element, index) => (
558
597
  <li key={index} title={nls.localize('theia/ai/chat-ui/openDiff', 'Open Diff')} onClick={() => element.openChange?.()}>
559
598
  <div className={`theia-ChatInput-ChangeSet-Icon ${element.iconClass}`} />
560
599
  <span className='theia-ChatInput-ChangeSet-labelParts'>
@@ -591,7 +630,7 @@ const ChangeSetBox: React.FunctionComponent<{ changeSet: ChangeSetUI }> = ({ cha
591
630
  </ul>
592
631
  </div>
593
632
  </div>
594
- );
633
+ ));
595
634
 
596
635
  interface ChatInputOptionsProps {
597
636
  leftOptions: Option[];
@@ -640,24 +679,12 @@ const ChatInputOptions: React.FunctionComponent<ChatInputOptionsProps> = ({ left
640
679
  </div>
641
680
  );
642
681
 
643
- function applyAllPendingElements(changeSet: ChangeSet): void {
644
- getPendingElements(changeSet).forEach(e => e.apply!());
645
- }
646
-
647
- function hasPendingElementsToAccept(changeSet: ChangeSet): boolean | undefined {
648
- return getPendingElements(changeSet).length > 0;
649
- }
650
-
651
- function getPendingElements(changeSet: ChangeSet): ChangeSetElement[] {
652
- return changeSet.getElements().filter(e => e.apply && (e.state === undefined || e.state === 'pending'));
653
- }
654
-
655
682
  function getLatestRequest(chatModel: ChatModel): ChatRequestModel | undefined {
656
683
  const requests = chatModel.getRequests();
657
684
  return requests.length > 0 ? requests[requests.length - 1] : undefined;
658
685
  }
659
686
 
660
- function buildContextUI(context: AIVariableResolutionRequest[] | undefined, labelProvider: LabelProvider, onDeleteContextElement: (index: number) => void): ChatContextUI {
687
+ function buildContextUI(context: readonly AIVariableResolutionRequest[] | undefined, labelProvider: LabelProvider, onDeleteContextElement: (index: number) => void): ChatContextUI {
661
688
  if (!context) {
662
689
  return { context: [] };
663
690
  }