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

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 (62) hide show
  1. package/lib/browser/ai-chat-ui-contribution.d.ts +29 -1
  2. package/lib/browser/ai-chat-ui-contribution.d.ts.map +1 -1
  3. package/lib/browser/ai-chat-ui-contribution.js +156 -0
  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 +7 -6
  9. package/lib/browser/chat-input-widget.d.ts.map +1 -1
  10. package/lib/browser/chat-input-widget.js +81 -22
  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.js +9 -9
  29. package/lib/browser/chat-response-renderer/toolcall-part-renderer.js.map +1 -1
  30. package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts +3 -1
  31. package/lib/browser/chat-tree-view/chat-view-tree-widget.d.ts.map +1 -1
  32. package/lib/browser/chat-tree-view/chat-view-tree-widget.js +50 -8
  33. package/lib/browser/chat-tree-view/chat-view-tree-widget.js.map +1 -1
  34. package/lib/browser/chat-tree-view/sub-chat-widget.d.ts +22 -0
  35. package/lib/browser/chat-tree-view/sub-chat-widget.d.ts.map +1 -0
  36. package/lib/browser/chat-tree-view/sub-chat-widget.js +92 -0
  37. package/lib/browser/chat-tree-view/sub-chat-widget.js.map +1 -0
  38. package/lib/browser/chat-view-commands.d.ts +1 -0
  39. package/lib/browser/chat-view-commands.d.ts.map +1 -1
  40. package/lib/browser/chat-view-commands.js +5 -0
  41. package/lib/browser/chat-view-commands.js.map +1 -1
  42. package/lib/browser/chat-view-contribution.js +2 -1
  43. package/lib/browser/chat-view-contribution.js.map +1 -1
  44. package/lib/browser/chat-view-widget.d.ts +1 -1
  45. package/lib/browser/chat-view-widget.d.ts.map +1 -1
  46. package/lib/browser/chat-view-widget.js +1 -4
  47. package/lib/browser/chat-view-widget.js.map +1 -1
  48. package/package.json +10 -10
  49. package/src/browser/ai-chat-ui-contribution.ts +164 -3
  50. package/src/browser/ai-chat-ui-frontend-module.ts +11 -0
  51. package/src/browser/chat-input-widget.tsx +111 -35
  52. package/src/browser/chat-node-toolbar-action-contribution.ts +14 -0
  53. package/src/browser/chat-response-renderer/delegation-response-renderer.tsx +177 -0
  54. package/src/browser/chat-response-renderer/index.ts +1 -0
  55. package/src/browser/chat-response-renderer/tool-confirmation.tsx +30 -30
  56. package/src/browser/chat-response-renderer/toolcall-part-renderer.tsx +10 -10
  57. package/src/browser/chat-tree-view/chat-view-tree-widget.tsx +58 -8
  58. package/src/browser/chat-tree-view/sub-chat-widget.tsx +101 -0
  59. package/src/browser/chat-view-commands.ts +6 -0
  60. package/src/browser/chat-view-contribution.ts +1 -1
  61. package/src/browser/chat-view-widget.tsx +2 -5
  62. package/src/browser/style/index.css +178 -3
@@ -142,6 +142,8 @@ export class ChatViewTreeWidget extends TreeWidget {
142
142
 
143
143
  onScrollLockChange?: (temporaryLocked: boolean) => void;
144
144
 
145
+ protected lastScrollTop = 0;
146
+
145
147
  set shouldScrollToEnd(shouldScrollToEnd: boolean) {
146
148
  this._shouldScrollToEnd = shouldScrollToEnd;
147
149
  this.shouldScrollToRow = this._shouldScrollToEnd;
@@ -189,6 +191,9 @@ export class ChatViewTreeWidget extends TreeWidget {
189
191
  this.handleScrollEvent(scrollEvent);
190
192
  })
191
193
  ]);
194
+
195
+ // Initialize lastScrollTop with current scroll position
196
+ this.lastScrollTop = this.getCurrentScrollTop(undefined);
192
197
  }
193
198
 
