@theia/ai-chat-ui 1.57.1 → 1.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -74,10 +74,16 @@ export class ToolCallPartRenderer implements ChatResponsePartRenderer<ToolCallCh
74
74
  private tryPrettyPrintJson(response: ToolCallChatResponseContent): string | undefined {
75
75
  let responseContent = response.result;
76
76
  try {
77
- if (response.result) {
78
- responseContent = JSON.stringify(JSON.parse(response.result), undefined, 2);
77
+ if (responseContent) {
78
+ if (typeof responseContent === 'string') {
79
+ responseContent = JSON.parse(responseContent);
80
+ }
81
+ responseContent = JSON.stringify(responseContent, undefined, 2);
79
82
  }
80
83
  } catch (e) {
84
+ if (typeof responseContent !== 'string') {
85
+ responseContent = `The content could not be converted to string: '${e.message}'. This is the original content: '${responseContent}'.`;
86
+ }
81
87
  // fall through
82
88
  }
83
89
  return responseContent;
@@ -39,7 +39,6 @@ export class ChatViewLanguageContribution implements FrontendApplicationContribu
39
39
  private providers: ContributionProvider<ToolProvider>;
40
40
 
41
41
  onStart(_app: FrontendApplication): MaybePromise<void> {
42
- console.log('ChatViewLanguageContribution started');
43
42
  monaco.languages.register({ id: CHAT_VIEW_LANGUAGE_ID, extensions: [CHAT_VIEW_LANGUAGE_EXTENSION] });
44
43
 
45
44
  monaco.languages.registerCompletionItemProvider(CHAT_VIEW_LANGUAGE_ID, {
@@ -14,7 +14,7 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
  import { CommandService, deepClone, Emitter, Event, MessageService } from '@theia/core';
17
- import { ChatRequest, ChatRequestModel, ChatRequestModelImpl, ChatService, ChatSession } from '@theia/ai-chat';
17
+ import { ChatRequest, ChatRequestModel, ChatService, ChatSession } from '@theia/ai-chat';
18
18
  import { BaseWidget, codicon, ExtractableWidget, Message, PanelLayout, PreferenceService, StatefulWidget } from '@theia/core/lib/browser';
19
19
  import { nls } from '@theia/core/lib/common/nls';
20
20
  import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
@@ -93,6 +93,8 @@ export class ChatViewWidget extends BaseWidget implements ExtractableWidget, Sta
93
93
  this.inputWidget.onQuery = this.onQuery.bind(this);
94
94
  this.inputWidget.onCancel = this.onCancel.bind(this);
95
95
  this.inputWidget.chatModel = this.chatSession.model;
96
+ this.inputWidget.onDeleteChangeSet = this.onDeleteChangeSet.bind(this);
97
+ this.inputWidget.onDeleteChangeSetElement = this.onDeleteChangeSetElement.bind(this);
96
98
  this.treeWidget.trackChatModel(this.chatSession.model);
97
99
 
98
100
  this.initListeners();
@@ -165,7 +167,7 @@ export class ChatViewWidget extends BaseWidget implements ExtractableWidget, Sta
165
167
  const requestProgress = await this.chatService.sendRequest(this.chatSession.id, chatRequest);
166
168
  requestProgress?.responseCompleted.then(responseModel => {
167
169
  if (responseModel.isError) {
168
- this.messageService.error(responseModel.errorObject?.message ?? 'An error occurred druring chat service invocation.');
170
+ this.messageService.error(responseModel.errorObject?.message ?? 'An error occurred during chat service invocation.');
169
171
  }
170
172
  });
171
173
  if (!requestProgress) {
@@ -176,9 +178,15 @@ export class ChatViewWidget extends BaseWidget implements ExtractableWidget, Sta
176
178
  }
177
179
 
178
180
  protected onCancel(requestModel: ChatRequestModel): void {
179
- // TODO we should pass a cancellation token with the request (or retrieve one from the request invocation) so we can cleanly cancel here
180
- // For now we cancel manually via casting
181
- (requestModel as ChatRequestModelImpl).response.cancel();
181
+ this.chatService.cancelRequest(requestModel.session.id, requestModel.id);
182
+ }
183
+
184
+ protected onDeleteChangeSet(sessionId: string): void {
185
+ this.chatService.deleteChangeSet(sessionId);
186
+ }
187
+
188
+ protected onDeleteChangeSetElement(sessionId: string, index: number): void {
189
+ this.chatService.deleteChangeSetElement(sessionId, index);
182
190
  }
183
191
 
184
192
  lock(): void {
@@ -153,51 +153,191 @@ div:last-child > .theia-ChatNode {
153
153
  }
154
154
 
155
155
  .theia-ChatInput {
156
+ margin-top: 16px;
156
157
  position: relative;
157
158
  width: 100%;
158
159
  box-sizing: border-box;
159
160
  gap: 4px;
160
161
  }
161
162
 
162
- .theia-ChatInput-Editor-Box {
163
- margin-bottom: 2px;
164
- padding: 10px;
163
+ .theia-ChatInput-ChangeSet-Box {
164
+ margin: 0 16px -5px 16px;
165
+ padding: 2px;
166
+ padding-bottom: 12px;
165
167
  height: auto;
168
+ border: var(--theia-border-width) solid var(--theia-dropdown-border);
169
+ border-radius: 4px 4px 0 0;
170
+ background-color: var(--theia-activityBar-background);
166
171
  display: flex;
167
172
  flex-direction: column;
168
- justify-content: flex-end;
173
+ }
174
+
175
+ .theia-ChatInput-ChangeSet-Header {
176
+ display: flex;
177
+ justify-content: space-between;
178
+ align-items: center;
179
+ margin: 4px;
180
+ }
181
+
182
+ .theia-ChatInput-ChangeSet-Box h3 {
183
+ font-size: 12px;
184
+ color: var(--theia-disabledForeground);
185
+ padding-top: 0;
186
+ margin: 0;
187
+ display: flex;
188
+ }
189
+
190
+ .theia-ChatInput-ChangeSet-Header-Actions button {
191
+ font-size: 12px;
192
+ padding: 2px 4px;
193
+ min-width: 40px;
194
+ margin-left: 6px;
195
+ }
196
+
197
+ .theia-ChatInput-ChangeSet-List ul {
198
+ list-style-type: none;
199
+ padding: 0;
200
+ margin: 4px;
201
+ }
202
+
203
+ .theia-ChatInput-ChangeSet-List ul li {
204
+ display: flex;
205
+ flex-direction: row;
206
+ line-height: 18px;
207
+ padding: 0;
208
+ padding-top: 2px;
209
+ margin: 0 2px 2px 0px;
210
+ border-radius: 4px;
211
+ position: relative;
212
+ }
213
+
214
+ .theia-ChatInput-ChangeSet-List ul li:hover {
215
+ background-color: var(--theia-toolbar-hoverBackground);
216
+ }
217
+
218
+ .theia-ChatInput-ChangeSet-Actions {
219
+ display: none;
220
+ position: absolute;
221
+ right: 8px;
222
+ top: 2px;
223
+ gap: 4px;
224
+ }
225
+
226
+ .theia-ChatInput-ChangeSet-List ul {
227
+ max-height: 150px;
228
+ overflow-y: auto;
229
+ }
230
+
231
+ .theia-ChatInput-ChangeSet-List ul li {
232
+ cursor: pointer;
233
+ }
234
+
235
+ .theia-ChatInput-ChangeSet-List ul li:hover .theia-ChatInput-ChangeSet-Actions {
236
+ display: flex;
237
+ }
238
+
239
+ .theia-ChatInput-ChangeSet-List .theia-ChatInput-ChangeSet-Icon {
240
+ padding-left: 2px;
241
+ padding-right: 4px;
242
+ min-width: var(--theia-icon-size);
243
+ display: flex;
244
+ justify-content: center;
245
+ align-items: center;
246
+ }
247
+
248
+ .theia-ChatInput-ChangeSet-List .theia-ChatInput-ChangeSet-Icon::before {
249
+ text-align: center;
250
+ margin-right: 4px;
251
+ font-size: calc(var(--theia-content-font-size) * 0.8);
252
+ }
253
+
254
+ .theia-ChatInput-ChangeSet-List
255
+ .theia-ChatInput-ChangeSet-Icon.codicon::before {
256
+ font-size: var(--theia-ui-font-size1);
257
+ }
258
+
259
+ .theia-ChatInput-ChangeSet-Actions .action {
260
+ width: 16px;
261
+ height: 16px;
262
+ cursor: pointer;
263
+ }
264
+
265
+ .theia-ChatInput-ChangeSet-additionalInfo {
266
+ margin-left: 8px;
267
+ color: var(--theia-disabledForeground);
268
+ }
269
+
270
+ .theia-ChatInput-ChangeSet-title {
271
+ white-space: nowrap;
272
+ overflow: visible;
273
+ }
274
+
275
+ .theia-ChatInput-ChangeSet-Header-Actions,
276
+ .theia-ChatInput-ChangeSet-Box h3,
277
+ .theia-ChatInput-ChangeSet-additionalInfo {
278
+ white-space: nowrap;
169
279
  overflow: hidden;
280
+ text-overflow: ellipsis;
170
281
  }
171
282
 
172
- .theia-ChatInput-Editor {
173
- width: 100%;
283
+ .theia-ChatInput-ChangeSet-Header-Actions .codicon.action {
284
+ font-size: 18px;
285
+ height: 20px;
286
+ vertical-align: middle;
287
+ margin-left: 4px;
288
+ border-radius: 4px;
289
+ cursor: pointer;
290
+ }
291
+ .theia-ChatInput-ChangeSet-Header-Actions .codicon.action:hover {
292
+ background-color: var(--theia-toolbar-hoverBackground);
293
+ }
294
+
295
+ .theia-ChatInput-ChangeSet-title.rejected {
296
+ text-decoration: line-through;
297
+ }
298
+
299
+ .theia-ChatInput-ChangeSet-title.add.pending {
300
+ color: var(--theia-charts-green);
301
+ }
302
+ .theia-ChatInput-ChangeSet-title.modify.pending {
303
+ color: var(--theia-charts-orange);
304
+ }
305
+ .theia-ChatInput-ChangeSet-title.delete.pending {
306
+ color: var(--theia-charts-red);
307
+ }
308
+
309
+ .theia-ChatInput-Editor-Box {
310
+ margin: 0 16px 16px 16px;
311
+ padding: 2px;
174
312
  height: auto;
175
313
  border: var(--theia-border-width) solid var(--theia-dropdown-border);
176
314
  border-radius: 4px;
315
+ background-color: var(--theia-editor-background);
177
316
  display: flex;
178
- flex-direction: column-reverse;
317
+ flex-direction: column;
318
+ justify-content: flex-end;
179
319
  overflow: hidden;
180
- transition: height 0.05s ease-in-out;
181
320
  }
182
321
 
183
- .theia-ChatInput-Editor:has(.monaco-editor.focused) {
322
+ .theia-ChatInput-Editor-Box:has(.monaco-editor.focused) {
184
323
  border-color: var(--theia-focusBorder);
185
324
  }
186
325
 
187
- .theia-ChatInput-Editor .monaco-editor {
188
- display: flex;
326
+ .theia-ChatInput-Editor {
189
327
  width: 100%;
190
- height: 100%;
328
+ height: auto;
329
+ display: flex;
330
+ flex-direction: column-reverse;
191
331
  overflow: hidden;
332
+ transition: height 0.05s ease-in-out;
192
333
  position: relative;
193
334
  }
194
335
 
195
336
  .theia-ChatInput-Editor-Placeholder {
196
337
  position: absolute;
197
- top: -3px;
198
- left: 19px;
338
+ top: 9px;
339
+ left: 8px;
199
340
  right: 0;
200
- bottom: 0;
201
341
  display: flex;
202
342
  align-items: center;
203
343
  color: var(--theia-descriptionForeground);
@@ -209,6 +349,14 @@ div:last-child > .theia-ChatNode {
209
349
  display: none;
210
350
  }
211
351
 
352
+ .theia-ChatInput-Editor .monaco-editor {
353
+ display: flex;
354
+ width: 100%;
355
+ height: 100%;
356
+ overflow: hidden;
357
+ position: relative;
358
+ }
359
+
212
360
  .theia-ChatInput-Editor .monaco-editor .margin,
213
361
  .theia-ChatInput-Editor .monaco-editor .monaco-editor-background,
214
362
  .theia-ChatInput-Editor .monaco-editor .inputarea.ime-input {
@@ -216,29 +364,45 @@ div:last-child > .theia-ChatNode {
216
364
  }
217
365
 
218
366
  .theia-ChatInputOptions {
219
- position: absolute;
220
- bottom: 31px;
221
- right: 26px;
222
- width: 10px;
223
- height: 10px;
367
+ width: 100%;
368
+ height: 25px;
369
+ padding-left: 6px;
370
+ padding-right: 6px;
371
+ display: flex;
372
+ justify-content: space-between;
373
+ }
374
+
375
+ .theia-ChatInputOptions .theia-ChatInputOptions-left,
376
+ .theia-ChatInputOptions .theia-ChatInputOptions-right {
377
+ display: flex;
378
+ }
379
+ .theia-ChatInputOptions .theia-ChatInputOptions-right {
380
+ margin-right: 12px;
224
381
  }
225
382
 
226
383
  .theia-ChatInputOptions .option {
227
384
  width: 21px;
228
385
  height: 21px;
229
- margin-top: 2px;
386
+ padding: 2px;
230
387
  display: inline-block;
231
388
  box-sizing: border-box;
232
389
  user-select: none;
233
390
  background-repeat: no-repeat;
234
391
  background-position: center;
392
+ border-radius: 5px;
235
393
  border: var(--theia-border-width) solid transparent;
236
- opacity: 0.7;
237
394
  cursor: pointer;
238
395
  }
239
396
 
397
+ .theia-ChatInputOptions .option.disabled {
398
+ cursor: default;
399
+ opacity: var(--theia-mod-disabled-opacity);
400
+ pointer-events: none;
401
+ }
402
+
240
403
  .theia-ChatInputOptions .option:hover {
241
404
  opacity: 1;
405
+ background-color: var(--theia-toolbar-hoverBackground);
242
406
  }
243
407
 
244
408
  .theia-CodePartRenderer-root {