@theia/ai-chat-ui 1.63.0-next.24 → 1.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/lib/browser/ai-chat-ui-contribution.d.ts +31 -1
  2. package/lib/browser/ai-chat-ui-contribution.d.ts.map +1 -1
  3. package/lib/browser/ai-chat-ui-contribution.js +192 -8
  4. package/lib/browser/ai-chat-ui-contribution.js.map +1 -1
  5. package/lib/browser/ai-chat-ui-frontend-module.d.ts.map +1 -1
  6. package/lib/browser/ai-chat-ui-frontend-module.js +8 -0
  7. package/lib/browser/ai-chat-ui-frontend-module.js.map +1 -1
  8. package/lib/browser/chat-input-widget.d.ts +24 -16
  9. package/lib/browser/chat-input-widget.d.ts.map +1 -1
  10. package/lib/browser/chat-input-widget.js +199 -37
  11. package/lib/browser/chat-input-widget.js.map +1 -1
  12. package/lib/browser/chat-node-toolbar-action-contribution.d.ts +1 -0
  13. package/lib/browser/chat-node-toolbar-action-contribution.d.ts.map +1 -1
  14. package/lib/browser/chat-node-toolbar-action-contribution.js +13 -0
  15. package/lib/browser/chat-node-toolbar-action-contribution.js.map +1 -1
  16. package/lib/browser/chat-response-renderer/delegation-response-renderer.d.ts +14 -0
  17. package/lib/browser/chat-response-renderer/delegation-response-renderer.d.ts.map +1 -0
  18. package/lib/browser/chat-response-renderer/delegation-response-renderer.js +144 -0
  19. package/lib/browser/chat-response-renderer/delegation-response-renderer.js.map +1 -0
  20. package/lib/browser/chat-response-renderer/index.d.ts +1 -0
  21. package/lib/browser/chat-response-renderer/index.d.ts.map +1 -1
  22. package/lib/browser/chat-response-renderer/index.js +1 -0
  23. package/lib/browser/chat-response-renderer/index.js.map +1 -1
  24. package/lib/browser/chat-response-renderer/tool-confirmation.d.ts +2 -2
  25. package/lib/browser/chat-response-renderer/tool-confirmation.d.ts.map +1 -1
  26. package/lib/browser/chat-response-renderer/tool-confirmation.js +23 -23
  27. package/lib/browser/chat-response-renderer/tool-confirmation.js.map +1 -1
  28. package/lib/browser/chat-response-renderer/toolcall-part-renderer.d.ts +4 -1
  29. package/lib/browser/chat-response-renderer/toolcall-part-renderer.d.ts.map +1 -1
  30. package/lib/browser/chat-response-renderer/toolcall-part-renderer.js +65 -32
  31. package/lib/browser/chat-response-renderer/toolcall-part-renderer.js.map +1 -1
  32. package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts +3 -1
  33. package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts.map +1 -1
  34. package/lib/browser/chat-tree-view/chat-view-tree-widget.js +50 -8
  35. package/lib/browser/chat-tree-view/chat-view-tree-widget.js.map +1 -1
  36. package/lib/browser/chat-tree-view/sub-chat-widget.d.ts +22 -0
  37. package/lib/browser/chat-tree-view/sub-chat-widget.d.ts.map +1 -0
  38. package/lib/browser/chat-tree-view/sub-chat-widget.js +92 -0
  39. package/lib/browser/chat-tree-view/sub-chat-widget.js.map +1 -0
  40. package/lib/browser/chat-view-commands.d.ts +1 -0
  41. package/lib/browser/chat-view-commands.d.ts.map +1 -1
  42. package/lib/browser/chat-view-commands.js +5 -0
  43. package/lib/browser/chat-view-commands.js.map +1 -1
  44. package/lib/browser/chat-view-contribution.d.ts +2 -0
  45. package/lib/browser/chat-view-contribution.d.ts.map +1 -1
  46. package/lib/browser/chat-view-contribution.js +31 -18
  47. package/lib/browser/chat-view-contribution.js.map +1 -1
  48. package/lib/browser/chat-view-widget-toolbar-contribution.d.ts +2 -0
  49. package/lib/browser/chat-view-widget-toolbar-contribution.d.ts.map +1 -1
  50. package/lib/browser/chat-view-widget-toolbar-contribution.js +13 -5
  51. package/lib/browser/chat-view-widget-toolbar-contribution.js.map +1 -1
  52. package/lib/browser/chat-view-widget.d.ts +1 -1
  53. package/lib/browser/chat-view-widget.d.ts.map +1 -1
  54. package/lib/browser/chat-view-widget.js +1 -4
  55. package/lib/browser/chat-view-widget.js.map +1 -1
  56. package/package.json +11 -11
  57. package/src/browser/ai-chat-ui-contribution.ts +191 -12
  58. package/src/browser/ai-chat-ui-frontend-module.ts +11 -0
  59. package/src/browser/chat-input-widget.tsx +253 -58
  60. package/src/browser/chat-node-toolbar-action-contribution.ts +14 -0
  61. package/src/browser/chat-response-renderer/delegation-response-renderer.tsx +177 -0
  62. package/src/browser/chat-response-renderer/index.ts +1 -0
  63. package/src/browser/chat-response-renderer/tool-confirmation.tsx +30 -30
  64. package/src/browser/chat-response-renderer/toolcall-part-renderer.tsx +95 -60
  65. package/src/browser/chat-tree-view/chat-view-tree-widget.tsx +58 -8
  66. package/src/browser/chat-tree-view/sub-chat-widget.tsx +101 -0
  67. package/src/browser/chat-view-commands.ts +6 -0
  68. package/src/browser/chat-view-contribution.ts +29 -18
  69. package/src/browser/chat-view-widget-toolbar-contribution.tsx +12 -5
  70. package/src/browser/chat-view-widget.tsx +2 -5
  71. package/src/browser/style/index.css +209 -5
