@theia/ai-chat-ui 1.67.0-next.3 → 1.67.0-next.56

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 (165) hide show
  1. package/README.md +1 -0
  2. package/package.json +10 -10
  3. package/src/browser/chat-input-widget.tsx +77 -14
  4. package/src/browser/chat-response-renderer/markdown-part-renderer.tsx +4 -3
  5. package/src/browser/style/index.css +31 -0
  6. package/lib/browser/ai-chat-ui-contribution.d.ts +0 -66
  7. package/lib/browser/ai-chat-ui-contribution.d.ts.map +0 -1
  8. package/lib/browser/ai-chat-ui-contribution.js +0 -587
  9. package/lib/browser/ai-chat-ui-contribution.js.map +0 -1
  10. package/lib/browser/ai-chat-ui-frontend-module.d.ts +0 -5
  11. package/lib/browser/ai-chat-ui-frontend-module.d.ts.map +0 -1
  12. package/lib/browser/ai-chat-ui-frontend-module.js +0 -153
  13. package/lib/browser/ai-chat-ui-frontend-module.js.map +0 -1
  14. package/lib/browser/change-set-actions/change-set-accept-action.d.ts +0 -10
  15. package/lib/browser/change-set-actions/change-set-accept-action.d.ts.map +0 -1
  16. package/lib/browser/change-set-actions/change-set-accept-action.js +0 -47
  17. package/lib/browser/change-set-actions/change-set-accept-action.js.map +0 -1
  18. package/lib/browser/change-set-actions/change-set-action-service.d.ts +0 -31
  19. package/lib/browser/change-set-actions/change-set-action-service.d.ts.map +0 -1
  20. package/lib/browser/change-set-actions/change-set-action-service.js +0 -57
  21. package/lib/browser/change-set-actions/change-set-action-service.js.map +0 -1
  22. package/lib/browser/chat-input-agent-suggestions.d.ts +0 -11
  23. package/lib/browser/chat-input-agent-suggestions.d.ts.map +0 -1
  24. package/lib/browser/chat-input-agent-suggestions.js +0 -76
  25. package/lib/browser/chat-input-agent-suggestions.js.map +0 -1
  26. package/lib/browser/chat-input-history-contribution.d.ts +0 -17
  27. package/lib/browser/chat-input-history-contribution.d.ts.map +0 -1
  28. package/lib/browser/chat-input-history-contribution.js +0 -158
  29. package/lib/browser/chat-input-history-contribution.js.map +0 -1
  30. package/lib/browser/chat-input-history.d.ts +0 -32
  31. package/lib/browser/chat-input-history.d.ts.map +0 -1
  32. package/lib/browser/chat-input-history.js +0 -125
  33. package/lib/browser/chat-input-history.js.map +0 -1
  34. package/lib/browser/chat-input-mode-contribution.d.ts +0 -12
  35. package/lib/browser/chat-input-mode-contribution.d.ts.map +0 -1
  36. package/lib/browser/chat-input-mode-contribution.js +0 -77
  37. package/lib/browser/chat-input-mode-contribution.js.map +0 -1
  38. package/lib/browser/chat-input-widget.d.ts +0 -115
  39. package/lib/browser/chat-input-widget.d.ts.map +0 -1
  40. package/lib/browser/chat-input-widget.js +0 -973
  41. package/lib/browser/chat-input-widget.js.map +0 -1
  42. package/lib/browser/chat-node-toolbar-action-contribution.d.ts +0 -56
  43. package/lib/browser/chat-node-toolbar-action-contribution.d.ts.map +0 -1
  44. package/lib/browser/chat-node-toolbar-action-contribution.js +0 -92
  45. package/lib/browser/chat-node-toolbar-action-contribution.js.map +0 -1
  46. package/lib/browser/chat-progress-message.d.ts +0 -7
  47. package/lib/browser/chat-progress-message.d.ts.map +0 -1
  48. package/lib/browser/chat-progress-message.js +0 -33
  49. package/lib/browser/chat-progress-message.js.map +0 -1
  50. package/lib/browser/chat-response-part-renderer.d.ts +0 -10
  51. package/lib/browser/chat-response-part-renderer.d.ts.map +0 -1
  52. package/lib/browser/chat-response-part-renderer.js +0 -20
  53. package/lib/browser/chat-response-part-renderer.js.map +0 -1
  54. package/lib/browser/chat-response-renderer/ai-selection-resolver.d.ts +0 -23
  55. package/lib/browser/chat-response-renderer/ai-selection-resolver.d.ts.map +0 -1
  56. package/lib/browser/chat-response-renderer/ai-selection-resolver.js +0 -148
  57. package/lib/browser/chat-response-renderer/ai-selection-resolver.js.map +0 -1
  58. package/lib/browser/chat-response-renderer/code-part-renderer.d.ts +0 -73
  59. package/lib/browser/chat-response-renderer/code-part-renderer.d.ts.map +0 -1
  60. package/lib/browser/chat-response-renderer/code-part-renderer.js +0 -227
  61. package/lib/browser/chat-response-renderer/code-part-renderer.js.map +0 -1
  62. package/lib/browser/chat-response-renderer/command-part-renderer.d.ts +0 -12
  63. package/lib/browser/chat-response-renderer/command-part-renderer.d.ts.map +0 -1
  64. package/lib/browser/chat-response-renderer/command-part-renderer.js +0 -67
  65. package/lib/browser/chat-response-renderer/command-part-renderer.js.map +0 -1
  66. package/lib/browser/chat-response-renderer/delegation-response-renderer.d.ts +0 -14
  67. package/lib/browser/chat-response-renderer/delegation-response-renderer.d.ts.map +0 -1
  68. package/lib/browser/chat-response-renderer/delegation-response-renderer.js +0 -144
  69. package/lib/browser/chat-response-renderer/delegation-response-renderer.js.map +0 -1
  70. package/lib/browser/chat-response-renderer/error-part-renderer.d.ts +0 -9
  71. package/lib/browser/chat-response-renderer/error-part-renderer.d.ts.map +0 -1
  72. package/lib/browser/chat-response-renderer/error-part-renderer.js +0 -40
  73. package/lib/browser/chat-response-renderer/error-part-renderer.js.map +0 -1
  74. package/lib/browser/chat-response-renderer/horizontal-layout-part-renderer.d.ts +0 -12
  75. package/lib/browser/chat-response-renderer/horizontal-layout-part-renderer.d.ts.map +0 -1
  76. package/lib/browser/chat-response-renderer/horizontal-layout-part-renderer.js +0 -54
  77. package/lib/browser/chat-response-renderer/horizontal-layout-part-renderer.js.map +0 -1
  78. package/lib/browser/chat-response-renderer/index.d.ts +0 -13
  79. package/lib/browser/chat-response-renderer/index.d.ts.map +0 -1
  80. package/lib/browser/chat-response-renderer/index.js +0 -31
  81. package/lib/browser/chat-response-renderer/index.js.map +0 -1
  82. package/lib/browser/chat-response-renderer/markdown-part-renderer.d.ts +0 -36
  83. package/lib/browser/chat-response-renderer/markdown-part-renderer.d.ts.map +0 -1
  84. package/lib/browser/chat-response-renderer/markdown-part-renderer.js +0 -128
  85. package/lib/browser/chat-response-renderer/markdown-part-renderer.js.map +0 -1
  86. package/lib/browser/chat-response-renderer/progress-part-renderer.d.ts +0 -9
  87. package/lib/browser/chat-response-renderer/progress-part-renderer.d.ts.map +0 -1
  88. package/lib/browser/chat-response-renderer/progress-part-renderer.js +0 -39
  89. package/lib/browser/chat-response-renderer/progress-part-renderer.js.map +0 -1
  90. package/lib/browser/chat-response-renderer/question-part-renderer.d.ts +0 -10
  91. package/lib/browser/chat-response-renderer/question-part-renderer.d.ts.map +0 -1
  92. package/lib/browser/chat-response-renderer/question-part-renderer.js +0 -49
  93. package/lib/browser/chat-response-renderer/question-part-renderer.js.map +0 -1
  94. package/lib/browser/chat-response-renderer/text-part-renderer.d.ts +0 -9
  95. package/lib/browser/chat-response-renderer/text-part-renderer.d.ts.map +0 -1
  96. package/lib/browser/chat-response-renderer/text-part-renderer.js +0 -43
  97. package/lib/browser/chat-response-renderer/text-part-renderer.js.map +0 -1
  98. package/lib/browser/chat-response-renderer/text-part-renderer.spec.d.ts +0 -2
  99. package/lib/browser/chat-response-renderer/text-part-renderer.spec.d.ts.map +0 -1
  100. package/lib/browser/chat-response-renderer/text-part-renderer.spec.js +0 -46
  101. package/lib/browser/chat-response-renderer/text-part-renderer.spec.js.map +0 -1
  102. package/lib/browser/chat-response-renderer/thinking-part-renderer.d.ts +0 -9
  103. package/lib/browser/chat-response-renderer/thinking-part-renderer.d.ts.map +0 -1
  104. package/lib/browser/chat-response-renderer/thinking-part-renderer.js +0 -42
  105. package/lib/browser/chat-response-renderer/thinking-part-renderer.js.map +0 -1
  106. package/lib/browser/chat-response-renderer/tool-confirmation.d.ts +0 -17
  107. package/lib/browser/chat-response-renderer/tool-confirmation.d.ts.map +0 -1
  108. package/lib/browser/chat-response-renderer/tool-confirmation.js +0 -122
  109. package/lib/browser/chat-response-renderer/tool-confirmation.js.map +0 -1
  110. package/lib/browser/chat-response-renderer/toolcall-part-renderer.d.ts +0 -20
  111. package/lib/browser/chat-response-renderer/toolcall-part-renderer.d.ts.map +0 -1
  112. package/lib/browser/chat-response-renderer/toolcall-part-renderer.js +0 -223
  113. package/lib/browser/chat-response-renderer/toolcall-part-renderer.js.map +0 -1
  114. package/lib/browser/chat-response-renderer/unknown-part-renderer.d.ts +0 -9
  115. package/lib/browser/chat-response-renderer/unknown-part-renderer.d.ts.map +0 -1
  116. package/lib/browser/chat-response-renderer/unknown-part-renderer.js +0 -42
  117. package/lib/browser/chat-response-renderer/unknown-part-renderer.js.map +0 -1
  118. package/lib/browser/chat-tree-view/chat-view-tree-container.d.ts +0 -4
  119. package/lib/browser/chat-tree-view/chat-view-tree-container.d.ts.map +0 -1
  120. package/lib/browser/chat-tree-view/chat-view-tree-container.js +0 -33
  121. package/lib/browser/chat-tree-view/chat-view-tree-container.js.map +0 -1
  122. package/lib/browser/chat-tree-view/chat-view-tree-input-widget.d.ts +0 -38
  123. package/lib/browser/chat-tree-view/chat-view-tree-input-widget.d.ts.map +0 -1
  124. package/lib/browser/chat-tree-view/chat-view-tree-input-widget.js +0 -88
  125. package/lib/browser/chat-tree-view/chat-view-tree-input-widget.js.map +0 -1
  126. package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts +0 -120
  127. package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts.map +0 -1
  128. package/lib/browser/chat-tree-view/chat-view-tree-widget.js +0 -654
  129. package/lib/browser/chat-tree-view/chat-view-tree-widget.js.map +0 -1
  130. package/lib/browser/chat-tree-view/index.d.ts +0 -3
  131. package/lib/browser/chat-tree-view/index.d.ts.map +0 -1
  132. package/lib/browser/chat-tree-view/index.js +0 -21
  133. package/lib/browser/chat-tree-view/index.js.map +0 -1
  134. package/lib/browser/chat-tree-view/sub-chat-widget.d.ts +0 -22
  135. package/lib/browser/chat-tree-view/sub-chat-widget.d.ts.map +0 -1
  136. package/lib/browser/chat-tree-view/sub-chat-widget.js +0 -92
  137. package/lib/browser/chat-tree-view/sub-chat-widget.js.map +0 -1
  138. package/lib/browser/chat-view-commands.d.ts +0 -15
  139. package/lib/browser/chat-view-commands.d.ts.map +0 -1
  140. package/lib/browser/chat-view-commands.js +0 -76
  141. package/lib/browser/chat-view-commands.js.map +0 -1
  142. package/lib/browser/chat-view-contribution.d.ts +0 -21
  143. package/lib/browser/chat-view-contribution.d.ts.map +0 -1
  144. package/lib/browser/chat-view-contribution.js +0 -183
  145. package/lib/browser/chat-view-contribution.js.map +0 -1
  146. package/lib/browser/chat-view-language-contribution.d.ts +0 -41
  147. package/lib/browser/chat-view-language-contribution.d.ts.map +0 -1
  148. package/lib/browser/chat-view-language-contribution.js +0 -269
  149. package/lib/browser/chat-view-language-contribution.js.map +0 -1
  150. package/lib/browser/chat-view-widget-toolbar-contribution.d.ts +0 -20
  151. package/lib/browser/chat-view-widget-toolbar-contribution.d.ts.map +0 -1
  152. package/lib/browser/chat-view-widget-toolbar-contribution.js +0 -115
  153. package/lib/browser/chat-view-widget-toolbar-contribution.js.map +0 -1
  154. package/lib/browser/chat-view-widget.d.ts +0 -60
  155. package/lib/browser/chat-view-widget.d.ts.map +0 -1
  156. package/lib/browser/chat-view-widget.js +0 -243
  157. package/lib/browser/chat-view-widget.js.map +0 -1
  158. package/lib/browser/context-variable-picker.d.ts +0 -9
  159. package/lib/browser/context-variable-picker.d.ts.map +0 -1
  160. package/lib/browser/context-variable-picker.js +0 -86
  161. package/lib/browser/context-variable-picker.js.map +0 -1
  162. package/lib/browser/session-settings-dialog.d.ts +0 -35
  163. package/lib/browser/session-settings-dialog.d.ts.map +0 -1
  164. package/lib/browser/session-settings-dialog.js +0 -118
  165. package/lib/browser/session-settings-dialog.js.map +0 -1
