@theia/ai-chat-ui 1.66.0-next.80 → 1.66.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.
- package/lib/browser/ai-chat-ui-frontend-module.d.ts.map +1 -1
- package/lib/browser/ai-chat-ui-frontend-module.js +4 -0
- package/lib/browser/ai-chat-ui-frontend-module.js.map +1 -1
- package/lib/browser/chat-input-mode-contribution.d.ts +12 -0
- package/lib/browser/chat-input-mode-contribution.d.ts.map +1 -0
- package/lib/browser/chat-input-mode-contribution.js +77 -0
- package/lib/browser/chat-input-mode-contribution.js.map +1 -0
- package/lib/browser/chat-input-widget.d.ts +11 -3
- package/lib/browser/chat-input-widget.d.ts.map +1 -1
- package/lib/browser/chat-input-widget.js +92 -25
- package/lib/browser/chat-input-widget.js.map +1 -1
- package/lib/browser/chat-view-widget.d.ts +1 -1
- package/lib/browser/chat-view-widget.d.ts.map +1 -1
- package/lib/browser/chat-view-widget.js +6 -2
- package/lib/browser/chat-view-widget.js.map +1 -1
- package/package.json +11 -11
- package/src/browser/ai-chat-ui-frontend-module.ts +5 -0
- package/src/browser/chat-input-mode-contribution.ts +75 -0
- package/src/browser/chat-input-widget.tsx +174 -50
- package/src/browser/chat-view-widget.tsx +6 -2
- package/src/browser/style/index.css +34 -0
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import {
|
|
17
17
|
ChangeSet, ChangeSetElement, ChatAgent, ChatChangeEvent, ChatHierarchyBranch,
|
|
18
18
|
ChatModel, ChatRequestModel, ChatService, ChatSuggestion, EditableChatRequestModel,
|
|
19
|
-
ChatRequestParser
|
|
19
|
+
ChatRequestParser, ChatMode
|
|
20
20
|
} from '@theia/ai-chat';
|
|
21
21
|
import { ChangeSetDecoratorService } from '@theia/ai-chat/lib/browser/change-set-decorator-service';
|
|
22
22
|
import { ImageContextVariable } from '@theia/ai-chat/lib/common/image-context-variable';
|
|
@@ -40,7 +40,7 @@ import { IModelDeltaDecoration } from '@theia/monaco-editor-core/esm/vs/editor/c
|
|
|
40
40
|
import { EditorOption } from '@theia/monaco-editor-core/esm/vs/editor/common/config/editorOptions';
|
|
41
41
|
import { ChatInputHistoryService, ChatInputNavigationState } from './chat-input-history';
|
|
42
42
|
|
|
43
|
-
type Query = (query: string) => Promise<void>;
|
|
43
|
+
type Query = (query: string, mode?: string) => Promise<void>;
|
|
44
44
|
type Unpin = () => void;
|
|
45
45
|
type Cancel = (requestModel: ChatRequestModel) => void;
|
|
46
46
|
type DeleteChangeSet = (requestModel: ChatRequestModel) => void;
|
|
@@ -106,11 +106,11 @@ export class AIChatInputWidget extends ReactWidget {
|
|
|
106
106
|
@inject(ChatRequestParser)
|
|
107
107
|
protected readonly chatRequestParser: ChatRequestParser;
|
|
108
108
|
|
|
109
|
-
protected navigationState: ChatInputNavigationState;
|
|
110
|
-
|
|
111
109
|
@inject(ContextKeyService)
|
|
112
110
|
protected readonly contextKeyService: ContextKeyService;
|
|
113
111
|
|
|
112
|
+
protected navigationState: ChatInputNavigationState;
|
|
113
|
+
|
|
114
114
|
protected editorRef: SimpleMonacoEditor | undefined = undefined;
|
|
115
115
|
protected readonly editorReady = new Deferred<void>();
|
|
116
116
|
|
|
@@ -136,15 +136,41 @@ export class AIChatInputWidget extends ReactWidget {
|
|
|
136
136
|
return this.navigationState.getNextPrompt();
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
cycleMode(): void {
|
|
140
|
+
if (!this.receivingAgent || !this.receivingAgent.modes || this.receivingAgent.modes.length <= 1) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const currentIndex = this.receivingAgent.modes.findIndex(mode => mode.id === this.receivingAgent!.currentModeId);
|
|
144
|
+
const nextIndex = currentIndex === -1 ? 1 : (currentIndex + 1) % this.receivingAgent.modes.length;
|
|
145
|
+
this.receivingAgent = {
|
|
146
|
+
...this.receivingAgent,
|
|
147
|
+
currentModeId: this.receivingAgent.modes[nextIndex].id
|
|
148
|
+
};
|
|
149
|
+
this.update();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
protected handleModeChange = (mode: string): void => {
|
|
153
|
+
if (this.receivingAgent) {
|
|
154
|
+
this.receivingAgent = { ...this.receivingAgent, currentModeId: mode };
|
|
155
|
+
this.update();
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
139
159
|
protected chatInputFocusKey: ContextKey<boolean>;
|
|
140
160
|
protected chatInputFirstLineKey: ContextKey<boolean>;
|
|
141
161
|
protected chatInputLastLineKey: ContextKey<boolean>;
|
|
142
162
|
protected chatInputReceivingAgentKey: ContextKey<string>;
|
|
163
|
+
protected chatInputHasModesKey: ContextKey<boolean>;
|
|
143
164
|
|
|
144
165
|
protected isEnabled = false;
|
|
145
166
|
protected heightInLines = 12;
|
|
146
167
|
|
|
147
168
|
protected updateReceivingAgentTimeout: number | undefined;
|
|
169
|
+
protected receivingAgent: {
|
|
170
|
+
agentId: string;
|
|
171
|
+
modes: ChatMode[];
|
|
172
|
+
currentModeId?: string;
|
|
173
|
+
} | undefined;
|
|
148
174
|
|
|
149
175
|
protected _branch?: ChatHierarchyBranch;
|
|
150
176
|
set branch(branch: ChatHierarchyBranch | undefined) {
|
|
@@ -156,12 +182,12 @@ export class AIChatInputWidget extends ReactWidget {
|
|
|
156
182
|
|
|
157
183
|
protected _onQuery: Query;
|
|
158
184
|
set onQuery(query: Query) {
|
|
159
|
-
this._onQuery = (prompt: string) => {
|
|
185
|
+
this._onQuery = (prompt: string, mode?: string) => {
|
|
160
186
|
if (this.configuration?.enablePromptHistory !== false && prompt.trim()) {
|
|
161
187
|
this.historyService.addToHistory(prompt);
|
|
162
188
|
this.navigationState.stopNavigation();
|
|
163
189
|
}
|
|
164
|
-
return query(prompt);
|
|
190
|
+
return query(prompt, mode);
|
|
165
191
|
};
|
|
166
192
|
}
|
|
167
193
|
protected _onUnpin: Unpin;
|
|
@@ -238,6 +264,7 @@ export class AIChatInputWidget extends ReactWidget {
|
|
|
238
264
|
this.chatInputFirstLineKey = this.contextKeyService.createKey<boolean>('chatInputFirstLine', false);
|
|
239
265
|
this.chatInputLastLineKey = this.contextKeyService.createKey<boolean>('chatInputLastLine', false);
|
|
240
266
|
this.chatInputReceivingAgentKey = this.contextKeyService.createKey<string>('chatInputReceivingAgent', '');
|
|
267
|
+
this.chatInputHasModesKey = this.contextKeyService.createKey<boolean>('chatInputHasModes', false);
|
|
241
268
|
}
|
|
242
269
|
|
|
243
270
|
updateCursorPositionKeys(): void {
|
|
@@ -288,7 +315,12 @@ export class AIChatInputWidget extends ReactWidget {
|
|
|
288
315
|
|
|
289
316
|
protected async updateReceivingAgent(): Promise<void> {
|
|
290
317
|
if (!this.editorRef || !this._chatModel) {
|
|
291
|
-
this.
|
|
318
|
+
if (this.receivingAgent !== undefined) {
|
|
319
|
+
this.chatInputReceivingAgentKey.set('');
|
|
320
|
+
this.chatInputHasModesKey.set(false);
|
|
321
|
+
this.receivingAgent = undefined;
|
|
322
|
+
this.update();
|
|
323
|
+
}
|
|
292
324
|
return;
|
|
293
325
|
}
|
|
294
326
|
|
|
@@ -300,13 +332,39 @@ export class AIChatInputWidget extends ReactWidget {
|
|
|
300
332
|
const session = this.chatService.getSessions().find(s => s.model.id === this._chatModel.id);
|
|
301
333
|
if (session) {
|
|
302
334
|
const agent = this.chatService.getAgent(parsedRequest, session);
|
|
303
|
-
|
|
304
|
-
|
|
335
|
+
const agentId = agent?.id ?? '';
|
|
336
|
+
const previousAgentId = this.receivingAgent?.agentId;
|
|
337
|
+
|
|
338
|
+
this.chatInputReceivingAgentKey.set(agentId);
|
|
339
|
+
|
|
340
|
+
// Only update and re-render when the agent changes
|
|
341
|
+
if (agent && agentId !== previousAgentId) {
|
|
342
|
+
const modes = agent.modes ?? [];
|
|
343
|
+
this.receivingAgent = {
|
|
344
|
+
agentId: agentId,
|
|
345
|
+
modes
|
|
346
|
+
};
|
|
347
|
+
this.chatInputHasModesKey.set(modes.length > 1);
|
|
348
|
+
this.update();
|
|
349
|
+
} else if (!agent && this.receivingAgent !== undefined) {
|
|
350
|
+
this.receivingAgent = undefined;
|
|
351
|
+
this.chatInputHasModesKey.set(false);
|
|
352
|
+
this.update();
|
|
353
|
+
}
|
|
354
|
+
} else if (this.receivingAgent !== undefined) {
|
|
305
355
|
this.chatInputReceivingAgentKey.set('');
|
|
356
|
+
this.chatInputHasModesKey.set(false);
|
|
357
|
+
this.receivingAgent = undefined;
|
|
358
|
+
this.update();
|
|
306
359
|
}
|
|
307
360
|
} catch (error) {
|
|
308
361
|
console.warn('Failed to determine receiving agent:', error);
|
|
309
|
-
this.
|
|
362
|
+
if (this.receivingAgent !== undefined) {
|
|
363
|
+
this.chatInputReceivingAgentKey.set('');
|
|
364
|
+
this.chatInputHasModesKey.set(false);
|
|
365
|
+
this.receivingAgent = undefined;
|
|
366
|
+
this.update();
|
|
367
|
+
}
|
|
310
368
|
}
|
|
311
369
|
}
|
|
312
370
|
|
|
@@ -433,6 +491,11 @@ export class AIChatInputWidget extends ReactWidget {
|
|
|
433
491
|
}
|
|
434
492
|
}}
|
|
435
493
|
onResize={() => this.onDidResizeEmitter.fire()}
|
|
494
|
+
modeSelectorProps={{
|
|
495
|
+
receivingAgentModes: this.receivingAgent?.modes,
|
|
496
|
+
currentMode: this.receivingAgent?.currentModeId,
|
|
497
|
+
onModeChange: this.handleModeChange,
|
|
498
|
+
}}
|
|
436
499
|
/>
|
|
437
500
|
);
|
|
438
501
|
}
|
|
@@ -543,7 +606,7 @@ export class AIChatInputWidget extends ReactWidget {
|
|
|
543
606
|
interface ChatInputProperties {
|
|
544
607
|
branch?: ChatHierarchyBranch;
|
|
545
608
|
onCancel: (requestModel: ChatRequestModel) => void;
|
|
546
|
-
onQuery: (query: string) => void;
|
|
609
|
+
onQuery: (query: string, mode?: string) => void;
|
|
547
610
|
onUnpin: () => void;
|
|
548
611
|
onDragOver: (event: React.DragEvent) => void;
|
|
549
612
|
onDrop: (event: React.DragEvent) => void;
|
|
@@ -580,6 +643,11 @@ interface ChatInputProperties {
|
|
|
580
643
|
heightInLines?: number;
|
|
581
644
|
onResponseChanged: () => void;
|
|
582
645
|
onResize: () => void;
|
|
646
|
+
modeSelectorProps: {
|
|
647
|
+
receivingAgentModes?: ChatMode[];
|
|
648
|
+
currentMode?: string;
|
|
649
|
+
onModeChange: (mode: string) => void;
|
|
650
|
+
}
|
|
583
651
|
}
|
|
584
652
|
|
|
585
653
|
// Utility to check if we have task context in the chat model
|
|
@@ -844,12 +912,12 @@ const ChatInput: React.FunctionComponent<ChatInputProperties> = (props: ChatInpu
|
|
|
844
912
|
if (!effectiveValue || effectiveValue.trim().length === 0) {
|
|
845
913
|
return;
|
|
846
914
|
}
|
|
847
|
-
props.onQuery(effectiveValue);
|
|
915
|
+
props.onQuery(effectiveValue, props.modeSelectorProps.currentMode);
|
|
848
916
|
setValue('');
|
|
849
917
|
if (editorRef.current && !editorRef.current.document.textEditorModel.isDisposed()) {
|
|
850
918
|
editorRef.current.document.textEditorModel.setValue('');
|
|
851
919
|
}
|
|
852
|
-
}, [props.context, props.onQuery, setValue, shouldUseTaskPlaceholder, taskPlaceholder]);
|
|
920
|
+
}, [props.context, props.onQuery, props.modeSelectorProps.currentMode, setValue, shouldUseTaskPlaceholder, taskPlaceholder]);
|
|
853
921
|
|
|
854
922
|
const onKeyDown = React.useCallback((event: React.KeyboardEvent) => {
|
|
855
923
|
if (!props.isEnabled) {
|
|
@@ -978,6 +1046,9 @@ const ChatInput: React.FunctionComponent<ChatInputProperties> = (props: ChatInpu
|
|
|
978
1046
|
|
|
979
1047
|
const contextUI = buildContextUI(props.context, props.labelProvider, props.onDeleteContextElement, props.onOpenContextElement);
|
|
980
1048
|
|
|
1049
|
+
// Show mode selector if agent has multiple modes
|
|
1050
|
+
const showModeSelector = (props.modeSelectorProps.receivingAgentModes?.length ?? 0) > 1;
|
|
1051
|
+
|
|
981
1052
|
return (
|
|
982
1053
|
<div className='theia-ChatInput' data-ai-disabled={!props.isEnabled} onDragOver={props.onDragOver} onDrop={props.onDrop} ref={containerRef}>
|
|
983
1054
|
{props.showSuggestions !== false && <ChatInputAgentSuggestions suggestions={props.suggestions} opener={props.openerService} />}
|
|
@@ -991,12 +1062,101 @@ const ChatInput: React.FunctionComponent<ChatInputProperties> = (props: ChatInpu
|
|
|
991
1062
|
{props.context && props.context.length > 0 &&
|
|
992
1063
|
<ChatContext context={contextUI.context} />
|
|
993
1064
|
}
|
|
994
|
-
<ChatInputOptions
|
|
1065
|
+
<ChatInputOptions
|
|
1066
|
+
leftOptions={leftOptions}
|
|
1067
|
+
rightOptions={rightOptions}
|
|
1068
|
+
isEnabled={props.isEnabled}
|
|
1069
|
+
modeSelectorProps={{
|
|
1070
|
+
show: showModeSelector,
|
|
1071
|
+
modes: props.modeSelectorProps.receivingAgentModes,
|
|
1072
|
+
currentMode: props.modeSelectorProps.currentMode,
|
|
1073
|
+
onModeChange: props.modeSelectorProps.onModeChange,
|
|
1074
|
+
}}
|
|
1075
|
+
/>
|
|
995
1076
|
</div>
|
|
996
1077
|
</div>
|
|
997
1078
|
);
|
|
998
1079
|
};
|
|
999
1080
|
|
|
1081
|
+
interface ChatInputOptionsProps {
|
|
1082
|
+
leftOptions: Option[];
|
|
1083
|
+
rightOptions: Option[];
|
|
1084
|
+
isEnabled?: boolean;
|
|
1085
|
+
modeSelectorProps: {
|
|
1086
|
+
show: boolean;
|
|
1087
|
+
modes?: ChatMode[];
|
|
1088
|
+
currentMode?: string;
|
|
1089
|
+
onModeChange: (mode: string) => void;
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
const ChatInputOptions: React.FunctionComponent<ChatInputOptionsProps> = ({
|
|
1094
|
+
leftOptions,
|
|
1095
|
+
rightOptions,
|
|
1096
|
+
isEnabled,
|
|
1097
|
+
modeSelectorProps
|
|
1098
|
+
}) => (
|
|
1099
|
+
<div className="theia-ChatInputOptions">
|
|
1100
|
+
<div className="theia-ChatInputOptions-left">
|
|
1101
|
+
{leftOptions.map((option, index) => (
|
|
1102
|
+
<span
|
|
1103
|
+
key={index}
|
|
1104
|
+
className={`option${option.disabled ? ' disabled' : ''}${option.text?.align === 'right' ? ' reverse' : ''}`}
|
|
1105
|
+
title={option.title}
|
|
1106
|
+
onClick={option.handler}
|
|
1107
|
+
>
|
|
1108
|
+
<span>{option.text?.content}</span>
|
|
1109
|
+
<span className={`codicon ${option.className}`} />
|
|
1110
|
+
</span>
|
|
1111
|
+
))}
|
|
1112
|
+
{modeSelectorProps.show && modeSelectorProps.modes && (
|
|
1113
|
+
<ChatModeSelector
|
|
1114
|
+
modes={modeSelectorProps.modes}
|
|
1115
|
+
currentMode={modeSelectorProps.currentMode}
|
|
1116
|
+
onModeChange={modeSelectorProps.onModeChange}
|
|
1117
|
+
disabled={!isEnabled}
|
|
1118
|
+
/>
|
|
1119
|
+
)}
|
|
1120
|
+
</div>
|
|
1121
|
+
<div className="theia-ChatInputOptions-right">
|
|
1122
|
+
{rightOptions.map((option, index) => (
|
|
1123
|
+
<span
|
|
1124
|
+
key={index}
|
|
1125
|
+
className={`option${option.disabled ? ' disabled' : ''}${option.text?.align === 'right' ? ' reverse' : ''}`}
|
|
1126
|
+
title={option.title}
|
|
1127
|
+
onClick={option.handler}
|
|
1128
|
+
>
|
|
1129
|
+
<span>{option.text?.content}</span>
|
|
1130
|
+
<span className={`codicon ${option.className}`} />
|
|
1131
|
+
</span>
|
|
1132
|
+
))}
|
|
1133
|
+
</div>
|
|
1134
|
+
</div>
|
|
1135
|
+
);
|
|
1136
|
+
|
|
1137
|
+
interface ChatModeSelectorProps {
|
|
1138
|
+
modes: ChatMode[];
|
|
1139
|
+
currentMode?: string;
|
|
1140
|
+
onModeChange: (mode: string) => void;
|
|
1141
|
+
disabled?: boolean;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
const ChatModeSelector: React.FunctionComponent<ChatModeSelectorProps> = React.memo(({ modes, currentMode, onModeChange, disabled }) => (
|
|
1145
|
+
<select
|
|
1146
|
+
className="theia-ChatInput-ModeSelector"
|
|
1147
|
+
value={currentMode ?? modes[0]?.id ?? ''}
|
|
1148
|
+
onChange={e => onModeChange(e.target.value)}
|
|
1149
|
+
disabled={disabled}
|
|
1150
|
+
title={modes.find(m => m.id === (currentMode ?? modes[0]?.id))?.name}
|
|
1151
|
+
>
|
|
1152
|
+
{modes.map(mode => (
|
|
1153
|
+
<option key={mode.id} value={mode.id} title={mode.name}>
|
|
1154
|
+
{mode.name}
|
|
1155
|
+
</option>
|
|
1156
|
+
))}
|
|
1157
|
+
</select>
|
|
1158
|
+
));
|
|
1159
|
+
|
|
1000
1160
|
const noPropagation = (handler: () => void) => (e: React.MouseEvent) => {
|
|
1001
1161
|
handler();
|
|
1002
1162
|
e.stopPropagation();
|
|
@@ -1118,11 +1278,6 @@ const ChangeSetElement: React.FC<ChangeSetUIElement> = element => (
|
|
|
1118
1278
|
</li>
|
|
1119
1279
|
);
|
|
1120
1280
|
|
|
1121
|
-
interface ChatInputOptionsProps {
|
|
1122
|
-
leftOptions: Option[];
|
|
1123
|
-
rightOptions: Option[];
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
1281
|
interface Option {
|
|
1127
1282
|
title: string;
|
|
1128
1283
|
handler: () => void;
|
|
@@ -1134,37 +1289,6 @@ interface Option {
|
|
|
1134
1289
|
};
|
|
1135
1290
|
}
|
|
1136
1291
|
|
|
1137
|
-
const ChatInputOptions: React.FunctionComponent<ChatInputOptionsProps> = ({ leftOptions, rightOptions }) => (
|
|
1138
|
-
<div className="theia-ChatInputOptions">
|
|
1139
|
-
<div className="theia-ChatInputOptions-left">
|
|
1140
|
-
{leftOptions.map((option, index) => (
|
|
1141
|
-
<span
|
|
1142
|
-
key={index}
|
|
1143
|
-
className={`option${option.disabled ? ' disabled' : ''}${option.text?.align === 'right' ? ' reverse' : ''}`}
|
|
1144
|
-
title={option.title}
|
|
1145
|
-
onClick={option.handler}
|
|
1146
|
-
>
|
|
1147
|
-
<span>{option.text?.content}</span>
|
|
1148
|
-
<span className={`codicon ${option.className}`} />
|
|
1149
|
-
</span>
|
|
1150
|
-
))}
|
|
1151
|
-
</div>
|
|
1152
|
-
<div className="theia-ChatInputOptions-right">
|
|
1153
|
-
{rightOptions.map((option, index) => (
|
|
1154
|
-
<span
|
|
1155
|
-
key={index}
|
|
1156
|
-
className={`option${option.disabled ? ' disabled' : ''}${option.text?.align === 'right' ? ' reverse' : ''}`}
|
|
1157
|
-
title={option.title}
|
|
1158
|
-
onClick={option.handler}
|
|
1159
|
-
>
|
|
1160
|
-
<span>{option.text?.content}</span>
|
|
1161
|
-
<span className={`codicon ${option.className}`} />
|
|
1162
|
-
</span>
|
|
1163
|
-
))}
|
|
1164
|
-
</div>
|
|
1165
|
-
</div>
|
|
1166
|
-
);
|
|
1167
|
-
|
|
1168
1292
|
function buildContextUI(
|
|
1169
1293
|
context: readonly AIVariableResolutionRequest[] | undefined,
|
|
1170
1294
|
labelProvider: LabelProvider,
|
|
@@ -180,8 +180,12 @@ export class ChatViewWidget extends BaseWidget implements ExtractableWidget, Sta
|
|
|
180
180
|
return this.onStateChangedEmitter.event;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
protected async onQuery(query?: string | ChatRequest): Promise<void> {
|
|
184
|
-
const chatRequest: ChatRequest = !query
|
|
183
|
+
protected async onQuery(query?: string | ChatRequest, modeId?: string): Promise<void> {
|
|
184
|
+
const chatRequest: ChatRequest = !query
|
|
185
|
+
? { text: '' }
|
|
186
|
+
: typeof query === 'string'
|
|
187
|
+
? { text: query, modeId }
|
|
188
|
+
: { ...query };
|
|
185
189
|
if (chatRequest.text.length === 0) { return; }
|
|
186
190
|
|
|
187
191
|
const requestProgress = await this.chatService.sendRequest(this.chatSession.id, chatRequest);
|
|
@@ -594,6 +594,40 @@ div:last-child > .theia-ChatNode {
|
|
|
594
594
|
flex-direction: row-reverse;
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
+
.theia-ChatInput-ModeSelector {
|
|
598
|
+
margin-left: 4px;
|
|
599
|
+
min-width: 21px;
|
|
600
|
+
height: 21px;
|
|
601
|
+
padding: 2px;
|
|
602
|
+
border: none;
|
|
603
|
+
background: var(--theia-editor-background);
|
|
604
|
+
color: var(--theia-foreground);
|
|
605
|
+
font-size: 13px;
|
|
606
|
+
border-radius: 5px;
|
|
607
|
+
outline: none;
|
|
608
|
+
cursor: pointer;
|
|
609
|
+
max-width: 150px;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
.theia-ChatInput-ModeSelector:hover:not(:disabled) {
|
|
613
|
+
background-color: var(--theia-toolbar-hoverBackground);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.theia-ChatInput-ModeSelector:disabled {
|
|
617
|
+
opacity: var(--theia-mod-disabled-opacity);
|
|
618
|
+
cursor: default;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
.theia-ChatInput-ModeSelector:focus {
|
|
622
|
+
outline: 1px solid var(--theia-focusBorder);
|
|
623
|
+
outline-offset: -1px;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.theia-ChatInput-ModeSelector option {
|
|
627
|
+
background: var(--theia-dropdown-background);
|
|
628
|
+
color: var(--theia-dropdown-foreground);
|
|
629
|
+
}
|
|
630
|
+
|
|
597
631
|
.theia-CodePartRenderer-root {
|
|
598
632
|
display: flex;
|
|
599
633
|
flex-direction: column;
|