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

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