@@ -1,973 +0,0 @@
1
- "use strict";
2
- var AIChatInputWidget_1;
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.AIChatInputWidget = exports.AIChatInputConfiguration = void 0;
5
- const tslib_1 = require("tslib");
6
- // *****************************************************************************
7
- // Copyright (C) 2024 EclipseSource GmbH.
8
- //
9
- // This program and the accompanying materials are made available under the
10
- // terms of the Eclipse Public License v. 2.0 which is available at
11
- // http://www.eclipse.org/legal/epl-2.0.
12
- //
13
- // This Source Code may also be made available under the following Secondary
14
- // Licenses when the conditions for such availability set forth in the Eclipse
15
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
16
- // with the GNU Classpath Exception which is available at
17
- // https://www.gnu.org/software/classpath/license.html.
18
- //
19
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
20
- // *****************************************************************************
21
- const ai_chat_1 = require("@theia/ai-chat");
22
- const change_set_decorator_service_1 = require("@theia/ai-chat/lib/browser/change-set-decorator-service");
23
- const image_context_variable_1 = require("@theia/ai-chat/lib/common/image-context-variable");
24
- const browser_1 = require("@theia/ai-core/lib/browser");
25
- const core_1 = require("@theia/core");
26
- const browser_2 = require("@theia/core/lib/browser");
27
- const context_key_service_1 = require("@theia/core/lib/browser/context-key-service");
28
- const promise_util_1 = require("@theia/core/lib/common/promise-util");
29
- const inversify_1 = require("@theia/core/shared/inversify");
30
- const React = require("@theia/core/shared/react");
31
- const monaco_editor_core_1 = require("@theia/monaco-editor-core");
32
- const monaco_editor_provider_1 = require("@theia/monaco/lib/browser/monaco-editor-provider");
33
- const change_set_action_service_1 = require("./change-set-actions/change-set-action-service");
34
- const chat_input_agent_suggestions_1 = require("./chat-input-agent-suggestions");
35
- const chat_view_language_contribution_1 = require("./chat-view-language-contribution");
36
- const context_variable_picker_1 = require("./context-variable-picker");
37
- const task_context_variable_1 = require("@theia/ai-chat/lib/browser/task-context-variable");
38
- const chat_input_history_1 = require("./chat-input-history");
39
- exports.AIChatInputConfiguration = Symbol('AIChatInputConfiguration');
40
- let AIChatInputWidget = AIChatInputWidget_1 = class AIChatInputWidget extends browser_2.ReactWidget {
41
- constructor() {
42
- super(...arguments);
43
- this.editorRef = undefined;
44
- this.editorReady = new promise_util_1.Deferred();
45
- this.handleModeChange = (mode) => {
46
- if (this.receivingAgent) {
47
- this.receivingAgent = { ...this.receivingAgent, currentModeId: mode };
48
- this.update();
49
- }
50
- };
51
- this.isEnabled = false;
52
- this.heightInLines = 12;
53
- this.onDisposeForChatModel = new core_1.DisposableCollection();
54
- this.onDidResizeEmitter = new core_1.Emitter();
55
- this.onDidResize = this.onDidResizeEmitter.event;
56
- }
57
- get editor() {
58
- return this.editorRef;
59
- }
60
- get inputConfiguration() {
61
- return this.configuration;
62
- }
63
- getPreviousPrompt(currentInput) {
64
- if (!this.navigationState) {
65
- return undefined;
66
- }
67
- return this.navigationState.getPreviousPrompt(currentInput);
68
- }
69
- getNextPrompt() {
70
- if (!this.navigationState) {
71
- return undefined;
72
- }
73
- return this.navigationState.getNextPrompt();
74
- }
75
- cycleMode() {
76
- if (!this.receivingAgent || !this.receivingAgent.modes || this.receivingAgent.modes.length <= 1) {
77
- return;
78
- }
79
- const currentIndex = this.receivingAgent.modes.findIndex(mode => mode.id === this.receivingAgent.currentModeId);
80
- const nextIndex = currentIndex === -1 ? 1 : (currentIndex + 1) % this.receivingAgent.modes.length;
81
- this.receivingAgent = {
82
- ...this.receivingAgent,
83
- currentModeId: this.receivingAgent.modes[nextIndex].id
84
- };
85
- this.update();
86
- }
87
- set branch(branch) {
88
- if (this._branch !== branch) {
89
- this._branch = branch;
90
- this.update();
91
- }
92
- }
93
- set onQuery(query) {
94
- this._onQuery = (prompt, mode) => {
95
- var _a;
96
- if (((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.enablePromptHistory) !== false && prompt.trim()) {
97
- this.historyService.addToHistory(prompt);
98
- this.navigationState.stopNavigation();
99
- }
100
- return query(prompt, mode);
101
- };
102
- }
103
- set onUnpin(unpin) {
104
- this._onUnpin = unpin;
105
- }
106
- set onCancel(cancel) {
107
- this._onCancel = cancel;
108
- }
109
- set onDeleteChangeSet(deleteChangeSet) {
110
- this._onDeleteChangeSet = deleteChangeSet;
111
- }
112
- set onDeleteChangeSetElement(deleteChangeSetElement) {
113
- this._onDeleteChangeSetElement = deleteChangeSetElement;
114
- }
115
- set initialValue(value) {
116
- this._initialValue = value;
117
- }
118
- set chatModel(chatModel) {
119
- this.onDisposeForChatModel.dispose();
120
- this.onDisposeForChatModel = new core_1.DisposableCollection();
121
- this.onDisposeForChatModel.push(chatModel.onDidChange(event => {
122
- if (event.kind === 'addVariable' || event.kind === 'removeVariable' || event.kind === 'addRequest' || event.kind === 'changeHierarchyBranch') {
123
- this.update();
124
- }
125
- }));
126
- this._chatModel = chatModel;
127
- this.scheduleUpdateReceivingAgent();
128
- this.update();
129
- }
130
- set pinnedAgent(pinnedAgent) {
131
- this._pinnedAgent = pinnedAgent;
132
- this.scheduleUpdateReceivingAgent();
133
- this.update();
134
- }
135
- init() {
136
- this.id = AIChatInputWidget_1.ID;
137
- this.title.closable = false;
138
- this.toDispose.push(this.resources.add(this.getResourceUri(), ''));
139
- this.toDispose.push(this.aiActivationService.onDidChangeActiveStatus(() => {
140
- this.setEnabled(this.aiActivationService.isActive);
141
- }));
142
- this.toDispose.push(this.onDidResizeEmitter);
143
- this.toDispose.push(core_1.Disposable.create(() => {
144
- if (this.updateReceivingAgentTimeout !== undefined) {
145
- clearTimeout(this.updateReceivingAgentTimeout);
146
- this.updateReceivingAgentTimeout = undefined;
147
- }
148
- }));
149
- this.setEnabled(this.aiActivationService.isActive);
150
- this.historyService.init().then(() => {
151
- this.navigationState = new chat_input_history_1.ChatInputNavigationState(this.historyService);
152
- });
153
- this.initializeContextKeys();
154
- this.update();
155
- }
156
- initializeContextKeys() {
157
- this.chatInputFocusKey = this.contextKeyService.createKey('chatInputFocus', false);
158
- this.chatInputFirstLineKey = this.contextKeyService.createKey('chatInputFirstLine', false);
159
- this.chatInputLastLineKey = this.contextKeyService.createKey('chatInputLastLine', false);
160
- this.chatInputReceivingAgentKey = this.contextKeyService.createKey('chatInputReceivingAgent', '');
161
- this.chatInputHasModesKey = this.contextKeyService.createKey('chatInputHasModes', false);
162
- }
163
- updateCursorPositionKeys() {
164
- if (!this.editorRef) {
165
- this.chatInputFirstLineKey.set(false);
166
- this.chatInputLastLineKey.set(false);
167
- return;
168
- }
169
- const editor = this.editorRef.getControl();
170
- const position = editor.getPosition();
171
- const model = editor.getModel();
172
- if (!position || !model) {
173
- this.chatInputFirstLineKey.set(false);
174
- this.chatInputLastLineKey.set(false);
175
- return;
176
- }
177
- const line = position.lineNumber;
178
- const col = position.column;
179
- const topAtPos = editor.getTopForPosition(line, col);
180
- const topAtLineStart = editor.getTopForLineNumber(line);
181
- const topAtLineEnd = editor.getTopForPosition(line, model.getLineMaxColumn(line));
182
- const lineHeight = editor.getOption(68 /* EditorOption.lineHeight */);
183
- const toleranceValue = 0.5;
184
- const isFirstVisualOfThisLine = Math.abs(topAtPos - topAtLineStart) < toleranceValue;
185
- const isLastVisualOfThisLine = Math.abs(topAtPos - topAtLineEnd) < toleranceValue || (topAtPos > topAtLineEnd - lineHeight + toleranceValue);
186
- const isFirstVisualOverall = line === 1 && isFirstVisualOfThisLine;
187
- const isLastVisualOverall = line === model.getLineCount() && isLastVisualOfThisLine;
188
- this.chatInputFirstLineKey.set(isFirstVisualOverall);
189
- this.chatInputLastLineKey.set(isLastVisualOverall);
190
- }
191
- scheduleUpdateReceivingAgent() {
192
- if (this.updateReceivingAgentTimeout !== undefined) {
193
- clearTimeout(this.updateReceivingAgentTimeout);
194
- }
195
- this.updateReceivingAgentTimeout = window.setTimeout(() => {
196
- this.updateReceivingAgent();
197
- this.updateReceivingAgentTimeout = undefined;
198
- }, 200);
199
- }
200
- async updateReceivingAgent() {
201
- var _a, _b, _c;
202
- if (!this.editorRef || !this._chatModel) {
203
- if (this.receivingAgent !== undefined) {
204
- this.chatInputReceivingAgentKey.set('');
205
- this.chatInputHasModesKey.set(false);
206
- this.receivingAgent = undefined;
207
- this.update();
208
- }
209
- return;
210
- }
211
- try {
212
- const inputText = this.editorRef.getControl().getValue();
213
- const request = { text: inputText };
214
- const resolvedContext = { variables: [] };
215
- const parsedRequest = await this.chatRequestParser.parseChatRequest(request, this._chatModel.location, resolvedContext);
216
- const session = this.chatService.getSessions().find(s => s.model.id === this._chatModel.id);
217
- if (session) {
218
- const agent = this.chatService.getAgent(parsedRequest, session);
219
- const agentId = (_a = agent === null || agent === void 0 ? void 0 : agent.id) !== null && _a !== void 0 ? _a : '';
220
- const previousAgentId = (_b = this.receivingAgent) === null || _b === void 0 ? void 0 : _b.agentId;
221
- this.chatInputReceivingAgentKey.set(agentId);
222
- // Only update and re-render when the agent changes
223
- if (agent && agentId !== previousAgentId) {
224
- const modes = (_c = agent.modes) !== null && _c !== void 0 ? _c : [];
225
- this.receivingAgent = {
226
- agentId: agentId,
227
- modes
228
- };
229
- this.chatInputHasModesKey.set(modes.length > 1);
230
- this.update();
231
- }
232
- else if (!agent && this.receivingAgent !== undefined) {
233
- this.receivingAgent = undefined;
234
- this.chatInputHasModesKey.set(false);
235
- this.update();
236
- }
237
- }
238
- else if (this.receivingAgent !== undefined) {
239
- this.chatInputReceivingAgentKey.set('');
240
- this.chatInputHasModesKey.set(false);
241
- this.receivingAgent = undefined;
242
- this.update();
243
- }
244
- }
245
- catch (error) {
246
- console.warn('Failed to determine receiving agent:', error);
247
- if (this.receivingAgent !== undefined) {
248
- this.chatInputReceivingAgentKey.set('');
249
- this.chatInputHasModesKey.set(false);
250
- this.receivingAgent = undefined;
251
- this.update();
252
- }
253
- }
254
- }
255
- setupEditorEventListeners() {
256
- if (!this.editorRef) {
257
- return;
258
- }
259
- const editor = this.editorRef.getControl();
260
- this.toDispose.push(editor.onDidFocusEditorWidget(() => {
261
- this.chatInputFocusKey.set(true);
262
- this.updateCursorPositionKeys();
263
- }));
264
- this.toDispose.push(editor.onDidBlurEditorWidget(() => {
265
- this.chatInputFocusKey.set(false);
266
- this.chatInputFirstLineKey.set(false);
267
- this.chatInputLastLineKey.set(false);
268
- }));
269
- this.toDispose.push(editor.onDidChangeCursorPosition(() => {
270
- if (editor.hasWidgetFocus()) {
271
- this.updateCursorPositionKeys();
272
- }
273
- }));
274
- this.toDispose.push(editor.onDidChangeModelContent(() => {
275
- if (editor.hasWidgetFocus()) {
276
- this.updateCursorPositionKeys();
277
- }
278
- this.scheduleUpdateReceivingAgent();
279
- }));
280
- if (editor.hasWidgetFocus()) {
281
- this.chatInputFocusKey.set(true);
282
- this.updateCursorPositionKeys();
283
- }
284
- }
285
- onActivateRequest(msg) {
286
- super.onActivateRequest(msg);
287
- this.editorReady.promise.then(() => {
288
- if (this.editorRef) {
289
- this.editorRef.focus();
290
- }
291
- });
292
- }
293
- async handleAgentCompletion(request) {
294
- try {
295
- const agentId = request.agentId;
296
- if (agentId) {
297
- await this.agentNotificationService.showCompletionNotification(agentId);
298
- }
299
- }
300
- catch (error) {
301
- console.error('Failed to handle agent completion notification:', error);
302
- }
303
- }
304
- getResourceUri() {
305
- return new core_1.URI(`ai-chat:/input.${chat_view_language_contribution_1.CHAT_VIEW_LANGUAGE_EXTENSION}`);
306
- }
307
- render() {
308
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
309
- const branch = this._branch;
310
- const chatModel = this._chatModel;
311
- // State of the input widget's action buttons depends on the state of the currently active or last processed
312
- // request, if there is one. If the chat model has branched, then the current request is the last on the
313
- // branch. Otherwise, it's the last request in the chat model.
314
- const currentRequest = (_c = (_b = (_a = branch === null || branch === void 0 ? void 0 : branch.items) === null || _a === void 0 ? void 0 : _a.at(-1)) === null || _b === void 0 ? void 0 : _b.element) !== null && _c !== void 0 ? _c : chatModel.getRequests().at(-1);
315
- const isEditing = !!(currentRequest && (ai_chat_1.EditableChatRequestModel.isEditing(currentRequest)));
316
- const isPending = () => !!(currentRequest && !isEditing && ai_chat_1.ChatRequestModel.isInProgress(currentRequest));
317
- const pending = isPending();
318
- return (React.createElement(ChatInput, { branch: this._branch, onQuery: this._onQuery.bind(this), onUnpin: this._onUnpin.bind(this), onCancel: this._onCancel.bind(this), onDragOver: this.onDragOver.bind(this), onDrop: this.onDrop.bind(this), onPaste: this.onPaste.bind(this), onEscape: this.onEscape.bind(this), onDeleteChangeSet: this._onDeleteChangeSet.bind(this), onDeleteChangeSetElement: this._onDeleteChangeSetElement.bind(this), onAddContextElement: this.addContextElement.bind(this), onDeleteContextElement: this.deleteContextElement.bind(this), onOpenContextElement: this.openContextElement.bind(this), context: this.getContext(), onAgentCompletion: this.handleAgentCompletion.bind(this), chatModel: this._chatModel, pinnedAgent: this._pinnedAgent, editorProvider: this.editorProvider, uri: this.getResourceUri(), contextMenuCallback: this.handleContextMenu.bind(this), isEnabled: this.isEnabled, setEditorRef: editor => {
319
- this.editorRef = editor;
320
- this.setupEditorEventListeners();
321
- this.editorReady.resolve();
322
- }, showContext: (_d = this.configuration) === null || _d === void 0 ? void 0 : _d.showContext, showPinnedAgent: (_e = this.configuration) === null || _e === void 0 ? void 0 : _e.showPinnedAgent, showChangeSet: (_f = this.configuration) === null || _f === void 0 ? void 0 : _f.showChangeSet, showSuggestions: (_g = this.configuration) === null || _g === void 0 ? void 0 : _g.showSuggestions, hasPromptHistory: (_h = this.configuration) === null || _h === void 0 ? void 0 : _h.enablePromptHistory, labelProvider: this.labelProvider, actionService: this.changeSetActionService, decoratorService: this.changeSetDecoratorService, initialValue: this._initialValue, openerService: this.openerService, suggestions: this._chatModel.suggestions, currentRequest: currentRequest, isEditing: isEditing, pending: pending, heightInLines: this.heightInLines, onResponseChanged: () => {
323
- if (isPending() !== pending) {
324
- this.update();
325
- }
326
- }, onResize: () => this.onDidResizeEmitter.fire(), modeSelectorProps: {
327
- receivingAgentModes: (_j = this.receivingAgent) === null || _j === void 0 ? void 0 : _j.modes,
328
- currentMode: (_k = this.receivingAgent) === null || _k === void 0 ? void 0 : _k.currentModeId,
329
- onModeChange: this.handleModeChange,
330
- } }));
331
- }
332
- onDragOver(event) {
333
- var _a;
334
- event.preventDefault();
335
- event.stopPropagation();
336
- this.node.classList.add('drag-over');
337
- if ((_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.types.includes('text/plain')) {
338
- event.dataTransfer.dropEffect = 'copy';
339
- }
340
- else {
341
- event.dataTransfer.dropEffect = 'link';
342
- }
343
- }
344
- onDrop(event) {
345
- var _a, _b, _c;
346
- event.preventDefault();
347
- event.stopPropagation();
348
- this.node.classList.remove('drag-over');
349
- const dataTransferText = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData('text/plain');
350
- const position = (_c = (_b = this.editorRef) === null || _b === void 0 ? void 0 : _b.getControl().getTargetAtClientPoint(event.clientX, event.clientY)) === null || _c === void 0 ? void 0 : _c.position;
351
- this.variableService.getDropResult(event.nativeEvent, { type: 'ai-chat-input-widget' }).then(result => {
352
- var _a, _b;
353
- result.variables.forEach(variable => this.addContext(variable));
354
- const text = (_a = result.text) !== null && _a !== void 0 ? _a : dataTransferText;
355
- if (position && text) {
356
- (_b = this.editorRef) === null || _b === void 0 ? void 0 : _b.getControl().executeEdits('drag-and-drop', [{
357
- range: {
358
- startLineNumber: position.lineNumber,
359
- startColumn: position.column,
360
- endLineNumber: position.lineNumber,
361
- endColumn: position.column
362
- },
363
- text
364
- }]);
365
- }
366
- });
367
- }
368
- onPaste(event) {
369
- this.variableService.getPasteResult(event, { type: 'ai-chat-input-widget' }).then(result => {
370
- var _a, _b;
371
- result.variables.forEach(variable => this.addContext(variable));
372
- if (result.text) {
373
- const position = (_a = this.editorRef) === null || _a === void 0 ? void 0 : _a.getControl().getPosition();
374
- if (position && result.text) {
375
- (_b = this.editorRef) === null || _b === void 0 ? void 0 : _b.getControl().executeEdits('paste', [{
376
- range: {
377
- startLineNumber: position.lineNumber,
378
- startColumn: position.column,
379
- endLineNumber: position.lineNumber,
380
- endColumn: position.column
381
- },
382
- text: result.text
383
- }]);
384
- }
385
- }
386
- });
387
- }
388
- onEscape() {
389
- var _a, _b, _c, _d;
390
- const currentRequest = (_d = (_c = (_b = (_a = this._branch) === null || _a === void 0 ? void 0 : _a.items) === null || _b === void 0 ? void 0 : _b.at(-1)) === null || _c === void 0 ? void 0 : _c.element) !== null && _d !== void 0 ? _d : this._chatModel.getRequests().at(-1);
391
- if (currentRequest && !ai_chat_1.EditableChatRequestModel.isEditing(currentRequest) && ai_chat_1.ChatRequestModel.isInProgress(currentRequest)) {
392
- this._onCancel(currentRequest);
393
- }
394
- }
395
- async openContextElement(request) {
396
- const session = this.chatService.getSessions().find(candidate => candidate.model.id === this._chatModel.id);
397
- const context = { session };
398
- await this.variableService.open(request, context);
399
- }
400
- setEnabled(enabled) {
401
- this.isEnabled = enabled;
402
- this.update();
403
- }
404
- addContextElement() {
405
- this.contextVariablePicker.pickContextVariable().then(contextElement => {
406
- if (contextElement) {
407
- this.addContext(contextElement);
408
- }
409
- });
410
- }
411
- deleteContextElement(index) {
412
- this._chatModel.context.deleteVariables(index);
413
- }
414
- handleContextMenu(event) {
415
- this.contextMenuRenderer.render({
416
- menuPath: AIChatInputWidget_1.CONTEXT_MENU,
417
- anchor: { x: event.posx, y: event.posy },
418
- context: event.target,
419
- args: [this.editorRef]
420
- });
421
- event.preventDefault();
422
- }
423
- addContext(variable) {
424
- this._chatModel.context.addVariables(variable);
425
- }
426
- getContext() {
427
- return this._chatModel.context.getVariables();
428
- }
429
- };
430
- exports.AIChatInputWidget = AIChatInputWidget;
431
- AIChatInputWidget.ID = 'chat-input-widget';
432
- AIChatInputWidget.CONTEXT_MENU = ['chat-input-context-menu'];
433
- tslib_1.__decorate([
434
- (0, inversify_1.inject)(monaco_editor_provider_1.MonacoEditorProvider),
435
- tslib_1.__metadata("design:type", monaco_editor_provider_1.MonacoEditorProvider)
436
- ], AIChatInputWidget.prototype, "editorProvider", void 0);
437
- tslib_1.__decorate([
438
- (0, inversify_1.inject)(core_1.InMemoryResources),
439
- tslib_1.__metadata("design:type", core_1.InMemoryResources)
440
- ], AIChatInputWidget.prototype, "resources", void 0);
441
- tslib_1.__decorate([
442
- (0, inversify_1.inject)(browser_2.ContextMenuRenderer),
443
- tslib_1.__metadata("design:type", browser_2.ContextMenuRenderer)
444
- ], AIChatInputWidget.prototype, "contextMenuRenderer", void 0);
445
- tslib_1.__decorate([
446
- (0, inversify_1.inject)(exports.AIChatInputConfiguration),
447
- (0, inversify_1.optional)(),
448
- tslib_1.__metadata("design:type", Object)
449
- ], AIChatInputWidget.prototype, "configuration", void 0);
450
- tslib_1.__decorate([
451
- (0, inversify_1.inject)(browser_1.FrontendVariableService),
452
- tslib_1.__metadata("design:type", Object)
453
- ], AIChatInputWidget.prototype, "variableService", void 0);
454
- tslib_1.__decorate([
455
- (0, inversify_1.inject)(browser_2.LabelProvider),
456
- tslib_1.__metadata("design:type", browser_2.LabelProvider)
457
- ], AIChatInputWidget.prototype, "labelProvider", void 0);
458
- tslib_1.__decorate([
459
- (0, inversify_1.inject)(context_variable_picker_1.ContextVariablePicker),
460
- tslib_1.__metadata("design:type", context_variable_picker_1.ContextVariablePicker)
461
- ], AIChatInputWidget.prototype, "contextVariablePicker", void 0);
462
- tslib_1.__decorate([
463
- (0, inversify_1.inject)(change_set_action_service_1.ChangeSetActionService),
464
- tslib_1.__metadata("design:type", change_set_action_service_1.ChangeSetActionService)
465
- ], AIChatInputWidget.prototype, "changeSetActionService", void 0);
466
- tslib_1.__decorate([
467
- (0, inversify_1.inject)(browser_1.AgentCompletionNotificationService),
468
- tslib_1.__metadata("design:type", browser_1.AgentCompletionNotificationService)
469
- ], AIChatInputWidget.prototype, "agentNotificationService", void 0);
470
- tslib_1.__decorate([
471
- (0, inversify_1.inject)(change_set_decorator_service_1.ChangeSetDecoratorService),
472
- tslib_1.__metadata("design:type", change_set_decorator_service_1.ChangeSetDecoratorService)
473
- ], AIChatInputWidget.prototype, "changeSetDecoratorService", void 0);
474
- tslib_1.__decorate([
475
- (0, inversify_1.inject)(browser_2.OpenerService),
476
- tslib_1.__metadata("design:type", Object)
477
- ], AIChatInputWidget.prototype, "openerService", void 0);
478
- tslib_1.__decorate([
479
- (0, inversify_1.inject)(ai_chat_1.ChatService),
480
- tslib_1.__metadata("design:type", Object)
481
- ], AIChatInputWidget.prototype, "chatService", void 0);
482
- tslib_1.__decorate([
483
- (0, inversify_1.inject)(browser_1.AIActivationService),
484
- tslib_1.__metadata("design:type", Object)
485
- ], AIChatInputWidget.prototype, "aiActivationService", void 0);
486
- tslib_1.__decorate([
487
- (0, inversify_1.inject)(chat_input_history_1.ChatInputHistoryService),
488
- tslib_1.__metadata("design:type", chat_input_history_1.ChatInputHistoryService)
489
- ], AIChatInputWidget.prototype, "historyService", void 0);
490
- tslib_1.__decorate([
491
- (0, inversify_1.inject)(ai_chat_1.ChatRequestParser),
492
- tslib_1.__metadata("design:type", Object)
493
- ], AIChatInputWidget.prototype, "chatRequestParser", void 0);
494
- tslib_1.__decorate([
495
- (0, inversify_1.inject)(context_key_service_1.ContextKeyService),
496
- tslib_1.__metadata("design:type", Object)
497
- ], AIChatInputWidget.prototype, "contextKeyService", void 0);
498
- tslib_1.__decorate([
499
- (0, inversify_1.postConstruct)(),
500
- tslib_1.__metadata("design:type", Function),
501
- tslib_1.__metadata("design:paramtypes", []),
502
- tslib_1.__metadata("design:returntype", void 0)
503
- ], AIChatInputWidget.prototype, "init", null);
504
- exports.AIChatInputWidget = AIChatInputWidget = AIChatInputWidget_1 = tslib_1.__decorate([
505
- (0, inversify_1.injectable)()
506
- ], AIChatInputWidget);
507
- // Utility to check if we have task context in the chat model
508
- const hasTaskContext = (chatModel) => chatModel.context.getVariables().some(variable => { var _a; return ((_a = variable.variable) === null || _a === void 0 ? void 0 : _a.id) === task_context_variable_1.TASK_CONTEXT_VARIABLE.id; });
509
- const ChatInput = (props) => {
510
- var _a, _b;
511
- const onDeleteChangeSet = () => props.onDeleteChangeSet(props.chatModel.id);
512
- const onDeleteChangeSetElement = (uri) => props.onDeleteChangeSetElement(props.chatModel.id, uri);
513
- const [isInputEmpty, setIsInputEmpty] = React.useState(true);
514
- const [isInputFocused, setIsInputFocused] = React.useState(false);
515
- const [placeholderText, setPlaceholderText] = React.useState('');
516
- const [changeSetUI, setChangeSetUI] = React.useState(() => buildChangeSetUI(props.chatModel.changeSet, props.labelProvider, props.decoratorService, props.actionService.getActionsForChangeset(props.chatModel.changeSet), onDeleteChangeSet, onDeleteChangeSetElement));
517
- // eslint-disable-next-line no-null/no-null
518
- const editorContainerRef = React.useRef(null);
519
- // eslint-disable-next-line no-null/no-null
520
- const placeholderRef = React.useRef(null);
521
- const editorRef = React.useRef(undefined);
522
- // eslint-disable-next-line no-null/no-null
523
- const containerRef = React.useRef(null);
524
- // On the first request of the chat, if the chat has a task context and a pinned
525
- // agent, show a "Perform this task." placeholder which is the message to send by default
526
- const isFirstRequest = props.chatModel.getRequests().length === 0;
527
- const shouldUseTaskPlaceholder = isFirstRequest && props.pinnedAgent && hasTaskContext(props.chatModel);
528
- const taskPlaceholder = core_1.nls.localize('theia/ai/chat-ui/performThisTask', 'Perform this task.');
529
- // Update placeholder text when focus state or other dependencies change
530
- React.useEffect(() => {
531
- const newPlaceholderText = !props.isEnabled
532
- ? core_1.nls.localize('theia/ai/chat-ui/aiDisabled', 'AI features are disabled')
533
- : shouldUseTaskPlaceholder
534
- ? taskPlaceholder
535
- : core_1.nls.localizeByDefault('Ask a question') + (props.hasPromptHistory && isInputFocused ? core_1.nls.localizeByDefault(' ({0} for history)', '⇅') : '');
536
- setPlaceholderText(newPlaceholderText);
537
- }, [props.isEnabled, shouldUseTaskPlaceholder, taskPlaceholder, props.hasPromptHistory, isInputFocused]);
538
- // Handle paste events on the container
539
- const handlePaste = React.useCallback((event) => {
540
- props.onPaste(event);
541
- }, [props.onPaste]);
542
- // Set up paste handler on the container div
543
- React.useEffect(() => {
544
- const container = containerRef.current;
545
- if (container) {
546
- container.addEventListener('paste', handlePaste, true);
547
- return () => {
548
- container.removeEventListener('paste', handlePaste, true);
549
- };
550
- }
551
- return undefined;
552
- }, [handlePaste]);
553
- React.useEffect(() => {
554
- const uri = props.uri;
555
- const createInputElement = async () => {
556
- var _a, _b;
557
- const paddingTop = 6;
558
- const lineHeight = 20;
559
- const maxHeightPx = ((_a = props.heightInLines) !== null && _a !== void 0 ? _a : 12) * lineHeight;
560
- const editor = await props.editorProvider.createSimpleInline(uri, editorContainerRef.current, {
561
- language: chat_view_language_contribution_1.CHAT_VIEW_LANGUAGE_EXTENSION,
562
- // Disable code lens, inlay hints and hover support to avoid console errors from other contributions
563
- codeLens: false,
564
- inlayHints: { enabled: 'off' },
565
- hover: { enabled: false },
566
- autoSizing: false, // we handle the sizing ourselves
567
- scrollBeyondLastLine: false,
568
- scrollBeyondLastColumn: 0,
569
- minHeight: 1,
570
- fontFamily: 'var(--theia-ui-font-family)',
571
- fontSize: 13,
572
- cursorWidth: 1,
573
- maxHeight: -1,
574
- scrollbar: { horizontal: 'hidden', alwaysConsumeMouseWheel: false, handleMouseWheel: true },
575
- automaticLayout: true,
576
- lineNumbers: 'off',
577
- lineHeight,
578
- padding: { top: paddingTop },
579
- suggest: {
580
- showIcons: true,
581
- showSnippets: false,
582
- showWords: false,
583
- showStatusBar: false,
584
- insertMode: 'replace',
585
- },
586
- bracketPairColorization: { enabled: false },
587
- wrappingStrategy: 'advanced',
588
- stickyScroll: { enabled: false },
589
- });
590
- if (editorContainerRef.current) {
591
- editorContainerRef.current.style.overflowY = 'auto'; // ensure vertical scrollbar
592
- editorContainerRef.current.style.height = (lineHeight + (2 * paddingTop)) + 'px';
593
- editorContainerRef.current.addEventListener('wheel', e => {
594
- // Prevent parent from scrolling
595
- e.stopPropagation();
596
- }, { passive: false });
597
- }
598
- const updateEditorHeight = () => {
599
- if (editorContainerRef.current) {
600
- const contentHeight = editor.getControl().getContentHeight() + paddingTop;
601
- editorContainerRef.current.style.height = `${Math.min(contentHeight, maxHeightPx)}px`;
602
- }
603
- };
604
- editor.getControl().onDidChangeModelContent(() => {
605
- const value = editor.getControl().getValue();
606
- setIsInputEmpty(!value || value.length === 0);
607
- updateEditorHeight();
608
- handleOnChange();
609
- });
610
- const resizeObserver = new ResizeObserver(() => {
611
- updateEditorHeight();
612
- props.onResize();
613
- });
614
- if (editorContainerRef.current) {
615
- resizeObserver.observe(editorContainerRef.current);
616
- }
617
- editor.getControl().onDidDispose(() => {
618
- resizeObserver.disconnect();
619
- });
620
- editor.getControl().onContextMenu(e => props.contextMenuCallback(e.event));
621
- const updateLineCounts = () => {
622
- // We need the line numbers to allow scrolling by using the keyboard
623
- const model = editor.getControl().getModel();
624
- const lineCount = model.getLineCount();
625
- const decorations = [];
626
- for (let lineNumber = 1; lineNumber <= lineCount; lineNumber++) {
627
- decorations.push({
628
- range: new monaco_editor_core_1.Range(lineNumber, 1, lineNumber, 1),
629
- options: {
630
- description: `line-number-${lineNumber}`,
631
- isWholeLine: false,
632
- className: `line-number-${lineNumber}`,
633
- }
634
- });
635
- }
636
- const lineNumbers = model.getAllDecorations().filter(predicate => { var _a; return (_a = predicate.options.description) === null || _a === void 0 ? void 0 : _a.startsWith('line-number-'); });
637
- editor.getControl().removeDecorations(lineNumbers.map(d => d.id));
638
- editor.getControl().createDecorationsCollection(decorations);
639
- };
640
- (_b = editor.getControl().getModel()) === null || _b === void 0 ? void 0 : _b.onDidChangeContent(() => {
641
- updateLineCounts();
642
- });
643
- editor.getControl().onDidChangeCursorPosition(e => {
644
- var _a;
645
- const lineNumber = e.position.lineNumber;
646
- const line = (_a = editor.getControl().getDomNode()) === null || _a === void 0 ? void 0 : _a.querySelector(`.line-number-${lineNumber}`);
647
- line === null || line === void 0 ? void 0 : line.scrollIntoView({ behavior: 'instant', block: 'nearest' });
648
- });
649
- editorRef.current = editor;
650
- props.setEditorRef(editor);
651
- if (props.initialValue) {
652
- setValue(props.initialValue);
653
- }
654
- updateLineCounts();
655
- };
656
- createInputElement();
657
- return () => {
658
- props.setEditorRef(undefined);
659
- if (editorRef.current) {
660
- editorRef.current.dispose();
661
- }
662
- };
663
- }, []);
664
- React.useEffect(() => {
665
- setChangeSetUI(buildChangeSetUI(props.chatModel.changeSet, props.labelProvider, props.decoratorService, props.actionService.getActionsForChangeset(props.chatModel.changeSet), onDeleteChangeSet, onDeleteChangeSetElement));
666
- const listener = props.chatModel.onDidChange(event => {
667
- if (ai_chat_1.ChatChangeEvent.isChangeSetEvent(event)) {
668
- setChangeSetUI(buildChangeSetUI(props.chatModel.changeSet, props.labelProvider, props.decoratorService, props.actionService.getActionsForChangeset(props.chatModel.changeSet), onDeleteChangeSet, onDeleteChangeSetElement));
669
- }
670
- if (event.kind === 'addRequest') {
671
- // Listen for when this request's response becomes complete
672
- const responseListener = event.request.response.onDidChange(() => {
673
- if (event.request.response.isComplete) {
674
- props.onAgentCompletion(event.request);
675
- responseListener.dispose(); // Clean up the listener once notification is sent
676
- }
677
- });
678
- }
679
- });
680
- return () => {
681
- listener.dispose();
682
- };
683
- }, [props.chatModel, props.labelProvider, props.decoratorService, props.actionService]);
684
- React.useEffect(() => {
685
- const disposable = props.actionService.onDidChange(() => {
686
- const newActions = props.actionService.getActionsForChangeset(props.chatModel.changeSet);
687
- setChangeSetUI(current => !current ? current : { ...current, actions: newActions });
688
- });
689
- return () => disposable.dispose();
690
- }, [props.actionService, props.chatModel.changeSet]);
691
- React.useEffect(() => {
692
- const disposable = props.decoratorService.onDidChangeDecorations(() => {
693
- setChangeSetUI(buildChangeSetUI(props.chatModel.changeSet, props.labelProvider, props.decoratorService, props.actionService.getActionsForChangeset(props.chatModel.changeSet), onDeleteChangeSet, onDeleteChangeSetElement));
694
- });
695
- return () => disposable.dispose();
696
- });
697
- const setValue = React.useCallback((value) => {
698
- if (editorRef.current && !editorRef.current.document.isDisposed()) {
699
- editorRef.current.document.textEditorModel.setValue(value);
700
- }
701
- }, [editorRef]);
702
- // Without user input, if we can default to "Perform this task.", do so
703
- const submit = React.useCallback(function submit(value) {
704
- let effectiveValue = value;
705
- if ((!value || value.trim().length === 0) && shouldUseTaskPlaceholder) {
706
- effectiveValue = taskPlaceholder;
707
- }
708
- if (!effectiveValue || effectiveValue.trim().length === 0) {
709
- return;
710
- }
711
- props.onQuery(effectiveValue, props.modeSelectorProps.currentMode);
712
- setValue('');
713
- if (editorRef.current && !editorRef.current.document.textEditorModel.isDisposed()) {
714
- editorRef.current.document.textEditorModel.setValue('');
715
- }
716
- }, [props.context, props.onQuery, props.modeSelectorProps.currentMode, setValue, shouldUseTaskPlaceholder, taskPlaceholder]);
717
- const onKeyDown = React.useCallback((event) => {
718
- var _a;
719
- if (!props.isEnabled) {
720
- return;
721
- }
722
- if (event.key === 'Enter' && !event.shiftKey) {
723
- event.preventDefault();
724
- // On Enter, read input and submit (handles task context)
725
- const currentValue = ((_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.document.textEditorModel.getValue()) || '';
726
- submit(currentValue);
727
- }
728
- else if (event.key === 'Escape') {
729
- event.preventDefault();
730
- props.onEscape();
731
- }
732
- }, [props.isEnabled, submit]);
733
- const handleInputFocus = () => {
734
- setIsInputFocused(true);
735
- hidePlaceholderIfEditorFilled();
736
- };
737
- const handleOnChange = () => {
738
- showPlaceholderIfEditorEmpty();
739
- hidePlaceholderIfEditorFilled();
740
- };
741
- const handleInputBlur = () => {
742
- setIsInputFocused(false);
743
- showPlaceholderIfEditorEmpty();
744
- };
745
- const showPlaceholderIfEditorEmpty = () => {
746
- var _a, _b;
747
- if (!((_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.getControl().getValue())) {
748
- (_b = placeholderRef.current) === null || _b === void 0 ? void 0 : _b.classList.remove('hidden');
749
- }
750
- };
751
- const hidePlaceholderIfEditorFilled = () => {
752
- var _a, _b;
753
- const value = (_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.getControl().getValue();
754
- if (value && value.length > 0) {
755
- (_b = placeholderRef.current) === null || _b === void 0 ? void 0 : _b.classList.add('hidden');
756
- }
757
- };
758
- const handlePin = () => {
759
- var _a, _b;
760
- if (editorRef.current) {
761
- (_a = editorRef.current.getControl().getModel()) === null || _a === void 0 ? void 0 : _a.applyEdits([{
762
- range: {
763
- startLineNumber: 1,
764
- startColumn: 1,
765
- endLineNumber: 1,
766
- endColumn: 1
767
- },
768
- text: '@',
769
- }]);
770
- editorRef.current.getControl().setPosition({ lineNumber: 1, column: 2 });
771
- (_b = editorRef.current.getControl().getAction('editor.action.triggerSuggest')) === null || _b === void 0 ? void 0 : _b.run();
772
- }
773
- };
774
- const leftOptions = [
775
- ...(props.showContext
776
- ? [{
777
- title: core_1.nls.localize('theia/ai/chat-ui/attachToContext', 'Attach elements to context'),
778
- handler: () => props.onAddContextElement(),
779
- className: 'codicon-add',
780
- disabled: !props.isEnabled
781
- }]
782
- : []),
783
- ...(props.showPinnedAgent
784
- ? [{
785
- title: props.pinnedAgent ? core_1.nls.localize('theia/ai/chat-ui/unpinAgent', 'Unpin Agent') : core_1.nls.localize('theia/ai/chat-ui/agent', 'Agent'),
786
- handler: props.pinnedAgent ? props.onUnpin : handlePin,
787
- className: 'at-icon',
788
- disabled: !props.isEnabled,
789
- text: {
790
- align: 'right',
791
- content: props.pinnedAgent && props.pinnedAgent.name
792
- },
793
- }]
794
- : []),
795
- ];
796
- let rightOptions = [];
797
- const { currentRequest: latestRequest, isEditing, pending, onResponseChanged } = props;
798
- React.useEffect(() => {
799
- if (!latestRequest) {
800
- return;
801
- }
802
- const disposable = latestRequest.response.onDidChange(onResponseChanged);
803
- return () => disposable.dispose();
804
- }, [latestRequest, onResponseChanged]);
805
- if (isEditing) {
806
- rightOptions = [{
807
- title: core_1.nls.localize('theia/ai/chat-ui/send', 'Send (Enter)'),
808
- handler: () => {
809
- var _a;
810
- if (props.isEnabled) {
811
- submit(((_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.document.textEditorModel.getValue()) || '');
812
- }
813
- },
814
- className: 'codicon-send',
815
- disabled: (isInputEmpty && !shouldUseTaskPlaceholder) || !props.isEnabled
816
- }];
817
- }
818
- else if (pending) {
819
- rightOptions = [{
820
- title: core_1.nls.localize('theia/ai/chat-ui/cancel', 'Cancel (Esc)'),
821
- handler: () => {
822
- if (latestRequest) {
823
- props.onCancel(latestRequest);
824
- }
825
- },
826
- className: 'codicon-stop-circle'
827
- }];
828
- }
829
- else {
830
- rightOptions = [{
831
- title: core_1.nls.localize('theia/ai/chat-ui/send', 'Send (Enter)'),
832
- handler: () => {
833
- var _a;
834
- if (props.isEnabled) {
835
- submit(((_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.document.textEditorModel.getValue()) || '');
836
- }
837
- },
838
- className: 'codicon-send',
839
- disabled: (isInputEmpty && !shouldUseTaskPlaceholder) || !props.isEnabled
840
- }];
841
- }
842
- const contextUI = buildContextUI(props.context, props.labelProvider, props.onDeleteContextElement, props.onOpenContextElement);
843
- // Show mode selector if agent has multiple modes
844
- const showModeSelector = ((_b = (_a = props.modeSelectorProps.receivingAgentModes) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 1;
845
- return (React.createElement("div", { className: 'theia-ChatInput', "data-ai-disabled": !props.isEnabled, onDragOver: props.onDragOver, onDrop: props.onDrop, ref: containerRef },
846
- props.showSuggestions !== false && React.createElement(chat_input_agent_suggestions_1.ChatInputAgentSuggestions, { suggestions: props.suggestions, opener: props.openerService }),
847
- props.showChangeSet && (changeSetUI === null || changeSetUI === void 0 ? void 0 : changeSetUI.elements) &&
848
- React.createElement(ChangeSetBox, { changeSet: changeSetUI }),
849
- React.createElement("div", { className: 'theia-ChatInput-Editor-Box' },
850
- React.createElement("div", { className: 'theia-ChatInput-Editor', ref: editorContainerRef, onKeyDown: onKeyDown, onFocus: handleInputFocus, onBlur: handleInputBlur },
851
- React.createElement("div", { ref: placeholderRef, className: 'theia-ChatInput-Editor-Placeholder' }, placeholderText)),
852
- props.context && props.context.length > 0 &&
853
- React.createElement(ChatContext, { context: contextUI.context }),
854
- React.createElement(ChatInputOptions, { leftOptions: leftOptions, rightOptions: rightOptions, isEnabled: props.isEnabled, modeSelectorProps: {
855
- show: showModeSelector,
856
- modes: props.modeSelectorProps.receivingAgentModes,
857
- currentMode: props.modeSelectorProps.currentMode,
858
- onModeChange: props.modeSelectorProps.onModeChange,
859
- } }))));
860
- };
861
- const ChatInputOptions = ({ leftOptions, rightOptions, isEnabled, modeSelectorProps }) => (React.createElement("div", { className: "theia-ChatInputOptions" },
862
- React.createElement("div", { className: "theia-ChatInputOptions-left" },
863
- leftOptions.map((option, index) => {
864
- var _a, _b;
865
- return (React.createElement("span", { key: index, className: `option${option.disabled ? ' disabled' : ''}${((_a = option.text) === null || _a === void 0 ? void 0 : _a.align) === 'right' ? ' reverse' : ''}`, title: option.title, onClick: option.handler },
866
- React.createElement("span", null, (_b = option.text) === null || _b === void 0 ? void 0 : _b.content),
867
- React.createElement("span", { className: `codicon ${option.className}` })));
868
- }),
869
- modeSelectorProps.show && modeSelectorProps.modes && (React.createElement(ChatModeSelector, { modes: modeSelectorProps.modes, currentMode: modeSelectorProps.currentMode, onModeChange: modeSelectorProps.onModeChange, disabled: !isEnabled }))),
870
- React.createElement("div", { className: "theia-ChatInputOptions-right" }, rightOptions.map((option, index) => {
871
- var _a, _b;
872
- return (React.createElement("span", { key: index, className: `option${option.disabled ? ' disabled' : ''}${((_a = option.text) === null || _a === void 0 ? void 0 : _a.align) === 'right' ? ' reverse' : ''}`, title: option.title, onClick: option.handler },
873
- React.createElement("span", null, (_b = option.text) === null || _b === void 0 ? void 0 : _b.content),
874
- React.createElement("span", { className: `codicon ${option.className}` })));
875
- }))));
876
- const ChatModeSelector = React.memo(({ modes, currentMode, onModeChange, disabled }) => {
877
- var _a, _b, _c;
878
- return (React.createElement("select", { className: "theia-ChatInput-ModeSelector", value: (_b = currentMode !== null && currentMode !== void 0 ? currentMode : (_a = modes[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '', onChange: e => onModeChange(e.target.value), disabled: disabled, title: (_c = modes.find(m => { var _a; return m.id === (currentMode !== null && currentMode !== void 0 ? currentMode : (_a = modes[0]) === null || _a === void 0 ? void 0 : _a.id); })) === null || _c === void 0 ? void 0 : _c.name }, modes.map(mode => (React.createElement("option", { key: mode.id, value: mode.id, title: mode.name }, mode.name)))));
879
- });
880
- const noPropagation = (handler) => (e) => {
881
- handler();
882
- e.stopPropagation();
883
- };
884
- const buildChangeSetUI = (changeSet, labelProvider, decoratorService, actions, onDeleteChangeSet, onDeleteChangeSetElement) => {
885
- const elements = changeSet.getElements();
886
- return elements.length ? ({
887
- title: changeSet.title,
888
- changeSet,
889
- deleteChangeSet: onDeleteChangeSet,
890
- elements: changeSet.getElements().map(element => toUiElement(element, onDeleteChangeSetElement, labelProvider, decoratorService)),
891
- actions
892
- }) : undefined;
893
- };
894
- /** Memo because the parent element rerenders on every key press in the chat widget. */
895
- const ChangeSetBox = React.memo(({ changeSet: { changeSet, title, deleteChangeSet, elements, actions } }) => (React.createElement("div", { className: 'theia-ChatInput-ChangeSet-Box' },
896
- React.createElement("div", { className: 'theia-ChatInput-ChangeSet-Header' },
897
- React.createElement("h3", null, title),
898
- React.createElement("div", { className: 'theia-ChatInput-ChangeSet-Header-Actions' },
899
- actions.map(action => React.createElement("div", { key: action.id, className: 'theia-changeSet-Action' }, action.render(changeSet))),
900
- React.createElement("span", { className: 'codicon codicon-close action', title: core_1.nls.localize('theia/ai/chat-ui/deleteChangeSet', 'Delete Change Set'), onClick: () => deleteChangeSet() }))),
901
- React.createElement("div", { className: 'theia-ChatInput-ChangeSet-List' },
902
- React.createElement("ul", null, elements.map(element => ChangeSetElement(element)))))));
903
- function toUiElement(element, onDeleteChangeSetElement, labelProvider, decoratorService) {
904
- var _a, _b, _c, _d, _e, _f, _g, _h;
905
- return ({
906
- open: (_a = element.open) === null || _a === void 0 ? void 0 : _a.bind(element),
907
- uri: element.uri.toString(),
908
- iconClass: (_c = (_b = element.icon) !== null && _b !== void 0 ? _b : labelProvider.getIcon(element.uri)) !== null && _c !== void 0 ? _c : labelProvider.fileIcon,
909
- nameClass: `${element.type} ${element.state}`,
910
- name: (_d = element.name) !== null && _d !== void 0 ? _d : labelProvider.getName(element.uri),
911
- additionalInfo: (_e = element.additionalInfo) !== null && _e !== void 0 ? _e : labelProvider.getDetails(element.uri),
912
- additionalInfoSuffixIcon: decoratorService.getAdditionalInfoSuffixIcon(element),
913
- openChange: (_f = element === null || element === void 0 ? void 0 : element.openChange) === null || _f === void 0 ? void 0 : _f.bind(element),
914
- apply: element.state !== 'applied' ? (_g = element === null || element === void 0 ? void 0 : element.apply) === null || _g === void 0 ? void 0 : _g.bind(element) : undefined,
915
- revert: element.state === 'applied' || element.state === 'stale' ? (_h = element === null || element === void 0 ? void 0 : element.revert) === null || _h === void 0 ? void 0 : _h.bind(element) : undefined,
916
- delete: () => onDeleteChangeSetElement(element.uri)
917
- });
918
- }
919
- const ChangeSetElement = element => (React.createElement("li", { key: element.uri, title: core_1.nls.localize('theia/ai/chat-ui/openDiff', 'Open Diff'), onClick: () => { var _a; return (_a = element.openChange) === null || _a === void 0 ? void 0 : _a.call(element); } },
920
- React.createElement("div", { className: `theia-ChatInput-ChangeSet-Icon ${element.iconClass}` }),
921
- React.createElement("div", { className: 'theia-ChatInput-ChangeSet-labelParts' },
922
- React.createElement("span", { className: `theia-ChatInput-ChangeSet-title ${element.nameClass}` }, element.name),
923
- React.createElement("div", { className: 'theia-ChatInput-ChangeSet-additionalInfo' },
924
- element.additionalInfo && React.createElement("span", null, element.additionalInfo),
925
- element.additionalInfoSuffixIcon
926
- && React.createElement("div", { className: `theia-ChatInput-ChangeSet-AdditionalInfo-SuffixIcon ${element.additionalInfoSuffixIcon.join(' ')}` }))),
927
- React.createElement("div", { className: 'theia-ChatInput-ChangeSet-Actions' },
928
- element.open && (React.createElement("span", { className: 'codicon codicon-file action', title: core_1.nls.localize('theia/ai/chat-ui/openOriginalFile', 'Open Original File'), onClick: noPropagation(() => element.open()) })),
929
- element.revert && (React.createElement("span", { className: 'codicon codicon-discard action', title: core_1.nls.localizeByDefault('Revert'), onClick: noPropagation(() => element.revert()) })),
930
- element.apply && (React.createElement("span", { className: 'codicon codicon-check action', title: core_1.nls.localizeByDefault('Apply'), onClick: noPropagation(() => element.apply()) })),
931
- React.createElement("span", { className: 'codicon codicon-close action', title: core_1.nls.localizeByDefault('Delete'), onClick: noPropagation(() => element.delete()) }))));
932
- function buildContextUI(context, labelProvider, onDeleteContextElement, onOpen) {
933
- if (!context) {
934
- return { context: [] };
935
- }
936
- return {
937
- context: context.map((element, index) => ({
938
- variable: element,
939
- name: labelProvider.getName(element),
940
- iconClass: labelProvider.getIcon(element),
941
- nameClass: element.variable.name,
942
- additionalInfo: labelProvider.getDetails(element),
943
- details: labelProvider.getLongName(element),
944
- delete: () => onDeleteContextElement(index),
945
- open: () => onOpen(element)
946
- }))
947
- };
948
- }
949
- const ChatContext = ({ context }) => (React.createElement("div", { className: "theia-ChatInput-ChatContext" },
950
- React.createElement("ul", null, context.map((element, index) => {
951
- var _a, _b, _c;
952
- if (image_context_variable_1.ImageContextVariable.isImageContextRequest(element.variable)) {
953
- const variable = image_context_variable_1.ImageContextVariable.parseRequest(element.variable);
954
- return React.createElement("li", { key: index, className: "theia-ChatInput-ChatContext-Element theia-ChatInput-ImageContext-Element", title: (_a = variable.name) !== null && _a !== void 0 ? _a : variable.wsRelativePath, onClick: () => { var _a; return (_a = element.open) === null || _a === void 0 ? void 0 : _a.call(element); } },
955
- React.createElement("div", { className: "theia-ChatInput-ChatContext-Row" },
956
- React.createElement("div", { className: `theia-ChatInput-ChatContext-Icon ${element.iconClass}` }),
957
- React.createElement("div", { className: "theia-ChatInput-ChatContext-labelParts" },
958
- React.createElement("span", { className: `theia-ChatInput-ChatContext-title ${element.nameClass}` }, (_b = variable.name) !== null && _b !== void 0 ? _b : (_c = variable.wsRelativePath) === null || _c === void 0 ? void 0 : _c.split('/').pop()),
959
- React.createElement("span", { className: 'theia-ChatInput-ChatContext-additionalInfo' }, element.additionalInfo)),
960
- React.createElement("span", { className: "codicon codicon-close action", title: core_1.nls.localizeByDefault('Delete'), onClick: e => { e.stopPropagation(); element.delete(); } })),
961
- React.createElement("div", { className: "theia-ChatInput-ChatContext-ImageRow" },
962
- React.createElement("div", { className: 'theia-ChatInput-ImagePreview-Item' },
963
- React.createElement("img", { src: `data:${variable.mimeType};base64,${variable.data}`, alt: variable.name }))));
964
- }
965
- return React.createElement("li", { key: index, className: "theia-ChatInput-ChatContext-Element", title: element.details, onClick: () => { var _a; return (_a = element.open) === null || _a === void 0 ? void 0 : _a.call(element); } },
966
- React.createElement("div", { className: "theia-ChatInput-ChatContext-Row" },
967
- React.createElement("div", { className: `theia-ChatInput-ChatContext-Icon ${element.iconClass}` }),
968
- React.createElement("div", { className: "theia-ChatInput-ChatContext-labelParts" },
969
- React.createElement("span", { className: `theia-ChatInput-ChatContext-title ${element.nameClass}` }, element.name),
970
- React.createElement("span", { className: 'theia-ChatInput-ChatContext-additionalInfo' }, element.additionalInfo)),
971
- React.createElement("span", { className: "codicon codicon-close action", title: core_1.nls.localizeByDefault('Delete'), onClick: e => { e.stopPropagation(); element.delete(); } })));
972
- }))));
973
- //# sourceMappingURL=chat-input-widget.js.map