@lvce-editor/chat-view 6.66.0 → 6.68.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 +990 -179
- 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,12 +1849,14 @@ 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';
|
|
1853
1856
|
const Rename = 'Rename';
|
|
1854
1857
|
const Archive = 'Archive';
|
|
1855
1858
|
const AddProjectChat = 'Add Project';
|
|
1859
|
+
const RemoveProject = 'Remove Project';
|
|
1856
1860
|
const Settings$1 = 'Settings';
|
|
1857
1861
|
const LoginToBackend = 'Login to backend';
|
|
1858
1862
|
const LogoutFromBackend = 'Logout from backend';
|
|
@@ -1867,7 +1871,7 @@ const ComposePlaceholder = 'Type your message. Enter to send.';
|
|
|
1867
1871
|
const AttachImageAsContext = 'Attach Image as Context';
|
|
1868
1872
|
const OpenImageInNewTab = 'Open image in new tab';
|
|
1869
1873
|
const RemoveAttachment = 'Remove attachment';
|
|
1870
|
-
const ImageCouldNotBeLoaded = '
|
|
1874
|
+
const ImageCouldNotBeLoaded = 'Image preview could not be loaded';
|
|
1871
1875
|
const OpenRouterApiKeyPlaceholder = 'Enter OpenRouter API key';
|
|
1872
1876
|
const OpenApiApiKeyPlaceholder = 'Enter OpenAI API key';
|
|
1873
1877
|
const SendMessage = 'Send message';
|
|
@@ -1912,6 +1916,9 @@ const newChat = () => {
|
|
|
1912
1916
|
const addProject = () => {
|
|
1913
1917
|
return i18nString(AddProjectChat);
|
|
1914
1918
|
};
|
|
1919
|
+
const removeProject = () => {
|
|
1920
|
+
return i18nString(RemoveProject);
|
|
1921
|
+
};
|
|
1915
1922
|
const debug = () => {
|
|
1916
1923
|
return i18nString(Debug);
|
|
1917
1924
|
};
|
|
@@ -1927,6 +1934,9 @@ const settings = () => {
|
|
|
1927
1934
|
const search = () => {
|
|
1928
1935
|
return i18nString(Search$1);
|
|
1929
1936
|
};
|
|
1937
|
+
const scrollDown = () => {
|
|
1938
|
+
return i18nString(ScrollDown$1);
|
|
1939
|
+
};
|
|
1930
1940
|
const searchModels = () => {
|
|
1931
1941
|
return i18nString(SearchModels);
|
|
1932
1942
|
};
|
|
@@ -2079,16 +2089,19 @@ const getDefaultModelsOpenAi = () => {
|
|
|
2079
2089
|
id: 'openapi/gpt-4o-mini',
|
|
2080
2090
|
name: 'GPT-4o Mini',
|
|
2081
2091
|
provider: 'openApi',
|
|
2092
|
+
supportsImages: true,
|
|
2082
2093
|
usageCost: 1
|
|
2083
2094
|
}, {
|
|
2084
2095
|
id: 'openapi/gpt-4o',
|
|
2085
2096
|
name: 'GPT-4o',
|
|
2086
2097
|
provider: 'openApi',
|
|
2098
|
+
supportsImages: true,
|
|
2087
2099
|
usageCost: 3
|
|
2088
2100
|
}, {
|
|
2089
2101
|
id: 'openapi/gpt-4.1-mini',
|
|
2090
2102
|
name: 'GPT-4.1 Mini',
|
|
2091
2103
|
provider: 'openApi',
|
|
2104
|
+
supportsImages: true,
|
|
2092
2105
|
usageCost: 1
|
|
2093
2106
|
}];
|
|
2094
2107
|
};
|
|
@@ -2326,6 +2339,8 @@ const createDefaultState = () => {
|
|
|
2326
2339
|
chatSendAreaPaddingLeft: 8,
|
|
2327
2340
|
chatSendAreaPaddingRight: 8,
|
|
2328
2341
|
chatSendAreaPaddingTop: 10,
|
|
2342
|
+
composerAttachmentPreviewOverlayAttachmentId: '',
|
|
2343
|
+
composerAttachmentPreviewOverlayError: false,
|
|
2329
2344
|
composerAttachments: [],
|
|
2330
2345
|
composerAttachmentsHeight: 0,
|
|
2331
2346
|
composerDropActive: false,
|
|
@@ -2356,12 +2371,14 @@ const createDefaultState = () => {
|
|
|
2356
2371
|
messagesScrollTop: 0,
|
|
2357
2372
|
mockAiResponseDelay: 800,
|
|
2358
2373
|
mockApiCommandId: '',
|
|
2374
|
+
mockOpenApiRequests: [],
|
|
2359
2375
|
modelPickerHeaderHeight,
|
|
2360
2376
|
modelPickerHeight: getModelPickerHeight(modelPickerHeaderHeight, visibleModels.length),
|
|
2361
2377
|
modelPickerListScrollTop: 0,
|
|
2362
2378
|
modelPickerOpen: false,
|
|
2363
2379
|
modelPickerSearchValue: '',
|
|
2364
2380
|
models,
|
|
2381
|
+
nextAttachmentId: 1,
|
|
2365
2382
|
nextMessageId: 1,
|
|
2366
2383
|
openApiApiBaseUrl: 'https://api.openai.com/v1',
|
|
2367
2384
|
openApiApiKey: '',
|
|
@@ -2392,6 +2409,7 @@ const createDefaultState = () => {
|
|
|
2392
2409
|
responsivePickerVisibilityEnabled,
|
|
2393
2410
|
runMode: 'local',
|
|
2394
2411
|
runModePickerOpen: false,
|
|
2412
|
+
scrollDownButtonEnabled: false,
|
|
2395
2413
|
searchEnabled: false,
|
|
2396
2414
|
searchFieldVisible: false,
|
|
2397
2415
|
searchValue: '',
|
|
@@ -2622,6 +2640,13 @@ const getComposerAttachmentPreviewSrc = async (blob, displayType, mimeType) => {
|
|
|
2622
2640
|
return `data:${mimeType || 'application/octet-stream'};base64,${base64}`;
|
|
2623
2641
|
};
|
|
2624
2642
|
|
|
2643
|
+
const getComposerAttachmentTextContent = async (blob, displayType) => {
|
|
2644
|
+
if (displayType !== 'text-file') {
|
|
2645
|
+
return undefined;
|
|
2646
|
+
}
|
|
2647
|
+
return blob.text();
|
|
2648
|
+
};
|
|
2649
|
+
|
|
2625
2650
|
const isChatAttachmentAddedEvent = event => {
|
|
2626
2651
|
return event.type === 'chat-attachment-added';
|
|
2627
2652
|
};
|
|
@@ -2644,6 +2669,7 @@ const getComposerAttachments = async sessionId => {
|
|
|
2644
2669
|
}
|
|
2645
2670
|
const displayType = await getComposerAttachmentDisplayType(event.blob, event.name, event.mimeType);
|
|
2646
2671
|
const previewSrc = await getComposerAttachmentPreviewSrc(event.blob, displayType, event.mimeType);
|
|
2672
|
+
const textContent = await getComposerAttachmentTextContent(event.blob, displayType);
|
|
2647
2673
|
attachments.set(event.attachmentId, {
|
|
2648
2674
|
attachmentId: event.attachmentId,
|
|
2649
2675
|
displayType,
|
|
@@ -2652,7 +2678,10 @@ const getComposerAttachments = async sessionId => {
|
|
|
2652
2678
|
...(previewSrc ? {
|
|
2653
2679
|
previewSrc
|
|
2654
2680
|
} : {}),
|
|
2655
|
-
size: event.size
|
|
2681
|
+
size: event.size,
|
|
2682
|
+
...(typeof textContent === 'string' ? {
|
|
2683
|
+
textContent
|
|
2684
|
+
} : {})
|
|
2656
2685
|
});
|
|
2657
2686
|
}
|
|
2658
2687
|
return [...attachments.values()];
|
|
@@ -3214,7 +3243,8 @@ const openModelPicker = state => {
|
|
|
3214
3243
|
return {
|
|
3215
3244
|
...state,
|
|
3216
3245
|
agentModePickerOpen: false,
|
|
3217
|
-
focus: 'model-picker-input',
|
|
3246
|
+
focus: modelPickerOpen ? 'model-picker-input' : state.focus,
|
|
3247
|
+
focused: modelPickerOpen ? true : state.focused,
|
|
3218
3248
|
modelPickerHeight: getModelPickerHeight(state.modelPickerHeaderHeight, visibleModels.length),
|
|
3219
3249
|
modelPickerListScrollTop: 0,
|
|
3220
3250
|
modelPickerOpen,
|
|
@@ -3250,6 +3280,10 @@ const getKeyBindings = () => {
|
|
|
3250
3280
|
command: 'Chat.chatListFocusPrevious',
|
|
3251
3281
|
key: UpArrow,
|
|
3252
3282
|
when: FocusChatList
|
|
3283
|
+
}, {
|
|
3284
|
+
command: 'Chat.handleClickNew',
|
|
3285
|
+
key: CtrlCmd | KeyN,
|
|
3286
|
+
when: FocusChatInput
|
|
3253
3287
|
}, {
|
|
3254
3288
|
command: 'Chat.handleSubmit',
|
|
3255
3289
|
key: Enter,
|
|
@@ -3348,6 +3382,7 @@ const ComposerDropTarget = 'composer-drop-target';
|
|
|
3348
3382
|
const ComposerAttachmentPrefix = 'composer-attachment:';
|
|
3349
3383
|
const ComposerAttachmentPreviewPrefix = 'composer-attachment-preview:';
|
|
3350
3384
|
const ComposerAttachmentRemovePrefix = 'composer-attachment-remove:';
|
|
3385
|
+
const ComposerAttachmentPreviewOverlay = 'composer-attachment-preview-overlay';
|
|
3351
3386
|
const AddContext = 'add-context';
|
|
3352
3387
|
const Dictate = 'dictate';
|
|
3353
3388
|
const CreatePullRequest$1 = 'create-pull-request';
|
|
@@ -3357,10 +3392,12 @@ const FocusCommit = 'focus-commit';
|
|
|
3357
3392
|
const FocusOpenTerminal = 'focus-open-terminal';
|
|
3358
3393
|
const FocusShowDiff = 'focus-show-diff';
|
|
3359
3394
|
const Send = 'send';
|
|
3395
|
+
const ScrollDown = 'scroll-down';
|
|
3360
3396
|
const Back = 'back';
|
|
3361
3397
|
const ModelPickerToggle = 'model-picker-toggle';
|
|
3362
3398
|
const ModelPickerSearch = 'model-picker-search';
|
|
3363
3399
|
const ModelPickerList = 'model-picker-list';
|
|
3400
|
+
const PickerList = 'picker-list';
|
|
3364
3401
|
const AgentModePickerToggle = 'agent-mode-picker-toggle';
|
|
3365
3402
|
const AgentModePickerItemPrefix = 'agent-mode-picker-item:';
|
|
3366
3403
|
const ReasoningEffortPickerToggle = 'reasoning-effort-picker-toggle';
|
|
@@ -3379,6 +3416,7 @@ const Login = 'login';
|
|
|
3379
3416
|
const Logout = 'logout';
|
|
3380
3417
|
const CloseChat = 'close-chat';
|
|
3381
3418
|
const SessionDelete = 'SessionDelete';
|
|
3419
|
+
const ProjectDelete = 'ProjectDelete';
|
|
3382
3420
|
const ProjectPrefix = 'project:';
|
|
3383
3421
|
const SessionPrefix = 'session:';
|
|
3384
3422
|
const RenamePrefix = 'session-rename:';
|
|
@@ -3422,6 +3460,12 @@ const getModelPickerItemInputName = modelId => {
|
|
|
3422
3460
|
const getComposerAttachmentInputName = attachmentId => {
|
|
3423
3461
|
return `${ComposerAttachmentPrefix}${attachmentId}`;
|
|
3424
3462
|
};
|
|
3463
|
+
const isComposerAttachmentInputName = name => {
|
|
3464
|
+
return name.startsWith(ComposerAttachmentPrefix);
|
|
3465
|
+
};
|
|
3466
|
+
const getAttachmentIdFromComposerAttachmentInputName = name => {
|
|
3467
|
+
return name.slice(ComposerAttachmentPrefix.length);
|
|
3468
|
+
};
|
|
3425
3469
|
const getComposerAttachmentRemoveInputName = attachmentId => {
|
|
3426
3470
|
return `${ComposerAttachmentRemovePrefix}${attachmentId}`;
|
|
3427
3471
|
};
|
|
@@ -3437,6 +3481,9 @@ const isComposerAttachmentRemoveInputName = name => {
|
|
|
3437
3481
|
const getAttachmentIdFromComposerAttachmentRemoveInputName = name => {
|
|
3438
3482
|
return name.slice(ComposerAttachmentRemovePrefix.length);
|
|
3439
3483
|
};
|
|
3484
|
+
const isComposerAttachmentPreviewOverlayInputName = name => {
|
|
3485
|
+
return name === ComposerAttachmentPreviewOverlay;
|
|
3486
|
+
};
|
|
3440
3487
|
const isModelPickerItemInputName = name => {
|
|
3441
3488
|
return name.startsWith(ModelPickerItemPrefix);
|
|
3442
3489
|
};
|
|
@@ -3478,17 +3525,27 @@ const menuEntryAddProject = {
|
|
|
3478
3525
|
id: 'addProject',
|
|
3479
3526
|
label: addProject()
|
|
3480
3527
|
};
|
|
3481
|
-
const getMenuEntriesChatProjectList = (projectId = '') => {
|
|
3528
|
+
const getMenuEntriesChatProjectList = (projectId = '', canRemoveProject = true) => {
|
|
3482
3529
|
if (!projectId) {
|
|
3483
3530
|
return [menuEntryAddProject];
|
|
3484
3531
|
}
|
|
3485
|
-
|
|
3532
|
+
const entries = [{
|
|
3486
3533
|
args: [getCreateSessionInProjectInputName(projectId)],
|
|
3487
3534
|
command: 'Chat.handleClick',
|
|
3488
3535
|
flags: None,
|
|
3489
3536
|
id: 'newChat',
|
|
3490
3537
|
label: newChat()
|
|
3491
3538
|
}, menuEntryAddProject];
|
|
3539
|
+
if (canRemoveProject) {
|
|
3540
|
+
entries.push({
|
|
3541
|
+
args: [ProjectDelete, projectId],
|
|
3542
|
+
command: 'Chat.handleClick',
|
|
3543
|
+
flags: None,
|
|
3544
|
+
id: 'removeProject',
|
|
3545
|
+
label: removeProject()
|
|
3546
|
+
});
|
|
3547
|
+
}
|
|
3548
|
+
return entries;
|
|
3492
3549
|
};
|
|
3493
3550
|
|
|
3494
3551
|
const getMenuEntriesProjectAddButton = () => {
|
|
@@ -3522,7 +3579,7 @@ const getMenuEntries = (menuId, props) => {
|
|
|
3522
3579
|
case MenuChatList:
|
|
3523
3580
|
return getMenuEntriesChatList();
|
|
3524
3581
|
case MenuChatProjectList:
|
|
3525
|
-
return getMenuEntriesChatProjectList(props.projectId);
|
|
3582
|
+
return getMenuEntriesChatProjectList(props.projectId, props.canRemoveProject);
|
|
3526
3583
|
case MenuProjectAddButton:
|
|
3527
3584
|
return getMenuEntriesProjectAddButton();
|
|
3528
3585
|
default:
|
|
@@ -3530,6 +3587,10 @@ const getMenuEntries = (menuId, props) => {
|
|
|
3530
3587
|
}
|
|
3531
3588
|
};
|
|
3532
3589
|
|
|
3590
|
+
const getMockOpenApiRequests = state => {
|
|
3591
|
+
return state.mockOpenApiRequests;
|
|
3592
|
+
};
|
|
3593
|
+
|
|
3533
3594
|
const getQuickPickMenuEntries = () => {
|
|
3534
3595
|
return [];
|
|
3535
3596
|
};
|
|
@@ -3619,6 +3680,15 @@ const handleChatListContextMenu = async (state, eventX, eventY) => {
|
|
|
3619
3680
|
};
|
|
3620
3681
|
};
|
|
3621
3682
|
|
|
3683
|
+
const focusInput = state => {
|
|
3684
|
+
return {
|
|
3685
|
+
...state,
|
|
3686
|
+
focus: 'composer',
|
|
3687
|
+
focused: true,
|
|
3688
|
+
listFocusedIndex: -1
|
|
3689
|
+
};
|
|
3690
|
+
};
|
|
3691
|
+
|
|
3622
3692
|
const generateSessionId = () => {
|
|
3623
3693
|
return crypto.randomUUID();
|
|
3624
3694
|
};
|
|
@@ -3634,7 +3704,7 @@ const createSession = async (state, projectIdOverride = '') => {
|
|
|
3634
3704
|
title: `Chat ${state.sessions.length + 1}`
|
|
3635
3705
|
};
|
|
3636
3706
|
await saveChatSession(session);
|
|
3637
|
-
return {
|
|
3707
|
+
return focusInput({
|
|
3638
3708
|
...state,
|
|
3639
3709
|
composerAttachments: [],
|
|
3640
3710
|
composerAttachmentsHeight: 0,
|
|
@@ -3643,6 +3713,84 @@ const createSession = async (state, projectIdOverride = '') => {
|
|
|
3643
3713
|
selectedProjectId: projectId,
|
|
3644
3714
|
selectedSessionId: id,
|
|
3645
3715
|
sessions: [...state.sessions, session]
|
|
3716
|
+
});
|
|
3717
|
+
};
|
|
3718
|
+
|
|
3719
|
+
const getBlankProjectId = (state, removedProjectId) => {
|
|
3720
|
+
return state.projects.find(project => project.id !== removedProjectId && project.name === '_blank')?.id || '';
|
|
3721
|
+
};
|
|
3722
|
+
const getNextViewMode = (state, hasSelectedSession) => {
|
|
3723
|
+
if (state.viewMode === 'chat-focus') {
|
|
3724
|
+
return 'chat-focus';
|
|
3725
|
+
}
|
|
3726
|
+
if (!hasSelectedSession) {
|
|
3727
|
+
return 'list';
|
|
3728
|
+
}
|
|
3729
|
+
return state.viewMode === 'detail' ? 'detail' : 'list';
|
|
3730
|
+
};
|
|
3731
|
+
const ensureExpandedProject = (state, projectExpandedIds, selectedProjectId, visibleSessions) => {
|
|
3732
|
+
if (state.viewMode !== 'chat-focus' || !selectedProjectId || visibleSessions.length === 0 || projectExpandedIds.includes(selectedProjectId)) {
|
|
3733
|
+
return projectExpandedIds;
|
|
3734
|
+
}
|
|
3735
|
+
return [...projectExpandedIds, selectedProjectId];
|
|
3736
|
+
};
|
|
3737
|
+
const deleteProject = async (state, projectId) => {
|
|
3738
|
+
const project = state.projects.find(candidate => candidate.id === projectId);
|
|
3739
|
+
if (!project || project.name === '_blank') {
|
|
3740
|
+
return state;
|
|
3741
|
+
}
|
|
3742
|
+
const blankProjectId = getBlankProjectId(state, projectId);
|
|
3743
|
+
if (!blankProjectId) {
|
|
3744
|
+
return state;
|
|
3745
|
+
}
|
|
3746
|
+
const projects = state.projects.filter(candidate => candidate.id !== projectId);
|
|
3747
|
+
const sessions = await Promise.all(state.sessions.map(async session => {
|
|
3748
|
+
if (session.projectId !== projectId) {
|
|
3749
|
+
return session;
|
|
3750
|
+
}
|
|
3751
|
+
const updatedSession = {
|
|
3752
|
+
...session,
|
|
3753
|
+
projectId: blankProjectId
|
|
3754
|
+
};
|
|
3755
|
+
await saveChatSession(updatedSession);
|
|
3756
|
+
return updatedSession;
|
|
3757
|
+
}));
|
|
3758
|
+
const selectedProjectId = !state.selectedProjectId || state.selectedProjectId === projectId || !projects.some(candidate => candidate.id === state.selectedProjectId) ? blankProjectId : state.selectedProjectId;
|
|
3759
|
+
const projectExpandedIds = state.projectExpandedIds.filter(expandedProjectId => expandedProjectId !== projectId && projects.some(candidate => candidate.id === expandedProjectId));
|
|
3760
|
+
const visibleSessions = getVisibleSessions(sessions, selectedProjectId);
|
|
3761
|
+
const nextProjectExpandedIds = ensureExpandedProject(state, projectExpandedIds, selectedProjectId, visibleSessions);
|
|
3762
|
+
if (visibleSessions.length === 0) {
|
|
3763
|
+
return {
|
|
3764
|
+
...state,
|
|
3765
|
+
composerAttachments: [],
|
|
3766
|
+
composerAttachmentsHeight: 0,
|
|
3767
|
+
projectExpandedIds: nextProjectExpandedIds,
|
|
3768
|
+
projects,
|
|
3769
|
+
selectedProjectId,
|
|
3770
|
+
selectedSessionId: '',
|
|
3771
|
+
sessions,
|
|
3772
|
+
viewMode: getNextViewMode(state, false)
|
|
3773
|
+
};
|
|
3774
|
+
}
|
|
3775
|
+
const selectedSessionId = visibleSessions.some(session => session.id === state.selectedSessionId) ? state.selectedSessionId : visibleSessions[0].id;
|
|
3776
|
+
const loadedSession = await getChatSession(selectedSessionId);
|
|
3777
|
+
const composerAttachments = await getComposerAttachments(selectedSessionId);
|
|
3778
|
+
const hydratedSessions = sessions.map(session => {
|
|
3779
|
+
if (session.id !== selectedSessionId || !loadedSession) {
|
|
3780
|
+
return session;
|
|
3781
|
+
}
|
|
3782
|
+
return loadedSession;
|
|
3783
|
+
});
|
|
3784
|
+
return {
|
|
3785
|
+
...state,
|
|
3786
|
+
composerAttachments,
|
|
3787
|
+
composerAttachmentsHeight: getComposerAttachmentsHeight(composerAttachments, state.width),
|
|
3788
|
+
projectExpandedIds: nextProjectExpandedIds,
|
|
3789
|
+
projects,
|
|
3790
|
+
selectedProjectId,
|
|
3791
|
+
selectedSessionId,
|
|
3792
|
+
sessions: hydratedSessions,
|
|
3793
|
+
viewMode: getNextViewMode(state, true)
|
|
3646
3794
|
};
|
|
3647
3795
|
};
|
|
3648
3796
|
|
|
@@ -3655,6 +3803,12 @@ const getModelPickerClickIndex = (y, height, eventY, modelPickerBottomOffset, mo
|
|
|
3655
3803
|
return Math.floor(relativeY / modelPickerItemHeight);
|
|
3656
3804
|
};
|
|
3657
3805
|
|
|
3806
|
+
const AutoScrollTopA = Number.MAX_SAFE_INTEGER;
|
|
3807
|
+
const AutoScrollTopB = Number.MAX_SAFE_INTEGER - 1;
|
|
3808
|
+
const getNextAutoScrollTop = currentScrollTop => {
|
|
3809
|
+
return currentScrollTop === AutoScrollTopA ? AutoScrollTopB : AutoScrollTopA;
|
|
3810
|
+
};
|
|
3811
|
+
|
|
3658
3812
|
const openFolder = async () => {
|
|
3659
3813
|
try {
|
|
3660
3814
|
return await invoke('FilePicker.showDirectoryPicker');
|
|
@@ -4232,6 +4386,54 @@ const getBasicChatTools = async (agentMode = defaultAgentMode, questionToolEnabl
|
|
|
4232
4386
|
}
|
|
4233
4387
|
};
|
|
4234
4388
|
|
|
4389
|
+
const getAttachmentTextPart = attachment => {
|
|
4390
|
+
switch (attachment.displayType) {
|
|
4391
|
+
case 'file':
|
|
4392
|
+
return {
|
|
4393
|
+
text: `Attached file "${attachment.name}" (${attachment.mimeType || 'application/octet-stream'}, ${attachment.size} bytes).`,
|
|
4394
|
+
type: 'input_text'
|
|
4395
|
+
};
|
|
4396
|
+
case 'image':
|
|
4397
|
+
return {
|
|
4398
|
+
text: `Attached image "${attachment.name}" could not be encoded for the AI request.`,
|
|
4399
|
+
type: 'input_text'
|
|
4400
|
+
};
|
|
4401
|
+
case 'invalid-image':
|
|
4402
|
+
return {
|
|
4403
|
+
text: `Attached file "${attachment.name}" could not be processed as a valid image.`,
|
|
4404
|
+
type: 'input_text'
|
|
4405
|
+
};
|
|
4406
|
+
case 'text-file':
|
|
4407
|
+
return {
|
|
4408
|
+
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'}).`,
|
|
4409
|
+
type: 'input_text'
|
|
4410
|
+
};
|
|
4411
|
+
}
|
|
4412
|
+
};
|
|
4413
|
+
const getChatMessageOpenAiContent = message => {
|
|
4414
|
+
if (!message.attachments || message.attachments.length === 0) {
|
|
4415
|
+
return message.text;
|
|
4416
|
+
}
|
|
4417
|
+
const parts = [];
|
|
4418
|
+
if (message.text) {
|
|
4419
|
+
parts.push({
|
|
4420
|
+
text: message.text,
|
|
4421
|
+
type: 'input_text'
|
|
4422
|
+
});
|
|
4423
|
+
}
|
|
4424
|
+
for (const attachment of message.attachments) {
|
|
4425
|
+
if (attachment.displayType === 'image' && attachment.previewSrc) {
|
|
4426
|
+
parts.push({
|
|
4427
|
+
image_url: attachment.previewSrc,
|
|
4428
|
+
type: 'input_image'
|
|
4429
|
+
});
|
|
4430
|
+
continue;
|
|
4431
|
+
}
|
|
4432
|
+
parts.push(getAttachmentTextPart(attachment));
|
|
4433
|
+
}
|
|
4434
|
+
return parts;
|
|
4435
|
+
};
|
|
4436
|
+
|
|
4235
4437
|
const getClientRequestIdHeader = () => {
|
|
4236
4438
|
return {
|
|
4237
4439
|
'x-client-request-id': crypto.randomUUID()
|
|
@@ -4247,11 +4449,22 @@ const getMockAiResponse = async (userMessage, delayInMs) => {
|
|
|
4247
4449
|
return `Mock AI response: I received "${userMessage}".`;
|
|
4248
4450
|
};
|
|
4249
4451
|
|
|
4452
|
+
let requests = [];
|
|
4453
|
+
const reset$2 = () => {
|
|
4454
|
+
requests = [];
|
|
4455
|
+
};
|
|
4456
|
+
const capture = request => {
|
|
4457
|
+
requests = [...requests, request];
|
|
4458
|
+
};
|
|
4459
|
+
const getAll = () => {
|
|
4460
|
+
return requests;
|
|
4461
|
+
};
|
|
4462
|
+
|
|
4250
4463
|
let queue = [];
|
|
4251
4464
|
let waiters = [];
|
|
4252
4465
|
let finished = false;
|
|
4253
4466
|
let errorResult;
|
|
4254
|
-
const reset$
|
|
4467
|
+
const reset$1 = () => {
|
|
4255
4468
|
queue = [];
|
|
4256
4469
|
waiters = [];
|
|
4257
4470
|
finished = false;
|
|
@@ -4325,6 +4538,47 @@ const readNextChunk = async () => {
|
|
|
4325
4538
|
return promise;
|
|
4326
4539
|
};
|
|
4327
4540
|
|
|
4541
|
+
const lastRequestSummaryToken = '__MOCK_OPENAPI_LAST_REQUEST_SUMMARY__';
|
|
4542
|
+
const getLastRequestSummary = () => {
|
|
4543
|
+
const requests = getAll();
|
|
4544
|
+
const request = requests.at(-1);
|
|
4545
|
+
if (!request || !request.payload || typeof request.payload !== 'object') {
|
|
4546
|
+
return 'mock-request-summary images=0 text-files=0';
|
|
4547
|
+
}
|
|
4548
|
+
const input = Reflect.get(request.payload, 'input');
|
|
4549
|
+
if (!Array.isArray(input) || input.length === 0) {
|
|
4550
|
+
return 'mock-request-summary images=0 text-files=0';
|
|
4551
|
+
}
|
|
4552
|
+
let imageCount = 0;
|
|
4553
|
+
let textFileCount = 0;
|
|
4554
|
+
for (const item of input) {
|
|
4555
|
+
if (!item || typeof item !== 'object') {
|
|
4556
|
+
continue;
|
|
4557
|
+
}
|
|
4558
|
+
const content = Reflect.get(item, 'content');
|
|
4559
|
+
if (!Array.isArray(content)) {
|
|
4560
|
+
continue;
|
|
4561
|
+
}
|
|
4562
|
+
for (const part of content) {
|
|
4563
|
+
if (!part || typeof part !== 'object') {
|
|
4564
|
+
continue;
|
|
4565
|
+
}
|
|
4566
|
+
const type = Reflect.get(part, 'type');
|
|
4567
|
+
if (type === 'input_image') {
|
|
4568
|
+
imageCount++;
|
|
4569
|
+
continue;
|
|
4570
|
+
}
|
|
4571
|
+
if (type !== 'input_text') {
|
|
4572
|
+
continue;
|
|
4573
|
+
}
|
|
4574
|
+
const text = Reflect.get(part, 'text');
|
|
4575
|
+
if (typeof text === 'string' && text.startsWith('Attached text file "')) {
|
|
4576
|
+
textFileCount++;
|
|
4577
|
+
}
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
return `mock-request-summary images=${imageCount} text-files=${textFileCount}`;
|
|
4581
|
+
};
|
|
4328
4582
|
const getResponseFunctionCalls$1 = value => {
|
|
4329
4583
|
if (!value || typeof value !== 'object') {
|
|
4330
4584
|
return [];
|
|
@@ -4522,9 +4776,10 @@ const getMockOpenApiAssistantText = async (stream, onTextChunk, onToolCallsChunk
|
|
|
4522
4776
|
}
|
|
4523
4777
|
continue;
|
|
4524
4778
|
}
|
|
4525
|
-
|
|
4779
|
+
const resolvedChunk = chunk === lastRequestSummaryToken ? getLastRequestSummary() : chunk;
|
|
4780
|
+
text += resolvedChunk;
|
|
4526
4781
|
if (stream && onTextChunk) {
|
|
4527
|
-
await onTextChunk(
|
|
4782
|
+
await onTextChunk(resolvedChunk);
|
|
4528
4783
|
}
|
|
4529
4784
|
}
|
|
4530
4785
|
if (!requestDone && remainder) {
|
|
@@ -5361,7 +5616,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
5361
5616
|
stream: false
|
|
5362
5617
|
};
|
|
5363
5618
|
const openAiInput = messages.map(message => ({
|
|
5364
|
-
content: message
|
|
5619
|
+
content: getChatMessageOpenAiContent(message),
|
|
5365
5620
|
role: message.role
|
|
5366
5621
|
}));
|
|
5367
5622
|
const tools = await getBasicChatTools(agentMode, questionToolEnabled, toolEnablement);
|
|
@@ -5754,12 +6009,22 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
5754
6009
|
};
|
|
5755
6010
|
};
|
|
5756
6011
|
|
|
6012
|
+
const imageRegex = /\b(?:image|vision|multimodal)\b/i;
|
|
6013
|
+
const unsupportedRegex = /\bdoes(?:\s+not|n't)\s+support|not\s+support(?:ed)?|unsupported\b/i;
|
|
5757
6014
|
const isOffline = () => {
|
|
5758
6015
|
if (!globalThis.navigator) {
|
|
5759
6016
|
return false;
|
|
5760
6017
|
}
|
|
5761
6018
|
return globalThis.navigator.onLine === false;
|
|
5762
6019
|
};
|
|
6020
|
+
const isImageNotSupportedError = errorResult => {
|
|
6021
|
+
const haystack = [errorResult.errorCode, errorResult.errorMessage, errorResult.errorType].filter(Boolean).join(' ');
|
|
6022
|
+
return imageRegex.test(haystack) && unsupportedRegex.test(haystack);
|
|
6023
|
+
};
|
|
6024
|
+
const getImageNotSupportedMessage = modelName => {
|
|
6025
|
+
const subject = modelName ? `${modelName} does not support image attachments.` : 'This model does not support image attachments.';
|
|
6026
|
+
return `${subject} Choose a vision-capable model like GPT-4o Mini or GPT-4o, or remove the image and try again.`;
|
|
6027
|
+
};
|
|
5763
6028
|
const getOpenApiErrorMessage = errorResult => {
|
|
5764
6029
|
switch (errorResult.details) {
|
|
5765
6030
|
case 'http-error':
|
|
@@ -5773,6 +6038,9 @@ const getOpenApiErrorMessage = errorResult => {
|
|
|
5773
6038
|
const status = typeof errorResult.statusCode === 'number' ? errorResult.statusCode : 401;
|
|
5774
6039
|
return `OpenAI request failed (Status ${status}): Invalid API key. Please verify your OpenAI API key in Chat Settings.`;
|
|
5775
6040
|
}
|
|
6041
|
+
if (isImageNotSupportedError(errorResult)) {
|
|
6042
|
+
return getImageNotSupportedMessage();
|
|
6043
|
+
}
|
|
5776
6044
|
if (errorResult.statusCode === 429) {
|
|
5777
6045
|
let prefix = 'OpenAI rate limit exceeded (429)';
|
|
5778
6046
|
if (hasErrorCode) {
|
|
@@ -6221,17 +6489,6 @@ const isOpenRouterModel = (selectedModelId, models) => {
|
|
|
6221
6489
|
return selectedModelId.toLowerCase().startsWith('openrouter/');
|
|
6222
6490
|
};
|
|
6223
6491
|
|
|
6224
|
-
let requests = [];
|
|
6225
|
-
const reset$1 = () => {
|
|
6226
|
-
requests = [];
|
|
6227
|
-
};
|
|
6228
|
-
const capture = request => {
|
|
6229
|
-
requests = [...requests, request];
|
|
6230
|
-
};
|
|
6231
|
-
const getAll = () => {
|
|
6232
|
-
return requests;
|
|
6233
|
-
};
|
|
6234
|
-
|
|
6235
6492
|
/* eslint-disable prefer-destructuring */
|
|
6236
6493
|
|
|
6237
6494
|
const trailingSlashesRegex = /\/+$/;
|
|
@@ -6246,6 +6503,9 @@ const getEffectiveBackendModelId = selectedModelId => {
|
|
|
6246
6503
|
}
|
|
6247
6504
|
return selectedModelId.slice(separatorIndex + 1);
|
|
6248
6505
|
};
|
|
6506
|
+
const hasImageAttachments = messages => {
|
|
6507
|
+
return messages.some(message => message.attachments?.some(attachment => attachment.displayType === 'image'));
|
|
6508
|
+
};
|
|
6249
6509
|
const getBackendAssistantText = async (messages, selectedModelId, backendUrl, authAccessToken, systemPrompt) => {
|
|
6250
6510
|
let response;
|
|
6251
6511
|
try {
|
|
@@ -6293,6 +6553,7 @@ const getAiResponse = async ({
|
|
|
6293
6553
|
nextMessageId,
|
|
6294
6554
|
onDataEvent,
|
|
6295
6555
|
onEventStreamFinished,
|
|
6556
|
+
onMockOpenApiRequestCaptured,
|
|
6296
6557
|
onTextChunk,
|
|
6297
6558
|
onToolCallsChunk,
|
|
6298
6559
|
openApiApiBaseUrl,
|
|
@@ -6368,7 +6629,15 @@ const getAiResponse = async ({
|
|
|
6368
6629
|
}
|
|
6369
6630
|
}
|
|
6370
6631
|
let text = '';
|
|
6371
|
-
|
|
6632
|
+
const usesOpenApiModel = isOpenApiModel(selectedModelId, models);
|
|
6633
|
+
const usesOpenRouterModel = isOpenRouterModel(selectedModelId, models);
|
|
6634
|
+
const selectedModel = models.find(model => model.id === selectedModelId);
|
|
6635
|
+
const supportsImages = selectedModel?.supportsImages ?? false;
|
|
6636
|
+
const supportsReasoningEffort = selectedModel?.supportsReasoningEffort ?? false;
|
|
6637
|
+
if (hasImageAttachments(messages) && !supportsImages) {
|
|
6638
|
+
text = getImageNotSupportedMessage(selectedModel?.name);
|
|
6639
|
+
}
|
|
6640
|
+
if (!text && authEnabled) {
|
|
6372
6641
|
if (!backendUrl) {
|
|
6373
6642
|
text = backendUrlRequiredMessage;
|
|
6374
6643
|
} else if (authAccessToken) {
|
|
@@ -6377,15 +6646,11 @@ const getAiResponse = async ({
|
|
|
6377
6646
|
text = backendAccessTokenRequiredMessage;
|
|
6378
6647
|
}
|
|
6379
6648
|
}
|
|
6380
|
-
const usesOpenApiModel = isOpenApiModel(selectedModelId, models);
|
|
6381
|
-
const usesOpenRouterModel = isOpenRouterModel(selectedModelId, models);
|
|
6382
|
-
const selectedModel = models.find(model => model.id === selectedModelId);
|
|
6383
|
-
const supportsReasoningEffort = selectedModel?.supportsReasoningEffort ?? false;
|
|
6384
6649
|
if (!text && usesOpenApiModel) {
|
|
6385
6650
|
const safeMaxToolCalls = Math.max(1, maxToolCalls);
|
|
6386
6651
|
if (useMockApi) {
|
|
6387
6652
|
const openAiInput = messages.map(message => ({
|
|
6388
|
-
content: message
|
|
6653
|
+
content: getChatMessageOpenAiContent(message),
|
|
6389
6654
|
role: message.role
|
|
6390
6655
|
}));
|
|
6391
6656
|
const modelId = getOpenApiModelId(selectedModelId);
|
|
@@ -6397,12 +6662,16 @@ const getAiResponse = async ({
|
|
|
6397
6662
|
const maxToolIterations = safeMaxToolCalls - 1;
|
|
6398
6663
|
let previousResponseId;
|
|
6399
6664
|
for (let i = 0; i <= maxToolIterations; i++) {
|
|
6400
|
-
|
|
6665
|
+
const request = {
|
|
6401
6666
|
headers,
|
|
6402
6667
|
method: 'POST',
|
|
6403
6668
|
payload: getOpenAiParams(openAiInput, modelId, streamingEnabled, passIncludeObfuscation, await getBasicChatTools(agentMode, questionToolEnabled, toolEnablement), agentMode === 'plan' ? false : webSearchEnabled, safeMaxToolCalls, systemPrompt, previousResponseId, reasoningEffort, supportsReasoningEffort),
|
|
6404
6669
|
url: getOpenApiApiEndpoint(openApiApiBaseUrl)
|
|
6405
|
-
}
|
|
6670
|
+
};
|
|
6671
|
+
capture(request);
|
|
6672
|
+
if (onMockOpenApiRequestCaptured) {
|
|
6673
|
+
await Promise.resolve(onMockOpenApiRequestCaptured(request));
|
|
6674
|
+
}
|
|
6406
6675
|
const result = await getMockOpenApiAssistantText(streamingEnabled, onTextChunk, onToolCallsChunk, onDataEvent, onEventStreamFinished);
|
|
6407
6676
|
if (result.type !== 'success') {
|
|
6408
6677
|
text = getOpenApiErrorMessage(result);
|
|
@@ -6559,6 +6828,7 @@ const ChatAuthError = 'ChatAuthError';
|
|
|
6559
6828
|
const ChatFocus = 'ChatFocus';
|
|
6560
6829
|
const ChatFocusActions = 'ChatFocusActions';
|
|
6561
6830
|
const ChatFocusHeader = 'ChatFocusHeader';
|
|
6831
|
+
const ChatFocusMainArea = 'ChatFocusMainArea';
|
|
6562
6832
|
const ChatFocusProject = 'ChatFocusProject';
|
|
6563
6833
|
const ChatHeader = 'ChatHeader';
|
|
6564
6834
|
const ChatHeaderLabel = 'ChatHeaderLabel';
|
|
@@ -6595,9 +6865,19 @@ const ChatComposerAttachmentImage = 'ChatComposerAttachmentImage';
|
|
|
6595
6865
|
const ChatComposerAttachmentInvalidImage = 'ChatComposerAttachmentInvalidImage';
|
|
6596
6866
|
const ChatComposerAttachmentLabel = 'ChatComposerAttachmentLabel';
|
|
6597
6867
|
const ChatComposerAttachmentPreview = 'ChatComposerAttachmentPreview';
|
|
6868
|
+
const ChatComposerAttachmentPreviewOverlay = 'ChatComposerAttachmentPreviewOverlay';
|
|
6869
|
+
const ChatComposerAttachmentPreviewOverlayError = 'ChatComposerAttachmentPreviewOverlayError';
|
|
6870
|
+
const ChatComposerAttachmentPreviewOverlayImage = 'ChatComposerAttachmentPreviewOverlayImage';
|
|
6598
6871
|
const ChatComposerAttachmentRemoveButton = 'ChatComposerAttachmentRemoveButton';
|
|
6599
6872
|
const ChatComposerAttachments = 'ChatComposerAttachments';
|
|
6600
6873
|
const ChatComposerAttachmentTextFile = 'ChatComposerAttachmentTextFile';
|
|
6874
|
+
const ChatAttachment = 'ChatAttachment';
|
|
6875
|
+
const ChatAttachmentImage = 'ChatAttachmentImage';
|
|
6876
|
+
const ChatAttachmentInvalidImage = 'ChatAttachmentInvalidImage';
|
|
6877
|
+
const ChatAttachmentLabel = 'ChatAttachmentLabel';
|
|
6878
|
+
const ChatAttachmentPreview = 'ChatAttachmentPreview';
|
|
6879
|
+
const ChatAttachments = 'ChatAttachments';
|
|
6880
|
+
const ChatAttachmentTextFile = 'ChatAttachmentTextFile';
|
|
6601
6881
|
const ChatSendArea = 'ChatSendArea';
|
|
6602
6882
|
const ChatSendAreaBottom = 'ChatSendAreaBottom';
|
|
6603
6883
|
const ChatSendAreaContent = 'ChatSendAreaContent';
|
|
@@ -6633,6 +6913,7 @@ const FileIcon = 'FileIcon';
|
|
|
6633
6913
|
const IconButton = 'IconButton';
|
|
6634
6914
|
const IconButtonDisabled = 'IconButtonDisabled';
|
|
6635
6915
|
const ImageElement = 'ImageElement';
|
|
6916
|
+
const ImageErrorMessage = 'ImageErrorMessage';
|
|
6636
6917
|
const InputBox = 'InputBox';
|
|
6637
6918
|
const Insertion = 'Insertion';
|
|
6638
6919
|
const Label = 'Label';
|
|
@@ -6646,6 +6927,7 @@ const MaskIconAccount = 'MaskIconAccount';
|
|
|
6646
6927
|
const MaskIconAdd = 'MaskIconAdd';
|
|
6647
6928
|
const MaskIconArrowLeft = 'MaskIconArrowLeft';
|
|
6648
6929
|
const MaskIconChevronDown = 'MaskIconChevronDown';
|
|
6930
|
+
const MaskIconChevronRight = 'MaskIconChevronRight';
|
|
6649
6931
|
const MaskIconChevronUp = 'MaskIconChevronUp';
|
|
6650
6932
|
const MaskIconClose = 'MaskIconClose';
|
|
6651
6933
|
const MaskIconDebugPause = 'MaskIconDebugPause';
|
|
@@ -8245,15 +8527,6 @@ const getSlashCommandHandler = command => {
|
|
|
8245
8527
|
return slashCommandRegistry[command];
|
|
8246
8528
|
};
|
|
8247
8529
|
|
|
8248
|
-
const focusInput = state => {
|
|
8249
|
-
return {
|
|
8250
|
-
...state,
|
|
8251
|
-
focus: 'composer',
|
|
8252
|
-
focused: true,
|
|
8253
|
-
listFocusedIndex: -1
|
|
8254
|
-
};
|
|
8255
|
-
};
|
|
8256
|
-
|
|
8257
8530
|
const withClearedComposer = state => {
|
|
8258
8531
|
return focusInput({
|
|
8259
8532
|
...state,
|
|
@@ -8407,12 +8680,6 @@ const getMentionContextMessage = async value => {
|
|
|
8407
8680
|
};
|
|
8408
8681
|
};
|
|
8409
8682
|
|
|
8410
|
-
const AutoScrollTopA = Number.MAX_SAFE_INTEGER;
|
|
8411
|
-
const AutoScrollTopB = Number.MAX_SAFE_INTEGER - 1;
|
|
8412
|
-
const getNextAutoScrollTop = currentScrollTop => {
|
|
8413
|
-
return currentScrollTop === AutoScrollTopA ? AutoScrollTopB : AutoScrollTopA;
|
|
8414
|
-
};
|
|
8415
|
-
|
|
8416
8683
|
const slashCommandRegex = /^\/([a-z][a-z0-9-]*)(?:\s+.*)?$/i;
|
|
8417
8684
|
const getSlashCommand = value => {
|
|
8418
8685
|
const trimmed = value.trim();
|
|
@@ -8690,6 +8957,19 @@ const withUpdatedMessageScrollTop = state => {
|
|
|
8690
8957
|
};
|
|
8691
8958
|
};
|
|
8692
8959
|
const workspaceUriPlaceholder = '{{workspaceUri}}';
|
|
8960
|
+
const clearComposerAttachments = async (sessionId, attachmentIds) => {
|
|
8961
|
+
if (!sessionId) {
|
|
8962
|
+
return;
|
|
8963
|
+
}
|
|
8964
|
+
for (const attachmentId of attachmentIds) {
|
|
8965
|
+
await appendChatViewEvent({
|
|
8966
|
+
attachmentId,
|
|
8967
|
+
sessionId,
|
|
8968
|
+
timestamp: new Date().toISOString(),
|
|
8969
|
+
type: 'chat-attachment-removed'
|
|
8970
|
+
});
|
|
8971
|
+
}
|
|
8972
|
+
};
|
|
8693
8973
|
const getCurrentDate = () => {
|
|
8694
8974
|
return new Date().toISOString().slice(0, 10);
|
|
8695
8975
|
};
|
|
@@ -8782,7 +9062,12 @@ const handleSubmit = async state => {
|
|
|
8782
9062
|
minute: '2-digit'
|
|
8783
9063
|
});
|
|
8784
9064
|
const userMessageId = crypto.randomUUID();
|
|
9065
|
+
const composerAttachments = state.composerAttachments.length > 0 ? state.composerAttachments : await getComposerAttachments(state.selectedSessionId);
|
|
9066
|
+
await clearComposerAttachments(state.selectedSessionId, composerAttachments.map(attachment => attachment.attachmentId));
|
|
8785
9067
|
const userMessage = {
|
|
9068
|
+
...(composerAttachments.length > 0 ? {
|
|
9069
|
+
attachments: composerAttachments
|
|
9070
|
+
} : {}),
|
|
8786
9071
|
id: userMessageId,
|
|
8787
9072
|
role: 'user',
|
|
8788
9073
|
text: userText,
|
|
@@ -8897,6 +9182,9 @@ const handleSubmit = async state => {
|
|
|
8897
9182
|
latestState: optimisticState,
|
|
8898
9183
|
previousState: optimisticState
|
|
8899
9184
|
};
|
|
9185
|
+
let {
|
|
9186
|
+
mockOpenApiRequests
|
|
9187
|
+
} = optimisticState;
|
|
8900
9188
|
const selectedOptimisticSession = optimisticState.sessions.find(session => session.id === optimisticState.selectedSessionId);
|
|
8901
9189
|
const systemPrompt = getEffectiveSystemPrompt(optimisticState, selectedOptimisticSession);
|
|
8902
9190
|
const workspaceUri = getWorkspaceUri(optimisticState, selectedOptimisticSession);
|
|
@@ -8939,6 +9227,9 @@ const handleSubmit = async state => {
|
|
|
8939
9227
|
value: '[DONE]'
|
|
8940
9228
|
});
|
|
8941
9229
|
},
|
|
9230
|
+
onMockOpenApiRequestCaptured: async request => {
|
|
9231
|
+
mockOpenApiRequests = [...mockOpenApiRequests, request];
|
|
9232
|
+
},
|
|
8942
9233
|
...(handleTextChunkFunctionRef ? {
|
|
8943
9234
|
onTextChunk: handleTextChunkFunctionRef
|
|
8944
9235
|
} : {}),
|
|
@@ -8995,6 +9286,7 @@ const handleSubmit = async state => {
|
|
|
8995
9286
|
}
|
|
8996
9287
|
return withUpdatedMessageScrollTop(focusInput({
|
|
8997
9288
|
...latestState,
|
|
9289
|
+
mockOpenApiRequests,
|
|
8998
9290
|
nextMessageId: latestState.nextMessageId + 1,
|
|
8999
9291
|
parsedMessages: finalParsedMessages,
|
|
9000
9292
|
sessions: updatedSessions
|
|
@@ -9056,6 +9348,8 @@ const openAgentModePicker = state => {
|
|
|
9056
9348
|
return {
|
|
9057
9349
|
...state,
|
|
9058
9350
|
agentModePickerOpen,
|
|
9351
|
+
focus: agentModePickerOpen ? 'picker-list' : state.focus,
|
|
9352
|
+
focused: agentModePickerOpen ? true : state.focused,
|
|
9059
9353
|
modelPickerOpen: false,
|
|
9060
9354
|
modelPickerSearchValue: '',
|
|
9061
9355
|
reasoningEffortPickerOpen: false,
|
|
@@ -9074,6 +9368,8 @@ const openReasoningEffortPicker = state => {
|
|
|
9074
9368
|
return {
|
|
9075
9369
|
...state,
|
|
9076
9370
|
agentModePickerOpen: false,
|
|
9371
|
+
focus: reasoningEffortPickerOpen ? 'picker-list' : state.focus,
|
|
9372
|
+
focused: reasoningEffortPickerOpen ? true : state.focused,
|
|
9077
9373
|
modelPickerOpen: false,
|
|
9078
9374
|
modelPickerSearchValue: '',
|
|
9079
9375
|
reasoningEffortPickerOpen,
|
|
@@ -9099,6 +9395,8 @@ const openRunModePicker = state => {
|
|
|
9099
9395
|
return {
|
|
9100
9396
|
...state,
|
|
9101
9397
|
agentModePickerOpen: false,
|
|
9398
|
+
focus: runModePickerOpen ? 'picker-list' : state.focus,
|
|
9399
|
+
focused: runModePickerOpen ? true : state.focused,
|
|
9102
9400
|
modelPickerOpen: false,
|
|
9103
9401
|
modelPickerSearchValue: '',
|
|
9104
9402
|
reasoningEffortPickerOpen: false,
|
|
@@ -9360,8 +9658,16 @@ const handleClick = async (state, name, id = '', eventX = 0, eventY = 0) => {
|
|
|
9360
9658
|
}
|
|
9361
9659
|
case name === SessionDelete:
|
|
9362
9660
|
return deleteSession(state, id);
|
|
9661
|
+
case name === ProjectDelete:
|
|
9662
|
+
return deleteProject(state, id);
|
|
9363
9663
|
case name === Send:
|
|
9364
9664
|
return handleClickSend(state);
|
|
9665
|
+
case name === ScrollDown:
|
|
9666
|
+
return {
|
|
9667
|
+
...state,
|
|
9668
|
+
messagesAutoScrollEnabled: true,
|
|
9669
|
+
messagesScrollTop: getNextAutoScrollTop(state.messagesScrollTop)
|
|
9670
|
+
};
|
|
9365
9671
|
case name === SaveOpenRouterApiKey:
|
|
9366
9672
|
return handleClickSaveOpenRouterApiKey(state);
|
|
9367
9673
|
case name === SaveOpenApiApiKey:
|
|
@@ -9592,6 +9898,7 @@ const handleDropFiles = async (state, name, fileHandles = []) => {
|
|
|
9592
9898
|
const {
|
|
9593
9899
|
composerDropActive,
|
|
9594
9900
|
composerDropEnabled,
|
|
9901
|
+
nextAttachmentId,
|
|
9595
9902
|
selectedSessionId,
|
|
9596
9903
|
width
|
|
9597
9904
|
} = state;
|
|
@@ -9614,9 +9921,10 @@ const handleDropFiles = async (state, name, fileHandles = []) => {
|
|
|
9614
9921
|
const nextAttachments = [];
|
|
9615
9922
|
for (const droppedFileHandle of droppedFileHandles) {
|
|
9616
9923
|
const file = await droppedFileHandle.getFile();
|
|
9617
|
-
const attachmentId =
|
|
9924
|
+
const attachmentId = `attachment-${nextAttachmentId + nextAttachments.length}`;
|
|
9618
9925
|
const displayType = await getComposerAttachmentDisplayType(file, file.name, file.type);
|
|
9619
9926
|
const previewSrc = await getComposerAttachmentPreviewSrc(file, displayType, file.type);
|
|
9927
|
+
const textContent = await getComposerAttachmentTextContent(file, displayType);
|
|
9620
9928
|
await appendChatViewEvent({
|
|
9621
9929
|
attachmentId,
|
|
9622
9930
|
blob: file,
|
|
@@ -9635,13 +9943,27 @@ const handleDropFiles = async (state, name, fileHandles = []) => {
|
|
|
9635
9943
|
...(previewSrc ? {
|
|
9636
9944
|
previewSrc
|
|
9637
9945
|
} : {}),
|
|
9638
|
-
size: file.size
|
|
9946
|
+
size: file.size,
|
|
9947
|
+
...(typeof textContent === 'string' ? {
|
|
9948
|
+
textContent
|
|
9949
|
+
} : {})
|
|
9639
9950
|
});
|
|
9640
9951
|
}
|
|
9641
9952
|
return {
|
|
9642
9953
|
...nextState,
|
|
9643
9954
|
composerAttachments: [...nextState.composerAttachments, ...nextAttachments],
|
|
9644
|
-
composerAttachmentsHeight: getComposerAttachmentsHeight([...nextState.composerAttachments, ...nextAttachments], width)
|
|
9955
|
+
composerAttachmentsHeight: getComposerAttachmentsHeight([...nextState.composerAttachments, ...nextAttachments], width),
|
|
9956
|
+
nextAttachmentId: nextAttachmentId + nextAttachments.length
|
|
9957
|
+
};
|
|
9958
|
+
};
|
|
9959
|
+
|
|
9960
|
+
const handleErrorComposerAttachmentPreviewOverlay = async state => {
|
|
9961
|
+
if (!state.composerAttachmentPreviewOverlayAttachmentId || state.composerAttachmentPreviewOverlayError) {
|
|
9962
|
+
return state;
|
|
9963
|
+
}
|
|
9964
|
+
return {
|
|
9965
|
+
...state,
|
|
9966
|
+
composerAttachmentPreviewOverlayError: true
|
|
9645
9967
|
};
|
|
9646
9968
|
};
|
|
9647
9969
|
|
|
@@ -9845,6 +10167,60 @@ const handleModelChange = async (state, value) => {
|
|
|
9845
10167
|
};
|
|
9846
10168
|
};
|
|
9847
10169
|
|
|
10170
|
+
const hideComposerAttachmentPreviewOverlay = async state => {
|
|
10171
|
+
if (!state.composerAttachmentPreviewOverlayAttachmentId && !state.composerAttachmentPreviewOverlayError) {
|
|
10172
|
+
return state;
|
|
10173
|
+
}
|
|
10174
|
+
return {
|
|
10175
|
+
...state,
|
|
10176
|
+
composerAttachmentPreviewOverlayAttachmentId: '',
|
|
10177
|
+
composerAttachmentPreviewOverlayError: false
|
|
10178
|
+
};
|
|
10179
|
+
};
|
|
10180
|
+
|
|
10181
|
+
const isCurrentAttachmentTarget = (name, attachmentId) => {
|
|
10182
|
+
return name === getComposerAttachmentInputName(attachmentId) || isComposerAttachmentRemoveInputName(name) && getAttachmentIdFromComposerAttachmentRemoveInputName(name) === attachmentId;
|
|
10183
|
+
};
|
|
10184
|
+
const handleMouseOut = async (state, name, relatedName = '') => {
|
|
10185
|
+
const {
|
|
10186
|
+
composerAttachmentPreviewOverlayAttachmentId
|
|
10187
|
+
} = state;
|
|
10188
|
+
if (!composerAttachmentPreviewOverlayAttachmentId) {
|
|
10189
|
+
return state;
|
|
10190
|
+
}
|
|
10191
|
+
const isLeavingOverlay = isComposerAttachmentPreviewOverlayInputName(name);
|
|
10192
|
+
if (!isLeavingOverlay) {
|
|
10193
|
+
return state;
|
|
10194
|
+
}
|
|
10195
|
+
if (isComposerAttachmentPreviewOverlayInputName(relatedName) || isCurrentAttachmentTarget(relatedName, composerAttachmentPreviewOverlayAttachmentId)) {
|
|
10196
|
+
return state;
|
|
10197
|
+
}
|
|
10198
|
+
return hideComposerAttachmentPreviewOverlay(state);
|
|
10199
|
+
};
|
|
10200
|
+
|
|
10201
|
+
const showComposerAttachmentPreviewOverlay = async (state, attachmentId) => {
|
|
10202
|
+
const attachment = state.composerAttachments.find(item => item.attachmentId === attachmentId) ?? state.composerAttachments.find(item => item.displayType === 'image' && !!item.previewSrc);
|
|
10203
|
+
if (!attachment || attachment.displayType !== 'image' || !attachment.previewSrc) {
|
|
10204
|
+
return state;
|
|
10205
|
+
}
|
|
10206
|
+
if (state.composerAttachmentPreviewOverlayAttachmentId === attachmentId && !state.composerAttachmentPreviewOverlayError) {
|
|
10207
|
+
return state;
|
|
10208
|
+
}
|
|
10209
|
+
return {
|
|
10210
|
+
...state,
|
|
10211
|
+
composerAttachmentPreviewOverlayAttachmentId: attachmentId,
|
|
10212
|
+
composerAttachmentPreviewOverlayError: false
|
|
10213
|
+
};
|
|
10214
|
+
};
|
|
10215
|
+
|
|
10216
|
+
const handleMouseOver = async (state, name) => {
|
|
10217
|
+
if (!isComposerAttachmentInputName(name)) {
|
|
10218
|
+
return state;
|
|
10219
|
+
}
|
|
10220
|
+
const attachmentId = getAttachmentIdFromComposerAttachmentInputName(name);
|
|
10221
|
+
return showComposerAttachmentPreviewOverlay(state, attachmentId);
|
|
10222
|
+
};
|
|
10223
|
+
|
|
9848
10224
|
const handleNewline = async state => {
|
|
9849
10225
|
const {
|
|
9850
10226
|
composerValue
|
|
@@ -9870,7 +10246,7 @@ const handleProjectAddButtonContextMenu = async (state, button, x, y) => {
|
|
|
9870
10246
|
return state;
|
|
9871
10247
|
};
|
|
9872
10248
|
|
|
9873
|
-
const
|
|
10249
|
+
const getProjectAtIndex = (state, index) => {
|
|
9874
10250
|
const {
|
|
9875
10251
|
projectExpandedIds,
|
|
9876
10252
|
projects,
|
|
@@ -9880,7 +10256,7 @@ const getProjectIdAtIndex = (state, index) => {
|
|
|
9880
10256
|
let currentIndex = 0;
|
|
9881
10257
|
for (const project of projects) {
|
|
9882
10258
|
if (currentIndex === index) {
|
|
9883
|
-
return project
|
|
10259
|
+
return project;
|
|
9884
10260
|
}
|
|
9885
10261
|
currentIndex++;
|
|
9886
10262
|
if (projectExpandedIds.includes(project.id)) {
|
|
@@ -9890,13 +10266,13 @@ const getProjectIdAtIndex = (state, index) => {
|
|
|
9890
10266
|
continue;
|
|
9891
10267
|
}
|
|
9892
10268
|
if (currentIndex === index) {
|
|
9893
|
-
return project
|
|
10269
|
+
return project;
|
|
9894
10270
|
}
|
|
9895
10271
|
currentIndex++;
|
|
9896
10272
|
}
|
|
9897
10273
|
}
|
|
9898
10274
|
}
|
|
9899
|
-
return
|
|
10275
|
+
return undefined;
|
|
9900
10276
|
};
|
|
9901
10277
|
const handleProjectListContextMenu = async (state, button, x, y) => {
|
|
9902
10278
|
const {
|
|
@@ -9909,13 +10285,14 @@ const handleProjectListContextMenu = async (state, button, x, y) => {
|
|
|
9909
10285
|
if (index < 0) {
|
|
9910
10286
|
return state;
|
|
9911
10287
|
}
|
|
9912
|
-
const
|
|
9913
|
-
if (!
|
|
10288
|
+
const project = getProjectAtIndex(state, index);
|
|
10289
|
+
if (!project) {
|
|
9914
10290
|
return state;
|
|
9915
10291
|
}
|
|
9916
10292
|
await showContextMenu2(uid, MenuChatProjectList, x, y, {
|
|
10293
|
+
canRemoveProject: project.name !== '_blank',
|
|
9917
10294
|
menuId: MenuChatProjectList,
|
|
9918
|
-
projectId
|
|
10295
|
+
projectId: project.id
|
|
9919
10296
|
});
|
|
9920
10297
|
return state;
|
|
9921
10298
|
};
|
|
@@ -10038,6 +10415,23 @@ const getSavedChatListScrollTop = savedState => {
|
|
|
10038
10415
|
return chatListScrollTop;
|
|
10039
10416
|
};
|
|
10040
10417
|
|
|
10418
|
+
const getSavedComposerSelection = (savedState, composerValue) => {
|
|
10419
|
+
if (!isObject$1(savedState)) {
|
|
10420
|
+
return undefined;
|
|
10421
|
+
}
|
|
10422
|
+
const {
|
|
10423
|
+
composerSelectionEnd,
|
|
10424
|
+
composerSelectionStart
|
|
10425
|
+
} = savedState;
|
|
10426
|
+
if (typeof composerSelectionStart !== 'number') {
|
|
10427
|
+
return undefined;
|
|
10428
|
+
}
|
|
10429
|
+
if (typeof composerSelectionEnd !== 'number') {
|
|
10430
|
+
return undefined;
|
|
10431
|
+
}
|
|
10432
|
+
return getNormalizedComposerSelection(composerValue, composerSelectionStart, composerSelectionEnd);
|
|
10433
|
+
};
|
|
10434
|
+
|
|
10041
10435
|
const getSavedComposerValue = savedState => {
|
|
10042
10436
|
if (!isObject$1(savedState)) {
|
|
10043
10437
|
return undefined;
|
|
@@ -10339,16 +10733,25 @@ const loadReasoningPickerEnabled = async () => {
|
|
|
10339
10733
|
}
|
|
10340
10734
|
};
|
|
10341
10735
|
|
|
10342
|
-
const
|
|
10736
|
+
const loadScrollDownButtonEnabled = async () => {
|
|
10343
10737
|
try {
|
|
10344
|
-
const
|
|
10345
|
-
return typeof
|
|
10738
|
+
const savedScrollDownButtonEnabled = await get('chatView.scrollDownButtonEnabled');
|
|
10739
|
+
return typeof savedScrollDownButtonEnabled === 'boolean' ? savedScrollDownButtonEnabled : false;
|
|
10346
10740
|
} catch {
|
|
10347
10741
|
return false;
|
|
10348
10742
|
}
|
|
10349
10743
|
};
|
|
10350
10744
|
|
|
10351
|
-
const
|
|
10745
|
+
const loadSearchEnabled = async () => {
|
|
10746
|
+
try {
|
|
10747
|
+
const savedSearchEnabled = await get('chatView.searchEnabled');
|
|
10748
|
+
return typeof savedSearchEnabled === 'boolean' ? savedSearchEnabled : false;
|
|
10749
|
+
} catch {
|
|
10750
|
+
return false;
|
|
10751
|
+
}
|
|
10752
|
+
};
|
|
10753
|
+
|
|
10754
|
+
const loadStreamingEnabled = async () => {
|
|
10352
10755
|
try {
|
|
10353
10756
|
const savedStreamingEnabled = await get('chatView.streamingEnabled');
|
|
10354
10757
|
return typeof savedStreamingEnabled === 'boolean' ? savedStreamingEnabled : true;
|
|
@@ -10430,7 +10833,7 @@ const loadVoiceDictationEnabled = async () => {
|
|
|
10430
10833
|
};
|
|
10431
10834
|
|
|
10432
10835
|
const loadPreferences = async () => {
|
|
10433
|
-
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()]);
|
|
10836
|
+
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()]);
|
|
10434
10837
|
return {
|
|
10435
10838
|
aiSessionTitleGenerationEnabled,
|
|
10436
10839
|
authAccessToken,
|
|
@@ -10444,6 +10847,7 @@ const loadPreferences = async () => {
|
|
|
10444
10847
|
openRouterApiKey,
|
|
10445
10848
|
passIncludeObfuscation,
|
|
10446
10849
|
reasoningPickerEnabled,
|
|
10850
|
+
scrollDownButtonEnabled,
|
|
10447
10851
|
searchEnabled,
|
|
10448
10852
|
streamingEnabled,
|
|
10449
10853
|
todoListToolEnabled,
|
|
@@ -10501,6 +10905,9 @@ const loadContent = async (state, savedState) => {
|
|
|
10501
10905
|
const savedSelectedModelId = getSavedSelectedModelId(savedState);
|
|
10502
10906
|
const savedViewMode = getSavedViewMode(savedState);
|
|
10503
10907
|
const savedComposerValue = getSavedComposerValue(savedState);
|
|
10908
|
+
const composerValue = savedComposerValue ?? state.composerValue;
|
|
10909
|
+
const savedComposerSelection = getSavedComposerSelection(savedState, composerValue);
|
|
10910
|
+
const [composerSelectionStart, composerSelectionEnd] = savedComposerSelection ?? [state.composerSelectionStart, state.composerSelectionEnd];
|
|
10504
10911
|
const {
|
|
10505
10912
|
aiSessionTitleGenerationEnabled,
|
|
10506
10913
|
authAccessToken,
|
|
@@ -10514,6 +10921,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10514
10921
|
openRouterApiKey,
|
|
10515
10922
|
passIncludeObfuscation,
|
|
10516
10923
|
reasoningPickerEnabled,
|
|
10924
|
+
scrollDownButtonEnabled,
|
|
10517
10925
|
searchEnabled,
|
|
10518
10926
|
streamingEnabled,
|
|
10519
10927
|
todoListToolEnabled,
|
|
@@ -10592,7 +11000,9 @@ const loadContent = async (state, savedState) => {
|
|
|
10592
11000
|
composerAttachmentsHeight: getComposerAttachmentsHeight(composerAttachments, state.width),
|
|
10593
11001
|
composerDropActive: false,
|
|
10594
11002
|
composerDropEnabled,
|
|
10595
|
-
|
|
11003
|
+
composerSelectionEnd,
|
|
11004
|
+
composerSelectionStart,
|
|
11005
|
+
composerValue,
|
|
10596
11006
|
emitStreamingFunctionCallEvents,
|
|
10597
11007
|
initial: false,
|
|
10598
11008
|
lastNormalViewMode,
|
|
@@ -10614,6 +11024,7 @@ const loadContent = async (state, savedState) => {
|
|
|
10614
11024
|
reasoningEffortPickerOpen: false,
|
|
10615
11025
|
reasoningPickerEnabled,
|
|
10616
11026
|
runModePickerOpen: false,
|
|
11027
|
+
scrollDownButtonEnabled,
|
|
10617
11028
|
searchEnabled,
|
|
10618
11029
|
searchFieldVisible: false,
|
|
10619
11030
|
searchValue: '',
|
|
@@ -10671,7 +11082,7 @@ const mockOpenApiRequestGetAll = _state => {
|
|
|
10671
11082
|
};
|
|
10672
11083
|
|
|
10673
11084
|
const mockOpenApiRequestReset = state => {
|
|
10674
|
-
reset$
|
|
11085
|
+
reset$2();
|
|
10675
11086
|
return state;
|
|
10676
11087
|
};
|
|
10677
11088
|
|
|
@@ -10696,10 +11107,33 @@ const mockOpenApiStreamPushChunk = (state, chunk) => {
|
|
|
10696
11107
|
};
|
|
10697
11108
|
|
|
10698
11109
|
const mockOpenApiStreamReset = state => {
|
|
10699
|
-
reset$
|
|
11110
|
+
reset$1();
|
|
10700
11111
|
return state;
|
|
10701
11112
|
};
|
|
10702
11113
|
|
|
11114
|
+
const openMockProject = async (state, projectId, projectName, projectUri) => {
|
|
11115
|
+
if (!projectId || !projectName) {
|
|
11116
|
+
return state;
|
|
11117
|
+
}
|
|
11118
|
+
const project = {
|
|
11119
|
+
id: projectId,
|
|
11120
|
+
name: projectName,
|
|
11121
|
+
uri: projectUri
|
|
11122
|
+
};
|
|
11123
|
+
const projects = state.projects.some(candidate => candidate.id === projectId) ? state.projects.map(candidate => {
|
|
11124
|
+
if (candidate.id !== projectId) {
|
|
11125
|
+
return candidate;
|
|
11126
|
+
}
|
|
11127
|
+
return project;
|
|
11128
|
+
}) : [...state.projects, project];
|
|
11129
|
+
return {
|
|
11130
|
+
...state,
|
|
11131
|
+
projectExpandedIds: state.projectExpandedIds.includes(projectId) ? state.projectExpandedIds : [...state.projectExpandedIds, projectId],
|
|
11132
|
+
projects,
|
|
11133
|
+
selectedProjectId: projectId
|
|
11134
|
+
};
|
|
11135
|
+
};
|
|
11136
|
+
|
|
10703
11137
|
const openMockSession = async (state, mockSessionId, mockChatMessages) => {
|
|
10704
11138
|
const {
|
|
10705
11139
|
sessions: currentSessions
|
|
@@ -10744,7 +11178,7 @@ const pasteInput = async state => {
|
|
|
10744
11178
|
};
|
|
10745
11179
|
|
|
10746
11180
|
const registerMockResponse = (state, mockResponse) => {
|
|
10747
|
-
reset$
|
|
11181
|
+
reset$1();
|
|
10748
11182
|
pushChunk(mockResponse.text);
|
|
10749
11183
|
finish();
|
|
10750
11184
|
return state;
|
|
@@ -10852,6 +11286,93 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10852
11286
|
border-color: var(--vscode-charts-green, var(--vscode-widget-border, var(--vscode-panel-border)));
|
|
10853
11287
|
}
|
|
10854
11288
|
|
|
11289
|
+
.ChatAttachments{
|
|
11290
|
+
display: flex;
|
|
11291
|
+
flex-wrap: wrap;
|
|
11292
|
+
gap: 8px;
|
|
11293
|
+
margin-top: 8px;
|
|
11294
|
+
}
|
|
11295
|
+
|
|
11296
|
+
.ChatAttachment{
|
|
11297
|
+
align-items: center;
|
|
11298
|
+
display: inline-flex;
|
|
11299
|
+
gap: 6px;
|
|
11300
|
+
max-width: 100%;
|
|
11301
|
+
min-width: 0;
|
|
11302
|
+
overflow: hidden;
|
|
11303
|
+
border-radius: 999px;
|
|
11304
|
+
border: 1px solid var(--vscode-widget-border, var(--vscode-panel-border));
|
|
11305
|
+
padding: 4px 10px;
|
|
11306
|
+
background: var(--vscode-badge-background, color-mix(in srgb, var(--vscode-editor-background) 88%, white));
|
|
11307
|
+
color: var(--vscode-badge-foreground, var(--vscode-foreground));
|
|
11308
|
+
font-size: 12px;
|
|
11309
|
+
}
|
|
11310
|
+
|
|
11311
|
+
.ChatAttachmentLabel{
|
|
11312
|
+
min-width: 0;
|
|
11313
|
+
overflow: hidden;
|
|
11314
|
+
text-overflow: ellipsis;
|
|
11315
|
+
white-space: nowrap;
|
|
11316
|
+
}
|
|
11317
|
+
|
|
11318
|
+
.ChatAttachmentPreview{
|
|
11319
|
+
width: 20px;
|
|
11320
|
+
height: 20px;
|
|
11321
|
+
flex: none;
|
|
11322
|
+
border-radius: 4px;
|
|
11323
|
+
object-fit: cover;
|
|
11324
|
+
}
|
|
11325
|
+
|
|
11326
|
+
.ChatAttachmentImage{
|
|
11327
|
+
border-color: var(--vscode-charts-blue);
|
|
11328
|
+
}
|
|
11329
|
+
|
|
11330
|
+
.ChatAttachmentInvalidImage{
|
|
11331
|
+
border-color: var(--vscode-inputValidation-errorBorder, var(--vscode-errorForeground));
|
|
11332
|
+
color: var(--vscode-errorForeground, var(--vscode-foreground));
|
|
11333
|
+
}
|
|
11334
|
+
|
|
11335
|
+
.ChatAttachmentTextFile{
|
|
11336
|
+
border-color: var(--vscode-charts-green, var(--vscode-widget-border, var(--vscode-panel-border)));
|
|
11337
|
+
}
|
|
11338
|
+
|
|
11339
|
+
.Chat{
|
|
11340
|
+
position: relative;
|
|
11341
|
+
}
|
|
11342
|
+
|
|
11343
|
+
.ChatComposerAttachmentPreviewOverlay{
|
|
11344
|
+
position: absolute;
|
|
11345
|
+
left: calc(var(--ChatSendAreaPaddingLeft) + 8px);
|
|
11346
|
+
bottom: calc(var(--ChatSendAreaHeight) - 12px);
|
|
11347
|
+
z-index: 6;
|
|
11348
|
+
width: 240px;
|
|
11349
|
+
min-width: 160px;
|
|
11350
|
+
min-height: 160px;
|
|
11351
|
+
max-width: calc(100% - var(--ChatSendAreaPaddingLeft) - var(--ChatSendAreaPaddingRight) - 16px);
|
|
11352
|
+
display: flex;
|
|
11353
|
+
align-items: center;
|
|
11354
|
+
justify-content: center;
|
|
11355
|
+
border: 1px solid var(--vscode-widget-border, var(--vscode-panel-border));
|
|
11356
|
+
border-radius: 12px;
|
|
11357
|
+
background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
|
|
11358
|
+
box-shadow: 0 12px 28px color-mix(in srgb, var(--vscode-editor-background) 45%, black);
|
|
11359
|
+
overflow: hidden;
|
|
11360
|
+
}
|
|
11361
|
+
|
|
11362
|
+
.ChatComposerAttachmentPreviewOverlayImage{
|
|
11363
|
+
display: block;
|
|
11364
|
+
width: 100%;
|
|
11365
|
+
max-width: 100%;
|
|
11366
|
+
max-height: min(320px, calc(100vh - 200px));
|
|
11367
|
+
object-fit: contain;
|
|
11368
|
+
background: color-mix(in srgb, var(--vscode-editor-background) 88%, black);
|
|
11369
|
+
}
|
|
11370
|
+
|
|
11371
|
+
.ChatComposerAttachmentPreviewOverlayError{
|
|
11372
|
+
padding: 12px;
|
|
11373
|
+
color: var(--vscode-errorForeground, var(--vscode-foreground));
|
|
11374
|
+
}
|
|
11375
|
+
|
|
10855
11376
|
.CustomSelectContainer{
|
|
10856
11377
|
position: relative;
|
|
10857
11378
|
min-width: 0;
|
|
@@ -10889,6 +11410,13 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10889
11410
|
color: var(--vscode-textLink-foreground);
|
|
10890
11411
|
}
|
|
10891
11412
|
|
|
11413
|
+
.ProjectListChevron{
|
|
11414
|
+
display: inline-block;
|
|
11415
|
+
flex: none;
|
|
11416
|
+
height: 16px;
|
|
11417
|
+
width: 16px;
|
|
11418
|
+
}
|
|
11419
|
+
|
|
10892
11420
|
.ChatOrderedListItem{
|
|
10893
11421
|
align-items: flex-start;
|
|
10894
11422
|
display: flex;
|
|
@@ -10931,6 +11459,22 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10931
11459
|
min-width: 0;
|
|
10932
11460
|
}
|
|
10933
11461
|
|
|
11462
|
+
.ChatMessages > .Message{
|
|
11463
|
+
display: flex;
|
|
11464
|
+
}
|
|
11465
|
+
|
|
11466
|
+
.ChatMessages > .MessageUser{
|
|
11467
|
+
justify-content: flex-end;
|
|
11468
|
+
}
|
|
11469
|
+
|
|
11470
|
+
.ChatMessages > .MessageAssistant{
|
|
11471
|
+
justify-content: flex-start;
|
|
11472
|
+
}
|
|
11473
|
+
|
|
11474
|
+
.ChatMessages > .MessageUser .ChatAttachments{
|
|
11475
|
+
justify-content: flex-end;
|
|
11476
|
+
}
|
|
11477
|
+
|
|
10934
11478
|
.ChatFocus .ChatMessages > .Message{
|
|
10935
11479
|
inline-size: fit-content;
|
|
10936
11480
|
max-inline-size: min(100%, var(--ChatFocusContentMaxWidth));
|
|
@@ -10940,6 +11484,24 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
|
|
|
10940
11484
|
max-inline-size: 100%;
|
|
10941
11485
|
}
|
|
10942
11486
|
|
|
11487
|
+
|
|
11488
|
+
.Viewlet.Chat.ChatFocus{
|
|
11489
|
+
display: flex !important;
|
|
11490
|
+
min-width: 0;
|
|
11491
|
+
}
|
|
11492
|
+
|
|
11493
|
+
.ChatFocusMainArea{
|
|
11494
|
+
display: flex;
|
|
11495
|
+
flex: 1;
|
|
11496
|
+
flex-direction: column;
|
|
11497
|
+
min-width: 0;
|
|
11498
|
+
}
|
|
11499
|
+
|
|
11500
|
+
.ChatFocusMainArea > .ChatMessages{
|
|
11501
|
+
flex: 1;
|
|
11502
|
+
min-height: 0;
|
|
11503
|
+
}
|
|
11504
|
+
|
|
10943
11505
|
`;
|
|
10944
11506
|
return `${baseCss}
|
|
10945
11507
|
|
|
@@ -10977,6 +11539,7 @@ const renderCss = (oldState, newState) => {
|
|
|
10977
11539
|
return [SetCss, uid, css];
|
|
10978
11540
|
};
|
|
10979
11541
|
|
|
11542
|
+
const pickerListSelector = '.ChatOverlays .ChatModelPickerList';
|
|
10980
11543
|
const getFocusSelector = state => {
|
|
10981
11544
|
const {
|
|
10982
11545
|
focus,
|
|
@@ -11002,6 +11565,8 @@ const getFocusSelector = state => {
|
|
|
11002
11565
|
}
|
|
11003
11566
|
case 'model-picker-input':
|
|
11004
11567
|
return `[name="${ModelPickerSearch}"]`;
|
|
11568
|
+
case 'picker-list':
|
|
11569
|
+
return pickerListSelector;
|
|
11005
11570
|
case 'send-button':
|
|
11006
11571
|
return '[name="send"]';
|
|
11007
11572
|
default:
|
|
@@ -11012,6 +11577,9 @@ const renderFocus = (oldState, newState) => {
|
|
|
11012
11577
|
if (newState.modelPickerOpen && !oldState.modelPickerOpen) {
|
|
11013
11578
|
return [FocusSelector, `[name="${ModelPickerSearch}"]`];
|
|
11014
11579
|
}
|
|
11580
|
+
if (newState.agentModePickerOpen && !oldState.agentModePickerOpen || newState.runModePickerOpen && !oldState.runModePickerOpen || newState.reasoningEffortPickerOpen && !oldState.reasoningEffortPickerOpen) {
|
|
11581
|
+
return [FocusSelector, pickerListSelector];
|
|
11582
|
+
}
|
|
11015
11583
|
const selector = getFocusSelector(newState);
|
|
11016
11584
|
return [FocusSelector, selector];
|
|
11017
11585
|
};
|
|
@@ -11029,6 +11597,8 @@ const renderFocusContext = (oldState, newState) => {
|
|
|
11029
11597
|
const HandleListContextMenu = 2;
|
|
11030
11598
|
const HandleFocus = 3;
|
|
11031
11599
|
const HandleInput = 4;
|
|
11600
|
+
const HandleMouseOut = 5;
|
|
11601
|
+
const HandleMouseOver = 7;
|
|
11032
11602
|
const HandleClick = 11;
|
|
11033
11603
|
const HandleKeyDown = 12;
|
|
11034
11604
|
const HandleClickClose = 13;
|
|
@@ -11076,6 +11646,7 @@ const HandlePointerUpModelPickerList = 55;
|
|
|
11076
11646
|
const HandleClickReasoningEffortPickerToggle = 56;
|
|
11077
11647
|
const HandleClickAgentModePickerToggle = 57;
|
|
11078
11648
|
const HandleContextMenuChatImageAttachment = 58;
|
|
11649
|
+
const HandleErrorComposerAttachmentPreviewOverlay = 59;
|
|
11079
11650
|
|
|
11080
11651
|
const getAddContextButtonDom = () => {
|
|
11081
11652
|
return [{
|
|
@@ -11192,6 +11763,8 @@ const getReasoningEffortPickerVirtualDom = (selectedReasoningEffort, reasoningEf
|
|
|
11192
11763
|
}, {
|
|
11193
11764
|
childCount: reasoningEfforts.length,
|
|
11194
11765
|
className: ChatModelPickerList,
|
|
11766
|
+
name: PickerList,
|
|
11767
|
+
tabIndex: -1,
|
|
11195
11768
|
type: Ul
|
|
11196
11769
|
}, ...getReasoningEffortOptionsVirtualDom(selectedReasoningEffort)] : [])];
|
|
11197
11770
|
};
|
|
@@ -11200,6 +11773,21 @@ const getRunModePickerVirtualDom = (selectedRunMode, runModePickerOpen) => {
|
|
|
11200
11773
|
return getCustomSelectPickerToggleVirtualDom(selectedRunMode, RunModePickerToggle, runModePickerOpen, HandleClickRunModePickerToggle);
|
|
11201
11774
|
};
|
|
11202
11775
|
|
|
11776
|
+
const getScrollDownButtonDom = () => {
|
|
11777
|
+
return [{
|
|
11778
|
+
childCount: 1,
|
|
11779
|
+
className: mergeClassNames(Button, ButtonSecondary),
|
|
11780
|
+
inputType: 'button',
|
|
11781
|
+
name: ScrollDown,
|
|
11782
|
+
onClick: HandleClick,
|
|
11783
|
+
title: scrollDown(),
|
|
11784
|
+
type: Button$1
|
|
11785
|
+
}, {
|
|
11786
|
+
text: scrollDown(),
|
|
11787
|
+
type: Text
|
|
11788
|
+
}];
|
|
11789
|
+
};
|
|
11790
|
+
|
|
11203
11791
|
const getSendButtonClassName = isSendDisabled => {
|
|
11204
11792
|
return mergeClassNames(IconButton, isSendDisabled ? SendButtonDisabled : '');
|
|
11205
11793
|
};
|
|
@@ -11375,10 +11963,15 @@ const getComposerAttachmentsDom = composerAttachments => {
|
|
|
11375
11963
|
childCount: 1 + (removeButtonDom.length > 0 ? 1 : 0) + previewDom.length,
|
|
11376
11964
|
className: mergeClassNames(ChatComposerAttachment, getComposerAttachmentClassName(attachment.displayType)),
|
|
11377
11965
|
name: getComposerAttachmentInputName(attachment.attachmentId),
|
|
11966
|
+
onMouseOut: HandleMouseOut,
|
|
11967
|
+
onMouseOver: HandleMouseOver,
|
|
11968
|
+
onPointerOut: HandleMouseOut,
|
|
11969
|
+
onPointerOver: HandleMouseOver,
|
|
11378
11970
|
type: Div
|
|
11379
11971
|
}, ...removeButtonDom, ...previewDom, {
|
|
11380
11972
|
childCount: 1,
|
|
11381
11973
|
className: ChatComposerAttachmentLabel,
|
|
11974
|
+
name: getComposerAttachmentInputName(attachment.attachmentId),
|
|
11382
11975
|
type: Span
|
|
11383
11976
|
}, {
|
|
11384
11977
|
text: `${getComposerAttachmentLabel(attachment.displayType)} · ${attachment.name}`,
|
|
@@ -11400,11 +11993,12 @@ const getComposerTextAreaDom = () => {
|
|
|
11400
11993
|
type: TextArea
|
|
11401
11994
|
};
|
|
11402
11995
|
};
|
|
11403
|
-
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) => {
|
|
11996
|
+
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) => {
|
|
11404
11997
|
const isSendDisabled = composerValue.trim() === '';
|
|
11405
11998
|
const showAgentModePicker = hasSpaceForAgentModePicker;
|
|
11406
11999
|
const showResponsiveRunModePicker = showRunMode && hasSpaceForRunModePicker;
|
|
11407
|
-
const
|
|
12000
|
+
const showScrollDownButton = scrollDownButtonEnabled && !messagesAutoScrollEnabled;
|
|
12001
|
+
const bottomControlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (addContextButtonEnabled ? 1 : 0) + (showCreatePullRequestButton ? 1 : 0) + (voiceDictationEnabled ? 1 : 0) + (showScrollDownButton ? 1 : 0);
|
|
11408
12002
|
const primaryControlsCount = 1 + (showAgentModePicker ? 1 : 0) + (reasoningPickerEnabled ? 1 : 0) + (showResponsiveRunModePicker ? 1 : 0);
|
|
11409
12003
|
const hasTodoList = todoListToolEnabled && todoListItems.length > 0;
|
|
11410
12004
|
const hasComposerAttachments = composerAttachments.length > 0;
|
|
@@ -11428,7 +12022,7 @@ const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agent
|
|
|
11428
12022
|
className: ChatSendAreaPrimaryControls,
|
|
11429
12023
|
role: 'toolbar',
|
|
11430
12024
|
type: Div
|
|
11431
|
-
}, ...(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)];
|
|
12025
|
+
}, ...(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)];
|
|
11432
12026
|
};
|
|
11433
12027
|
|
|
11434
12028
|
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;';
|
|
@@ -11482,6 +12076,10 @@ const getChatHeaderDomFocusMode = (selectedSessionTitle, selectedProjectName) =>
|
|
|
11482
12076
|
}, ...items.flatMap(([label, name]) => getFocusHeaderActionButtonDom(label, name))];
|
|
11483
12077
|
};
|
|
11484
12078
|
|
|
12079
|
+
const getAgentModeOptionsVirtualDom = selectedAgentMode => {
|
|
12080
|
+
return agentModes.flatMap(agentMode => getCustomSelectOptionVirtualDom(getAgentModePickerItemInputName(agentMode), getAgentModeLabel(agentMode), agentMode === selectedAgentMode));
|
|
12081
|
+
};
|
|
12082
|
+
|
|
11485
12083
|
const getCustomSelectPopOverVirtualDom = (optionCount, height, optionNodes, containerClassName = '', popOverClassName = '') => {
|
|
11486
12084
|
return [{
|
|
11487
12085
|
childCount: 1,
|
|
@@ -11495,14 +12093,13 @@ const getCustomSelectPopOverVirtualDom = (optionCount, height, optionNodes, cont
|
|
|
11495
12093
|
}, {
|
|
11496
12094
|
childCount: optionCount,
|
|
11497
12095
|
className: ChatModelPickerList,
|
|
12096
|
+
name: PickerList,
|
|
12097
|
+
tabIndex: -1,
|
|
11498
12098
|
type: Ul
|
|
11499
12099
|
}, ...optionNodes];
|
|
11500
12100
|
};
|
|
11501
12101
|
|
|
11502
12102
|
const agentModePickerHeight = agentModes.length * 28;
|
|
11503
|
-
const getAgentModeOptionsVirtualDom = selectedAgentMode => {
|
|
11504
|
-
return agentModes.flatMap(agentMode => getCustomSelectOptionVirtualDom(getAgentModePickerItemInputName(agentMode), getAgentModeLabel(agentMode), agentMode === selectedAgentMode));
|
|
11505
|
-
};
|
|
11506
12103
|
const getAgentModePickerPopOverVirtualDom = selectedAgentMode => {
|
|
11507
12104
|
return getCustomSelectPopOverVirtualDom(agentModes.length, agentModePickerHeight, getAgentModeOptionsVirtualDom(selectedAgentMode));
|
|
11508
12105
|
};
|
|
@@ -11573,6 +12170,42 @@ const getChatModelPickerPopOverVirtualDom = (models, selectedModelId, modelPicke
|
|
|
11573
12170
|
}, ...getModelPickerHeaderDom(modelPickerSearchValue), ...getChatModelListVirtualDom(visibleModels, selectedModelId)];
|
|
11574
12171
|
};
|
|
11575
12172
|
|
|
12173
|
+
const getComposerAttachmentPreviewOverlayVirtualDom = (composerAttachments, attachmentId, hasError) => {
|
|
12174
|
+
if (!attachmentId) {
|
|
12175
|
+
return [];
|
|
12176
|
+
}
|
|
12177
|
+
const attachment = composerAttachments.find(item => item.attachmentId === attachmentId);
|
|
12178
|
+
if (!attachment || attachment.displayType !== 'image' || !attachment.previewSrc) {
|
|
12179
|
+
return [];
|
|
12180
|
+
}
|
|
12181
|
+
return [{
|
|
12182
|
+
childCount: 1,
|
|
12183
|
+
className: ChatComposerAttachmentPreviewOverlay,
|
|
12184
|
+
name: ComposerAttachmentPreviewOverlay,
|
|
12185
|
+
onMouseOut: HandleMouseOut,
|
|
12186
|
+
onMouseOver: HandleMouseOver,
|
|
12187
|
+
onPointerOut: HandleMouseOut,
|
|
12188
|
+
onPointerOver: HandleMouseOver,
|
|
12189
|
+
type: Div
|
|
12190
|
+
}, ...(hasError ? [{
|
|
12191
|
+
childCount: 1,
|
|
12192
|
+
className: mergeClassNames(ChatComposerAttachmentPreviewOverlayError, ImageErrorMessage),
|
|
12193
|
+
name: ComposerAttachmentPreviewOverlay,
|
|
12194
|
+
type: Div
|
|
12195
|
+
}, {
|
|
12196
|
+
text: imageCouldNotBeLoaded(),
|
|
12197
|
+
type: Text
|
|
12198
|
+
}] : [{
|
|
12199
|
+
alt: `Large image preview for ${attachment.name}`,
|
|
12200
|
+
childCount: 0,
|
|
12201
|
+
className: ChatComposerAttachmentPreviewOverlayImage,
|
|
12202
|
+
name: ComposerAttachmentPreviewOverlay,
|
|
12203
|
+
onError: HandleErrorComposerAttachmentPreviewOverlay,
|
|
12204
|
+
src: attachment.previewSrc,
|
|
12205
|
+
type: Img
|
|
12206
|
+
}])];
|
|
12207
|
+
};
|
|
12208
|
+
|
|
11576
12209
|
const runModes = ['local', 'background', 'cloud'];
|
|
11577
12210
|
const runModePickerHeight = runModes.length * 28;
|
|
11578
12211
|
const getRunModeOptionsVirtualDom = selectedRunMode => {
|
|
@@ -11599,6 +12232,10 @@ const getDropOverlayVirtualDom = () => {
|
|
|
11599
12232
|
const getChatOverlaysVirtualDom = ({
|
|
11600
12233
|
agentMode,
|
|
11601
12234
|
agentModePickerVisible,
|
|
12235
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
12236
|
+
composerAttachmentPreviewOverlayError,
|
|
12237
|
+
composerAttachmentPreviewOverlayVisible,
|
|
12238
|
+
composerAttachments,
|
|
11602
12239
|
dropOverlayVisible,
|
|
11603
12240
|
modelPickerSearchValue,
|
|
11604
12241
|
modelPickerVisible,
|
|
@@ -11607,7 +12244,7 @@ const getChatOverlaysVirtualDom = ({
|
|
|
11607
12244
|
selectedModelId,
|
|
11608
12245
|
visibleModels
|
|
11609
12246
|
}) => {
|
|
11610
|
-
const overlayChildCount = (dropOverlayVisible ? 1 : 0) + (agentModePickerVisible ? 1 : 0) + (modelPickerVisible ? 1 : 0) + (runModePickerVisible ? 1 : 0);
|
|
12247
|
+
const overlayChildCount = (dropOverlayVisible ? 1 : 0) + (composerAttachmentPreviewOverlayVisible ? 1 : 0) + (agentModePickerVisible ? 1 : 0) + (modelPickerVisible ? 1 : 0) + (runModePickerVisible ? 1 : 0);
|
|
11611
12248
|
if (!overlayChildCount) {
|
|
11612
12249
|
return [];
|
|
11613
12250
|
}
|
|
@@ -11615,7 +12252,7 @@ const getChatOverlaysVirtualDom = ({
|
|
|
11615
12252
|
childCount: overlayChildCount,
|
|
11616
12253
|
className: ChatOverlays,
|
|
11617
12254
|
type: Div
|
|
11618
|
-
}, ...(dropOverlayVisible ? getDropOverlayVirtualDom() : []), ...(agentModePickerVisible ? getAgentModePickerPopOverVirtualDom(agentMode) : []), ...(modelPickerVisible ? getChatModelPickerPopOverVirtualDom(visibleModels, selectedModelId, modelPickerSearchValue) : []), ...(runModePickerVisible ? getRunModePickerPopOverVirtualDom(runMode) : [])];
|
|
12255
|
+
}, ...(dropOverlayVisible ? getDropOverlayVirtualDom() : []), ...getComposerAttachmentPreviewOverlayVirtualDom(composerAttachments, composerAttachmentPreviewOverlayAttachmentId, composerAttachmentPreviewOverlayError), ...(agentModePickerVisible ? getAgentModePickerPopOverVirtualDom(agentMode) : []), ...(modelPickerVisible ? getChatModelPickerPopOverVirtualDom(visibleModels, selectedModelId, modelPickerSearchValue) : []), ...(runModePickerVisible ? getRunModePickerPopOverVirtualDom(runMode) : [])];
|
|
11619
12256
|
};
|
|
11620
12257
|
|
|
11621
12258
|
const getBoldInlineNodeDom = (inlineNode, useChatMathWorker, renderInlineNodeDom) => {
|
|
@@ -11748,12 +12385,17 @@ const getTokenDom = token => {
|
|
|
11748
12385
|
|
|
11749
12386
|
const getCodeBlockDom = node => {
|
|
11750
12387
|
const tokenDom = node.codeTokens.flatMap(getTokenDom);
|
|
12388
|
+
const languageAttribute = node.language ? {
|
|
12389
|
+
'data-lang': node.language
|
|
12390
|
+
} : {};
|
|
11751
12391
|
return [{
|
|
11752
12392
|
childCount: 1,
|
|
11753
|
-
type: Pre
|
|
12393
|
+
type: Pre,
|
|
12394
|
+
...languageAttribute
|
|
11754
12395
|
}, {
|
|
11755
12396
|
childCount: node.codeTokens.length,
|
|
11756
|
-
type: Code
|
|
12397
|
+
type: Code,
|
|
12398
|
+
...languageAttribute
|
|
11757
12399
|
}, ...tokenDom];
|
|
11758
12400
|
};
|
|
11759
12401
|
|
|
@@ -12287,69 +12929,6 @@ const getToolCallCreateDirectoryVirtualDom = toolCall => {
|
|
|
12287
12929
|
}, ...getToolCallFileNameDom(directoryName, fileNameClickableProps), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12288
12930
|
};
|
|
12289
12931
|
|
|
12290
|
-
const getToolCallEditFileVirtualDom = toolCall => {
|
|
12291
|
-
const target = getReadFileTarget(toolCall.arguments);
|
|
12292
|
-
if (!target) {
|
|
12293
|
-
return [];
|
|
12294
|
-
}
|
|
12295
|
-
const fileName = getFileNameFromUri(target.title);
|
|
12296
|
-
const fileNameClickableProps = target.clickableUri ? {
|
|
12297
|
-
'data-uri': target.clickableUri,
|
|
12298
|
-
onClick: HandleClickFileName
|
|
12299
|
-
} : {};
|
|
12300
|
-
return [{
|
|
12301
|
-
childCount: 3,
|
|
12302
|
-
className: ChatOrderedListItem,
|
|
12303
|
-
title: target.title,
|
|
12304
|
-
type: Li
|
|
12305
|
-
}, {
|
|
12306
|
-
childCount: 0,
|
|
12307
|
-
className: FileIcon,
|
|
12308
|
-
type: Div
|
|
12309
|
-
}, {
|
|
12310
|
-
childCount: 1,
|
|
12311
|
-
className: ToolCallName,
|
|
12312
|
-
type: Span
|
|
12313
|
-
}, text('edit_file '), {
|
|
12314
|
-
childCount: 1,
|
|
12315
|
-
className: ChatToolCallReadFileLink,
|
|
12316
|
-
title: target.clickableUri,
|
|
12317
|
-
...fileNameClickableProps,
|
|
12318
|
-
type: Span
|
|
12319
|
-
}, ...getToolCallFileNameDom(fileName, fileNameClickableProps)];
|
|
12320
|
-
};
|
|
12321
|
-
|
|
12322
|
-
const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
12323
|
-
if (!toolCall.result) {
|
|
12324
|
-
return [];
|
|
12325
|
-
}
|
|
12326
|
-
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
12327
|
-
const fileName = getFileNameFromUri(toolCall.result);
|
|
12328
|
-
const fileNameClickableProps = {
|
|
12329
|
-
'data-uri': toolCall.result,
|
|
12330
|
-
onClick: HandleClickFileName
|
|
12331
|
-
};
|
|
12332
|
-
return [{
|
|
12333
|
-
childCount: statusLabel ? 4 : 3,
|
|
12334
|
-
className: ChatOrderedListItem,
|
|
12335
|
-
title: toolCall.result,
|
|
12336
|
-
type: Li
|
|
12337
|
-
}, {
|
|
12338
|
-
childCount: 0,
|
|
12339
|
-
className: FileIcon,
|
|
12340
|
-
type: Div
|
|
12341
|
-
}, {
|
|
12342
|
-
childCount: 1,
|
|
12343
|
-
className: ToolCallName,
|
|
12344
|
-
type: Span
|
|
12345
|
-
}, text('get_workspace_uri '), {
|
|
12346
|
-
childCount: 1,
|
|
12347
|
-
className: ChatToolCallReadFileLink,
|
|
12348
|
-
...fileNameClickableProps,
|
|
12349
|
-
type: Span
|
|
12350
|
-
}, ...getToolCallFileNameDom(fileName, fileNameClickableProps), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12351
|
-
};
|
|
12352
|
-
|
|
12353
12932
|
const getToolCallArgumentPreview = rawArguments => {
|
|
12354
12933
|
if (!rawArguments.trim()) {
|
|
12355
12934
|
return '""';
|
|
@@ -12424,6 +13003,91 @@ const getToolCallLabel = toolCall => {
|
|
|
12424
13003
|
return `${displayName} ${argumentPreview}${statusLabel}`;
|
|
12425
13004
|
};
|
|
12426
13005
|
|
|
13006
|
+
const RE_TOOL_NAME_PREFIX = /^([^ :]+)/;
|
|
13007
|
+
const getToolCallDefaultDom = toolCall => {
|
|
13008
|
+
const label = getToolCallLabel(toolCall);
|
|
13009
|
+
const match = RE_TOOL_NAME_PREFIX.exec(label);
|
|
13010
|
+
const toolNamePrefix = match ? match[1] : label;
|
|
13011
|
+
const suffix = label.slice(toolNamePrefix.length);
|
|
13012
|
+
const hasSuffix = suffix.length > 0;
|
|
13013
|
+
const hoverTitle = hasSuffix && toolCall.arguments.trim() ? toolCall.arguments : undefined;
|
|
13014
|
+
return [{
|
|
13015
|
+
childCount: hasSuffix ? 2 : 1,
|
|
13016
|
+
className: ChatOrderedListItem,
|
|
13017
|
+
...(hoverTitle ? {
|
|
13018
|
+
title: hoverTitle
|
|
13019
|
+
} : {}),
|
|
13020
|
+
type: Li
|
|
13021
|
+
}, {
|
|
13022
|
+
childCount: 1,
|
|
13023
|
+
className: ToolCallName,
|
|
13024
|
+
type: Span
|
|
13025
|
+
}, text(toolNamePrefix), ...(hasSuffix ? [text(suffix)] : [])];
|
|
13026
|
+
};
|
|
13027
|
+
|
|
13028
|
+
const getToolCallEditFileVirtualDom = toolCall => {
|
|
13029
|
+
const target = getReadFileTarget(toolCall.arguments);
|
|
13030
|
+
if (!target) {
|
|
13031
|
+
return [];
|
|
13032
|
+
}
|
|
13033
|
+
const fileName = getFileNameFromUri(target.title);
|
|
13034
|
+
const fileNameClickableProps = target.clickableUri ? {
|
|
13035
|
+
'data-uri': target.clickableUri,
|
|
13036
|
+
onClick: HandleClickFileName
|
|
13037
|
+
} : {};
|
|
13038
|
+
return [{
|
|
13039
|
+
childCount: 3,
|
|
13040
|
+
className: ChatOrderedListItem,
|
|
13041
|
+
title: target.title,
|
|
13042
|
+
type: Li
|
|
13043
|
+
}, {
|
|
13044
|
+
childCount: 0,
|
|
13045
|
+
className: FileIcon,
|
|
13046
|
+
type: Div
|
|
13047
|
+
}, {
|
|
13048
|
+
childCount: 1,
|
|
13049
|
+
className: ToolCallName,
|
|
13050
|
+
type: Span
|
|
13051
|
+
}, text('edit_file '), {
|
|
13052
|
+
childCount: 1,
|
|
13053
|
+
className: ChatToolCallReadFileLink,
|
|
13054
|
+
title: target.clickableUri,
|
|
13055
|
+
...fileNameClickableProps,
|
|
13056
|
+
type: Span
|
|
13057
|
+
}, ...getToolCallFileNameDom(fileName, fileNameClickableProps)];
|
|
13058
|
+
};
|
|
13059
|
+
|
|
13060
|
+
const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
13061
|
+
if (!toolCall.result) {
|
|
13062
|
+
return [];
|
|
13063
|
+
}
|
|
13064
|
+
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
13065
|
+
const fileName = getFileNameFromUri(toolCall.result);
|
|
13066
|
+
const fileNameClickableProps = {
|
|
13067
|
+
'data-uri': toolCall.result,
|
|
13068
|
+
onClick: HandleClickFileName
|
|
13069
|
+
};
|
|
13070
|
+
return [{
|
|
13071
|
+
childCount: statusLabel ? 4 : 3,
|
|
13072
|
+
className: ChatOrderedListItem,
|
|
13073
|
+
title: toolCall.result,
|
|
13074
|
+
type: Li
|
|
13075
|
+
}, {
|
|
13076
|
+
childCount: 0,
|
|
13077
|
+
className: FileIcon,
|
|
13078
|
+
type: Div
|
|
13079
|
+
}, {
|
|
13080
|
+
childCount: 1,
|
|
13081
|
+
className: ToolCallName,
|
|
13082
|
+
type: Span
|
|
13083
|
+
}, text('get_workspace_uri '), {
|
|
13084
|
+
childCount: 1,
|
|
13085
|
+
className: ChatToolCallReadFileLink,
|
|
13086
|
+
...fileNameClickableProps,
|
|
13087
|
+
type: Span
|
|
13088
|
+
}, ...getToolCallFileNameDom(fileName, fileNameClickableProps), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
13089
|
+
};
|
|
13090
|
+
|
|
12427
13091
|
const getToolCallReadFileVirtualDom = toolCall => {
|
|
12428
13092
|
const target = getReadFileTarget(toolCall.arguments);
|
|
12429
13093
|
if (!target) {
|
|
@@ -12847,7 +13511,6 @@ const getToolCallWriteFileVirtualDom = toolCall => {
|
|
|
12847
13511
|
}, text(` -${linesDeleted}`)] : []), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
12848
13512
|
};
|
|
12849
13513
|
|
|
12850
|
-
const RE_TOOL_NAME_PREFIX = /^([^ :]+)/;
|
|
12851
13514
|
const getToolCallDom = toolCall => {
|
|
12852
13515
|
if (toolCall.name === 'getWorkspaceUri') {
|
|
12853
13516
|
const virtualDom = getToolCallGetWorkspaceUriVirtualDom(toolCall);
|
|
@@ -12891,24 +13554,7 @@ const getToolCallDom = toolCall => {
|
|
|
12891
13554
|
return virtualDom;
|
|
12892
13555
|
}
|
|
12893
13556
|
}
|
|
12894
|
-
|
|
12895
|
-
const match = RE_TOOL_NAME_PREFIX.exec(label);
|
|
12896
|
-
const toolNamePrefix = match ? match[1] : label;
|
|
12897
|
-
const suffix = label.slice(toolNamePrefix.length);
|
|
12898
|
-
const hasSuffix = suffix.length > 0;
|
|
12899
|
-
const hoverTitle = hasSuffix && toolCall.arguments.trim() ? toolCall.arguments : undefined;
|
|
12900
|
-
return [{
|
|
12901
|
-
childCount: hasSuffix ? 2 : 1,
|
|
12902
|
-
className: ChatOrderedListItem,
|
|
12903
|
-
...(hoverTitle ? {
|
|
12904
|
-
title: hoverTitle
|
|
12905
|
-
} : {}),
|
|
12906
|
-
type: Li
|
|
12907
|
-
}, {
|
|
12908
|
-
childCount: 1,
|
|
12909
|
-
className: ToolCallName,
|
|
12910
|
-
type: Span
|
|
12911
|
-
}, text(toolNamePrefix), ...(hasSuffix ? [text(suffix)] : [])];
|
|
13557
|
+
return getToolCallDefaultDom(toolCall);
|
|
12912
13558
|
};
|
|
12913
13559
|
|
|
12914
13560
|
const withOrderedListMarker = (virtualDom, index) => {
|
|
@@ -12966,6 +13612,70 @@ const getTopLevelNodeCount = nodes => {
|
|
|
12966
13612
|
return topLevelCount;
|
|
12967
13613
|
};
|
|
12968
13614
|
|
|
13615
|
+
const getChatAttachmentLabel = displayType => {
|
|
13616
|
+
switch (displayType) {
|
|
13617
|
+
case 'file':
|
|
13618
|
+
return 'File';
|
|
13619
|
+
case 'image':
|
|
13620
|
+
return 'Image';
|
|
13621
|
+
case 'invalid-image':
|
|
13622
|
+
return 'Invalid image';
|
|
13623
|
+
case 'text-file':
|
|
13624
|
+
return 'Text file';
|
|
13625
|
+
default:
|
|
13626
|
+
return displayType;
|
|
13627
|
+
}
|
|
13628
|
+
};
|
|
13629
|
+
const getChatAttachmentClassName = displayType => {
|
|
13630
|
+
switch (displayType) {
|
|
13631
|
+
case 'file':
|
|
13632
|
+
return ChatAttachment;
|
|
13633
|
+
case 'image':
|
|
13634
|
+
return ChatAttachmentImage;
|
|
13635
|
+
case 'invalid-image':
|
|
13636
|
+
return ChatAttachmentInvalidImage;
|
|
13637
|
+
case 'text-file':
|
|
13638
|
+
return ChatAttachmentTextFile;
|
|
13639
|
+
default:
|
|
13640
|
+
return ChatAttachment;
|
|
13641
|
+
}
|
|
13642
|
+
};
|
|
13643
|
+
const getChatAttachmentPreviewDom = attachment => {
|
|
13644
|
+
if (!attachment.previewSrc) {
|
|
13645
|
+
return [];
|
|
13646
|
+
}
|
|
13647
|
+
return [{
|
|
13648
|
+
alt: `Attachment preview for ${attachment.name}`,
|
|
13649
|
+
childCount: 0,
|
|
13650
|
+
className: ChatAttachmentPreview,
|
|
13651
|
+
src: attachment.previewSrc,
|
|
13652
|
+
type: Img
|
|
13653
|
+
}];
|
|
13654
|
+
};
|
|
13655
|
+
const getChatAttachmentsDom = attachments => {
|
|
13656
|
+
if (attachments.length === 0) {
|
|
13657
|
+
return [];
|
|
13658
|
+
}
|
|
13659
|
+
return [{
|
|
13660
|
+
childCount: attachments.length,
|
|
13661
|
+
className: ChatAttachments,
|
|
13662
|
+
type: Div
|
|
13663
|
+
}, ...attachments.flatMap(attachment => {
|
|
13664
|
+
const previewDom = getChatAttachmentPreviewDom(attachment);
|
|
13665
|
+
return [{
|
|
13666
|
+
childCount: 1 + previewDom.length,
|
|
13667
|
+
className: mergeClassNames(ChatAttachment, getChatAttachmentClassName(attachment.displayType)),
|
|
13668
|
+
type: Div
|
|
13669
|
+
}, ...previewDom, {
|
|
13670
|
+
childCount: 1,
|
|
13671
|
+
className: ChatAttachmentLabel,
|
|
13672
|
+
type: Span
|
|
13673
|
+
}, {
|
|
13674
|
+
text: `${getChatAttachmentLabel(attachment.displayType)} · ${attachment.name}`,
|
|
13675
|
+
type: Text
|
|
13676
|
+
}];
|
|
13677
|
+
})];
|
|
13678
|
+
};
|
|
12969
13679
|
const getChatMessageDom = (message, parsedMessageContent, _openRouterApiKeyInput, _openApiApiKeyInput = '', openApiApiKeyState = 'idle', openApiApiKeysSettingsUrl = 'https://platform.openai.com/api-keys', openApiApiKeyInputPattern = '^sk-.+', openRouterApiKeyState = 'idle', useChatMathWorker = false) => {
|
|
12970
13680
|
const roleClassName = message.role === 'user' ? MessageUser : MessageAssistant;
|
|
12971
13681
|
const isOpenApiApiKeyMissingMessage = message.role === 'assistant' && message.text === openApiApiKeyRequiredMessage;
|
|
@@ -12973,10 +13683,12 @@ const getChatMessageDom = (message, parsedMessageContent, _openRouterApiKeyInput
|
|
|
12973
13683
|
const isOpenRouterRequestFailedMessage = message.role === 'assistant' && message.text === openRouterRequestFailedMessage;
|
|
12974
13684
|
const isOpenRouterTooManyRequestsMessage = message.role === 'assistant' && message.text.startsWith(openRouterTooManyRequestsMessage);
|
|
12975
13685
|
const messageDom = getMessageContentDom(parsedMessageContent, useChatMathWorker);
|
|
13686
|
+
const attachmentsDom = message.role === 'user' ? getChatAttachmentsDom(message.attachments ?? []) : [];
|
|
12976
13687
|
const toolCallsDom = getToolCallsDom(message);
|
|
12977
13688
|
const toolCallsChildCount = toolCallsDom.length > 0 ? 1 : 0;
|
|
12978
13689
|
const messageDomChildCount = getTopLevelNodeCount(messageDom);
|
|
12979
|
-
const
|
|
13690
|
+
const attachmentsChildCount = attachmentsDom.length > 0 ? 1 : 0;
|
|
13691
|
+
const extraChildCount = isOpenApiApiKeyMissingMessage || isOpenRouterApiKeyMissingMessage || isOpenRouterRequestFailedMessage || isOpenRouterTooManyRequestsMessage ? messageDomChildCount + 1 + toolCallsChildCount + attachmentsChildCount : messageDomChildCount + toolCallsChildCount + attachmentsChildCount;
|
|
12980
13692
|
return [{
|
|
12981
13693
|
childCount: 1,
|
|
12982
13694
|
className: mergeClassNames(Message, roleClassName),
|
|
@@ -12985,7 +13697,7 @@ const getChatMessageDom = (message, parsedMessageContent, _openRouterApiKeyInput
|
|
|
12985
13697
|
childCount: extraChildCount,
|
|
12986
13698
|
className: ChatMessageContent,
|
|
12987
13699
|
type: Div
|
|
12988
|
-
}, ...toolCallsDom, ...messageDom, ...(isOpenApiApiKeyMissingMessage ? getMissingOpenApiApiKeyDom(openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern) : []), ...(isOpenRouterApiKeyMissingMessage ? getMissingOpenRouterApiKeyDom(openRouterApiKeyState) : []), ...(isOpenRouterRequestFailedMessage ? getOpenRouterRequestFailedDom() : []), ...(isOpenRouterTooManyRequestsMessage ? getOpenRouterTooManyRequestsDom() : [])];
|
|
13700
|
+
}, ...toolCallsDom, ...messageDom, ...attachmentsDom, ...(isOpenApiApiKeyMissingMessage ? getMissingOpenApiApiKeyDom(openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern) : []), ...(isOpenRouterApiKeyMissingMessage ? getMissingOpenRouterApiKeyDom(openRouterApiKeyState) : []), ...(isOpenRouterRequestFailedMessage ? getOpenRouterRequestFailedDom() : []), ...(isOpenRouterTooManyRequestsMessage ? getOpenRouterTooManyRequestsDom() : [])];
|
|
12989
13701
|
};
|
|
12990
13702
|
|
|
12991
13703
|
const parentNode$1 = {
|
|
@@ -13041,7 +13753,18 @@ const getDisplayMessages = (messages, parsedMessages) => {
|
|
|
13041
13753
|
};
|
|
13042
13754
|
const getMessagesDom = (messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput = '', openApiApiKeyState = 'idle', openApiApiKeysSettingsUrl = 'https://platform.openai.com/api-keys', openApiApiKeyInputPattern = '^sk-.+', openRouterApiKeyState = 'idle', messagesScrollTop = 0, useChatMathWorker = false, hideWelcomeMessage = false) => {
|
|
13043
13755
|
if (messages.length === 0) {
|
|
13044
|
-
|
|
13756
|
+
if (!hideWelcomeMessage) {
|
|
13757
|
+
return getEmptyMessagesDom();
|
|
13758
|
+
}
|
|
13759
|
+
return [{
|
|
13760
|
+
childCount: 0,
|
|
13761
|
+
className: 'ChatMessages',
|
|
13762
|
+
onContextMenu: HandleMessagesContextMenu,
|
|
13763
|
+
onScroll: HandleMessagesScroll,
|
|
13764
|
+
role: 'log',
|
|
13765
|
+
scrollTop: messagesScrollTop,
|
|
13766
|
+
type: Div
|
|
13767
|
+
}];
|
|
13045
13768
|
}
|
|
13046
13769
|
const displayMessages = getDisplayMessages(messages, parsedMessages);
|
|
13047
13770
|
return [{
|
|
@@ -13108,10 +13831,10 @@ const getProjectGroupDom = (project, sessions, projectExpandedIds, selectedProje
|
|
|
13108
13831
|
tabIndex: 0,
|
|
13109
13832
|
type: Div
|
|
13110
13833
|
}, {
|
|
13111
|
-
childCount:
|
|
13112
|
-
className: ProjectListChevron,
|
|
13113
|
-
type:
|
|
13114
|
-
},
|
|
13834
|
+
childCount: 0,
|
|
13835
|
+
className: mergeClassNames(ProjectListChevron, MaskIcon, expanded ? MaskIconChevronDown : MaskIconChevronRight),
|
|
13836
|
+
type: Div
|
|
13837
|
+
}, {
|
|
13115
13838
|
childCount: 0,
|
|
13116
13839
|
className: 'MaskIcon MaskIconFolder',
|
|
13117
13840
|
type: Div
|
|
@@ -13167,6 +13890,8 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13167
13890
|
authEnabled = false,
|
|
13168
13891
|
authErrorMessage = '',
|
|
13169
13892
|
authStatus = 'signed-out',
|
|
13893
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
13894
|
+
composerAttachmentPreviewOverlayError = false,
|
|
13170
13895
|
composerAttachments,
|
|
13171
13896
|
composerDropActive = false,
|
|
13172
13897
|
composerDropEnabled = true,
|
|
@@ -13177,6 +13902,7 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13177
13902
|
composerValue,
|
|
13178
13903
|
hasSpaceForAgentModePicker,
|
|
13179
13904
|
hasSpaceForRunModePicker,
|
|
13905
|
+
messagesAutoScrollEnabled,
|
|
13180
13906
|
messagesScrollTop = 0,
|
|
13181
13907
|
modelPickerOpen = false,
|
|
13182
13908
|
modelPickerSearchValue = '',
|
|
@@ -13196,6 +13922,7 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13196
13922
|
reasoningPickerEnabled,
|
|
13197
13923
|
runMode,
|
|
13198
13924
|
runModePickerOpen = false,
|
|
13925
|
+
scrollDownButtonEnabled,
|
|
13199
13926
|
selectedModelId,
|
|
13200
13927
|
selectedProjectId = '',
|
|
13201
13928
|
selectedSessionId,
|
|
@@ -13217,20 +13944,29 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
13217
13944
|
const selectedProjectName = selectedProject?.name || '';
|
|
13218
13945
|
const showCreatePullRequestButton = canCreatePullRequest(selectedSession);
|
|
13219
13946
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
13947
|
+
const isComposerAttachmentPreviewOverlayVisible = !!composerAttachmentPreviewOverlayAttachmentId;
|
|
13220
13948
|
const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
|
|
13221
13949
|
const isNewModelPickerVisible = modelPickerOpen;
|
|
13222
13950
|
const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
|
|
13223
|
-
const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13224
|
-
const chatRootChildCount =
|
|
13951
|
+
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13952
|
+
const chatRootChildCount = 2 + (hasVisibleOverlays ? 1 : 0);
|
|
13225
13953
|
return [{
|
|
13226
13954
|
childCount: chatRootChildCount,
|
|
13227
13955
|
className: mergeClassNames(Viewlet, Chat, ChatFocus),
|
|
13228
13956
|
onDragEnter: HandleDragEnterChatView,
|
|
13229
13957
|
onDragOver: HandleDragOverChatView,
|
|
13230
13958
|
type: Div
|
|
13231
|
-
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop, true),
|
|
13959
|
+
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop, true), {
|
|
13960
|
+
childCount: 3,
|
|
13961
|
+
className: ChatFocusMainArea,
|
|
13962
|
+
type: Div
|
|
13963
|
+
}, ...getChatHeaderDomFocusMode(selectedSessionTitle, selectedProjectName), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, 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({
|
|
13232
13964
|
agentMode,
|
|
13233
13965
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
13966
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
13967
|
+
composerAttachmentPreviewOverlayError,
|
|
13968
|
+
composerAttachmentPreviewOverlayVisible: isComposerAttachmentPreviewOverlayVisible,
|
|
13969
|
+
composerAttachments,
|
|
13234
13970
|
dropOverlayVisible: isDropOverlayVisible,
|
|
13235
13971
|
modelPickerSearchValue,
|
|
13236
13972
|
modelPickerVisible: isNewModelPickerVisible,
|
|
@@ -13277,22 +14013,31 @@ const getHeaderActionVirtualDom = item => {
|
|
|
13277
14013
|
}];
|
|
13278
14014
|
};
|
|
13279
14015
|
|
|
13280
|
-
const
|
|
13281
|
-
const toggleTitle = viewMode === 'chat-focus' ? normalChatMode() : chatFocusMode();
|
|
14016
|
+
const getAuthAction = (authEnabled, authStatus) => {
|
|
13282
14017
|
const isSigningIn = authStatus === 'signing-in';
|
|
13283
|
-
|
|
13284
|
-
|
|
13285
|
-
|
|
13286
|
-
|
|
13287
|
-
|
|
13288
|
-
|
|
13289
|
-
|
|
14018
|
+
if (!authEnabled) {
|
|
14019
|
+
return undefined;
|
|
14020
|
+
}
|
|
14021
|
+
if (authStatus !== 'signed-in') {
|
|
14022
|
+
return {
|
|
14023
|
+
disabled: isSigningIn,
|
|
14024
|
+
icon: mergeClassNames(MaskIcon, MaskIconAccount),
|
|
14025
|
+
name: Login,
|
|
14026
|
+
onClick: HandleClick,
|
|
14027
|
+
title: isSigningIn ? loggingInToBackend() : loginToBackend()
|
|
14028
|
+
};
|
|
14029
|
+
}
|
|
14030
|
+
return {
|
|
13290
14031
|
disabled: false,
|
|
13291
14032
|
icon: mergeClassNames(MaskIcon, MaskIconSignOut),
|
|
13292
14033
|
name: Logout,
|
|
13293
14034
|
onClick: HandleClick,
|
|
13294
14035
|
title: logoutFromBackend()
|
|
13295
|
-
}
|
|
14036
|
+
};
|
|
14037
|
+
};
|
|
14038
|
+
const getChatHeaderActionsDom = (viewMode, authEnabled = false, authStatus = 'signed-out', searchEnabled = false) => {
|
|
14039
|
+
const toggleTitle = viewMode === 'chat-focus' ? normalChatMode() : chatFocusMode();
|
|
14040
|
+
const authAction = getAuthAction(authEnabled, authStatus);
|
|
13296
14041
|
const items = [{
|
|
13297
14042
|
icon: mergeClassNames(MaskIcon, MaskIconLayoutPanelLeft),
|
|
13298
14043
|
name: ToggleChatFocus,
|
|
@@ -13368,6 +14113,8 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13368
14113
|
authEnabled = false,
|
|
13369
14114
|
authErrorMessage = '',
|
|
13370
14115
|
authStatus = 'signed-out',
|
|
14116
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14117
|
+
composerAttachmentPreviewOverlayError = false,
|
|
13371
14118
|
composerAttachments,
|
|
13372
14119
|
composerDropActive = false,
|
|
13373
14120
|
composerDropEnabled = true,
|
|
@@ -13378,6 +14125,7 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13378
14125
|
composerValue,
|
|
13379
14126
|
hasSpaceForAgentModePicker,
|
|
13380
14127
|
hasSpaceForRunModePicker,
|
|
14128
|
+
messagesAutoScrollEnabled,
|
|
13381
14129
|
messagesScrollTop = 0,
|
|
13382
14130
|
modelPickerOpen = false,
|
|
13383
14131
|
modelPickerSearchValue = '',
|
|
@@ -13394,6 +14142,7 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13394
14142
|
reasoningPickerEnabled,
|
|
13395
14143
|
runMode,
|
|
13396
14144
|
runModePickerOpen = false,
|
|
14145
|
+
scrollDownButtonEnabled,
|
|
13397
14146
|
selectedModelId,
|
|
13398
14147
|
selectedSessionId,
|
|
13399
14148
|
sessions,
|
|
@@ -13412,10 +14161,11 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13412
14161
|
const messages = selectedSession ? selectedSession.messages : [];
|
|
13413
14162
|
const showCreatePullRequestButton = canCreatePullRequest(selectedSession);
|
|
13414
14163
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
14164
|
+
const isComposerAttachmentPreviewOverlayVisible = !!composerAttachmentPreviewOverlayAttachmentId;
|
|
13415
14165
|
const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
|
|
13416
14166
|
const isNewModelPickerVisible = modelPickerOpen;
|
|
13417
14167
|
const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
|
|
13418
|
-
const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
14168
|
+
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13419
14169
|
const chatRootChildCount = 3 + (hasVisibleOverlays ? 1 : 0);
|
|
13420
14170
|
return [{
|
|
13421
14171
|
childCount: chatRootChildCount,
|
|
@@ -13423,9 +14173,13 @@ const getChatModeDetailVirtualDom = ({
|
|
|
13423
14173
|
onDragEnter: HandleDragEnterChatView,
|
|
13424
14174
|
onDragOver: HandleDragOverChatView,
|
|
13425
14175
|
type: Div
|
|
13426
|
-
}, ...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({
|
|
14176
|
+
}, ...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({
|
|
13427
14177
|
agentMode,
|
|
13428
14178
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
14179
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14180
|
+
composerAttachmentPreviewOverlayError,
|
|
14181
|
+
composerAttachmentPreviewOverlayVisible: isComposerAttachmentPreviewOverlayVisible,
|
|
14182
|
+
composerAttachments,
|
|
13429
14183
|
dropOverlayVisible: isDropOverlayVisible,
|
|
13430
14184
|
modelPickerSearchValue,
|
|
13431
14185
|
modelPickerVisible: isNewModelPickerVisible,
|
|
@@ -13570,6 +14324,8 @@ const getChatModeListVirtualDom = ({
|
|
|
13570
14324
|
authErrorMessage = '',
|
|
13571
14325
|
authStatus = 'signed-out',
|
|
13572
14326
|
chatListScrollTop = 0,
|
|
14327
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14328
|
+
composerAttachmentPreviewOverlayError = false,
|
|
13573
14329
|
composerAttachments,
|
|
13574
14330
|
composerDropActive = false,
|
|
13575
14331
|
composerDropEnabled = true,
|
|
@@ -13605,10 +14361,11 @@ const getChatModeListVirtualDom = ({
|
|
|
13605
14361
|
voiceDictationEnabled = false
|
|
13606
14362
|
}) => {
|
|
13607
14363
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
14364
|
+
const isComposerAttachmentPreviewOverlayVisible = !!composerAttachmentPreviewOverlayAttachmentId;
|
|
13608
14365
|
const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
|
|
13609
14366
|
const isNewModelPickerVisible = modelPickerOpen;
|
|
13610
14367
|
const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
|
|
13611
|
-
const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
14368
|
+
const hasVisibleOverlays = isDropOverlayVisible || isComposerAttachmentPreviewOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
|
|
13612
14369
|
const chatRootChildCount = 3 + (hasVisibleOverlays ? 1 : 0);
|
|
13613
14370
|
const searchValueTrimmed = searchValue.trim().toLowerCase();
|
|
13614
14371
|
const visibleSessions = searchEnabled && searchValueTrimmed ? sessions.filter(session => session.title.toLowerCase().includes(searchValueTrimmed)) : sessions;
|
|
@@ -13621,6 +14378,10 @@ const getChatModeListVirtualDom = ({
|
|
|
13621
14378
|
}, ...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({
|
|
13622
14379
|
agentMode,
|
|
13623
14380
|
agentModePickerVisible: isAgentModePickerVisible,
|
|
14381
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14382
|
+
composerAttachmentPreviewOverlayError,
|
|
14383
|
+
composerAttachmentPreviewOverlayVisible: isComposerAttachmentPreviewOverlayVisible,
|
|
14384
|
+
composerAttachments,
|
|
13624
14385
|
dropOverlayVisible: isDropOverlayVisible,
|
|
13625
14386
|
modelPickerSearchValue,
|
|
13626
14387
|
modelPickerVisible: isNewModelPickerVisible,
|
|
@@ -13719,6 +14480,8 @@ const getChatVirtualDom = options => {
|
|
|
13719
14480
|
authErrorMessage = '',
|
|
13720
14481
|
authStatus = 'signed-out',
|
|
13721
14482
|
chatListScrollTop,
|
|
14483
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14484
|
+
composerAttachmentPreviewOverlayError = false,
|
|
13722
14485
|
composerAttachments,
|
|
13723
14486
|
composerDropActive = false,
|
|
13724
14487
|
composerDropEnabled = true,
|
|
@@ -13730,6 +14493,7 @@ const getChatVirtualDom = options => {
|
|
|
13730
14493
|
hasSpaceForAgentModePicker,
|
|
13731
14494
|
hasSpaceForRunModePicker,
|
|
13732
14495
|
listFocusedIndex = -1,
|
|
14496
|
+
messagesAutoScrollEnabled,
|
|
13733
14497
|
messagesScrollTop,
|
|
13734
14498
|
modelPickerOpen = false,
|
|
13735
14499
|
modelPickerSearchValue = '',
|
|
@@ -13749,6 +14513,7 @@ const getChatVirtualDom = options => {
|
|
|
13749
14513
|
reasoningPickerEnabled,
|
|
13750
14514
|
runMode,
|
|
13751
14515
|
runModePickerOpen = false,
|
|
14516
|
+
scrollDownButtonEnabled,
|
|
13752
14517
|
searchEnabled = false,
|
|
13753
14518
|
searchFieldVisible = false,
|
|
13754
14519
|
searchValue = '',
|
|
@@ -13777,6 +14542,8 @@ const getChatVirtualDom = options => {
|
|
|
13777
14542
|
authEnabled,
|
|
13778
14543
|
authErrorMessage,
|
|
13779
14544
|
authStatus,
|
|
14545
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14546
|
+
composerAttachmentPreviewOverlayError,
|
|
13780
14547
|
composerAttachments,
|
|
13781
14548
|
composerDropActive,
|
|
13782
14549
|
composerDropEnabled,
|
|
@@ -13787,6 +14554,7 @@ const getChatVirtualDom = options => {
|
|
|
13787
14554
|
composerValue,
|
|
13788
14555
|
hasSpaceForAgentModePicker,
|
|
13789
14556
|
hasSpaceForRunModePicker,
|
|
14557
|
+
messagesAutoScrollEnabled,
|
|
13790
14558
|
messagesScrollTop,
|
|
13791
14559
|
modelPickerOpen,
|
|
13792
14560
|
modelPickerSearchValue,
|
|
@@ -13806,6 +14574,7 @@ const getChatVirtualDom = options => {
|
|
|
13806
14574
|
reasoningPickerEnabled,
|
|
13807
14575
|
runMode,
|
|
13808
14576
|
runModePickerOpen,
|
|
14577
|
+
scrollDownButtonEnabled,
|
|
13809
14578
|
selectedModelId,
|
|
13810
14579
|
selectedProjectId,
|
|
13811
14580
|
selectedSessionId,
|
|
@@ -13828,6 +14597,8 @@ const getChatVirtualDom = options => {
|
|
|
13828
14597
|
authEnabled,
|
|
13829
14598
|
authErrorMessage,
|
|
13830
14599
|
authStatus,
|
|
14600
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14601
|
+
composerAttachmentPreviewOverlayError,
|
|
13831
14602
|
composerAttachments,
|
|
13832
14603
|
composerDropActive,
|
|
13833
14604
|
composerDropEnabled,
|
|
@@ -13838,6 +14609,7 @@ const getChatVirtualDom = options => {
|
|
|
13838
14609
|
composerValue,
|
|
13839
14610
|
hasSpaceForAgentModePicker,
|
|
13840
14611
|
hasSpaceForRunModePicker,
|
|
14612
|
+
messagesAutoScrollEnabled,
|
|
13841
14613
|
messagesScrollTop,
|
|
13842
14614
|
modelPickerOpen,
|
|
13843
14615
|
modelPickerSearchValue,
|
|
@@ -13854,6 +14626,7 @@ const getChatVirtualDom = options => {
|
|
|
13854
14626
|
reasoningPickerEnabled,
|
|
13855
14627
|
runMode,
|
|
13856
14628
|
runModePickerOpen,
|
|
14629
|
+
scrollDownButtonEnabled,
|
|
13857
14630
|
selectedModelId,
|
|
13858
14631
|
selectedSessionId,
|
|
13859
14632
|
sessions,
|
|
@@ -13876,6 +14649,8 @@ const getChatVirtualDom = options => {
|
|
|
13876
14649
|
authErrorMessage,
|
|
13877
14650
|
authStatus,
|
|
13878
14651
|
chatListScrollTop,
|
|
14652
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14653
|
+
composerAttachmentPreviewOverlayError,
|
|
13879
14654
|
composerAttachments,
|
|
13880
14655
|
composerDropActive,
|
|
13881
14656
|
composerDropEnabled,
|
|
@@ -13924,6 +14699,8 @@ const renderItems = (oldState, newState) => {
|
|
|
13924
14699
|
authErrorMessage,
|
|
13925
14700
|
authStatus,
|
|
13926
14701
|
chatListScrollTop,
|
|
14702
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14703
|
+
composerAttachmentPreviewOverlayError,
|
|
13927
14704
|
composerAttachments,
|
|
13928
14705
|
composerDropActive,
|
|
13929
14706
|
composerDropEnabled,
|
|
@@ -13936,6 +14713,7 @@ const renderItems = (oldState, newState) => {
|
|
|
13936
14713
|
hasSpaceForRunModePicker,
|
|
13937
14714
|
initial,
|
|
13938
14715
|
listFocusedIndex,
|
|
14716
|
+
messagesAutoScrollEnabled,
|
|
13939
14717
|
messagesScrollTop,
|
|
13940
14718
|
modelPickerOpen,
|
|
13941
14719
|
modelPickerSearchValue,
|
|
@@ -13955,6 +14733,7 @@ const renderItems = (oldState, newState) => {
|
|
|
13955
14733
|
reasoningPickerEnabled,
|
|
13956
14734
|
runMode,
|
|
13957
14735
|
runModePickerOpen,
|
|
14736
|
+
scrollDownButtonEnabled,
|
|
13958
14737
|
searchEnabled,
|
|
13959
14738
|
searchFieldVisible,
|
|
13960
14739
|
searchValue,
|
|
@@ -13984,6 +14763,8 @@ const renderItems = (oldState, newState) => {
|
|
|
13984
14763
|
authErrorMessage,
|
|
13985
14764
|
authStatus,
|
|
13986
14765
|
chatListScrollTop,
|
|
14766
|
+
composerAttachmentPreviewOverlayAttachmentId,
|
|
14767
|
+
composerAttachmentPreviewOverlayError,
|
|
13987
14768
|
composerAttachments,
|
|
13988
14769
|
composerDropActive,
|
|
13989
14770
|
composerDropEnabled,
|
|
@@ -13995,6 +14776,7 @@ const renderItems = (oldState, newState) => {
|
|
|
13995
14776
|
hasSpaceForAgentModePicker,
|
|
13996
14777
|
hasSpaceForRunModePicker,
|
|
13997
14778
|
listFocusedIndex,
|
|
14779
|
+
messagesAutoScrollEnabled,
|
|
13998
14780
|
messagesScrollTop,
|
|
13999
14781
|
modelPickerOpen,
|
|
14000
14782
|
modelPickerSearchValue,
|
|
@@ -14014,6 +14796,7 @@ const renderItems = (oldState, newState) => {
|
|
|
14014
14796
|
reasoningPickerEnabled,
|
|
14015
14797
|
runMode,
|
|
14016
14798
|
runModePickerOpen,
|
|
14799
|
+
scrollDownButtonEnabled,
|
|
14017
14800
|
searchEnabled,
|
|
14018
14801
|
searchFieldVisible,
|
|
14019
14802
|
searchValue,
|
|
@@ -14132,6 +14915,12 @@ const renderEventListeners = () => {
|
|
|
14132
14915
|
}, {
|
|
14133
14916
|
name: HandleClick,
|
|
14134
14917
|
params: ['handleClick', TargetName, 'event.target.dataset.id', ClientX, ClientY]
|
|
14918
|
+
}, {
|
|
14919
|
+
name: HandleMouseOver,
|
|
14920
|
+
params: ['handleMouseOver', TargetName]
|
|
14921
|
+
}, {
|
|
14922
|
+
name: HandleMouseOut,
|
|
14923
|
+
params: ['handleMouseOut', TargetName, 'event.relatedTarget && event.relatedTarget.getAttribute ? event.relatedTarget.getAttribute("name") : ""']
|
|
14135
14924
|
}, {
|
|
14136
14925
|
name: HandleClickDictationButton,
|
|
14137
14926
|
params: ['handleClickDictationButton']
|
|
@@ -14298,6 +15087,9 @@ const renderEventListeners = () => {
|
|
|
14298
15087
|
name: HandleContextMenuChatImageAttachment,
|
|
14299
15088
|
params: ['handleContextMenuChatImageAttachment', TargetName, ClientX, ClientY],
|
|
14300
15089
|
preventDefault: true
|
|
15090
|
+
}, {
|
|
15091
|
+
name: HandleErrorComposerAttachmentPreviewOverlay,
|
|
15092
|
+
params: ['handleErrorComposerAttachmentPreviewOverlay']
|
|
14301
15093
|
}];
|
|
14302
15094
|
};
|
|
14303
15095
|
|
|
@@ -14379,6 +15171,8 @@ const saveState = state => {
|
|
|
14379
15171
|
const {
|
|
14380
15172
|
agentMode,
|
|
14381
15173
|
chatListScrollTop,
|
|
15174
|
+
composerSelectionEnd,
|
|
15175
|
+
composerSelectionStart,
|
|
14382
15176
|
composerValue,
|
|
14383
15177
|
lastNormalViewMode,
|
|
14384
15178
|
maxToolCalls,
|
|
@@ -14400,6 +15194,8 @@ const saveState = state => {
|
|
|
14400
15194
|
return {
|
|
14401
15195
|
agentMode,
|
|
14402
15196
|
chatListScrollTop,
|
|
15197
|
+
composerSelectionEnd,
|
|
15198
|
+
composerSelectionStart,
|
|
14403
15199
|
composerValue,
|
|
14404
15200
|
lastNormalViewMode,
|
|
14405
15201
|
maxToolCalls,
|
|
@@ -14496,6 +15292,13 @@ const setResponsivePickerVisibilityEnabled = (state, responsivePickerVisibilityE
|
|
|
14496
15292
|
};
|
|
14497
15293
|
};
|
|
14498
15294
|
|
|
15295
|
+
const setScrollDownButtonEnabled = (state, scrollDownButtonEnabled) => {
|
|
15296
|
+
return {
|
|
15297
|
+
...state,
|
|
15298
|
+
scrollDownButtonEnabled
|
|
15299
|
+
};
|
|
15300
|
+
};
|
|
15301
|
+
|
|
14499
15302
|
const setSearchEnabled = (state, searchEnabled) => {
|
|
14500
15303
|
return {
|
|
14501
15304
|
...state,
|
|
@@ -14628,6 +15431,7 @@ const commandMap = {
|
|
|
14628
15431
|
'Chat.getKeyBindings': getKeyBindings,
|
|
14629
15432
|
'Chat.getMenuEntries': getMenuEntries,
|
|
14630
15433
|
'Chat.getMenuEntryIds': getMenuEntryIds,
|
|
15434
|
+
'Chat.getMockOpenApiRequests': wrapGetter(getMockOpenApiRequests),
|
|
14631
15435
|
'Chat.getQuickPickMenuEntries': getQuickPickMenuEntries,
|
|
14632
15436
|
'Chat.getSelectedSessionId': wrapGetter(getSelectedSessionId),
|
|
14633
15437
|
'Chat.getSystemPrompt': wrapGetter(getSystemPrompt),
|
|
@@ -14660,6 +15464,7 @@ const commandMap = {
|
|
|
14660
15464
|
'Chat.handleDragLeave': wrapCommand(handleDragLeave),
|
|
14661
15465
|
'Chat.handleDragOver': wrapCommand(handleDragOver),
|
|
14662
15466
|
'Chat.handleDropFiles': wrapCommand(handleDropFiles),
|
|
15467
|
+
'Chat.handleErrorComposerAttachmentPreviewOverlay': wrapCommand(handleErrorComposerAttachmentPreviewOverlay),
|
|
14663
15468
|
'Chat.handleInput': wrapCommand(handleInput),
|
|
14664
15469
|
'Chat.handleInputFocus': wrapCommand(handleInputFocus),
|
|
14665
15470
|
'Chat.handleKeyDown': wrapCommand(handleKeyDown),
|
|
@@ -14670,6 +15475,8 @@ const commandMap = {
|
|
|
14670
15475
|
'Chat.handleModelChange': wrapCommand(handleModelChange),
|
|
14671
15476
|
'Chat.handleModelInputBlur': wrapCommand(handleModelInputBlur),
|
|
14672
15477
|
'Chat.handleModelPickerListScroll': wrapCommand(handleModelPickerListScroll),
|
|
15478
|
+
'Chat.handleMouseOut': wrapCommand(handleMouseOut),
|
|
15479
|
+
'Chat.handleMouseOver': wrapCommand(handleMouseOver),
|
|
14673
15480
|
'Chat.handlePointerDownModelPickerList': wrapCommand(handlePointerDownModelPickerList),
|
|
14674
15481
|
'Chat.handlePointerUpModelPickerList': wrapCommand(handlePointerUpModelPickerList),
|
|
14675
15482
|
'Chat.handleProjectAddButtonContextMenu': wrapCommand(handleProjectAddButtonContextMenu),
|
|
@@ -14679,6 +15486,7 @@ const commandMap = {
|
|
|
14679
15486
|
'Chat.handleRunModeChange': wrapCommand(handleRunModeChange),
|
|
14680
15487
|
'Chat.handleSearchValueChange': wrapCommand(handleSearchValueChange),
|
|
14681
15488
|
'Chat.handleSubmit': wrapCommand(handleSubmit),
|
|
15489
|
+
'Chat.hideComposerAttachmentPreviewOverlay': wrapCommand(hideComposerAttachmentPreviewOverlay),
|
|
14682
15490
|
'Chat.initialize': initialize,
|
|
14683
15491
|
'Chat.loadContent': wrapCommand(loadContent),
|
|
14684
15492
|
'Chat.loadContent2': wrapCommand(loadContent),
|
|
@@ -14691,6 +15499,7 @@ const commandMap = {
|
|
|
14691
15499
|
'Chat.mockOpenApiStreamPushChunk': wrapCommand(mockOpenApiStreamPushChunk),
|
|
14692
15500
|
'Chat.mockOpenApiStreamReset': wrapCommand(mockOpenApiStreamReset),
|
|
14693
15501
|
'Chat.openAgentModePicker': wrapCommand(openAgentModePicker),
|
|
15502
|
+
'Chat.openMockProject': wrapCommand(openMockProject),
|
|
14694
15503
|
'Chat.openMockSession': wrapCommand(openMockSession),
|
|
14695
15504
|
'Chat.openModelPicker': wrapCommand(openModelPicker),
|
|
14696
15505
|
'Chat.openReasoningEffortPicker': wrapCommand(openReasoningEffortPicker),
|
|
@@ -14715,6 +15524,7 @@ const commandMap = {
|
|
|
14715
15524
|
'Chat.setReasoningEffort': wrapCommand(setReasoningEffort),
|
|
14716
15525
|
'Chat.setReasoningPickerEnabled': wrapCommand(setReasoningPickerEnabled),
|
|
14717
15526
|
'Chat.setResponsivePickerVisibilityEnabled': wrapCommand(setResponsivePickerVisibilityEnabled),
|
|
15527
|
+
'Chat.setScrollDownButtonEnabled': wrapCommand(setScrollDownButtonEnabled),
|
|
14718
15528
|
'Chat.setSearchEnabled': wrapCommand(setSearchEnabled),
|
|
14719
15529
|
'Chat.setShowRunMode': wrapCommand(setShowRunMode),
|
|
14720
15530
|
'Chat.setStreamingEnabled': wrapCommand(setStreamingEnabled),
|
|
@@ -14725,6 +15535,7 @@ const commandMap = {
|
|
|
14725
15535
|
'Chat.setUseChatMathWorker': wrapCommand(setUseChatMathWorker),
|
|
14726
15536
|
'Chat.setUseChatMessageParsingWorker': wrapCommand(setUseChatMessageParsingWorker),
|
|
14727
15537
|
'Chat.setUseChatNetworkWorkerForRequests': wrapCommand(setUseChatNetworkWorkerForRequests),
|
|
15538
|
+
'Chat.showComposerAttachmentPreviewOverlay': wrapCommand(showComposerAttachmentPreviewOverlay),
|
|
14728
15539
|
'Chat.terminate': terminate,
|
|
14729
15540
|
'Chat.useMockApi': wrapCommand(useMockApi)
|
|
14730
15541
|
};
|