194
199
  public setEnabled(enabled: boolean): void {
@@ -196,20 +201,39 @@ export class ChatViewTreeWidget extends TreeWidget {
196
201
  this.update();
197
202
  }
198
203
 
199
- protected handleScrollEvent(_scrollEvent: unknown): void {
200
- // Check if we're at the bottom of the view
204
+ protected handleScrollEvent(scrollEvent: unknown): void {
205
+ // Get current scroll position
206
+ const currentScrollTop = this.getCurrentScrollTop(scrollEvent);
201
207
  const isAtBottom = this.isScrolledToBottom();
202
208
 
203
- // Only handle temporary scroll lock if auto-scroll is currently enabled
209
+ // Determine scroll direction
210
+ const isScrollingUp = currentScrollTop < this.lastScrollTop;
211
+ const isScrollingDown = currentScrollTop > this.lastScrollTop;
212
+
213
+ // Handle scroll lock logic based on direction and position
214
+ // The key insight is that we only enable temporary lock when scrolling UP,
215
+ // and only disable it when scrolling DOWN to the bottom. This prevents
216
+ // the jitter when users try to scroll up by just a few pixels from the bottom.
204
217
  if (this.shouldScrollToEnd) {
205
- if (!isAtBottom) {
206
- // User scrolled away from bottom, enable temporary lock
218
+ // Auto-scroll is enabled, check if we need to enable temporary lock
219
+ if (isScrollingUp) {
220
+ // User is scrolling up and not at bottom - enable temporary lock
207
221
  this.setTemporaryScrollLock(true);
208
222
  }
209
- } else if (isAtBottom) {
210
- // User scrolled back to bottom, disable temporary lock
211
- this.setTemporaryScrollLock(false);
223
+ // Note: We don't disable temporary lock when scrolling down while shouldScrollToEnd is true
224
+ // because that would cause jitter. The lock will be disabled when user reaches bottom.
225
+ } else {
226
+ // Temporary lock is active, check if we should disable it
227
+ if (isScrollingDown && isAtBottom) {
228
+ // User scrolled back to bottom - disable temporary lock
229
+ this.setTemporaryScrollLock(false);
230
+ }
231
+ // Note: We don't change the lock state when scrolling up while locked,
232
+ // as the user is intentionally scrolling away from auto-scroll behavior.
212
233
  }
234
+
235
+ // Update last scroll position for next comparison
236
+ this.lastScrollTop = currentScrollTop;
213
237
  }
214
238
 
215
239
  protected setTemporaryScrollLock(enabled: boolean): void {
@@ -217,6 +241,32 @@ export class ChatViewTreeWidget extends TreeWidget {
217
241
  this.onScrollLockChange?.(enabled);
218
242
  }
219
243
 
244
+ protected getCurrentScrollTop(scrollEvent: unknown): number {
245
+ // For virtualized trees, try to get scroll position from the virtualized view
246
+ if (this.props.virtualized !== false && this.view) {
247
+ const scrollState = this.getVirtualizedScrollState();
248
+ if (scrollState !== undefined) {
249
+ return scrollState.scrollTop;
250
+ }
251
+ }
252
+
253
+ // Try to extract scroll position from the scroll event
254
+ if (scrollEvent && typeof scrollEvent === 'object' && 'scrollTop' in scrollEvent) {
255
+ const scrollEventWithScrollTop = scrollEvent as { scrollTop: unknown };
256
+ const scrollTop = scrollEventWithScrollTop.scrollTop;
257
+ if (typeof scrollTop === 'number' && !isNaN(scrollTop)) {
258
+ return scrollTop;
259
+ }
260
+ }
261
+
262
+ // Last resort: use DOM scroll position
263
+ if (this.node && typeof this.node.scrollTop === 'number') {
264
+ return this.node.scrollTop;
265
+ }
266
+
267
+ return 0;
268
+ }
269
+
220
270
  protected override renderTree(model: TreeModel): React.ReactNode {
221
271
  if (!this.isEnabled) {
222
272
  return this.renderDisabledMessage();
@@ -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'),
@@ -117,7 +117,7 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
117
117
 
118
118
  protected getCopyText(arg: RequestNode | ResponseNode): string {
119
119
  if (isRequestNode(arg)) {
120
- return arg.request.request.text;
120
+ return arg.request.request.text ?? '';
121
121
  } else if (isResponseNode(arg)) {
122
122
  return arg.response.response.asDisplayString();
123
123
  }
@@ -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);
@@ -200,22 +200,28 @@ div:last-child > .theia-ChatNode {
200
200
  margin: 0;
201
201
  display: flex;
202
202
  flex-wrap: wrap;
203
+ align-items: center;
203
204
  gap: 6px;
204
205
  }
205
206
 
206
207
  .theia-ChatInput-ChatContext-Element {
207
208
  display: flex;
208
- align-items: center;
209
+ flex-direction: column;
209
210
  border-radius: calc(var(--theia-ui-padding) * 2 / 3);
210
211
  border: var(--theia-border-width) solid var(--theia-dropdown-border);
211
212
  padding: 2px 4px 2px 6px;
212
- height: 18px;
213
213
  line-height: 16px;
214
214
  min-width: 0;
215
215
  user-select: none;
216
216
  cursor: pointer;
217
217
  }
218
218
 
219
+ .theia-ChatInput-ChatContext-Row {
220
+ display: flex;
221
+ align-items: center;
222
+ width: 100%;
223
+ }
224
+
219
225
  .theia-ChatInput-ChatContext-labelParts {
220
226
  flex: 1;
221
227
  min-width: 0;
@@ -497,6 +503,32 @@ div:last-child > .theia-ChatNode {
497
503
  padding-left: 8px !important;
498
504
  }
499
505
 
506
+ .theia-ChatInput-ImagePreview-Item {
507
+ position: relative;
508
+ border: var(--theia-border-width) solid var(--theia-dropdown-border);
509
+ border-radius: 4px;
510
+ overflow: hidden;
511
+ height: 100px;
512
+ width: 120px;
513
+ }
514
+
515
+ .theia-ChatInput-ChatContext-ImageRow {
516
+ margin-top: 4px;
517
+ width: 100%;
518
+ display: flex;
519
+ justify-content: center;
520
+ }
521
+
522
+ .theia-ChatInput-ImageContext-Element {
523
+ min-width: 150px;
524
+ }
525
+
526
+ .theia-ChatInput-ImagePreview-Item img {
527
+ width: 100%;
528
+ height: 100%;
529
+ object-fit: contain;
530
+ }
531
+
500
532
  .theia-ChatInputOptions {
501
533
  width: 100%;
502
534
  height: 25px;
@@ -706,7 +738,7 @@ div:last-child > .theia-ChatNode {
706
738
  background: var(--theia-menu-background);
707
739
  border: 1px solid var(--theia-menu-border);
708
740
  border-radius: 4px;
709
- box-shadow: 0 2px 8px rgba(0,0,0,0.15);
741
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
710
742
  margin: 0;
711
743
  padding: 0;
712
744
  list-style: none;
@@ -900,6 +932,7 @@ details[open].collapsible-arguments .collapsible-arguments-summary {
900
932
  margin-bottom: 10px;
901
933
  height: calc(100% - 50px);
902
934
  }
935
+
903
936
  .monaco-session-settings-dialog {
904
937
  flex: 1;
905
938
  min-height: 350px;
@@ -909,6 +942,7 @@ details[open].collapsible-arguments .collapsible-arguments-summary {
909
942
  border: 1px solid var(--theia-editorWidget-border);
910
943
  margin-bottom: 10px;
911
944
  }
945
+
912
946
  .session-settings-error {
913
947
  color: var(--theia-errorForeground);
914
948
  min-height: 1em;
@@ -924,3 +958,144 @@ details[open].collapsible-arguments .collapsible-arguments-summary {
924
958
  padding-block-end: 8px;
925
959
  user-select: none;
926
960
  }
961
+
962
+ /* Delegation response styles */
963
+ .theia-delegation-container {
964
+ border: 2px solid var(--theia-sideBarSectionHeader-border);
965
+ border-radius: 8px;
966
+ margin: 8px 0;
967
+ background-color: var(--theia-sideBar-background);
968
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
969
+ }
970
+
971
+ .delegation-response-details {
972
+ width: 100%;
973
+ }
974
+
975
+ .delegation-summary {
976
+ cursor: pointer;
977
+ padding: 12px 16px;
978
+ background-color: var(--theia-editorGroupHeader-tabsBackground);
979
+ border-radius: 6px 6px 0 0;
980
+ border-bottom: 1px solid var(--theia-sideBarSectionHeader-border);
981
+ list-style: none;
982
+ position: relative;
983
+ }
984
+
985
+ .delegation-summary:hover {
986
+ background-color: var(--theia-toolbar-hoverBackground);
987
+ }
988
+
989
+ .delegation-summary::before {
990
+ content: '\25BC';
991
+ /* Down arrow */
992
+ position: absolute;
993
+ right: 8px;
994
+ top: 50%;
995
+ transform: translateY(-50%);
996
+ transition: transform 0.2s ease;
997
+ color: var(--theia-descriptionForeground);
998
+ font-size: 12px;
999
+ }
1000
+
1001
+ .delegation-response-details:not([open]) .delegation-summary::before {
1002
+ transform: translateY(-50%) rotate(-90deg);
1003
+ /* Right arrow when closed */
1004
+ }
1005
+
1006
+ .delegation-response-details:not([open]) .delegation-summary {
1007
+ border-bottom: none;
1008
+ border-radius: 6px;
1009
+ }
1010
+
1011
+ .delegation-summary::-webkit-details-marker {
1012
+ display: none;
1013
+ }
1014
+
1015
+ .delegation-summary::marker {
1016
+ content: '';
1017
+ }
1018
+
1019
+ .delegation-header {
1020
+ display: flex;
1021
+ align-items: center;
1022
+ width: 100%;
1023
+ gap: 16px;
1024
+ }
1025
+
1026
+ .delegation-agent {
1027
+ flex: 1;
1028
+ /* Takes up available space */
1029
+ font-size: 14px;
1030
+ color: var(--theia-foreground);
1031
+ }
1032
+
1033
+ .delegation-status {
1034
+ display: flex;
1035
+ align-items: center;
1036
+ gap: 6px;
1037
+ font-size: 13px;
1038
+ /* Leave space for the arrow */
1039
+ margin-right: 24px;
1040
+ }
1041
+
1042
+ .delegation-status-icon {
1043
+ font-size: 16px;
1044
+ }
1045
+
1046
+ .delegation-status-icon.codicon-loading {
1047
+ animation: spin 2s linear infinite;
1048
+ color: var(--theia-progressBar-background);
1049
+ }
1050
+
1051
+ .delegation-status-icon.codicon-check {
1052
+ color: var(--theia-charts-green);
1053
+ }
1054
+
1055
+ .delegation-status-icon.codicon-error {
1056
+ color: var(--theia-errorForeground);
1057
+ }
1058
+
1059
+ .delegation-status-icon.codicon-cancel {
1060
+ color: var(--theia-charts-orange);
1061
+ }
1062
+
1063
+ .delegation-status-text {
1064
+ color: var(--theia-descriptionForeground);
1065
+ font-weight: normal;
1066
+ }
1067
+
1068
+ .delegation-content {
1069
+ padding: 16px;
1070
+ }
1071
+
1072
+ .delegation-prompt-section {
1073
+ margin-bottom: 16px;
1074
+ padding-bottom: 12px;
1075
+ border-bottom: 1px solid var(--theia-sideBarSectionHeader-border);
1076
+ }
1077
+
1078
+ .delegation-prompt {
1079
+ margin-top: 6px;
1080
+ padding: 8px 12px;
1081
+ background-color: var(--theia-editor-background);
1082
+ border-radius: 4px;
1083
+ border: 1px solid var(--theia-dropdown-border);
1084
+ font-style: italic;
1085
+ color: var(--theia-descriptionForeground);
1086
+ }
1087
+
1088
+ .delegation-response-section {
1089
+ margin-top: 16px;
1090
+ }
1091
+
1092
+ .delegation-response-section>strong {
1093
+ display: block;
1094
+ margin-bottom: 8px;
1095
+ color: var(--theia-foreground);
1096
+ }
1097
+
1098
+ .delegation-response-placeholder {
1099
+ margin-top: 8px;
1100
+ min-height: 40px;
1101
+ }