@lvce-editor/chat-view 6.65.0 → 6.67.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/dist/chatViewWorkerMain.js +656 -57
- package/package.json +1 -1
|
@@ -1213,7 +1213,9 @@ const End = 255;
|
|
|
1213
1213
|
const Home = 12;
|
|
1214
1214
|
const UpArrow = 14;
|
|
1215
1215
|
const DownArrow = 16;
|
|
1216
|
+
const KeyN = 42;
|
|
1216
1217
|
|
|
1218
|
+
const CtrlCmd = 1 << 11 >>> 0;
|
|
1217
1219
|
const Shift = 1 << 10 >>> 0;
|
|
1218
1220
|
|
|
1219
1221
|
const Chat$2 = 97;
|
|
@@ -1847,6 +1849,7 @@ const Debug = 'Debug';
|
|
|
1847
1849
|
const BackToChats = 'Back to chats';
|
|
1848
1850
|
const BackToChatList = 'Back to chat list';
|
|
1849
1851
|
const Search$1 = 'Search';
|
|
1852
|
+
const ScrollDown$1 = 'Scroll down';
|
|
1850
1853
|
const SearchModels = 'Search models';
|
|
1851
1854
|
const SearchChats = 'Search chats';
|
|
1852
1855
|
const Paste = 'Paste';
|
|
@@ -1867,12 +1870,17 @@ const ComposePlaceholder = 'Type your message. Enter to send.';
|
|
|
1867
1870
|
const AttachImageAsContext = 'Attach Image as Context';
|
|
1868
1871
|
const OpenImageInNewTab = 'Open image in new tab';
|
|
1869
1872
|
const RemoveAttachment = 'Remove attachment';
|
|
1870
|
-
const ImageCouldNotBeLoaded = '
|
|
1873
|
+
const ImageCouldNotBeLoaded = 'Image preview could not be loaded';
|
|
1871
1874
|
const OpenRouterApiKeyPlaceholder = 'Enter OpenRouter API key';
|
|
1872
1875
|
const OpenApiApiKeyPlaceholder = 'Enter OpenAI API key';
|
|
1873
1876
|
const SendMessage = 'Send message';
|
|
1874
1877
|
const StartVoiceDictation = 'Start voice dictation';
|
|
1875
1878
|
const AddContext$1 = 'Add Context';
|
|
1879
|
+
const AddAction = 'Add Action';
|
|
1880
|
+
const OpenInVsCode = 'Open in VSCode';
|
|
1881
|
+
const Commit = 'Commit';
|
|
1882
|
+
const OpenTerminal = 'Open Terminal';
|
|
1883
|
+
const ShowDiff = 'Show Diff';
|
|
1876
1884
|
const CreatePullRequest$2 = 'Create PR';
|
|
1877
1885
|
const Save = 'Save';
|
|
1878
1886
|
const Saving = 'Saving...';
|
|
@@ -1922,6 +1930,9 @@ const settings = () => {
|
|
|
1922
1930
|
const search = () => {
|
|
1923
1931
|
return i18nString(Search$1);
|
|
1924
1932
|
};
|
|
1933
|
+
const scrollDown = () => {
|
|
1934
|
+
return i18nString(ScrollDown$1);
|
|
1935
|
+
};
|
|
1925
1936
|
const searchModels = () => {
|
|
1926
1937
|
return i18nString(SearchModels);
|
|
1927
1938
|
};
|
|
@@ -1985,6 +1996,21 @@ const startVoiceDictation = () => {
|
|
|
1985
1996
|
const addContext = () => {
|
|
1986
1997
|
return i18nString(AddContext$1);
|
|
1987
1998
|
};
|
|
1999
|
+
const addAction = () => {
|
|
2000
|
+
return i18nString(AddAction);
|
|
2001
|
+
};
|
|
2002
|
+
const openInVsCode = () => {
|
|
2003
|
+
return i18nString(OpenInVsCode);
|
|
2004
|
+
};
|
|
2005
|
+
const commit = () => {
|
|
2006
|
+
return i18nString(Commit);
|
|
2007
|
+
};
|
|
2008
|
+
const openTerminal = () => {
|
|
2009
|
+
return i18nString(OpenTerminal);
|
|
2010
|
+
};
|
|
2011
|
+
const showDiff = () => {
|
|
2012
|
+
return i18nString(ShowDiff);
|
|
2013
|
+
};
|
|
1988
2014
|
const createPullRequest = () => {
|
|
1989
2015
|
return i18nString(CreatePullRequest$2);
|
|
1990
2016
|
};
|
|
@@ -2059,16 +2085,19 @@ const getDefaultModelsOpenAi = () => {
|
|
|
2059
2085
|
id: 'openapi/gpt-4o-mini',
|
|
2060
2086
|
name: 'GPT-4o Mini',
|
|
2061
2087
|
provider: 'openApi',
|
|
2088
|
+
supportsImages: true,
|
|
2062
2089
|
usageCost: 1
|
|
2063
2090
|
}, {
|
|
2064
2091
|
id: 'openapi/gpt-4o',
|
|
2065
2092
|
name: 'GPT-4o',
|
|
2066
2093
|
provider: 'openApi',
|
|
2094
|
+
supportsImages: true,
|
|
2067
2095
|
usageCost: 3
|
|
2068
2096
|
}, {
|
|
2069
2097
|
id: 'openapi/gpt-4.1-mini',
|
|
2070
2098
|
name: 'GPT-4.1 Mini',
|
|
2071
2099
|
provider: 'openApi',
|
|
2100
|
+
supportsImages: true,
|
|
2072
2101
|
usageCost: 1
|
|
2073
2102
|
}];
|
|
2074
2103
|
};
|
|
@@ -2306,6 +2335,8 @@ const createDefaultState = () => {
|
|
|
2306
2335
|
chatSendAreaPaddingLeft: 8,
|
|
2307
2336
|
chatSendAreaPaddingRight: 8,
|
|
2308
2337
|
chatSendAreaPaddingTop: 10,
|
|
2338
|
+
composerAttachmentPreviewOverlayAttachmentId: '',
|
|
2339
|
+
composerAttachmentPreviewOverlayError: false,
|
|
2309
2340
|
composerAttachments: [],
|
|
2310
2341
|
composerAttachmentsHeight: 0,
|
|
2311
2342
|
composerDropActive: false,
|
|
@@ -2336,12 +2367,14 @@ const createDefaultState = () => {
|
|
|
2336
2367
|
messagesScrollTop: 0,
|
|
2337
2368
|
mockAiResponseDelay: 800,
|
|
2338
2369
|
mockApiCommandId: '',
|
|
2370
|
+
mockOpenApiRequests: [],
|
|
2339
2371
|
modelPickerHeaderHeight,
|
|
2340
2372
|
modelPickerHeight: getModelPickerHeight(modelPickerHeaderHeight, visibleModels.length),
|
|
2341
2373
|
modelPickerListScrollTop: 0,
|
|
2342
2374
|
modelPickerOpen: false,
|
|
2343
2375
|
modelPickerSearchValue: '',
|
|
2344
2376
|
models,
|
|
2377
|
+
nextAttachmentId: 1,
|
|
2345
2378
|
nextMessageId: 1,
|
|
2346
2379
|
openApiApiBaseUrl: 'https://api.openai.com/v1',
|
|
2347
2380
|
openApiApiKey: '',
|
|
@@ -2372,6 +2405,7 @@ const createDefaultState = () => {
|
|
|
2372
2405
|
responsivePickerVisibilityEnabled,
|
|
2373
2406
|
runMode: 'local',
|
|
2374
2407
|
runModePickerOpen: false,
|
|
2408
|
+
scrollDownButtonEnabled: false,
|
|
2375
2409
|
searchEnabled: false,
|
|
2376
2410
|
searchFieldVisible: false,
|
|
2377
2411
|
searchValue: '',
|
|
@@ -2602,6 +2636,13 @@ const getComposerAttachmentPreviewSrc = async (blob, displayType, mimeType) => {
|
|
|
2602
2636
|
return `data:${mimeType || 'application/octet-stream'};base64,${base64}`;
|
|
2603
2637
|
};
|
|
2604
2638
|
|
|
2639
|
+
const getComposerAttachmentTextContent = async (blob, displayType) => {
|
|
2640
|
+
if (displayType !== 'text-file') {
|
|
2641
|
+
return undefined;
|
|
2642
|
+
}
|
|
2643
|
+
return blob.text();
|
|
2644
|
+
};
|
|
2645
|
+
|
|
2605
2646
|
const isChatAttachmentAddedEvent = event => {
|
|
2606
2647
|
return event.type === 'chat-attachment-added';
|
|
2607
2648
|
};
|
|
@@ -2624,6 +2665,7 @@ const getComposerAttachments = async sessionId => {
|
|
|
2624
2665
|
}
|
|
2625
2666
|
const displayType = await getComposerAttachmentDisplayType(event.blob, event.name, event.mimeType);
|
|
2626
2667
|
const previewSrc = await getComposerAttachmentPreviewSrc(event.blob, displayType, event.mimeType);
|
|
2668
|
+
const textContent = await getComposerAttachmentTextContent(event.blob, displayType);
|
|
2627
2669
|
attachments.set(event.attachmentId, {
|
|
2628
2670
|
attachmentId: event.attachmentId,
|
|
2629
2671
|
displayType,
|
|
@@ -2632,7 +2674,10 @@ const getComposerAttachments = async sessionId => {
|
|
|
2632
2674
|
...(previewSrc ? {
|
|
2633
2675
|
previewSrc
|
|
2634
2676
|
} : {}),
|
|
2635
|
-
size: event.size
|
|
2677
|
+
size: event.size,
|
|
2678
|
+
...(typeof textContent === 'string' ? {
|
|
2679
|
+
textContent
|
|
2680
|
+
} : {})
|
|
2636
2681
|
});
|
|
2637
2682
|
}
|
|
2638
2683
|
return [...attachments.values()];
|
|
@@ -3194,7 +3239,8 @@ const openModelPicker = state => {
|
|
|
3194
3239
|
return {
|
|
3195
3240
|
...state,
|
|
3196
3241
|
agentModePickerOpen: false,
|
|
3197
|
-
focus: 'model-picker-input',
|
|
3242
|
+
focus: modelPickerOpen ? 'model-picker-input' : state.focus,
|
|
3243
|
+
focused: modelPickerOpen ? true : state.focused,
|
|
3198
3244
|
modelPickerHeight: getModelPickerHeight(state.modelPickerHeaderHeight, visibleModels.length),
|
|
3199
3245
|
modelPickerListScrollTop: 0,
|
|
3200
3246
|
modelPickerOpen,
|
|
@@ -3230,6 +3276,10 @@ const getKeyBindings = () => {
|
|
|
3230
3276
|
command: 'Chat.chatListFocusPrevious',
|
|
3231
3277
|
key: UpArrow,
|
|
3232
3278
|
when: FocusChatList
|
|
3279
|
+
}, {
|
|
3280
|
+
command: 'Chat.handleClickNew',
|
|
3281
|
+
key: CtrlCmd | KeyN,
|
|
3282
|
+
when: FocusChatInput
|
|
3233
3283
|
}, {
|
|
3234
3284
|
command: 'Chat.handleSubmit',
|
|
3235
3285
|
key: Enter,
|
|
@@ -3328,14 +3378,22 @@ const ComposerDropTarget = 'composer-drop-target';
|
|
|
3328
3378
|
const ComposerAttachmentPrefix = 'composer-attachment:';
|
|
3329
3379
|
const ComposerAttachmentPreviewPrefix = 'composer-attachment-preview:';
|
|
3330
3380
|
const ComposerAttachmentRemovePrefix = 'composer-attachment-remove:';
|
|
3381
|
+
const ComposerAttachmentPreviewOverlay = 'composer-attachment-preview-overlay';
|
|
3331
3382
|
const AddContext = 'add-context';
|
|
3332
3383
|
const Dictate = 'dictate';
|
|
3333
3384
|
const CreatePullRequest$1 = 'create-pull-request';
|
|
3385
|
+
const FocusAddAction = 'focus-add-action';
|
|
3386
|
+
const FocusOpenInVsCode = 'focus-open-in-vscode';
|
|
3387
|
+
const FocusCommit = 'focus-commit';
|
|
3388
|
+
const FocusOpenTerminal = 'focus-open-terminal';
|
|
3389
|
+
const FocusShowDiff = 'focus-show-diff';
|
|
3334
3390
|
const Send = 'send';
|
|
3391
|
+
const ScrollDown = 'scroll-down';
|
|
3335
3392
|
const Back = 'back';
|
|
3336
3393
|
const ModelPickerToggle = 'model-picker-toggle';
|
|
3337
3394
|
const ModelPickerSearch = 'model-picker-search';
|
|
3338
3395
|
const ModelPickerList = 'model-picker-list';
|
|
3396
|
+
const PickerList = 'picker-list';
|
|
3339
3397
|
const AgentModePickerToggle = 'agent-mode-picker-toggle';
|
|
3340
3398
|
const AgentModePickerItemPrefix = 'agent-mode-picker-item:';
|
|
3341
3399
|
const ReasoningEffortPickerToggle = 'reasoning-effort-picker-toggle';
|
|
@@ -3397,6 +3455,12 @@ const getModelPickerItemInputName = modelId => {
|
|
|
3397
3455
|
const getComposerAttachmentInputName = attachmentId => {
|
|
3398
3456
|
return `${ComposerAttachmentPrefix}${attachmentId}`;
|
|
3399
3457
|
};
|
|
3458
|
+
const isComposerAttachmentInputName = name => {
|
|
3459
|
+
return name.startsWith(ComposerAttachmentPrefix);
|
|
3460
|
+
};
|
|
3461
|
+
const getAttachmentIdFromComposerAttachmentInputName = name => {
|
|
3462
|
+
return name.slice(ComposerAttachmentPrefix.length);
|
|
3463
|
+
};
|
|
3400
3464
|
const getComposerAttachmentRemoveInputName = attachmentId => {
|
|
3401
3465
|
return `${ComposerAttachmentRemovePrefix}${attachmentId}`;
|
|
3402
3466
|
};
|
|
@@ -3412,6 +3476,9 @@ const isComposerAttachmentRemoveInputName = name => {
|
|
|
3412
3476
|
const getAttachmentIdFromComposerAttachmentRemoveInputName = name => {
|
|
3413
3477
|
return name.slice(ComposerAttachmentRemovePrefix.length);
|
|
3414
3478
|
};
|
|
3479
|
+
const isComposerAttachmentPreviewOverlayInputName = name => {
|
|
3480
|
+
return name === ComposerAttachmentPreviewOverlay;
|
|
3481
|
+
};
|
|
3415
3482
|
const isModelPickerItemInputName = name => {
|
|
3416
3483
|
return name.startsWith(ModelPickerItemPrefix);
|
|
3417
3484
|
};
|
|
@@ -3505,6 +3572,10 @@ const getMenuEntries = (menuId, props) => {
|
|
|
3505
3572
|
}
|
|
3506
3573
|
};
|
|
3507
3574
|
|
|
3575
|
+
const getMockOpenApiRequests = state => {
|
|
3576
|
+
return state.mockOpenApiRequests;
|
|
3577
|
+
};
|
|
3578
|
+
|
|
3508
3579
|
const getQuickPickMenuEntries = () => {
|
|
3509
3580
|
return [];
|
|
3510
3581
|
};
|
|
@@ -3630,6 +3701,12 @@ const getModelPickerClickIndex = (y, height, eventY, modelPickerBottomOffset, mo
|
|
|
3630
3701
|
return Math.floor(relativeY / modelPickerItemHeight);
|
|
3631
3702
|
};
|
|
3632
3703
|
|
|
3704
|
+
const AutoScrollTopA = Number.MAX_SAFE_INTEGER;
|
|
3705
|
+
const AutoScrollTopB = Number.MAX_SAFE_INTEGER - 1;
|
|
3706
|
+
const getNextAutoScrollTop = currentScrollTop => {
|
|
3707
|
+
return currentScrollTop === AutoScrollTopA ? AutoScrollTopB : AutoScrollTopA;
|
|
3708
|
+
};
|
|
3709
|
+
|
|
3633
3710
|
const openFolder = async () => {
|
|
3634
3711
|
try {
|
|
3635
3712
|
return await invoke('FilePicker.showDirectoryPicker');
|
|
@@ -4207,6 +4284,54 @@ const getBasicChatTools = async (agentMode = defaultAgentMode, questionToolEnabl
|
|
|
4207
4284
|
}
|
|
4208
4285
|
};
|
|
4209
4286
|
|
|
4287
|
+
const getAttachmentTextPart = attachment => {
|
|
4288
|
+
switch (attachment.displayType) {
|
|
4289
|
+
case 'file':
|
|
4290
|
+
return {
|
|
4291
|
+
text: `Attached file "${attachment.name}" (${attachment.mimeType || 'application/octet-stream'}, ${attachment.size} bytes).`,
|
|
4292
|
+
type: 'input_text'
|
|
4293
|
+
};
|
|
4294
|
+
case 'image':
|
|
4295
|
+
return {
|
|
4296
|
+
text: `Attached image "${attachment.name}" could not be encoded for the AI request.`,
|
|
4297
|
+
type: 'input_text'
|
|
4298
|
+
};
|
|
4299
|
+
case 'invalid-image':
|
|
4300
|
+
return {
|
|
4301
|
+
text: `Attached file "${attachment.name}" could not be processed as a valid image.`,
|
|
4302
|
+
type: 'input_text'
|
|
4303
|
+
};
|
|
4304
|
+
case 'text-file':
|
|
4305
|
+
return {
|
|
4306
|
+
text: attachment.textContent ? `Attached text file "${attachment.name}" (${attachment.mimeType || 'text/plain'}):\n\n${attachment.textContent}` : `Attached text file "${attachment.name}" (${attachment.mimeType || 'text/plain'}).`,
|
|
4307
|
+
type: 'input_text'
|
|
4308
|
+
};
|
|
4309
|
+
}
|
|
4310
|
+
};
|
|
4311
|
+
const getChatMessageOpenAiContent = message => {
|
|
4312
|
+
if (!message.attachments || message.attachments.length === 0) {
|
|
4313
|
+
return message.text;
|
|
4314
|
+
}
|
|
4315
|
+
const parts = [];
|
|
4316
|
+
if (message.text) {
|
|
4317
|
+
parts.push({
|
|
4318
|
+
text: message.text,
|
|
4319
|
+
type: 'input_text'
|
|
4320
|
+
});
|
|
4321
|
+
}
|
|
4322
|
+
for (const attachment of message.attachments) {
|
|
4323
|
+
if (attachment.displayType === 'image' && attachment.previewSrc) {
|
|
4324
|
+
parts.push({
|
|
4325
|
+
image_url: attachment.previewSrc,
|
|
4326
|
+
type: 'input_image'
|
|
4327
|
+
});
|
|
4328
|
+
continue;
|
|
4329
|
+
}
|
|
4330
|
+
parts.push(getAttachmentTextPart(attachment));
|
|
4331
|
+
}
|
|
4332
|
+
return parts;
|
|
4333
|
+
};
|
|
4334
|
+
|
|
4210
4335
|
const getClientRequestIdHeader = () => {
|
|
4211
4336
|
return {
|
|
4212
4337
|
'x-client-request-id': crypto.randomUUID()
|
|
@@ -4222,11 +4347,22 @@ const getMockAiResponse = async (userMessage, delayInMs) => {
|
|
|
4222
4347
|
return `Mock AI response: I received "${userMessage}".`;
|
|
4223
4348
|
};
|
|
4224
4349
|
|
|
4350
|
+
let requests = [];
|
|
4351
|
+
const reset$2 = () => {
|
|
4352
|
+
requests = [];
|
|
4353
|
+
};
|
|
4354
|
+
const capture = request => {
|
|
4355
|
+
requests = [...requests, request];
|
|
4356
|
+
};
|
|
4357
|
+
const getAll = () => {
|
|
4358
|
+
return requests;
|
|
4359
|
+
};
|
|
4360
|
+
|
|
4225
4361
|
let queue = [];
|
|
4226
4362
|
let waiters = [];
|
|
4227
4363
|
let finished = false;
|
|
4228
4364
|
let errorResult;
|
|
4229
|
-
const reset$
|
|
4365
|
+
const reset$1 = () => {
|
|
4230
4366
|
queue = [];
|
|
4231
4367
|
waiters = [];
|
|
4232
4368
|
finished = false;
|
|
@@ -4300,6 +4436,47 @@ const readNextChunk = async () => {
|
|
|
4300
4436
|
return promise;
|
|
4301
4437
|
};
|
|
4302
4438
|
|
|
4439
|
+
const lastRequestSummaryToken = '__MOCK_OPENAPI_LAST_REQUEST_SUMMARY__';
|
|
4440
|
+
const getLastRequestSummary = () => {
|
|
4441
|
+
const requests = getAll();
|
|
4442
|
+
const request = requests.at(-1);
|
|
4443
|
+
if (!request || !request.payload || typeof request.payload !== 'object') {
|
|
4444
|
+
return 'mock-request-summary images=0 text-files=0';
|
|
4445
|
+
}
|
|
4446
|
+
const input = Reflect.get(request.payload, 'input');
|
|
4447
|
+
if (!Array.isArray(input) || input.length === 0) {
|
|
4448
|
+
return 'mock-request-summary images=0 text-files=0';
|
|
4449
|
+
}
|
|
4450
|
+
let imageCount = 0;
|
|
4451
|
+
let textFileCount = 0;
|
|
4452
|
+
for (const item of input) {
|
|
4453
|
+
if (!item || typeof item !== 'object') {
|
|
4454
|
+
continue;
|
|
4455
|
+
}
|
|
4456
|
+
const content = Reflect.get(item, 'content');
|
|
4457
|
+
if (!Array.isArray(content)) {
|
|
4458
|
+
continue;
|
|
4459
|
+
}
|
|
4460
|
+
for (const part of content) {
|
|
4461
|
+
if (!part || typeof part !== 'object') {
|
|
4462
|
+
continue;
|
|
4463
|
+
}
|
|
4464
|
+
const type = Reflect.get(part, 'type');
|
|
4465
|
+
if (type === 'input_image') {
|
|
4466
|
+
imageCount++;
|
|
4467
|
+
continue;
|
|
4468
|
+
}
|
|
4469
|
+
if (type !== 'input_text') {
|
|
4470
|
+
continue;
|
|
4471
|
+
}
|
|
4472
|
+
const text = Reflect.get(part, 'text');
|
|
4473
|
+
if (typeof text === 'string' && text.startsWith('Attached text file "')) {
|
|
4474
|
+
textFileCount++;
|
|
4475
|
+
}
|
|
4476
|
+
}
|
|
4477
|
+
}
|
|
4478
|
+
return `mock-request-summary images=${imageCount} text-files=${textFileCount}`;
|
|
4479
|
+
};
|
|
4303
4480
|
const getResponseFunctionCalls$1 = value => {
|
|
4304
4481
|
if (!value || typeof value !== 'object') {
|
|
4305
4482
|
return [];
|
|
@@ -4497,9 +4674,10 @@ const getMockOpenApiAssistantText = async (stream, onTextChunk, onToolCallsChunk
|
|
|
4497
4674
|
}
|
|
4498
4675
|
continue;
|
|
4499
4676
|
}
|
|
4500
|
-
|
|
4677
|
+
const resolvedChunk = chunk === lastRequestSummaryToken ? getLastRequestSummary() : chunk;
|
|
4678
|
+
text += resolvedChunk;
|
|
4501
4679
|
if (stream && onTextChunk) {
|
|
4502
|
-
await onTextChunk(
|
|
4680
|
+
await onTextChunk(resolvedChunk);
|
|
4503
4681
|
}
|
|
4504
4682
|
}
|
|
4505
4683
|
if (!requestDone && remainder) {
|
|
@@ -5336,7 +5514,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
5336
5514
|
stream: false
|
|
5337
5515
|
};
|
|
5338
5516
|
const openAiInput = messages.map(message => ({
|
|
5339
|
-
content: message
|
|
5517
|
+
content: getChatMessageOpenAiContent(message),
|
|
5340
5518
|
role: message.role
|
|
5341
5519
|
}));
|
|
5342
5520
|
const tools = await getBasicChatTools(agentMode, questionToolEnabled, toolEnablement);
|
|
@@ -5729,12 +5907,22 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
5729
5907
|
};
|
|
5730
5908
|
};
|
|
5731
5909
|
|
|
5910
|
+
const imageRegex = /\b(?:image|vision|multimodal)\b/i;
|
|
5911
|
+
const unsupportedRegex = /\bdoes(?:\s+not|n't)\s+support|not\s+support(?:ed)?|unsupported\b/i;
|
|
5732
5912
|
const isOffline = () => {
|
|
5733
5913
|
if (!globalThis.navigator) {
|
|
5734
5914
|
return false;
|
|
5735
5915
|
}
|
|
5736
5916
|
return globalThis.navigator.onLine === false;
|
|
5737
5917
|
};
|
|
5918
|
+
const isImageNotSupportedError = errorResult => {
|
|
5919
|
+
const haystack = [errorResult.errorCode, errorResult.errorMessage, errorResult.errorType].filter(Boolean).join(' ');
|
|
5920
|
+
return imageRegex.test(haystack) && unsupportedRegex.test(haystack);
|
|
5921
|
+
};
|
|
5922
|
+
const getImageNotSupportedMessage = modelName => {
|
|
5923
|
+
const subject = modelName ? `${modelName} does not support image attachments.` : 'This model does not support image attachments.';
|
|
5924
|
+
return `${subject} Choose a vision-capable model like GPT-4o Mini or GPT-4o, or remove the image and try again.`;
|
|
5925
|
+
};
|
|
5738
5926
|
const getOpenApiErrorMessage = errorResult => {
|
|
5739
5927
|
switch (errorResult.details) {
|
|
5740
5928
|
case 'http-error':
|
|
@@ -5748,6 +5936,9 @@ const getOpenApiErrorMessage = errorResult => {
|
|
|
5748
5936
|
const status = typeof errorResult.statusCode === 'number' ? errorResult.statusCode : 401;
|
|
5749
5937
|
return `OpenAI request failed (Status ${status}): Invalid API key. Please verify your OpenAI API key in Chat Settings.`;
|
|
5750
5938
|
}
|
|
5939
|
+
if (isImageNotSupportedError(errorResult)) {
|
|
5940
|
+
return getImageNotSupportedMessage();
|
|
5941
|
+
}
|
|
5751
5942
|
if (errorResult.statusCode === 429) {
|
|
5752
5943
|
let prefix = 'OpenAI rate limit exceeded (429)';
|
|
5753
5944
|
if (hasErrorCode) {
|
|
@@ -6196,17 +6387,6 @@ const isOpenRouterModel = (selectedModelId, models) => {
|
|
|
6196
6387
|
return selectedModelId.toLowerCase().startsWith('openrouter/');
|
|
6197
6388
|
};
|
|
6198
6389
|
|
|
6199
|
-
let requests = [];
|
|
6200
|
-
const reset$1 = () => {
|
|
6201
|
-
requests = [];
|
|
6202
|
-
};
|
|
6203
|
-
const capture = request => {
|
|
6204
|
-
requests = [...requests, request];
|
|
6205
|
-
};
|
|
6206
|
-
const getAll = () => {
|
|
6207
|
-
return requests;
|
|
6208
|
-
};
|
|
6209
|
-
|
|
6210
6390
|
/* eslint-disable prefer-destructuring */
|
|
6211
6391
|
|
|
6212
6392
|
const trailingSlashesRegex = /\/+$/;
|
|
@@ -6221,6 +6401,9 @@ const getEffectiveBackendModelId = selectedModelId => {
|
|
|
6221
6401
|
}
|
|
6222
6402
|
return selectedModelId.slice(separatorIndex + 1);
|
|
6223
6403
|
};
|
|
6404
|
+
const hasImageAttachments = messages => {
|
|
6405
|
+
return messages.some(message => message.attachments?.some(attachment => attachment.displayType === 'image'));
|
|
6406
|
+
};
|
|
6224
6407
|
const getBackendAssistantText = async (messages, selectedModelId, backendUrl, authAccessToken, systemPrompt) => {
|
|
6225
6408
|
let response;
|
|
6226
6409
|
try {
|
|
@@ -6268,6 +6451,7 @@ const getAiResponse = async ({
|
|
|
6268
6451
|
nextMessageId,
|
|
6269
6452
|
onDataEvent,
|
|
6270
6453
|
onEventStreamFinished,
|
|
6454
|
+
onMockOpenApiRequestCaptured,
|
|
6271
6455
|
onTextChunk,
|
|
6272
6456
|
onToolCallsChunk,
|
|
6273
6457
|
openApiApiBaseUrl,
|
|
@@ -6343,7 +6527,15 @@ const getAiResponse = async ({
|
|
|
6343
6527
|
}
|
|
6344
6528
|
}
|
|
6345
6529
|
let text = '';
|
|
6346
|
-
|
|
6530
|
+
const usesOpenApiModel = isOpenApiModel(selectedModelId, models);
|
|
6531
|
+
const usesOpenRouterModel = isOpenRouterModel(selectedModelId, models);
|
|
6532
|
+
const selectedModel = models.find(model => model.id === selectedModelId);
|
|
6533
|
+
const supportsImages = selectedModel?.supportsImages ?? false;
|
|
6534
|
+
const supportsReasoningEffort = selectedModel?.supportsReasoningEffort ?? false;
|
|
6535
|
+
if (hasImageAttachments(messages) && !supportsImages) {
|
|
6536
|
+
text = getImageNotSupportedMessage(selectedModel?.name);
|
|
6537
|
+
}
|
|
6538
|
+
if (!text && authEnabled) {
|
|
6347
6539
|
if (!backendUrl) {
|
|
6348
6540
|
text = backendUrlRequiredMessage;
|
|
6349
6541
|
} else if (authAccessToken) {
|
|
@@ -6352,15 +6544,11 @@ const getAiResponse = async ({
|
|
|
6352
6544
|
text = backendAccessTokenRequiredMessage;
|
|
6353
6545
|
}
|
|
6354
6546
|
}
|
|
6355
|
-
const usesOpenApiModel = isOpenApiModel(selectedModelId, models);
|
|
6356
|
-
const usesOpenRouterModel = isOpenRouterModel(selectedModelId, models);
|
|
6357
|
-
const selectedModel = models.find(model => model.id === selectedModelId);
|
|
6358
|
-
const supportsReasoningEffort = selectedModel?.supportsReasoningEffort ?? false;
|
|
6359
6547
|
if (!text && usesOpenApiModel) {
|
|
6360
6548
|
const safeMaxToolCalls = Math.max(1, maxToolCalls);
|
|
6361
6549
|
if (useMockApi) {
|
|
6362
6550
|
const openAiInput = messages.map(message => ({
|
|
6363
|
-
content: message
|
|
6551
|
+
content: getChatMessageOpenAiContent(message),
|
|
6364
6552
|
role: message.role
|
|
6365
6553
|
}));
|
|
6366
6554
|
const modelId = getOpenApiModelId(selectedModelId);
|
|
@@ -6372,12 +6560,16 @@ const getAiResponse = async ({
|
|
|
6372
6560
|
const maxToolIterations = safeMaxToolCalls - 1;
|
|
6373
6561
|
let previousResponseId;
|
|
6374
6562
|
for (let i = 0; i <= maxToolIterations; i++) {
|
|
6375
|
-
|
|
6563
|
+
const request = {
|
|
6376
6564
|
headers,
|
|
6377
6565
|
method: 'POST',
|
|
6378
6566
|
payload: getOpenAiParams(openAiInput, modelId, streamingEnabled, passIncludeObfuscation, await getBasicChatTools(agentMode, questionToolEnabled, toolEnablement), agentMode === 'plan' ? false : webSearchEnabled, safeMaxToolCalls, systemPrompt, previousResponseId, reasoningEffort, supportsReasoningEffort),
|
|
6379
6567
|
url: getOpenApiApiEndpoint(openApiApiBaseUrl)
|
|
6380
|
-
}
|
|
6568
|
+
};
|
|
6569
|
+
capture(request);
|
|
6570
|
+
if (onMockOpenApiRequestCaptured) {
|
|
6571
|
+
await Promise.resolve(onMockOpenApiRequestCaptured(request));
|
|
6572
|
+
}
|
|
6381
6573
|
const result = await getMockOpenApiAssistantText(streamingEnabled, onTextChunk, onToolCallsChunk, onDataEvent, onEventStreamFinished);
|
|
6382
6574
|
if (result.type !== 'success') {
|
|
6383
6575
|
text = getOpenApiErrorMessage(result);
|
|
@@ -6532,6 +6724,9 @@ const Chat = 'Chat';
|
|
|
6532
6724
|
const ChatActions = 'ChatActions';
|
|
6533
6725
|
const ChatAuthError = 'ChatAuthError';
|
|
6534
6726
|
const ChatFocus = 'ChatFocus';
|
|
6727
|
+
const ChatFocusActions = 'ChatFocusActions';
|
|
6728
|
+
const ChatFocusHeader = 'ChatFocusHeader';
|
|
6729
|
+
const ChatFocusProject = 'ChatFocusProject';
|
|
6535
6730
|
const ChatHeader = 'ChatHeader';
|
|
6536
6731
|
const ChatHeaderLabel = 'ChatHeaderLabel';
|
|
6537
6732
|
const ChatInputBox = 'ChatInputBox';
|
|
@@ -6567,6 +6762,9 @@ const ChatComposerAttachmentImage = 'ChatComposerAttachmentImage';
|
|
|
6567
6762
|
const ChatComposerAttachmentInvalidImage = 'ChatComposerAttachmentInvalidImage';
|
|
6568
6763
|
const ChatComposerAttachmentLabel = 'ChatComposerAttachmentLabel';
|
|
6569
6764
|
const ChatComposerAttachmentPreview = 'ChatComposerAttachmentPreview';
|
|
6765
|
+
const ChatComposerAttachmentPreviewOverlay = 'ChatComposerAttachmentPreviewOverlay';
|
|
6766
|
+
const ChatComposerAttachmentPreviewOverlayError = 'ChatComposerAttachmentPreviewOverlayError';
|
|
6767
|
+
const ChatComposerAttachmentPreviewOverlayImage = 'ChatComposerAttachmentPreviewOverlayImage';
|
|
6570
6768
|
const ChatComposerAttachmentRemoveButton = 'ChatComposerAttachmentRemoveButton';
|
|
6571
6769
|
const ChatComposerAttachments = 'ChatComposerAttachments';
|
|
6572
6770
|
const ChatComposerAttachmentTextFile = 'ChatComposerAttachmentTextFile';
|
|
@@ -6605,6 +6803,7 @@ const FileIcon = 'FileIcon';
|
|
|
6605
6803
|
const IconButton = 'IconButton';
|
|
6606
6804
|
const IconButtonDisabled = 'IconButtonDisabled';
|
|
6607
6805
|
const ImageElement = 'ImageElement';
|
|
6806
|
+
const ImageErrorMessage = 'ImageErrorMessage';
|
|
6608
6807
|
const InputBox = 'InputBox';
|
|
6609
6808
|
const Insertion = 'Insertion';
|
|
6610
6809
|
const Label = 'Label';
|
|
@@ -8379,12 +8578,6 @@ const getMentionContextMessage = async value => {
|
|
|
8379
8578
|
};
|
|
8380
8579
|
};
|
|
8381
8580
|
|
|
8382
|
-
const AutoScrollTopA = Number.MAX_SAFE_INTEGER;
|
|
8383
|
-
const AutoScrollTopB = Number.MAX_SAFE_INTEGER - 1;
|
|
8384
|
-
const getNextAutoScrollTop = currentScrollTop => {
|
|
8385
|
-
return currentScrollTop === AutoScrollTopA ? AutoScrollTopB : AutoScrollTopA;
|
|
8386
|
-
};
|
|
8387
|
-
|
|
8388
8581
|
const slashCommandRegex = /^\/([a-z][a-z0-9-]*)(?:\s+.*)?$/i;
|
|
8389
8582
|
const getSlashCommand = value => {
|
|
8390
8583
|
const trimmed = value.trim();
|
|
@@ -8662,6 +8855,19 @@ const withUpdatedMessageScrollTop = state => {
|
|
|
8662
8855
|
};
|
|
8663
8856
|
};
|
|
8664
8857
|
const workspaceUriPlaceholder = '{{workspaceUri}}';
|
|
8858
|
+
const clearComposerAttachments = async (sessionId, attachmentIds) => {
|
|
8859
|
+
if (!sessionId) {
|
|
8860
|
+
return;
|
|
8861
|
+
}
|
|
8862
|
+
for (const attachmentId of attachmentIds) {
|
|
8863
|
+
await appendChatViewEvent({
|
|
8864
|
+
attachmentId,
|
|
8865
|
+
sessionId,
|
|
8866
|
+
timestamp: new Date().toISOString(),
|
|
8867
|
+
type: 'chat-attachment-removed'
|
|
8868
|
+
});
|
|
8869
|
+
}
|
|
8870
|
+
};
|
|
8665
8871
|
const getCurrentDate = () => {
|
|
8666
8872
|
return new Date().toISOString().slice(0, 10);
|
|
8667
8873
|
};
|
|
@@ -8754,7 +8960,12 @@ const handleSubmit = async state => {
|
|
|
8754
8960
|
minute: '2-digit'
|
|
8755
8961
|
});
|
|
8756
8962
|
const userMessageId = crypto.randomUUID();
|
|
8963
|
+
const composerAttachments = state.composerAttachments.length > 0 ? state.composerAttachments : await getComposerAttachments(state.selectedSessionId);
|
|
8964
|
+
await clearComposerAttachments(state.selectedSessionId, composerAttachments.map(attachment => attachment.attachmentId));
|
|
8757
8965
|
const userMessage = {
|
|
8966
|
+
...(composerAttachments.length > 0 ? {
|
|
8967
|
+
attachments: composerAttachments
|
|
8968
|
+
} : {}),
|
|
8758
8969
|
id: userMessageId,
|
|
8759
8970
|
role: 'user',
|
|
8760
8971
|
text: userText,
|
|
@@ -8869,6 +9080,9 @@ const handleSubmit = async state => {
|
|
|
8869
9080
|
latestState: optimisticState,
|
|
8870
9081
|
previousState: optimisticState
|
|
8871
9082
|
};
|
|
9083
|
+
let {
|
|
9084
|
+
mockOpenApiRequests
|
|
9085
|
+
} = optimisticState;
|
|
8872
9086
|
const selectedOptimisticSession = optimisticState.sessions.find(session => session.id === optimisticState.selectedSessionId);
|
|
8873
9087
|
const systemPrompt = getEffectiveSystemPrompt(optimisticState, selectedOptimisticSession);
|
|
8874
9088
|
const workspaceUri = getWorkspaceUri(optimisticState, selectedOptimisticSession);
|
|
@@ -8911,6 +9125,9 @@ const handleSubmit = async state => {
|
|
|
8911
9125
|
value: '[DONE]'
|
|
8912
9126
|
});
|
|
8913
9127
|
},
|
|
9128
|
+
onMockOpenApiRequestCaptured: async request => {
|
|
9129
|
+
mockOpenApiRequests = [...mockOpenApiRequests, request];
|
|
9130
|
+
},
|
|
8914
9131
|
...(handleTextChunkFunctionRef ? {
|
|
8915
9132
|
onTextChunk: handleTextChunkFunctionRef
|
|
8916
9133
|
} : {}),
|
|
@@ -8967,6 +9184,7 @@ const handleSubmit = async state => {
|
|
|
8967
9184
|
}
|
|
8968
9185
|
return withUpdatedMessageScrollTop(focusInput({
|
|
8969
9186
|
...latestState,
|
|
9187
|
+
mockOpenApiRequests,
|
|
8970
9188
|
nextMessageId: latestState.nextMessageId + 1,
|
|
8971
9189
|
parsedMessages: finalParsedMessages,
|
|
8972
9190
|
sessions: updatedSessions
|
|
@@ -9028,6 +9246,8 @@ const openAgentModePicker = state => {
|
|
|
9028
9246
|
return {
|
|
9029
9247
|
...state,
|
|
9030
9248
|
agentModePickerOpen,
|
|
9249
|
+
focus: agentModePickerOpen ? 'picker-list' : state.focus,
|
|
9250
|
+
focused: agentModePickerOpen ? true : state.focused,
|
|
9031
9251
|
modelPickerOpen: false,
|
|
9032
9252
|
modelPickerSearchValue: '',
|
|
9033
9253
|
reasoningEffortPickerOpen: false,
|
|
@@ -9046,6 +9266,8 @@ const openReasoningEffortPicker = state => {
|
|
|
9046
9266
|
return {
|
|
9047
9267
|
...state,
|
|
9048
9268
|
agentModePickerOpen: false,
|
|
9269
|
+
focus: reasoningEffortPickerOpen ? 'picker-list' : state.focus,
|
|
9270
|
+
focused: reasoningEffortPickerOpen ? true : state.focused,
|
|
9049
9271
|
modelPickerOpen: false,
|
|
9050
9272
|
modelPickerSearchValue: '',
|
|
9051
9273
|
reasoningEffortPickerOpen,
|
|
@@ -9071,6 +9293,8 @@ const openRunModePicker = state => {
|
|
|
9071
9293
|
return {
|
|
9072
9294
|
...state,
|
|
9073
9295
|
agentModePickerOpen: false,
|
|
9296
|
+
focus: runModePickerOpen ? 'picker-list' : state.focus,
|
|
9297
|
+
focused: runModePickerOpen ? true : state.focused,
|
|
9074
9298
|
modelPickerOpen: false,
|
|
9075
9299
|
modelPickerSearchValue: '',
|
|
9076
9300
|
reasoningEffortPickerOpen: false,
|
|
@@ -9334,6 +9558,12 @@ const handleClick = async (state, name, id = '', eventX = 0, eventY = 0) => {
|
|
|
9334
9558
|
return deleteSession(state, id);
|
|
9335
9559
|
case name === Send:
|
|
9336
9560
|
return handleClickSend(state);
|
|
9561
|
+
case name === ScrollDown:
|
|
9562
|
+
return {
|
|
9563
|
+
...state,
|
|
9564
|
+
messagesAutoScrollEnabled: true,
|
|
9565
|
+
messagesScrollTop: getNextAutoScrollTop(state.messagesScrollTop)
|
|
9566
|
+
};
|
|
9337
9567
|
case name === SaveOpenRouterApiKey:
|
|
9338
9568
|
return handleClickSaveOpenRouterApiKey(state);
|
|
9339
9569
|
case name === SaveOpenApiApiKey:
|
|
@@ -9564,6 +9794,7 @@ const handleDropFiles = async (state, name, fileHandles = []) => {
|
|
|
9564
9794
|
const {
|
|
9565
9795
|
composerDropActive,
|
|
9566
9796
|
composerDropEnabled,
|
|
9797
|
+
nextAttachmentId,
|
|
9567
9798
|
selectedSessionId,
|
|
9568
9799
|
width
|
|
9569
9800
|
} = state;
|
|
@@ -9586,9 +9817,10 @@ const handleDropFiles = async (state, name, fileHandles = []) => {
|
|
|
9586
9817
|
const nextAttachments = [];
|
|
9587
9818
|
for (const droppedFileHandle of droppedFileHandles) {
|
|
9588
9819
|
const file = await droppedFileHandle.getFile();
|
|
9589
|
-
const attachmentId =
|
|
9820
|
+
const attachmentId = `attachment-${nextAttachmentId + nextAttachments.length}`;
|
|
9590
9821
|
const displayType = await getComposerAttachmentDisplayType(file, file.name, file.type);
|
|
9591
9822
|
const previewSrc = await getComposerAttachmentPreviewSrc(file, displayType, file.type);
|
|
9823
|
+
const textContent = await getComposerAttachmentTextContent(file, displayType);
|
|
9592
9824
|
await appendChatViewEvent({
|
|
9593
9825
|
attachmentId,
|
|
9594
9826
|
blob: file,
|
|
@@ -9607,13 +9839,27 @@ const handleDropFiles = async (state, name, fileHandles = []) => {
|
|
|
9607
9839
|
...(previewSrc ? {
|
|
9608
9840
|
previewSrc
|
|
9609
9841
|
} : {}),
|
|
9610
|
-
size: file.size
|
|
9842
|
+
size: file.size,
|
|
9843
|
+
...(typeof textContent === 'string' ? {
|
|
9844
|
+
textContent
|
|
9845
|
+
} : {})
|
|
9611
9846
|
});
|
|
9612
9847
|
}
|
|
9613
9848
|
return {
|
|
9614
9849
|
...nextState,
|
|
9615
9850
|
composerAttachments: [...nextState.composerAttachments, ...nextAttachments],
|
|
9616
|
-
composerAttachmentsHeight: getComposerAttachmentsHeight([...nextState.composerAttachments, ...nextAttachments], width)
|
|
9851
|
+
composerAttachmentsHeight: getComposerAttachmentsHeight([...nextState.composerAttachments, ...nextAttachments], width),
|
|
9852
|
+
nextAttachmentId: nextAttachmentId + nextAttachments.length
|
|
9853
|
+
};
|
|
9854
|
+
};
|
|
9855
|
+
|
|
9856
|
+
const handleErrorComposerAttachmentPreviewOverlay = async state => {
|
|
9857
|
+
if (!state.composerAttachmentPreviewOverlayAttachmentId || state.composerAttachmentPreviewOverlayError) {
|
|
9858
|
+
return state;
|
|
9859
|
+
}
|
|
9860
|
+
return {
|
|
9861
|
+
...state,
|
|
9862
|
+
composerAttachmentPreviewOverlayError: true
|
|
9617
9863
|
};
|
|
9618
9864
|
};
|
|
9619
9865
|
|
|
@@ -9817,6 +10063,60 @@ const handleModelChange = async (state, value) => {
|
|
|
9817
10063
|
};
|
|
9818
10064
|
};
|
|
9819
10065
|
|
|
10066
|
+
const hideComposerAttachmentPreviewOverlay = async state => {
|
|
10067
|
+
if (!state.composerAttachmentPreviewOverlayAttachmentId && !state.composerAttachmentPreviewOverlayError) {
|
|
10068
|
+
return state;
|
|
10069
|
+
}
|
|
10070
|
+
return {
|
|
10071
|
+
...state,
|
|
10072
|
+
composerAttachmentPreviewOverlayAttachmentId: '',
|
|
10073
|
+
composerAttachmentPreviewOverlayError: false
|
|
10074
|
+
};
|
|
10075
|
+
};
|
|
10076
|
+
|
|
10077
|
+
const isCurrentAttachmentTarget = (name, attachmentId) => {
|
|
10078
|
+
return name === getComposerAttachmentInputName(attachmentId) || isComposerAttachmentRemoveInputName(name) && getAttachmentIdFromComposerAttachmentRemoveInputName(name) === attachmentId;
|
|
10079
|
+
};
|
|
10080
|
+
const handleMouseOut = async (state, name, relatedName = '') => {
|
|
10081
|
+
const {
|
|
10082
|
+
composerAttachmentPreviewOverlayAttachmentId
|
|
10083
|
+
} = state;
|
|
10084
|
+
if (!composerAttachmentPreviewOverlayAttachmentId) {
|
|
10085
|
+
return state;
|
|
10086
|
+
}
|
|
10087
|
+
const isLeavingOverlay = isComposerAttachmentPreviewOverlayInputName(name);
|
|
10088
|
+
if (!isLeavingOverlay) {
|
|
10089
|
+
return state;
|
|
10090
|
+
}
|
|
10091
|
+
if (isComposerAttachmentPreviewOverlayInputName(relatedName) || isCurrentAttachmentTarget(relatedName, composerAttachmentPreviewOverlayAttachmentId)) {
|
|
10092
|
+
return state;
|
|
10093
|
+
}
|
|
10094
|
+
return hideComposerAttachmentPreviewOverlay(state);
|
|
10095
|
+
};
|
|
10096
|
+
|
|
10097
|
+
const showComposerAttachmentPreviewOverlay = async (state, attachmentId) => {
|
|
10098
|
+
const attachment = state.composerAttachments.find(item => item.attachmentId === attachmentId) ?? state.composerAttachments.find(item => item.displayType === 'image' && !!item.previewSrc);
|
|
10099
|
+
if (!attachment || attachment.displayType !== 'image' || !attachment.previewSrc) {
|
|
10100
|
+
return state;
|
|
10101
|
+
}
|
|
10102
|
+
if (state.composerAttachmentPreviewOverlayAttachmentId === attachmentId && !state.composerAttachmentPreviewOverlayError) {
|
|
10103
|
+
return state;
|
|
10104
|
+
}
|
|
10105
|
+
return {
|
|
10106
|
+
...state,
|
|
10107
|
+
composerAttachmentPreviewOverlayAttachmentId: attachmentId,
|
|
10108
|
+
composerAttachmentPreviewOverlayError: false
|
|
10109
|
+
};
|
|
10110
|
+
};
|
|
10111
|
+
|
|
10112
|
+
const handleMouseOver = async (state, name) => {
|
|
10113
|
+
if (!isComposerAttachmentInputName(name)) {
|
|
10114
|
+
return state;
|
|
10115
|
+
}
|
|
10116
|
+
const attachmentId = getAttachmentIdFromComposerAttachmentInputName(name);
|
|
10117
|
+
return showComposerAttachmentPreviewOverlay(state, attachmentId);
|
|
10118
|
+
};
|
|
10119
|
+
|
|
9820
10120
|
const handleNewline = async state => {
|
|
9821
10121
|
const {
|
|
9822
10122
|
composerValue
|
|
@@ -10010,6 +10310,23 @@ const getSavedChatListScrollTop = savedState => {
|
|
|
10010
10310
|
return chatListScrollTop;
|
|
10011
10311
|
};
|
|
10012
10312
|
|
|
10313
|
+
const getSavedComposerSelection = (savedState, composerValue) => {
|
|
10314
|
+
if (!isObject$1(savedState)) {
|
|
10315
|
+
return undefined;
|
|
10316
|
+
}
|
|
10317
|
+
const {
|
|
10318
|
+
composerSelectionEnd,
|
|
10319
|
+
composerSelectionStart
|
|
10320
|
+
} = savedState;
|
|
10321
|
+
if (typeof composerSelectionStart !== 'number') {
|
|
10322
|
+
return undefined;
|
|
10323
|
+
}
|
|
10324
|
+
if (typeof composerSelectionEnd !== 'number') {
|
|
10325
|
+
return undefined;
|
|
10326
|
+
}
|
|
10327
|
+
return getNormalizedComposerSelection(composerValue, composerSelectionStart, composerSelectionEnd);
|
|
10328
|
+
};
|
|
10329
|
+
|
|
10013
10330
|
const getSavedComposerValue = savedState => {
|
|
10014
10331
|
if (!isObject$1(savedState)) {
|
|
10015
10332
|
return undefined;
|
|
@@ -10311,6 +10628,15 @@ const loadReasoningPickerEnabled = async () => {
|
|
|
10311
10628
|
}
|
|
10312
10629
|
};
|
|
10313
10630
|
|
|
10631
|
+
const loadScrollDownButtonEnabled = async () => {
|
|
10632
|
+
try {
|
|
10633
|
+
const savedScrollDownButtonEnabled = await get('chatView.scrollDownButtonEnabled');
|
|
10634
|
+
return typeof savedScrollDownButtonEnabled === 'boolean' ? savedScrollDownButtonEnabled : false;
|
|
10635
|
+
} catch {
|
|
10636
|
+
return false;
|
|
10637
|
+
}
|
|
10638
|
+
};
|
|
10639
|
+
|
|
10314
10640
|
const loadSearchEnabled = async () => {
|
|
10315
10641
|
try {
|
|
10316
10642
|
const savedSearchEnabled = await get('chatView.searchEnabled');
|
|
@@ -10402,7 +10728,7 @@ const loadVoiceDictationEnabled = async () => {
|
|
|
10402
10728
|
};
|
|
10403
10729
|
|
|
10404
10730
|
const loadPreferences = async () => {
|
|
10405
|
-
const [aiSessionTitleGenerationEnabled, authAccessToken, authEnabled, authRefreshToken, backendUrl, chatHistoryEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, reasoningPickerEnabled, searchEnabled, streamingEnabled, todoListToolEnabled, toolEnablement, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatMessageParsingWorker, useChatNetworkWorkerForRequests, useChatToolWorker, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadBackendAccessToken(), loadAuthEnabled(), loadBackendRefreshToken(), loadBackendUrl(), loadChatHistoryEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadReasoningPickerEnabled(), loadSearchEnabled(), loadStreamingEnabled(), loadTodoListToolEnabled(), loadToolEnablement(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatMessageParsingWorker(), loadUseChatNetworkWorkerForRequests(), loadUseChatToolWorker(), loadVoiceDictationEnabled()]);
|
|
10731
|
+
const [aiSessionTitleGenerationEnabled, authAccessToken, authEnabled, authRefreshToken, backendUrl, chatHistoryEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, reasoningPickerEnabled, scrollDownButtonEnabled, searchEnabled, streamingEnabled, todoListToolEnabled, toolEnablement, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatMessageParsingWorker, useChatNetworkWorkerForRequests, useChatToolWorker, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadBackendAccessToken(), loadAuthEnabled(), loadBackendRefreshToken(), loadBackendUrl(), loadChatHistoryEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadReasoningPickerEnabled(), loadScrollDownButtonEnabled(), loadSearchEnabled(), loadStreamingEnabled(), loadTodoListToolEnabled(), loadToolEnablement(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatMessageParsingWorker(), loadUseChatNetworkWorkerForRequests(), loadUseChatToolWorker(), loadVoiceDictationEnabled()]);
|
|
10406
10732
|
return {
|
|
10407
10733
|
aiSessionTitleGenerationEnabled,
|
|
10408
10734
|
authAccessToken,
|
|
@@ -10416,6 +10742,7 @@ const loadPreferences = async () => {
|
|
|
10416
10742
|
openRouterApiKey,
|
|
10417
10743
|
passIncludeObfuscation,
|
|
10418
10744
|
reasoningPickerEnabled,
|
|
10745
|
+
scrollDownButtonEnabled,
|
|
10419
10746
|
searchEnabled,
|
|
10420
10747
|
streamingEnabled,
|
|
10421
10748
|
todoListToolEnabled,
|
|
@@ -10473,6 +10800,9 @@ const loadContent = async (state, savedState) => {
|
|
|
10473
10800
|
const savedSelectedModelId = getSavedSelectedModelId(savedState);
|
|
10474
10801
|
const savedViewMode = getSavedViewMode(savedState);
|
|
10475
10802
|
const savedComposerValue = getSavedComposerValue(savedState);
|
|
10803
|
+
const composerValue = savedComposerValue ?? state.composerValue;
|
|
10804
|
+
const savedComposerSelection = getSavedComposerSelection(savedState, composerValue);
|
|
10805
|
+
const [composerSelectionStart, composerSelectionEnd] = savedComposerSelection ?? [state.composerSelectionStart, state.composerSelectionEnd];
|
|
10476
10806
|
const {
|
|
10477
10807
|
aiSessionTitleGenerationEnabled,
|
|
10478
10808
|
authAccessToken,
|
|
@@ -10486,6 +10816,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10486
10816
|
openRouterApiKey,
|
|
10487
10817
|
passIncludeObfuscation,
|
|
10488
10818
|
reasoningPickerEnabled,
|
|
10819
|
+
scrollDownButtonEnabled,
|
|
10489
10820
|
searchEnabled,
|
|
10490
10821
|
streamingEnabled,
|
|
10491
10822
|
todoListToolEnabled,
|
|
@@ -10564,7 +10895,9 @@ const loadContent = async (state, savedState) => {
|
|
|
10564
10895
|
composerAttachmentsHeight: getComposerAttachmentsHeight(composerAttachments, state.width),
|
|
10565
10896
|
composerDropActive: false,
|
|
10566
10897
|
composerDropEnabled,
|
|
10567
|
-
|
|
10898
|
+
composerSelectionEnd,
|
|
10899
|
+
composerSelectionStart,
|
|
10900
|
+
composerValue,
|
|
10568
10901
|
emitStreamingFunctionCallEvents,
|
|
10569
10902
|
initial: false,
|
|
10570
10903
|
lastNormalViewMode,
|
|
@@ -10586,6 +10919,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10586
10919
|
reasoningEffortPickerOpen: false,
|
|
10587
10920
|
reasoningPickerEnabled,
|
|
10588
10921
|
runModePickerOpen: false,
|
|
10922
|
+
scrollDownButtonEnabled,
|
|
10589
10923
|
searchEnabled,
|
|
10590
10924
|
searchFieldVisible: false,
|
|
10591
10925
|
searchValue: '',
|
|
@@ -10643,7 +10977,7 @@ const mockOpenApiRequestGetAll = _state => {
|
|
|
10643
10977
|
};
|
|
10644
10978
|
|
|
10645
10979
|
const mockOpenApiRequestReset = state => {
|
|
10646
|
-
reset$
|
|
10980
|
+
reset$2();
|
|
10647
10981
|
return state;
|
|
10648
10982
|
};
|
|
10649
10983
|
|
|
@@ -10668,7 +11002,7 @@ const mockOpenApiStreamPushChunk = (state, chunk) => {
|
|
|
10668
11002
|
};
|
|
10669
11003
|
|
|
10670
11004
|
const mockOpenApiStreamReset = state => {
|
|
10671
|
-
reset$
|
|
11005
|
+
reset$1();
|
|
10672
11006
|
return state;
|
|
10673
11007
|
};
|
|
10674
11008
|
|
|
@@ -10716,7 +11050,7 @@ const pasteInput = async state => {
|
|
|
10716
11050
|
};
|
|
10717
11051
|
|
|
10718
11052
|
const registerMockResponse = (state, mockResponse) => {
|
|
10719
|
-
reset$
|
|
11053
|
+
reset$1();
|
|
10720
11054
|
pushChunk(mockResponse.text);
|
|
10721
11055
|
finish();
|
|
10722
11056
|
return state;
|
|
@@ -10824,6 +11158,43 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10824
11158
|
border-color: var(--vscode-charts-green, var(--vscode-widget-border, var(--vscode-panel-border)));
|
|
10825
11159
|
}
|
|
10826
11160
|
|
|
11161
|
+
.Chat{
|
|
11162
|
+
position: relative;
|
|
11163
|
+
}
|
|
11164
|
+
|
|
11165
|
+
.ChatComposerAttachmentPreviewOverlay{
|
|
11166
|
+
position: absolute;
|
|
11167
|
+
left: calc(var(--ChatSendAreaPaddingLeft) + 8px);
|
|
11168
|
+
bottom: calc(var(--ChatSendAreaHeight) - 12px);
|
|
11169
|
+
z-index: 6;
|
|
11170
|
+
width: 240px;
|
|
11171
|
+
min-width: 160px;
|
|
11172
|
+
min-height: 160px;
|
|
11173
|
+
max-width: calc(100% - var(--ChatSendAreaPaddingLeft) - var(--ChatSendAreaPaddingRight) - 16px);
|
|
11174
|
+
display: flex;
|
|
11175
|
+
align-items: center;
|
|
11176
|
+
justify-content: center;
|
|
11177
|
+
border: 1px solid var(--vscode-widget-border, var(--vscode-panel-border));
|
|
11178
|
+
border-radius: 12px;
|
|
11179
|
+
background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
|
|
11180
|
+
box-shadow: 0 12px 28px color-mix(in srgb, var(--vscode-editor-background) 45%, black);
|
|
11181
|
+
overflow: hidden;
|
|
11182
|
+
}
|
|
11183
|
+
|
|
11184
|
+
.ChatComposerAttachmentPreviewOverlayImage{
|
|
11185
|
+
display: block;
|
|
11186
|
+
width: 100%;
|
|
11187
|
+
max-width: 100%;
|
|
11188
|
+
max-height: min(320px, calc(100vh - 200px));
|
|
11189
|
+
object-fit: contain;
|
|
11190
|
+
background: color-mix(in srgb, var(--vscode-editor-background) 88%, black);
|
|
11191
|
+
}
|
|
11192
|
+
|
|
11193
|
+
.ChatComposerAttachmentPreviewOverlayError{
|
|
11194
|
+
padding: 12px;
|
|
11195
|
+
color: var(--vscode-errorForeground, var(--vscode-foreground));
|
|
11196
|
+
}
|
|
11197
|
+
|
|
10827
11198
|
.CustomSelectContainer{
|
|
10828
11199
|
position: relative;
|
|
10829
11200
|
min-width: 0;
|
|
@@ -10845,6 +11216,10 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10845
11216
|
pointer-events: auto;
|
|
10846
11217
|
}
|
|
10847
11218
|
|
|
11219
|
+
.ChatViewDropOverlayActive{
|
|
11220
|
+
background: rgba(255, 255, 255, 0.1);
|
|
11221
|
+
}
|
|
11222
|
+
|
|
10848
11223
|
.RunModePickerPopOver{
|
|
10849
11224
|
overflow: hidden;
|
|
10850
11225
|
border: 1px solid var(--vscode-widget-border, var(--vscode-panel-border));
|
|
@@ -10899,6 +11274,27 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10899
11274
|
min-width: 0;
|
|
10900
11275
|
}
|
|
10901
11276
|
|
|
11277
|
+
.ChatMessages > .Message{
|
|
11278
|
+
display: flex;
|
|
11279
|
+
}
|
|
11280
|
+
|
|
11281
|
+
.ChatMessages > .MessageUser{
|
|
11282
|
+
justify-content: flex-end;
|
|
11283
|
+
}
|
|
11284
|
+
|
|
11285
|
+
.ChatMessages > .MessageAssistant{
|
|
11286
|
+
justify-content: flex-start;
|
|
11287
|
+
}
|
|
11288
|
+
|
|
11289
|
+
.ChatFocus .ChatMessages > .Message{
|
|
11290
|
+
inline-size: fit-content;
|
|
11291
|
+
max-inline-size: min(100%, var(--ChatFocusContentMaxWidth));
|
|
11292
|
+
}
|
|
11293
|
+
|
|
11294
|
+
.ChatFocus .ChatMessages > .Message > .ChatMessageContent{
|
|
11295
|
+
max-inline-size: 100%;
|
|
11296
|
+
}
|
|
11297
|
+
|
|
10902
11298
|
`;
|
|
10903
11299
|
return `${baseCss}
|
|
10904
11300
|
|
|
@@ -10936,6 +11332,7 @@ const renderCss = (oldState, newState) => {
|
|
|
10936
11332
|
return [SetCss, uid, css];
|
|
10937
11333
|
};
|
|
10938
11334
|
|
|
11335
|
+
const pickerListSelector = '.ChatOverlays .ChatModelPickerList';
|
|
10939
11336
|
const getFocusSelector = state => {
|
|
10940
11337
|
const {
|
|
10941
11338
|
focus,
|
|
@@ -10961,6 +11358,8 @@ const getFocusSelector = state => {
|
|
|
10961
11358
|
}
|
|
10962
11359
|
case 'model-picker-input':
|
|
10963
11360
|
return `[name="${ModelPickerSearch}"]`;
|
|
11361
|
+
case 'picker-list':
|
|
11362
|
+
return pickerListSelector;
|
|
10964
11363
|
case 'send-button':
|
|
10965
11364
|
return '[name="send"]';
|
|
10966
11365
|
default:
|
|
@@ -10971,6 +11370,9 @@ const renderFocus = (oldState, newState) => {
|
|
|
10971
11370
|
if (newState.modelPickerOpen && !oldState.modelPickerOpen) {
|
|
10972
11371
|
return [FocusSelector, `[name="${ModelPickerSearch}"]`];
|
|
10973
11372
|
}
|
|
11373
|
+
if (newState.agentModePickerOpen && !oldState.agentModePickerOpen || newState.runModePickerOpen && !oldState.runModePickerOpen || newState.reasoningEffortPickerOpen && !oldState.reasoningEffortPickerOpen) {
|
|
11374
|
+
return [FocusSelector, pickerListSelector];
|
|
11375
|
+
}
|
|
10974
11376
|
const selector = getFocusSelector(newState);
|
|
10975
11377
|
return [FocusSelector, selector];
|
|
10976
11378
|
};
|
|
@@ -10988,6 +11390,8 @@ const renderFocusContext = (oldState, newState) => {
|
|
|
10988
11390
|
const HandleListContextMenu = 2;
|
|
10989
11391
|
const HandleFocus = 3;
|
|
10990
11392
|
const HandleInput = 4;
|
|
11393
|
+
const HandleMouseOut = 5;
|
|
11394
|
+
const HandleMouseOver = 7;
|
|
10991
11395
|
const HandleClick = 11;
|
|
10992
11396
|
const HandleKeyDown = 12;
|
|
10993
11397
|
const HandleClickClose = 13;
|
|
@@ -11035,6 +11439,7 @@ const HandlePointerUpModelPickerList = 55;
|
|
|
11035
11439
|
const HandleClickReasoningEffortPickerToggle = 56;
|
|
11036
11440
|
const HandleClickAgentModePickerToggle = 57;
|
|
11037
11441
|
const HandleContextMenuChatImageAttachment = 58;
|
|
11442
|
+
const HandleErrorComposerAttachmentPreviewOverlay = 59;
|
|
11038
11443
|
|
|
11039
11444
|
const getAddContextButtonDom = () => {
|
|
11040
11445
|
return [{
|
|
@@ -11151,6 +11556,8 @@ const getReasoningEffortPickerVirtualDom = (selectedReasoningEffort, reasoningEf
|
|
|
11151
11556
|
}, {
|
|
11152
11557
|
childCount: reasoningEfforts.length,
|
|
11153
11558
|
className: ChatModelPickerList,
|
|
11559
|
+
name: PickerList,
|
|
11560
|
+
tabIndex: -1,
|
|
11154
11561
|
type: Ul
|
|
11155
11562
|
}, ...getReasoningEffortOptionsVirtualDom(selectedReasoningEffort)] : [])];
|
|
11156
11563
|
};
|
|
@@ -11159,6 +11566,21 @@ const getRunModePickerVirtualDom = (selectedRunMode, runModePickerOpen) => {
|
|
|
11159
11566
|
return getCustomSelectPickerToggleVirtualDom(selectedRunMode, RunModePickerToggle, runModePickerOpen, HandleClickRunModePickerToggle);
|
|
11160
11567
|
};
|
|
11161
11568
|
|
|
11569
|
+
const getScrollDownButtonDom = () => {
|
|
11570
|
+
return [{
|
|
11571
|
+
childCount: 1,
|
|
11572
|
+
className: mergeClassNames(Button, ButtonSecondary),
|
|
11573
|
+
inputType: 'button',
|
|
11574
|
+
name: ScrollDown,
|
|
11575
|
+
onClick: HandleClick,
|
|
11576
|
+
title: scrollDown(),
|
|
11577
|
+
type: Button$1
|
|
11578
|
+
}, {
|
|
11579
|
+
text: scrollDown(),
|
|
11580
|
+
type: Text
|
|
11581
|
+
}];
|
|
11582
|
+
};
|
|
11583
|
+
|
|
11162
11584
|
const getSendButtonClassName = isSendDisabled => {
|
|
11163
11585
|
return mergeClassNames(IconButton, isSendDisabled ? SendButtonDisabled : '');
|
|
11164
11586
|
};
|
|
@@ -11334,10 +11756,15 @@ const getComposerAttachmentsDom = composerAttachments => {
|
|
|
11334
11756
|
childCount: 1 + (removeButtonDom.length > 0 ? 1 : 0) + previewDom.length,
|
|
11335
11757
|
className: mergeClassNames(ChatComposerAttachment, getComposerAttachmentClassName(attachment.displayType)),
|
|
11336
11758
|
name: getComposerAttachmentInputName(attachment.attachmentId),
|
|
11759
|
+
onMouseOut: HandleMouseOut,
|
|
11760
|
+
onMouseOver: HandleMouseOver,
|
|
11761
|
+
onPointerOut: HandleMouseOut,
|
|
11762
|
+
onPointerOver: HandleMouseOver,
|
|
11337
11763
|
type: Div
|
|
11338
11764
|
}, ...removeButtonDom, ...previewDom, {
|
|
11339
11765
|
childCount: 1,
|
|
11340
11766
|
className: ChatComposerAttachmentLabel,
|
|
11767
|
+
name: getComposerAttachmentInputName(attachment.attachmentId),
|
|
11341
11768
|
type: Span
|
|
11342
11769
|
}, {
|
|
11343
11770
|
text: `${getComposerAttachmentLabel(attachment.displayType)} · ${attachment.name}`,
|
|
@@ -11359,11 +11786,12 @@ const getComposerTextAreaDom = () => {
|
|
|
11359
11786
|
type: TextArea
|
|
11360
11787
|
};
|
|
11361
11788
|
};
|
|
11362
|
-
const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton = false, voiceDictationEnabled = false) => {
|
|
11789
|
+
const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton = false, voiceDictationEnabled = false, scrollDownButtonEnabled = false, messagesAutoScrollEnabled = true) => {
|
|
11363
11790
|
const isSendDisabled = composerValue.trim() === '';
|
|
11364
11791
|
const showAgentModePicker = hasSpaceForAgentModePicker;
|
|
11365
11792
|
const showResponsiveRunModePicker = showRunMode && hasSpaceForRunModePicker;
|
|
11366
|
-
const
|
|
11793
|
+
const showScrollDownButton = scrollDownButtonEnabled && !messagesAutoScrollEnabled;
|
|
11794
|
+
const bottomControlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (addContextButtonEnabled ? 1 : 0) + (showCreatePullRequestButton ? 1 : 0) + (voiceDictationEnabled ? 1 : 0) + (showScrollDownButton ? 1 : 0);
|
|
11367
11795
|
const primaryControlsCount = 1 + (showAgentModePicker ? 1 : 0) + (reasoningPickerEnabled ? 1 : 0) + (showResponsiveRunModePicker ? 1 : 0);
|
|
11368
11796
|
const hasTodoList = todoListToolEnabled && todoListItems.length > 0;
|
|
11369
11797
|
const hasComposerAttachments = composerAttachments.length > 0;
|
|
@@ -11387,7 +11815,58 @@ const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agent
|
|
|
11387
11815
|
className: ChatSendAreaPrimaryControls,
|
|
11388
11816
|
role: 'toolbar',
|
|
11389
11817
|
type: Div
|
|
11390
|
-
}, ...(showAgentModePicker ? getAgentModePickerVirtualDom(agentMode, agentModePickerOpen) : []), ...getChatModelPickerToggleVirtualDom(models, selectedModelId, modelPickerOpen), ...(reasoningPickerEnabled ? getReasoningEffortPickerVirtualDom(reasoningEffort, reasoningEffortPickerOpen) : []), ...(showResponsiveRunModePicker ? getRunModePickerVirtualDom(runMode, runModePickerOpen) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...(showCreatePullRequestButton ? getCreatePullRequestButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
11818
|
+
}, ...(showAgentModePicker ? getAgentModePickerVirtualDom(agentMode, agentModePickerOpen) : []), ...getChatModelPickerToggleVirtualDom(models, selectedModelId, modelPickerOpen), ...(reasoningPickerEnabled ? getReasoningEffortPickerVirtualDom(reasoningEffort, reasoningEffortPickerOpen) : []), ...(showResponsiveRunModePicker ? getRunModePickerVirtualDom(runMode, runModePickerOpen) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...(showCreatePullRequestButton ? getCreatePullRequestButtonDom() : []), ...(showScrollDownButton ? getScrollDownButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
11819
|
+
};
|
|
11820
|
+
|
|
11821
|
+
const focusHeaderStyle = 'align-items:center;border-bottom:1px solid var(--vscode-panel-border, transparent);display:flex;gap:12px;justify-content:space-between;padding:8px 12px;';
|
|
11822
|
+
const focusHeaderMetaStyle = 'align-items:baseline;display:flex;gap:8px;min-width:0;overflow:hidden;';
|
|
11823
|
+
const focusHeaderTitleStyle = 'margin:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
11824
|
+
const focusHeaderProjectStyle = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';
|
|
11825
|
+
const focusHeaderActionsStyle = 'display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;';
|
|
11826
|
+
const focusHeaderButtonStyle = 'white-space:nowrap;';
|
|
11827
|
+
const getFocusHeaderActionButtonDom = (label, name) => {
|
|
11828
|
+
return [{
|
|
11829
|
+
childCount: 1,
|
|
11830
|
+
className: mergeClassNames(Button, ButtonSecondary),
|
|
11831
|
+
inputType: 'button',
|
|
11832
|
+
name,
|
|
11833
|
+
onClick: HandleClick,
|
|
11834
|
+
style: focusHeaderButtonStyle,
|
|
11835
|
+
title: label,
|
|
11836
|
+
type: Button$1
|
|
11837
|
+
}, text(label)];
|
|
11838
|
+
};
|
|
11839
|
+
const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName) => {
|
|
11840
|
+
const items = [[addAction(), FocusAddAction], [openInVsCode(), FocusOpenInVsCode], [commit(), FocusCommit], [openTerminal(), FocusOpenTerminal], [showDiff(), FocusShowDiff]];
|
|
11841
|
+
const hasProjectName = !!selectedProjectName;
|
|
11842
|
+
return [{
|
|
11843
|
+
childCount: 2,
|
|
11844
|
+
className: ChatFocusHeader,
|
|
11845
|
+
style: focusHeaderStyle,
|
|
11846
|
+
type: Header
|
|
11847
|
+
}, {
|
|
11848
|
+
childCount: hasProjectName ? 2 : 1,
|
|
11849
|
+
className: ChatName,
|
|
11850
|
+
style: focusHeaderMetaStyle,
|
|
11851
|
+
type: Div
|
|
11852
|
+
}, {
|
|
11853
|
+
childCount: 1,
|
|
11854
|
+
className: ChatHeaderLabel,
|
|
11855
|
+
style: focusHeaderTitleStyle,
|
|
11856
|
+
type: H2
|
|
11857
|
+
}, text(selectedSessionTitle), ...(hasProjectName ? [{
|
|
11858
|
+
childCount: 1,
|
|
11859
|
+
className: mergeClassNames(LabelDetail, ChatFocusProject),
|
|
11860
|
+
style: focusHeaderProjectStyle,
|
|
11861
|
+
type: Span
|
|
11862
|
+
}, text(selectedProjectName)] : []), {
|
|
11863
|
+
'aria-label': 'focus header actions',
|
|
11864
|
+
childCount: items.length,
|
|
11865
|
+
className: ChatFocusActions,
|
|
11866
|
+
role: ToolBar,
|
|
11867
|
+
style: focusHeaderActionsStyle,
|
|
11868
|
+
type: Div
|
|
11869
|
+
}, ...items.flatMap(([label, name]) => getFocusHeaderActionButtonDom(label, name))];
|
|
11391
11870
|
};
|
|
11392
11871
|
|
|
11393
11872
|
const getCustomSelectPopOverVirtualDom = (optionCount, height, optionNodes, containerClassName = '', popOverClassName = '') => {
|
|
@@ -11403,6 +11882,8 @@ const getCustomSelectPopOverVirtualDom = (optionCount, height, optionNodes, cont
|
|
|
11403
11882
|
}, {
|
|
11404
11883
|
childCount: optionCount,
|
|
11405
11884
|
className: ChatModelPickerList,
|
|
11885
|
+
name: PickerList,
|
|
11886
|
+
tabIndex: -1,
|
|
11406
11887
|
type: Ul
|
|
11407
11888
|
}, ...optionNodes];
|
|
11408
11889
|
};
|
|
@@ -11481,6 +11962,42 @@ const getChatModelPickerPopOverVirtualDom = (models, selectedModelId, modelPicke
|
|
|
11481
11962
|
}, ...getModelPickerHeaderDom(modelPickerSearchValue), ...getChatModelListVirtualDom(visibleModels, selectedModelId)];
|
|
11482
11963
|
};
|
|
11483
11964
|
|
|
11965
|
+
const getComposerAttachmentPreviewOverlayVirtualDom = (composerAttachments, attachmentId, hasError) => {
|
|
11966
|
+
if (!attachmentId) {
|
|
11967
|
+
return [];
|
|
11968
|
+
}
|
|
11969
|
+
const attachment = composerAttachments.find(item => item.attachmentId === attachmentId);
|
|
11970
|
+
if (!attachment || attachment.displayType !== 'image' || !attachment.previewSrc) {
|
|
11971
|
+
return [];
|
|
11972
|
+
}
|
|
11973
|
+
return [{
|
|
11974
|
+
childCount: 1,
|
|
11975
|
+
className: ChatComposerAttachmentPreviewOverlay,
|
|
11976
|
+
name: ComposerAttachmentPreviewOverlay,
|
|
11977
|
+
onMouseOut: HandleMouseOut,
|
|
11978
|
+
onMouseOver: HandleMouseOver,
|
|
11979
|
+
onPointerOut: HandleMouseOut,
|
|
11980
|
+
onPointerOver: HandleMouseOver,
|
|
11981
|
+
type: Div
|
|
11982
|
+
}, ...(hasError ? [{
|
|
11983
|
+
childCount: 1,
|
|
11984
|
+
className: mergeClassNames(ChatComposerAttachmentPreviewOverlayError, ImageErrorMessage),
|
|
11985
|
+
name: ComposerAttachmentPreviewOverlay,
|
|
11986
|
+
type: Div
|
|
11987
|
+
}, {
|
|
11988
|
+
text: imageCouldNotBeLoaded(),
|
|
11989
|
+
type: Text
|
|
11990
|
+
}] : [{
|
|
11991
|
+
alt: `Large image preview for ${attachment.name}`,
|
|
11992
|
+
childCount: 0,
|
|
11993
|
+
className: ChatComposerAttachmentPreviewOverlayImage,
|
|
11994
|
+
name: ComposerAttachmentPreviewOverlay,
|
|
11995
|
+
onError: HandleErrorComposerAttachmentPreviewOverlay,
|
|
11996
|
+
src: attachment.previewSrc,
|
|
11997
|
+
type: Img
|
|
11998
|
+
}])];
|
|
11999
|
+
};
|
|
12000
|
+
|
|
11484
12001
|
const runModes = ['local', 'background', 'cloud'];
|
|
11485
12002
|
const runModePickerHeight = runModes.length * 28;
|
|
11486
12003
|
const getRunModeOptionsVirtualDom = selectedRunMode => {
|
|
@@ -11507,6 +12024,10 @@ const getDropOverlayVirtualDom = () => {
|
|
|
11507
12024
|
const getChatOverlaysVirtualDom = ({
|
|
11508
12025
|
agentMode,
|
|
11509
12026
|
agentModePickerVisible,
|
|
12027
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
12028
|
+
composerAttachmentPreviewOverlayError,
|
|
12029
|
+
composerAttachmentPreviewOverlayVisible,
|
|
12030
|
+
composerAttachments,
|
|
11510
12031
|
dropOverlayVisible,
|
|
11511
12032
|
modelPickerSearchValue,
|
|
11512
12033
|
modelPickerVisible,
|
|
@@ -11515,7 +12036,7 @@ const getChatOverlaysVirtualDom = ({
|
|
|
11515
12036
|
selectedModelId,
|
|
11516
12037
|
visibleModels
|
|
11517
12038
|
}) => {
|
|
11518
|
-
const overlayChildCount = (dropOverlayVisible ? 1 : 0) + (agentModePickerVisible ? 1 : 0) + (modelPickerVisible ? 1 : 0) + (runModePickerVisible ? 1 : 0);
|
|
12039
|
+
const overlayChildCount = (dropOverlayVisible ? 1 : 0) + (composerAttachmentPreviewOverlayVisible ? 1 : 0) + (agentModePickerVisible ? 1 : 0) + (modelPickerVisible ? 1 : 0) + (runModePickerVisible ? 1 : 0);
|
|
11519
12040
|
if (!overlayChildCount) {
|
|
11520
12041
|
return [];
|
|
11521
12042
|
}
|
|
@@ -11523,7 +12044,7 @@ const getChatOverlaysVirtualDom = ({
|
|
|
11523
12044
|
childCount: overlayChildCount,
|
|
11524
12045
|
className: ChatOverlays,
|
|
11525
12046
|
type: Div
|
|
11526
|
-
}, ...(dropOverlayVisible ? getDropOverlayVirtualDom() : []), ...(agentModePickerVisible ? getAgentModePickerPopOverVirtualDom(agentMode) : []), ...(modelPickerVisible ? getChatModelPickerPopOverVirtualDom(visibleModels, selectedModelId, modelPickerSearchValue) : []), ...(runModePickerVisible ? getRunModePickerPopOverVirtualDom(runMode) : [])];
|
|
12047
|
+
}, ...(dropOverlayVisible ? getDropOverlayVirtualDom() : []), ...getComposerAttachmentPreviewOverlayVirtualDom(composerAttachments, composerAttachmentPreviewOverlayAttachmentId, composerAttachmentPreviewOverlayError), ...(agentModePickerVisible ? getAgentModePickerPopOverVirtualDom(agentMode) : []), ...(modelPickerVisible ? getChatModelPickerPopOverVirtualDom(visibleModels, selectedModelId, modelPickerSearchValue) : []), ...(runModePickerVisible ? getRunModePickerPopOverVirtualDom(runMode) : [])];
|
|
11527
12048
|
};
|
|
11528
12049
|
|
|
11529
12050
|
const getBoldInlineNodeDom = (inlineNode, useChatMathWorker, renderInlineNodeDom) => {
|
|
@@ -12963,19 +13484,20 @@ const getMessagesDom = (messages, parsedMessages, openRouterApiKeyInput, openApi
|
|
|
12963
13484
|
}, ...displayMessages.flatMap(item => getChatMessageDom(item.message, item.parsedContent, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, useChatMathWorker))];
|
|
12964
13485
|
};
|
|
12965
13486
|
|
|
13487
|
+
const arrowLeft$1 = {
|
|
13488
|
+
childCount: 0,
|
|
13489
|
+
className: mergeClassNames(MaskIcon, MaskIconArrowLeft),
|
|
13490
|
+
type: Div
|
|
13491
|
+
};
|
|
12966
13492
|
const getBackToChatsButtonDom = () => {
|
|
12967
13493
|
return [{
|
|
12968
13494
|
childCount: 1,
|
|
12969
|
-
className:
|
|
12970
|
-
inputType: 'button',
|
|
13495
|
+
className: IconButton,
|
|
12971
13496
|
name: Back,
|
|
12972
13497
|
onClick: HandleClickBack,
|
|
12973
13498
|
title: backToChatList(),
|
|
12974
13499
|
type: Button$1
|
|
12975
|
-
},
|
|
12976
|
-
text: backToChatList(),
|
|
12977
|
-
type: Text
|
|
12978
|
-
}];
|
|
13500
|
+
}, arrowLeft$1];
|
|
12979
13501
|
};
|
|
12980
13502
|
|
|
12981
13503
|
const getProjectSessionDom = (session, selectedSessionId) => {
|
|
@@ -13074,6 +13596,8 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13074
13596
|
authEnabled = false,
|
|
13075
13597
|
authErrorMessage = '',
|
|
13076
13598
|
authStatus = 'signed-out',
|
|
13599
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
13600
|
+
composerAttachmentPreviewOverlayError = false,
|
|
13077
13601
|
composerAttachments,
|
|
13078
13602
|
composerDropActive = false,
|
|
13079
13603
|
composerDropEnabled = true,
|
|
@@ -13084,6 +13608,7 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13084
13608
|
composerValue,
|
|
13085
13609
|
hasSpaceForAgentModePicker,
|
|
13086
13610
|
hasSpaceForRunModePicker,
|
|
13611
|
+
messagesAutoScrollEnabled,
|
|
13087
13612
|
messagesScrollTop = 0,
|
|
13088
13613
|
modelPickerOpen = false,
|
|
13089
13614
|
modelPickerSearchValue = '',
|
|
@@ -13103,6 +13628,7 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13103
13628
|
reasoningPickerEnabled,
|
|
13104
13629
|
runMode,
|
|
13105
13630
|
runModePickerOpen = false,
|
|
13631
|
+
scrollDownButtonEnabled,
|
|
13106
13632
|
selectedModelId,
|
|
13107
13633
|
selectedProjectId = '',
|
|
13108
13634
|
selectedSessionId,
|
|
@@ -13118,23 +13644,31 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13118
13644
|
voiceDictationEnabled = false
|
|
13119
13645
|
}) => {
|
|
13120
13646
|
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
13647
|
+
const selectedProject = projects.find(project => project.id === selectedProjectId);
|
|
13121
13648
|
const messages = selectedSession ? selectedSession.messages : [];
|
|
13649
|
+
const selectedSessionTitle = selectedSession?.title || chatTitle();
|
|
13650
|
+
const selectedProjectName = selectedProject?.name || '';
|
|
13122
13651
|
const showCreatePullRequestButton = canCreatePullRequest(selectedSession);
|
|
13123
13652
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
13653
|
+
const isComposerAttachmentPreviewOverlayVisible = !!composerAttachmentPreviewOverlayAttachmentId;
|
|
13124
13654
|
const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
|
|
13125
13655
|
const isNewModelPickerVisible = modelPickerOpen;
|
|
13126
13656
|
const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
|
|
13127
|
-
const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13128
|
-
const chatRootChildCount =
|
|
13657
|
+
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13658
|
+
const chatRootChildCount = 4 + (hasVisibleOverlays ? 1 : 0);
|
|
13129
13659
|
return [{
|
|
13130
13660
|
childCount: chatRootChildCount,
|
|
13131
13661
|
className: mergeClassNames(Viewlet, Chat, ChatFocus),
|
|
13132
13662
|
onDragEnter: HandleDragEnterChatView,
|
|
13133
13663
|
onDragOver: HandleDragOverChatView,
|
|
13134
13664
|
type: Div
|
|
13135
|
-
}, ...
|
|
13665
|
+
}, ...getChatHeaderDomFocusMode(selectedSessionTitle, selectedProjectName), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop, true), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled, scrollDownButtonEnabled, messagesAutoScrollEnabled), ...getChatOverlaysVirtualDom({
|
|
13136
13666
|
agentMode,
|
|
13137
13667
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
13668
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
13669
|
+
composerAttachmentPreviewOverlayError,
|
|
13670
|
+
composerAttachmentPreviewOverlayVisible: isComposerAttachmentPreviewOverlayVisible,
|
|
13671
|
+
composerAttachments,
|
|
13138
13672
|
dropOverlayVisible: isDropOverlayVisible,
|
|
13139
13673
|
modelPickerSearchValue,
|
|
13140
13674
|
modelPickerVisible: isNewModelPickerVisible,
|
|
@@ -13272,6 +13806,8 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13272
13806
|
authEnabled = false,
|
|
13273
13807
|
authErrorMessage = '',
|
|
13274
13808
|
authStatus = 'signed-out',
|
|
13809
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
13810
|
+
composerAttachmentPreviewOverlayError = false,
|
|
13275
13811
|
composerAttachments,
|
|
13276
13812
|
composerDropActive = false,
|
|
13277
13813
|
composerDropEnabled = true,
|
|
@@ -13282,6 +13818,7 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13282
13818
|
composerValue,
|
|
13283
13819
|
hasSpaceForAgentModePicker,
|
|
13284
13820
|
hasSpaceForRunModePicker,
|
|
13821
|
+
messagesAutoScrollEnabled,
|
|
13285
13822
|
messagesScrollTop = 0,
|
|
13286
13823
|
modelPickerOpen = false,
|
|
13287
13824
|
modelPickerSearchValue = '',
|
|
@@ -13298,6 +13835,7 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13298
13835
|
reasoningPickerEnabled,
|
|
13299
13836
|
runMode,
|
|
13300
13837
|
runModePickerOpen = false,
|
|
13838
|
+
scrollDownButtonEnabled,
|
|
13301
13839
|
selectedModelId,
|
|
13302
13840
|
selectedSessionId,
|
|
13303
13841
|
sessions,
|
|
@@ -13316,10 +13854,11 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13316
13854
|
const messages = selectedSession ? selectedSession.messages : [];
|
|
13317
13855
|
const showCreatePullRequestButton = canCreatePullRequest(selectedSession);
|
|
13318
13856
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
13857
|
+
const isComposerAttachmentPreviewOverlayVisible = !!composerAttachmentPreviewOverlayAttachmentId;
|
|
13319
13858
|
const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
|
|
13320
13859
|
const isNewModelPickerVisible = modelPickerOpen;
|
|
13321
13860
|
const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
|
|
13322
|
-
const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13861
|
+
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13323
13862
|
const chatRootChildCount = 3 + (hasVisibleOverlays ? 1 : 0);
|
|
13324
13863
|
return [{
|
|
13325
13864
|
childCount: chatRootChildCount,
|
|
@@ -13327,9 +13866,13 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13327
13866
|
onDragEnter: HandleDragEnterChatView,
|
|
13328
13867
|
onDragOver: HandleDragOverChatView,
|
|
13329
13868
|
type: Div
|
|
13330
|
-
}, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, authStatus, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled), ...getChatOverlaysVirtualDom({
|
|
13869
|
+
}, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, authStatus, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled, scrollDownButtonEnabled, messagesAutoScrollEnabled), ...getChatOverlaysVirtualDom({
|
|
13331
13870
|
agentMode,
|
|
13332
13871
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
13872
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
13873
|
+
composerAttachmentPreviewOverlayError,
|
|
13874
|
+
composerAttachmentPreviewOverlayVisible: isComposerAttachmentPreviewOverlayVisible,
|
|
13875
|
+
composerAttachments,
|
|
13333
13876
|
dropOverlayVisible: isDropOverlayVisible,
|
|
13334
13877
|
modelPickerSearchValue,
|
|
13335
13878
|
modelPickerVisible: isNewModelPickerVisible,
|
|
@@ -13474,6 +14017,8 @@ const getChatModeListVirtualDom = ({
|
|
|
13474
14017
|
authErrorMessage = '',
|
|
13475
14018
|
authStatus = 'signed-out',
|
|
13476
14019
|
chatListScrollTop = 0,
|
|
14020
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14021
|
+
composerAttachmentPreviewOverlayError = false,
|
|
13477
14022
|
composerAttachments,
|
|
13478
14023
|
composerDropActive = false,
|
|
13479
14024
|
composerDropEnabled = true,
|
|
@@ -13509,10 +14054,11 @@ const getChatModeListVirtualDom = ({
|
|
|
13509
14054
|
voiceDictationEnabled = false
|
|
13510
14055
|
}) => {
|
|
13511
14056
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
14057
|
+
const isComposerAttachmentPreviewOverlayVisible = !!composerAttachmentPreviewOverlayAttachmentId;
|
|
13512
14058
|
const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
|
|
13513
14059
|
const isNewModelPickerVisible = modelPickerOpen;
|
|
13514
14060
|
const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
|
|
13515
|
-
const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
14061
|
+
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13516
14062
|
const chatRootChildCount = 3 + (hasVisibleOverlays ? 1 : 0);
|
|
13517
14063
|
const searchValueTrimmed = searchValue.trim().toLowerCase();
|
|
13518
14064
|
const visibleSessions = searchEnabled && searchValueTrimmed ? sessions.filter(session => session.title.toLowerCase().includes(searchValueTrimmed)) : sessions;
|
|
@@ -13525,6 +14071,10 @@ const getChatModeListVirtualDom = ({
|
|
|
13525
14071
|
}, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, listFocusedIndex, chatListScrollTop), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, false, voiceDictationEnabled), ...getChatOverlaysVirtualDom({
|
|
13526
14072
|
agentMode,
|
|
13527
14073
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
14074
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14075
|
+
composerAttachmentPreviewOverlayError,
|
|
14076
|
+
composerAttachmentPreviewOverlayVisible: isComposerAttachmentPreviewOverlayVisible,
|
|
14077
|
+
composerAttachments,
|
|
13528
14078
|
dropOverlayVisible: isDropOverlayVisible,
|
|
13529
14079
|
modelPickerSearchValue,
|
|
13530
14080
|
modelPickerVisible: isNewModelPickerVisible,
|
|
@@ -13623,6 +14173,8 @@ const getChatVirtualDom = options => {
|
|
|
13623
14173
|
authErrorMessage = '',
|
|
13624
14174
|
authStatus = 'signed-out',
|
|
13625
14175
|
chatListScrollTop,
|
|
14176
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14177
|
+
composerAttachmentPreviewOverlayError = false,
|
|
13626
14178
|
composerAttachments,
|
|
13627
14179
|
composerDropActive = false,
|
|
13628
14180
|
composerDropEnabled = true,
|
|
@@ -13634,6 +14186,7 @@ const getChatVirtualDom = options => {
|
|
|
13634
14186
|
hasSpaceForAgentModePicker,
|
|
13635
14187
|
hasSpaceForRunModePicker,
|
|
13636
14188
|
listFocusedIndex = -1,
|
|
14189
|
+
messagesAutoScrollEnabled,
|
|
13637
14190
|
messagesScrollTop,
|
|
13638
14191
|
modelPickerOpen = false,
|
|
13639
14192
|
modelPickerSearchValue = '',
|
|
@@ -13653,6 +14206,7 @@ const getChatVirtualDom = options => {
|
|
|
13653
14206
|
reasoningPickerEnabled,
|
|
13654
14207
|
runMode,
|
|
13655
14208
|
runModePickerOpen = false,
|
|
14209
|
+
scrollDownButtonEnabled,
|
|
13656
14210
|
searchEnabled = false,
|
|
13657
14211
|
searchFieldVisible = false,
|
|
13658
14212
|
searchValue = '',
|
|
@@ -13681,6 +14235,8 @@ const getChatVirtualDom = options => {
|
|
|
13681
14235
|
authEnabled,
|
|
13682
14236
|
authErrorMessage,
|
|
13683
14237
|
authStatus,
|
|
14238
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14239
|
+
composerAttachmentPreviewOverlayError,
|
|
13684
14240
|
composerAttachments,
|
|
13685
14241
|
composerDropActive,
|
|
13686
14242
|
composerDropEnabled,
|
|
@@ -13691,6 +14247,7 @@ const getChatVirtualDom = options => {
|
|
|
13691
14247
|
composerValue,
|
|
13692
14248
|
hasSpaceForAgentModePicker,
|
|
13693
14249
|
hasSpaceForRunModePicker,
|
|
14250
|
+
messagesAutoScrollEnabled,
|
|
13694
14251
|
messagesScrollTop,
|
|
13695
14252
|
modelPickerOpen,
|
|
13696
14253
|
modelPickerSearchValue,
|
|
@@ -13710,6 +14267,7 @@ const getChatVirtualDom = options => {
|
|
|
13710
14267
|
reasoningPickerEnabled,
|
|
13711
14268
|
runMode,
|
|
13712
14269
|
runModePickerOpen,
|
|
14270
|
+
scrollDownButtonEnabled,
|
|
13713
14271
|
selectedModelId,
|
|
13714
14272
|
selectedProjectId,
|
|
13715
14273
|
selectedSessionId,
|
|
@@ -13732,6 +14290,8 @@ const getChatVirtualDom = options => {
|
|
|
13732
14290
|
authEnabled,
|
|
13733
14291
|
authErrorMessage,
|
|
13734
14292
|
authStatus,
|
|
14293
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14294
|
+
composerAttachmentPreviewOverlayError,
|
|
13735
14295
|
composerAttachments,
|
|
13736
14296
|
composerDropActive,
|
|
13737
14297
|
composerDropEnabled,
|
|
@@ -13742,6 +14302,7 @@ const getChatVirtualDom = options => {
|
|
|
13742
14302
|
composerValue,
|
|
13743
14303
|
hasSpaceForAgentModePicker,
|
|
13744
14304
|
hasSpaceForRunModePicker,
|
|
14305
|
+
messagesAutoScrollEnabled,
|
|
13745
14306
|
messagesScrollTop,
|
|
13746
14307
|
modelPickerOpen,
|
|
13747
14308
|
modelPickerSearchValue,
|
|
@@ -13758,6 +14319,7 @@ const getChatVirtualDom = options => {
|
|
|
13758
14319
|
reasoningPickerEnabled,
|
|
13759
14320
|
runMode,
|
|
13760
14321
|
runModePickerOpen,
|
|
14322
|
+
scrollDownButtonEnabled,
|
|
13761
14323
|
selectedModelId,
|
|
13762
14324
|
selectedSessionId,
|
|
13763
14325
|
sessions,
|
|
@@ -13780,6 +14342,8 @@ const getChatVirtualDom = options => {
|
|
|
13780
14342
|
authErrorMessage,
|
|
13781
14343
|
authStatus,
|
|
13782
14344
|
chatListScrollTop,
|
|
14345
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14346
|
+
composerAttachmentPreviewOverlayError,
|
|
13783
14347
|
composerAttachments,
|
|
13784
14348
|
composerDropActive,
|
|
13785
14349
|
composerDropEnabled,
|
|
@@ -13828,6 +14392,8 @@ const renderItems = (oldState, newState) => {
|
|
|
13828
14392
|
authErrorMessage,
|
|
13829
14393
|
authStatus,
|
|
13830
14394
|
chatListScrollTop,
|
|
14395
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14396
|
+
composerAttachmentPreviewOverlayError,
|
|
13831
14397
|
composerAttachments,
|
|
13832
14398
|
composerDropActive,
|
|
13833
14399
|
composerDropEnabled,
|
|
@@ -13840,6 +14406,7 @@ const renderItems = (oldState, newState) => {
|
|
|
13840
14406
|
hasSpaceForRunModePicker,
|
|
13841
14407
|
initial,
|
|
13842
14408
|
listFocusedIndex,
|
|
14409
|
+
messagesAutoScrollEnabled,
|
|
13843
14410
|
messagesScrollTop,
|
|
13844
14411
|
modelPickerOpen,
|
|
13845
14412
|
modelPickerSearchValue,
|
|
@@ -13859,6 +14426,7 @@ const renderItems = (oldState, newState) => {
|
|
|
13859
14426
|
reasoningPickerEnabled,
|
|
13860
14427
|
runMode,
|
|
13861
14428
|
runModePickerOpen,
|
|
14429
|
+
scrollDownButtonEnabled,
|
|
13862
14430
|
searchEnabled,
|
|
13863
14431
|
searchFieldVisible,
|
|
13864
14432
|
searchValue,
|
|
@@ -13888,6 +14456,8 @@ const renderItems = (oldState, newState) => {
|
|
|
13888
14456
|
authErrorMessage,
|
|
13889
14457
|
authStatus,
|
|
13890
14458
|
chatListScrollTop,
|
|
14459
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14460
|
+
composerAttachmentPreviewOverlayError,
|
|
13891
14461
|
composerAttachments,
|
|
13892
14462
|
composerDropActive,
|
|
13893
14463
|
composerDropEnabled,
|
|
@@ -13899,6 +14469,7 @@ const renderItems = (oldState, newState) => {
|
|
|
13899
14469
|
hasSpaceForAgentModePicker,
|
|
13900
14470
|
hasSpaceForRunModePicker,
|
|
13901
14471
|
listFocusedIndex,
|
|
14472
|
+
messagesAutoScrollEnabled,
|
|
13902
14473
|
messagesScrollTop,
|
|
13903
14474
|
modelPickerOpen,
|
|
13904
14475
|
modelPickerSearchValue,
|
|
@@ -13918,6 +14489,7 @@ const renderItems = (oldState, newState) => {
|
|
|
13918
14489
|
reasoningPickerEnabled,
|
|
13919
14490
|
runMode,
|
|
13920
14491
|
runModePickerOpen,
|
|
14492
|
+
scrollDownButtonEnabled,
|
|
13921
14493
|
searchEnabled,
|
|
13922
14494
|
searchFieldVisible,
|
|
13923
14495
|
searchValue,
|
|
@@ -14036,6 +14608,12 @@ const renderEventListeners = () => {
|
|
|
14036
14608
|
}, {
|
|
14037
14609
|
name: HandleClick,
|
|
14038
14610
|
params: ['handleClick', TargetName, 'event.target.dataset.id', ClientX, ClientY]
|
|
14611
|
+
}, {
|
|
14612
|
+
name: HandleMouseOver,
|
|
14613
|
+
params: ['handleMouseOver', TargetName]
|
|
14614
|
+
}, {
|
|
14615
|
+
name: HandleMouseOut,
|
|
14616
|
+
params: ['handleMouseOut', TargetName, 'event.relatedTarget && event.relatedTarget.getAttribute ? event.relatedTarget.getAttribute("name") : ""']
|
|
14039
14617
|
}, {
|
|
14040
14618
|
name: HandleClickDictationButton,
|
|
14041
14619
|
params: ['handleClickDictationButton']
|
|
@@ -14202,6 +14780,9 @@ const renderEventListeners = () => {
|
|
|
14202
14780
|
name: HandleContextMenuChatImageAttachment,
|
|
14203
14781
|
params: ['handleContextMenuChatImageAttachment', TargetName, ClientX, ClientY],
|
|
14204
14782
|
preventDefault: true
|
|
14783
|
+
}, {
|
|
14784
|
+
name: HandleErrorComposerAttachmentPreviewOverlay,
|
|
14785
|
+
params: ['handleErrorComposerAttachmentPreviewOverlay']
|
|
14205
14786
|
}];
|
|
14206
14787
|
};
|
|
14207
14788
|
|
|
@@ -14283,6 +14864,8 @@ const saveState = state => {
|
|
|
14283
14864
|
const {
|
|
14284
14865
|
agentMode,
|
|
14285
14866
|
chatListScrollTop,
|
|
14867
|
+
composerSelectionEnd,
|
|
14868
|
+
composerSelectionStart,
|
|
14286
14869
|
composerValue,
|
|
14287
14870
|
lastNormalViewMode,
|
|
14288
14871
|
maxToolCalls,
|
|
@@ -14304,6 +14887,8 @@ const saveState = state => {
|
|
|
14304
14887
|
return {
|
|
14305
14888
|
agentMode,
|
|
14306
14889
|
chatListScrollTop,
|
|
14890
|
+
composerSelectionEnd,
|
|
14891
|
+
composerSelectionStart,
|
|
14307
14892
|
composerValue,
|
|
14308
14893
|
lastNormalViewMode,
|
|
14309
14894
|
maxToolCalls,
|
|
@@ -14400,6 +14985,13 @@ const setResponsivePickerVisibilityEnabled = (state, responsivePickerVisibilityE
|
|
|
14400
14985
|
};
|
|
14401
14986
|
};
|
|
14402
14987
|
|
|
14988
|
+
const setScrollDownButtonEnabled = (state, scrollDownButtonEnabled) => {
|
|
14989
|
+
return {
|
|
14990
|
+
...state,
|
|
14991
|
+
scrollDownButtonEnabled
|
|
14992
|
+
};
|
|
14993
|
+
};
|
|
14994
|
+
|
|
14403
14995
|
const setSearchEnabled = (state, searchEnabled) => {
|
|
14404
14996
|
return {
|
|
14405
14997
|
...state,
|
|
@@ -14532,6 +15124,7 @@ const commandMap = {
|
|
|
14532
15124
|
'Chat.getKeyBindings': getKeyBindings,
|
|
14533
15125
|
'Chat.getMenuEntries': getMenuEntries,
|
|
14534
15126
|
'Chat.getMenuEntryIds': getMenuEntryIds,
|
|
15127
|
+
'Chat.getMockOpenApiRequests': wrapGetter(getMockOpenApiRequests),
|
|
14535
15128
|
'Chat.getQuickPickMenuEntries': getQuickPickMenuEntries,
|
|
14536
15129
|
'Chat.getSelectedSessionId': wrapGetter(getSelectedSessionId),
|
|
14537
15130
|
'Chat.getSystemPrompt': wrapGetter(getSystemPrompt),
|
|
@@ -14564,6 +15157,7 @@ const commandMap = {
|
|
|
14564
15157
|
'Chat.handleDragLeave': wrapCommand(handleDragLeave),
|
|
14565
15158
|
'Chat.handleDragOver': wrapCommand(handleDragOver),
|
|
14566
15159
|
'Chat.handleDropFiles': wrapCommand(handleDropFiles),
|
|
15160
|
+
'Chat.handleErrorComposerAttachmentPreviewOverlay': wrapCommand(handleErrorComposerAttachmentPreviewOverlay),
|
|
14567
15161
|
'Chat.handleInput': wrapCommand(handleInput),
|
|
14568
15162
|
'Chat.handleInputFocus': wrapCommand(handleInputFocus),
|
|
14569
15163
|
'Chat.handleKeyDown': wrapCommand(handleKeyDown),
|
|
@@ -14574,6 +15168,8 @@ const commandMap = {
|
|
|
14574
15168
|
'Chat.handleModelChange': wrapCommand(handleModelChange),
|
|
14575
15169
|
'Chat.handleModelInputBlur': wrapCommand(handleModelInputBlur),
|
|
14576
15170
|
'Chat.handleModelPickerListScroll': wrapCommand(handleModelPickerListScroll),
|
|
15171
|
+
'Chat.handleMouseOut': wrapCommand(handleMouseOut),
|
|
15172
|
+
'Chat.handleMouseOver': wrapCommand(handleMouseOver),
|
|
14577
15173
|
'Chat.handlePointerDownModelPickerList': wrapCommand(handlePointerDownModelPickerList),
|
|
14578
15174
|
'Chat.handlePointerUpModelPickerList': wrapCommand(handlePointerUpModelPickerList),
|
|
14579
15175
|
'Chat.handleProjectAddButtonContextMenu': wrapCommand(handleProjectAddButtonContextMenu),
|
|
@@ -14583,6 +15179,7 @@ const commandMap = {
|
|
|
14583
15179
|
'Chat.handleRunModeChange': wrapCommand(handleRunModeChange),
|
|
14584
15180
|
'Chat.handleSearchValueChange': wrapCommand(handleSearchValueChange),
|
|
14585
15181
|
'Chat.handleSubmit': wrapCommand(handleSubmit),
|
|
15182
|
+
'Chat.hideComposerAttachmentPreviewOverlay': wrapCommand(hideComposerAttachmentPreviewOverlay),
|
|
14586
15183
|
'Chat.initialize': initialize,
|
|
14587
15184
|
'Chat.loadContent': wrapCommand(loadContent),
|
|
14588
15185
|
'Chat.loadContent2': wrapCommand(loadContent),
|
|
@@ -14619,6 +15216,7 @@ const commandMap = {
|
|
|
14619
15216
|
'Chat.setReasoningEffort': wrapCommand(setReasoningEffort),
|
|
14620
15217
|
'Chat.setReasoningPickerEnabled': wrapCommand(setReasoningPickerEnabled),
|
|
14621
15218
|
'Chat.setResponsivePickerVisibilityEnabled': wrapCommand(setResponsivePickerVisibilityEnabled),
|
|
15219
|
+
'Chat.setScrollDownButtonEnabled': wrapCommand(setScrollDownButtonEnabled),
|
|
14622
15220
|
'Chat.setSearchEnabled': wrapCommand(setSearchEnabled),
|
|
14623
15221
|
'Chat.setShowRunMode': wrapCommand(setShowRunMode),
|
|
14624
15222
|
'Chat.setStreamingEnabled': wrapCommand(setStreamingEnabled),
|
|
@@ -14629,6 +15227,7 @@ const commandMap = {
|
|
|
14629
15227
|
'Chat.setUseChatMathWorker': wrapCommand(setUseChatMathWorker),
|
|
14630
15228
|
'Chat.setUseChatMessageParsingWorker': wrapCommand(setUseChatMessageParsingWorker),
|
|
14631
15229
|
'Chat.setUseChatNetworkWorkerForRequests': wrapCommand(setUseChatNetworkWorkerForRequests),
|
|
15230
|
+
'Chat.showComposerAttachmentPreviewOverlay': wrapCommand(showComposerAttachmentPreviewOverlay),
|
|
14632
15231
|
'Chat.terminate': terminate,
|
|
14633
15232
|
'Chat.useMockApi': wrapCommand(useMockApi)
|
|
14634
15233
|
};
|