@@ -0,0 +1,101 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2025 EclipseSource GmbH.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { inject, injectable, named } from '@theia/core/shared/inversify';
18
+ import { ProgressMessage } from '../chat-progress-message';
19
+ import { ChatViewTreeWidget, ResponseNode } from './chat-view-tree-widget';
20
+ import * as React from '@theia/core/shared/react';
21
+ import { ContributionProvider } from '@theia/core';
22
+ import { ChatResponsePartRenderer } from '../chat-response-part-renderer';
23
+ import { ChatNodeToolbarActionContribution } from '../chat-node-toolbar-action-contribution';
24
+ import { ChatResponseContent } from '@theia/ai-chat';
25
+ import { ContextMenuRenderer, TreeNode } from '@theia/core/lib/browser';
26
+ import { nls } from '@theia/core/lib/common/nls';
27
+
28
+ /**
29
+ * Subset of the ChatViewTreeWidget used to render ResponseNodes for delegated prompts.
30
+ */
31
+ @injectable()
32
+ export class SubChatWidget {
33
+
34
+ @inject(ContributionProvider) @named(ChatResponsePartRenderer)
35
+ protected readonly chatResponsePartRenderers: ContributionProvider<ChatResponsePartRenderer<ChatResponseContent>>;
36
+
37
+ @inject(ContributionProvider) @named(ChatNodeToolbarActionContribution)
38
+ protected readonly chatNodeToolbarActionContributions: ContributionProvider<ChatNodeToolbarActionContribution>;
39
+
40
+ @inject(ContextMenuRenderer) contextMenuRenderer: ContextMenuRenderer;
41
+
42
+ renderChatResponse(node: ResponseNode): React.ReactNode {
43
+ return (
44
+ <div className={'theia-ResponseNode'}>
45
+ {!node.response.isComplete
46
+ && node.response.response.content.length === 0
47
+ && node.response.progressMessages
48
+ .filter(c => c.show === 'untilFirstContent')
49
+ .map((c, i) =>
50
+ <ProgressMessage {...c} key={`${node.id}-progress-untilFirstContent-${i}`} />
51
+ )
52
+ }
53
+ {node.response.response.content.map((c, i) =>
54
+ <div className='theia-ResponseNode-Content' key={`${node.id}-content-${i}`}>{this.getChatResponsePartRenderer(c, node)}</div>
55
+ )}
56
+ {!node.response.isComplete
57
+ && node.response.progressMessages
58
+ .filter(c => c.show === 'whileIncomplete')
59
+ .map((c, i) =>
60
+ <ProgressMessage {...c} key={`${node.id}-progress-whileIncomplete-${i}`} />
61
+ )
62
+ }
63
+ {node.response.progressMessages
64
+ .filter(c => c.show === 'forever')
65
+ .map((c, i) =>
66
+ <ProgressMessage {...c} key={`${node.id}-progress-afterComplete-${i}`} />
67
+ )
68
+ }
69
+ </div>
70
+ );
71
+ }
72
+
73
+ protected getChatResponsePartRenderer(content: ChatResponseContent, node: ResponseNode): React.ReactNode {
74
+ const renderer = this.chatResponsePartRenderers.getContributions().reduce<[number, ChatResponsePartRenderer<ChatResponseContent> | undefined]>(
75
+ (prev, current) => {
76
+ const prio = current.canHandle(content);
77
+ if (prio > prev[0]) {
78
+ return [prio, current];
79
+ } return prev;
80
+ },
81
+ [-1, undefined])[1];
82
+ if (!renderer) {
83
+ console.error('No renderer found for content', content);
84
+ return <div>{nls.localize('theia/ai/chat-ui/chat-view-tree-widget/noRenderer', 'Error: No renderer found')}</div>;
85
+ }
86
+ return renderer.render(content, node);
87
+ }
88
+
89
+ protected handleContextMenu(node: TreeNode | undefined, event: React.MouseEvent<HTMLElement>): void {
90
+ this.contextMenuRenderer.render({
91
+ menuPath: ChatViewTreeWidget.CONTEXT_MENU,
92
+ anchor: { x: event.clientX, y: event.clientY },
93
+ args: [node],
94
+ context: event.currentTarget
95
+ });
96
+ event.preventDefault();
97
+ }
98
+ }
99
+
100
+ export const SubChatWidgetFactory = Symbol('SubChatWidgetFactory');
101
+ export type SubChatWidgetFactory = () => SubChatWidget;
@@ -43,6 +43,12 @@ export namespace ChatCommands {
43
43
  id: 'ai-chat.new-with-task-context',
44
44
  };
45
45
 
46
+ export const AI_CHAT_INITIATE_SESSION_WITH_TASK_CONTEXT = Command.toLocalizedCommand({
47
+ id: 'ai-chat.initiate-session-with-task-context',
48
+ label: 'Task Context: Initiate Session',
49
+ category: CHAT_CATEGORY
50
+ }, undefined, CHAT_CATEGORY_KEY);
51
+
46
52
  export const AI_CHAT_SUMMARIZE_CURRENT_SESSION = Command.toLocalizedCommand({
47
53
  id: 'ai-chat-summary-current-session',
48
54
  iconClass: codicon('go-to-editing-session'),
@@ -22,6 +22,7 @@ import {
22
22
  isResponseNode, RequestNode, ResponseNode, type EditableRequestNode
23
23
  } from './chat-tree-view/chat-view-tree-widget';
24
24
  import { AIChatInputWidget } from './chat-input-widget';
25
+ import { AICommandHandlerFactory, ENABLE_AI_CONTEXT_KEY } from '@theia/ai-core/lib/browser';
25
26
 
26
27
  export namespace ChatViewCommands {
27
28
  export const COPY_MESSAGE = Command.toDefaultLocalizedCommand({
@@ -51,8 +52,11 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
51
52
  @inject(CommandService)
52
53
  protected readonly commandService: CommandService;
53
54
 
55
+ @inject(AICommandHandlerFactory)
56
+ protected readonly commandHandlerFactory: AICommandHandlerFactory;
57
+
54
58
  registerCommands(commands: CommandRegistry): void {
55
- commands.registerHandler(CommonCommands.COPY.id, {
59
+ commands.registerHandler(CommonCommands.COPY.id, this.commandHandlerFactory({
56
60
  execute: (...args: unknown[]) => {
57
61
  if (window.getSelection()?.type !== 'Range' && containsRequestOrResponseNode(args)) {
58
62
  this.copyMessage(extractRequestOrResponseNodes(args));
@@ -61,16 +65,16 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
61
65
  }
62
66
  },
63
67
  isEnabled: (...args: unknown[]) => containsRequestOrResponseNode(args)
64
- });
65
- commands.registerCommand(ChatViewCommands.COPY_MESSAGE, {
68
+ }));
69
+ commands.registerCommand(ChatViewCommands.COPY_MESSAGE, this.commandHandlerFactory({
66
70
  execute: (...args: unknown[]) => {
67
71
  if (containsRequestOrResponseNode(args)) {
68
72
  this.copyMessage(extractRequestOrResponseNodes(args));
69
73
  }
70
74
  },
71
75
  isEnabled: (...args: unknown[]) => containsRequestOrResponseNode(args)
72
- });
73
- commands.registerCommand(ChatViewCommands.COPY_ALL, {
76
+ }));
77
+ commands.registerCommand(ChatViewCommands.COPY_ALL, this.commandHandlerFactory({
74
78
  execute: (...args: unknown[]) => {
75
79
  if (containsRequestOrResponseNode(args)) {
76
80
  const parent = extractRequestOrResponseNodes(args).find(arg => arg.parent)?.parent;
@@ -84,8 +88,8 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
84
88
  }
85
89
  },
86
90
  isEnabled: (...args: unknown[]) => containsRequestOrResponseNode(args)
87
- });
88
- commands.registerCommand(ChatViewCommands.COPY_CODE, {
91
+ }));
92
+ commands.registerCommand(ChatViewCommands.COPY_CODE, this.commandHandlerFactory({
89
93
  execute: (...args: unknown[]) => {
90
94
  if (containsCode(args)) {
91
95
  const code = args
@@ -96,14 +100,14 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
96
100
  }
97
101
  },
98
102
  isEnabled: (...args: unknown[]) => containsRequestOrResponseNode(args) && containsCode(args)
99
- });
100
- commands.registerCommand(ChatViewCommands.EDIT, {
103
+ }));
104
+ commands.registerCommand(ChatViewCommands.EDIT, this.commandHandlerFactory({
101
105
  execute: (...args: [EditableRequestNode, ...unknown[]]) => {
102
106
  args[0].request.enableEdit();
103
107
  },
104
108
  isEnabled: (...args: unknown[]) => hasAsFirstArg(args, isEditableRequestNode) && !args[0].request.isEditing,
105
109
  isVisible: (...args: unknown[]) => hasAsFirstArg(args, isEditableRequestNode) && !args[0].request.isEditing
106
- });
110
+ }));
107
111
  }
108
112
 
109
113
  protected copyMessage(args: (RequestNode | ResponseNode)[]): void {
@@ -117,7 +121,7 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
117
121
 
118
122
  protected getCopyText(arg: RequestNode | ResponseNode): string {
119
123
  if (isRequestNode(arg)) {
120
- return arg.request.request.text;
124
+ return arg.request.request.text ?? '';
121
125
  } else if (isResponseNode(arg)) {
122
126
  return arg.response.response.asDisplayString();
123
127
  }
@@ -126,25 +130,32 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
126
130
 
127
131
  registerMenus(menus: MenuModelRegistry): void {
128
132
  menus.registerMenuAction([...ChatViewTreeWidget.CONTEXT_MENU, '_1'], {
129
- commandId: CommonCommands.COPY.id
133
+ commandId: CommonCommands.COPY.id,
134
+ when: ENABLE_AI_CONTEXT_KEY
130
135
  });
131
136
  menus.registerMenuAction([...ChatViewTreeWidget.CONTEXT_MENU, '_1'], {
132
- commandId: ChatViewCommands.COPY_MESSAGE.id
137
+ commandId: ChatViewCommands.COPY_MESSAGE.id,
138
+ when: ENABLE_AI_CONTEXT_KEY
133
139
  });
134
140
  menus.registerMenuAction([...ChatViewTreeWidget.CONTEXT_MENU, '_1'], {
135
- commandId: ChatViewCommands.COPY_ALL.id
141
+ commandId: ChatViewCommands.COPY_ALL.id,
142
+ when: ENABLE_AI_CONTEXT_KEY
136
143
  });
137
144
  menus.registerMenuAction([...ChatViewTreeWidget.CONTEXT_MENU, '_1'], {
138
- commandId: ChatViewCommands.COPY_CODE.id
145
+ commandId: ChatViewCommands.COPY_CODE.id,
146
+ when: ENABLE_AI_CONTEXT_KEY
139
147
  });
140
148
  menus.registerMenuAction([...ChatViewTreeWidget.CONTEXT_MENU, '_1'], {
141
- commandId: ChatViewCommands.EDIT.id
149
+ commandId: ChatViewCommands.EDIT.id,
150
+ when: ENABLE_AI_CONTEXT_KEY
142
151
  });
143
152
  menus.registerMenuAction([...AIChatInputWidget.CONTEXT_MENU, '_1'], {
144
- commandId: CommonCommands.COPY.id
153
+ commandId: CommonCommands.COPY.id,
154
+ when: ENABLE_AI_CONTEXT_KEY
145
155
  });
146
156
  menus.registerMenuAction([...AIChatInputWidget.CONTEXT_MENU, '_1'], {
147
- commandId: CommonCommands.PASTE.id
157
+ commandId: CommonCommands.PASTE.id,
158
+ when: ENABLE_AI_CONTEXT_KEY
148
159
  });
149
160
  }
150
161
  }
@@ -23,6 +23,7 @@ import { CommandRegistry } from '@theia/core/lib/common/command';
23
23
  import { SessionSettingsDialog } from './session-settings-dialog';
24
24
  import { MonacoEditorProvider } from '@theia/monaco/lib/browser/monaco-editor-provider';
25
25
  import { ChatViewWidget } from './chat-view-widget';
26
+ import { AIActivationService, ENABLE_AI_CONTEXT_KEY } from '@theia/ai-core/lib/browser';
26
27
 
27
28
  @injectable()
28
29
  export class ChatViewWidgetToolbarContribution implements TabBarToolbarContribution {
@@ -38,6 +39,9 @@ export class ChatViewWidgetToolbarContribution implements TabBarToolbarContribut
38
39
  @inject(InMemoryResources)
39
40
  protected readonly resources: InMemoryResources;
40
41
 
42
+ @inject(AIActivationService)
43
+ protected readonly activationService: AIActivationService;
44
+
41
45
  protected readonly onChatWidgetStateChangedEmitter = new Emitter<void>();
42
46
  protected readonly onChatWidgetStateChanged = this.onChatWidgetStateChangedEmitter.event;
43
47
 
@@ -53,8 +57,8 @@ export class ChatViewWidgetToolbarContribution implements TabBarToolbarContribut
53
57
 
54
58
  this.commandRegistry.registerCommand(ChatCommands.EDIT_SESSION_SETTINGS, {
55
59
  execute: () => this.openJsonDataDialog(),
56
- isEnabled: widget => widget instanceof ChatViewWidget,
57
- isVisible: widget => widget instanceof ChatViewWidget
60
+ isEnabled: widget => this.activationService.isActive && widget instanceof ChatViewWidget,
61
+ isVisible: widget => this.activationService.isActive && widget instanceof ChatViewWidget
58
62
  });
59
63
  }
60
64
 
@@ -64,20 +68,23 @@ export class ChatViewWidgetToolbarContribution implements TabBarToolbarContribut
64
68
  command: ChatCommands.SCROLL_LOCK_WIDGET.id,
65
69
  tooltip: nls.localizeByDefault('Turn Auto Scrolling Off'),
66
70
  onDidChange: this.onChatWidgetStateChanged,
67
- priority: 2
71
+ priority: 2,
72
+ when: ENABLE_AI_CONTEXT_KEY
68
73
  });
69
74
  registry.registerItem({
70
75
  id: ChatCommands.SCROLL_UNLOCK_WIDGET.id,
71
76
  command: ChatCommands.SCROLL_UNLOCK_WIDGET.id,
72
77
  tooltip: nls.localizeByDefault('Turn Auto Scrolling On'),
73
78
  onDidChange: this.onChatWidgetStateChanged,
74
- priority: 2
79
+ priority: 2,
80
+ when: ENABLE_AI_CONTEXT_KEY
75
81
  });
76
82
  registry.registerItem({
77
83
  id: ChatCommands.EDIT_SESSION_SETTINGS.id,
78
84
  command: ChatCommands.EDIT_SESSION_SETTINGS.id,
79
85
  tooltip: nls.localize('theia/ai/session-settings-dialog/tooltip', 'Set Session Settings'),
80
- priority: 3
86
+ priority: 3,
87
+ when: ENABLE_AI_CONTEXT_KEY
81
88
  });
82
89
  }
83
90
 
@@ -136,9 +136,6 @@ export class ChatViewWidget extends BaseWidget implements ExtractableWidget, Sta
136
136
  this.treeWidget.trackChatModel(this.chatSession.model);
137
137
  this.inputWidget.chatModel = this.chatSession.model;
138
138
  this.inputWidget.pinnedAgent = this.chatSession.pinnedAgent;
139
- if (event.focus) {
140
- this.show();
141
- }
142
139
  } else {
143
140
  console.warn(`Session with ${event.sessionId} not found.`);
144
141
  }
@@ -182,8 +179,8 @@ export class ChatViewWidget extends BaseWidget implements ExtractableWidget, Sta
182
179
  return this.onStateChangedEmitter.event;
183
180
  }
184
181
 
185
- protected async onQuery(query: string | ChatRequest): Promise<void> {
186
- const chatRequest: ChatRequest = typeof query === 'string' ? { text: query } : { ...query };
182
+ protected async onQuery(query?: string | ChatRequest): Promise<void> {
183
+ const chatRequest: ChatRequest = !query ? { text: '' } : typeof query === 'string' ? { text: query } : { ...query };
187
184
  if (chatRequest.text.length === 0) { return; }
188
185
 
189
186
  const requestProgress = await this.chatService.sendRequest(this.chatSession.id, chatRequest);
@@ -194,28 +194,46 @@ div:last-child > .theia-ChatNode {
194
194
  gap: 4px;
195
195
  }
196
196
 
197
+ .theia-ChatInput[data-ai-disabled="true"] {
198
+ opacity: var(--theia-mod-disabled-opacity);
199
+ pointer-events: none;
200
+ }
201
+
202
+ .theia-ChatInput[data-ai-disabled="true"] .theia-ChatInput-Editor-Placeholder {
203
+ color: var(--theia-input-disabledForeground);
204
+ font-family: var(--theia-ui-font-family);
205
+ }
206
+
197
207
  .theia-ChatInput-ChatContext ul {
198
208
  list-style-type: none;
199
209
  padding: 0px 4px 8px 8px;
200
210
  margin: 0;
201
211
  display: flex;
202
212
  flex-wrap: wrap;
213
+ align-items: center;
203
214
  gap: 6px;
204
215
  }
205
216
 
206
217
  .theia-ChatInput-ChatContext-Element {
207
218
  display: flex;
208
- align-items: center;
219
+ flex-direction: column;
209
220
  border-radius: calc(var(--theia-ui-padding) * 2 / 3);
210
221
  border: var(--theia-border-width) solid var(--theia-dropdown-border);
211
222
  padding: 2px 4px 2px 6px;
212
- height: 18px;
213
223
  line-height: 16px;
214
224
  min-width: 0;
215
225
  user-select: none;
216
226
  cursor: pointer;
217
227
  }
218
228
 
229
+ .theia-ChatInput-ChatContext-Row {
230
+ display: flex;
231
+ align-items: center;
232
+ width: 100%;
233
+ color: var(--theia-foreground);
234
+ font-family: var(--theia-ui-font-family);
235
+ }
236
+
219
237
  .theia-ChatInput-ChatContext-labelParts {
220
238
  flex: 1;
221
239
  min-width: 0;
@@ -478,6 +496,7 @@ div:last-child > .theia-ChatNode {
478
496
  pointer-events: none;
479
497
  z-index: 10;
480
498
  text-align: left;
499
+ font-family: var(--theia-ui-font-family);
481
500
  }
482
501
 
483
502
  .theia-ChatInput-Editor-Placeholder.hidden {
@@ -497,6 +516,32 @@ div:last-child > .theia-ChatNode {
497
516
  padding-left: 8px !important;
498
517
  }
499
518
 
519
+ .theia-ChatInput-ImagePreview-Item {
520
+ position: relative;
521
+ border: var(--theia-border-width) solid var(--theia-dropdown-border);
522
+ border-radius: 4px;
523
+ overflow: hidden;
524
+ height: 100px;
525
+ width: 120px;
526
+ }
527
+
528
+ .theia-ChatInput-ChatContext-ImageRow {
529
+ margin-top: 4px;
530
+ width: 100%;
531
+ display: flex;
532
+ justify-content: center;
533
+ }
534
+
535
+ .theia-ChatInput-ImageContext-Element {
536
+ min-width: 150px;
537
+ }
538
+
539
+ .theia-ChatInput-ImagePreview-Item img {
540
+ width: 100%;
541
+ height: 100%;
542
+ object-fit: contain;
543
+ }
544
+
500
545
  .theia-ChatInputOptions {
501
546
  width: 100%;
502
547
  height: 25px;
@@ -504,6 +549,7 @@ div:last-child > .theia-ChatNode {
504
549
  padding-right: 6px;
505
550
  display: flex;
506
551
  justify-content: space-between;
552
+ color: var(--theia-foreground);
507
553
  }
508
554
 
509
555
  .theia-ChatInputOptions .theia-ChatInputOptions-left,
@@ -706,7 +752,7 @@ div:last-child > .theia-ChatNode {
706
752
  background: var(--theia-menu-background);
707
753
  border: 1px solid var(--theia-menu-border);
708
754
  border-radius: 4px;
709
- box-shadow: 0 2px 8px rgba(0,0,0,0.15);
755
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
710
756
  margin: 0;
711
757
  padding: 0;
712
758
  list-style: none;
@@ -789,14 +835,29 @@ div:last-child > .theia-ChatNode {
789
835
  color: var(--theia-errorForeground);
790
836
  }
791
837
 
792
- .theia-tool-pending {
838
+ .theia-toolCall-denied,
839
+ .theia-toolCall-finished summary,
840
+ .theia-toolCall-allowed,
841
+ .theia-toolCall-waiting {
842
+ font-weight: bold;
843
+ }
844
+
845
+ .theia-toolCall-allowed .codicon-loading {
846
+ font-size: 1em;
847
+ }
848
+
849
+ .theia-toolCall-pending {
793
850
  color: var(--theia-descriptionForeground);
794
851
  }
795
852
 
796
- .theia-tool-denied {
853
+ .theia-toolCall-denied {
797
854
  color: var(--theia-errorForeground);
798
855
  }
799
856
 
857
+ .theia-toolCall-response-result {
858
+ font-weight: normal;
859
+ }
860
+
800
861
  .theia-toolCall .fa,
801
862
  .theia-toolCall details summary::marker,
802
863
  .theia-thinking .fa,
@@ -900,6 +961,7 @@ details[open].collapsible-arguments .collapsible-arguments-summary {
900
961
  margin-bottom: 10px;
901
962
  height: calc(100% - 50px);
902
963
  }
964
+
903
965
  .monaco-session-settings-dialog {
904
966
  flex: 1;
905
967
  min-height: 350px;
@@ -909,6 +971,7 @@ details[open].collapsible-arguments .collapsible-arguments-summary {
909
971
  border: 1px solid var(--theia-editorWidget-border);
910
972
  margin-bottom: 10px;
911
973
  }
974
+
912
975
  .session-settings-error {
913
976
  color: var(--theia-errorForeground);
914
977
  min-height: 1em;
@@ -924,3 +987,144 @@ details[open].collapsible-arguments .collapsible-arguments-summary {
924
987
  padding-block-end: 8px;
925
988
  user-select: none;
926
989
  }
990
+
991
+ /* Delegation response styles */
992
+ .theia-delegation-container {
993
+ border: 2px solid var(--theia-sideBarSectionHeader-border);
994
+ border-radius: 8px;
995
+ margin: 8px 0;
996
+ background-color: var(--theia-sideBar-background);
997
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
998
+ }
999
+
1000
+ .delegation-response-details {
1001
+ width: 100%;
1002
+ }
1003
+
1004
+ .delegation-summary {
1005
+ cursor: pointer;
1006
+ padding: 12px 16px;
1007
+ background-color: var(--theia-editorGroupHeader-tabsBackground);
1008
+ border-radius: 6px 6px 0 0;
1009
+ border-bottom: 1px solid var(--theia-sideBarSectionHeader-border);
1010
+ list-style: none;
1011
+ position: relative;
1012
+ }
1013
+
1014
+ .delegation-summary:hover {
1015
+ background-color: var(--theia-toolbar-hoverBackground);
1016
+ }
1017
+
1018
+ .delegation-summary::before {
1019
+ content: "\25BC";
1020
+ /* Down arrow */
1021
+ position: absolute;
1022
+ right: 8px;
1023
+ top: 50%;
1024
+ transform: translateY(-50%);
1025
+ transition: transform 0.2s ease;
1026
+ color: var(--theia-descriptionForeground);
1027
+ font-size: 12px;
1028
+ }
1029
+
1030
+ .delegation-response-details:not([open]) .delegation-summary::before {
1031
+ transform: translateY(-50%) rotate(-90deg);
1032
+ /* Right arrow when closed */
1033
+ }
1034
+
1035
+ .delegation-response-details:not([open]) .delegation-summary {
1036
+ border-bottom: none;
1037
+ border-radius: 6px;
1038
+ }
1039
+
1040
+ .delegation-summary::-webkit-details-marker {
1041
+ display: none;
1042
+ }
1043
+
1044
+ .delegation-summary::marker {
1045
+ content: "";
1046
+ }
1047
+
1048
+ .delegation-header {
1049
+ display: flex;
1050
+ align-items: center;
1051
+ width: 100%;
1052
+ gap: 16px;
1053
+ }
1054
+
1055
+ .delegation-agent {
1056
+ flex: 1;
1057
+ /* Takes up available space */
1058
+ font-size: 14px;
1059
+ color: var(--theia-foreground);
1060
+ }
1061
+
1062
+ .delegation-status {
1063
+ display: flex;
1064
+ align-items: center;
1065
+ gap: 6px;
1066
+ font-size: 13px;
1067
+ /* Leave space for the arrow */
1068
+ margin-right: 24px;
1069
+ }
1070
+
1071
+ .delegation-status-icon {
1072
+ font-size: 16px;
1073
+ }
1074
+
1075
+ .delegation-status-icon.codicon-loading {
1076
+ animation: spin 2s linear infinite;
1077
+ color: var(--theia-progressBar-background);
1078
+ }
1079
+
1080
+ .delegation-status-icon.codicon-check {
1081
+ color: var(--theia-charts-green);
1082
+ }
1083
+
1084
+ .delegation-status-icon.codicon-error {
1085
+ color: var(--theia-errorForeground);
1086
+ }
1087
+
1088
+ .delegation-status-icon.codicon-cancel {
1089
+ color: var(--theia-charts-orange);
1090
+ }
1091
+
1092
+ .delegation-status-text {
1093
+ color: var(--theia-descriptionForeground);
1094
+ font-weight: normal;
1095
+ }
1096
+
1097
+ .delegation-content {
1098
+ padding: 16px;
1099
+ }
1100
+
1101
+ .delegation-prompt-section {
1102
+ margin-bottom: 16px;
1103
+ padding-bottom: 12px;
1104
+ border-bottom: 1px solid var(--theia-sideBarSectionHeader-border);
1105
+ }
1106
+
1107
+ .delegation-prompt {
1108
+ margin-top: 6px;
1109
+ padding: 8px 12px;
1110
+ background-color: var(--theia-editor-background);
1111
+ border-radius: 4px;
1112
+ border: 1px solid var(--theia-dropdown-border);
1113
+ font-style: italic;
1114
+ color: var(--theia-descriptionForeground);
1115
+ }
1116
+
1117
+ .delegation-response-section {
1118
+ margin-top: 16px;
1119
+ }
1120
+
1121
+ .delegation-response-section > strong {
1122
+ display: block;
1123
+ margin-bottom: 8px;
1124
+ color: var(--theia-foreground);
1125
+ }
1126
+
1127
+ .delegation-response-placeholder {
1128
+ margin-top: 8px;
1129
+ min-height: 40px;
1130
+ }