@lvce-editor/chat-view 6.21.0 → 6.22.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 +459 -120
- package/package.json +1 -1
|
@@ -1407,6 +1407,104 @@ const terminate = () => {
|
|
|
1407
1407
|
globalThis.close();
|
|
1408
1408
|
};
|
|
1409
1409
|
|
|
1410
|
+
const getVisibleSessions = (sessions, selectedProjectId) => {
|
|
1411
|
+
if (!selectedProjectId) {
|
|
1412
|
+
return sessions;
|
|
1413
|
+
}
|
|
1414
|
+
const hasAssignedProjects = sessions.some(session => !!session.projectId);
|
|
1415
|
+
if (!hasAssignedProjects) {
|
|
1416
|
+
return sessions;
|
|
1417
|
+
}
|
|
1418
|
+
return sessions.filter(session => session.projectId === selectedProjectId);
|
|
1419
|
+
};
|
|
1420
|
+
|
|
1421
|
+
const chatListFocusFirst = async state => {
|
|
1422
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
1423
|
+
if (visibleSessions.length === 0) {
|
|
1424
|
+
return {
|
|
1425
|
+
...state,
|
|
1426
|
+
focus: 'list',
|
|
1427
|
+
focused: true,
|
|
1428
|
+
listFocusedIndex: -1
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
return {
|
|
1432
|
+
...state,
|
|
1433
|
+
focus: 'list',
|
|
1434
|
+
focused: true,
|
|
1435
|
+
listFocusedIndex: 0
|
|
1436
|
+
};
|
|
1437
|
+
};
|
|
1438
|
+
|
|
1439
|
+
const chatListFocusLast = async state => {
|
|
1440
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
1441
|
+
if (visibleSessions.length === 0) {
|
|
1442
|
+
return {
|
|
1443
|
+
...state,
|
|
1444
|
+
focus: 'list',
|
|
1445
|
+
focused: true,
|
|
1446
|
+
listFocusedIndex: -1
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
return {
|
|
1450
|
+
...state,
|
|
1451
|
+
focus: 'list',
|
|
1452
|
+
focused: true,
|
|
1453
|
+
listFocusedIndex: visibleSessions.length - 1
|
|
1454
|
+
};
|
|
1455
|
+
};
|
|
1456
|
+
|
|
1457
|
+
const getListFocusIndex = state => {
|
|
1458
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
1459
|
+
if (visibleSessions.length === 0) {
|
|
1460
|
+
return -1;
|
|
1461
|
+
}
|
|
1462
|
+
if (state.listFocusedIndex >= 0 && state.listFocusedIndex < visibleSessions.length) {
|
|
1463
|
+
return state.listFocusedIndex;
|
|
1464
|
+
}
|
|
1465
|
+
return -1;
|
|
1466
|
+
};
|
|
1467
|
+
|
|
1468
|
+
const chatListFocusNext = async state => {
|
|
1469
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
1470
|
+
if (visibleSessions.length === 0) {
|
|
1471
|
+
return {
|
|
1472
|
+
...state,
|
|
1473
|
+
focus: 'list',
|
|
1474
|
+
focused: true,
|
|
1475
|
+
listFocusedIndex: -1
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
const currentIndex = getListFocusIndex(state);
|
|
1479
|
+
const nextIndex = currentIndex === -1 ? 0 : Math.min(currentIndex + 1, visibleSessions.length - 1);
|
|
1480
|
+
return {
|
|
1481
|
+
...state,
|
|
1482
|
+
focus: 'list',
|
|
1483
|
+
focused: true,
|
|
1484
|
+
listFocusedIndex: nextIndex
|
|
1485
|
+
};
|
|
1486
|
+
};
|
|
1487
|
+
|
|
1488
|
+
const chatListFocusPrevious = async state => {
|
|
1489
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
1490
|
+
if (visibleSessions.length === 0) {
|
|
1491
|
+
return {
|
|
1492
|
+
...state,
|
|
1493
|
+
focus: 'list',
|
|
1494
|
+
focused: true,
|
|
1495
|
+
listFocusedIndex: -1
|
|
1496
|
+
};
|
|
1497
|
+
}
|
|
1498
|
+
const currentIndex = getListFocusIndex(state);
|
|
1499
|
+
const previousIndex = currentIndex === -1 ? visibleSessions.length - 1 : Math.max(currentIndex - 1, 0);
|
|
1500
|
+
return {
|
|
1501
|
+
...state,
|
|
1502
|
+
focus: 'list',
|
|
1503
|
+
focused: true,
|
|
1504
|
+
listFocusedIndex: previousIndex
|
|
1505
|
+
};
|
|
1506
|
+
};
|
|
1507
|
+
|
|
1410
1508
|
const measureTextBlockHeight = async (text, fontFamily, fontSize, lineHeight, width) => {
|
|
1411
1509
|
// Upstream renderer types currently require number, but runtime accepts px strings.
|
|
1412
1510
|
// Keep forwarding the string to preserve chat-view behavior until upstream is updated.
|
|
@@ -1495,12 +1593,18 @@ const chats = () => {
|
|
|
1495
1593
|
const newChat = () => {
|
|
1496
1594
|
return i18nString('New Chat');
|
|
1497
1595
|
};
|
|
1596
|
+
const addProject = () => {
|
|
1597
|
+
return i18nString('Add Project');
|
|
1598
|
+
};
|
|
1498
1599
|
const debug = () => {
|
|
1499
1600
|
return i18nString('Debug');
|
|
1500
1601
|
};
|
|
1501
1602
|
const backToChats = () => {
|
|
1502
1603
|
return i18nString('Back to chats');
|
|
1503
1604
|
};
|
|
1605
|
+
const backToChatList = () => {
|
|
1606
|
+
return i18nString('Back to chat list');
|
|
1607
|
+
};
|
|
1504
1608
|
const settings = () => {
|
|
1505
1609
|
return i18nString('Settings');
|
|
1506
1610
|
};
|
|
@@ -1714,6 +1818,7 @@ const createDefaultState = () => {
|
|
|
1714
1818
|
inputSource: 'script',
|
|
1715
1819
|
lastNormalViewMode: 'list',
|
|
1716
1820
|
lastSubmittedSessionId: '',
|
|
1821
|
+
listFocusedIndex: -1,
|
|
1717
1822
|
listItemHeight: 40,
|
|
1718
1823
|
maxComposerRows: 5,
|
|
1719
1824
|
messagesAutoScrollEnabled: true,
|
|
@@ -2485,17 +2590,6 @@ const getNextSelectedSessionId = (sessions, deletedId) => {
|
|
|
2485
2590
|
return sessions[nextIndex].id;
|
|
2486
2591
|
};
|
|
2487
2592
|
|
|
2488
|
-
const getVisibleSessions = (sessions, selectedProjectId) => {
|
|
2489
|
-
if (!selectedProjectId) {
|
|
2490
|
-
return sessions;
|
|
2491
|
-
}
|
|
2492
|
-
const hasAssignedProjects = sessions.some(session => !!session.projectId);
|
|
2493
|
-
if (!hasAssignedProjects) {
|
|
2494
|
-
return sessions;
|
|
2495
|
-
}
|
|
2496
|
-
return sessions.filter(session => session.projectId === selectedProjectId);
|
|
2497
|
-
};
|
|
2498
|
-
|
|
2499
2593
|
const deleteSession = async (state, id) => {
|
|
2500
2594
|
const {
|
|
2501
2595
|
renamingSessionId,
|
|
@@ -2613,7 +2707,7 @@ const isEqualProjectExpandedIds = (a, b) => {
|
|
|
2613
2707
|
return true;
|
|
2614
2708
|
};
|
|
2615
2709
|
const isEqual = (oldState, newState) => {
|
|
2616
|
-
return oldState.addContextButtonEnabled === newState.addContextButtonEnabled && oldState.authEnabled === newState.authEnabled && oldState.authErrorMessage === newState.authErrorMessage && oldState.authStatus === newState.authStatus && oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.initial === newState.initial && oldState.modelPickerOpen === newState.modelPickerOpen && oldState.modelPickerSearchValue === newState.modelPickerSearchValue && oldState.newChatModelPickerEnabled === newState.newChatModelPickerEnabled && isEqualProjectExpandedIds(oldState.projectExpandedIds, newState.projectExpandedIds) && oldState.projectListScrollTop === newState.projectListScrollTop && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedProjectId === newState.selectedProjectId && oldState.selectedSessionId === newState.selectedSessionId && oldState.showRunMode === newState.showRunMode && oldState.runMode === newState.runMode && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.useChatMathWorker === newState.useChatMathWorker && oldState.viewMode === newState.viewMode && oldState.voiceDictationEnabled === newState.voiceDictationEnabled;
|
|
2710
|
+
return oldState.addContextButtonEnabled === newState.addContextButtonEnabled && oldState.authEnabled === newState.authEnabled && oldState.authErrorMessage === newState.authErrorMessage && oldState.authStatus === newState.authStatus && oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.initial === newState.initial && oldState.modelPickerOpen === newState.modelPickerOpen && oldState.modelPickerSearchValue === newState.modelPickerSearchValue && oldState.newChatModelPickerEnabled === newState.newChatModelPickerEnabled && oldState.listFocusedIndex === newState.listFocusedIndex && isEqualProjectExpandedIds(oldState.projectExpandedIds, newState.projectExpandedIds) && oldState.projectListScrollTop === newState.projectListScrollTop && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedProjectId === newState.selectedProjectId && oldState.selectedSessionId === newState.selectedSessionId && oldState.showRunMode === newState.showRunMode && oldState.runMode === newState.runMode && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.useChatMathWorker === newState.useChatMathWorker && oldState.viewMode === newState.viewMode && oldState.voiceDictationEnabled === newState.voiceDictationEnabled;
|
|
2617
2711
|
};
|
|
2618
2712
|
|
|
2619
2713
|
const diffScrollTop = (oldState, newState) => {
|
|
@@ -3026,23 +3120,158 @@ const deleteItem = () => {
|
|
|
3026
3120
|
return i18nString(Delete);
|
|
3027
3121
|
};
|
|
3028
3122
|
|
|
3029
|
-
const
|
|
3123
|
+
const getMenuEntriesChatHeader = () => {
|
|
3124
|
+
// TODO
|
|
3030
3125
|
return [{
|
|
3126
|
+
command: 'Chat.handleInputCut',
|
|
3127
|
+
flags: None,
|
|
3128
|
+
id: 'cut',
|
|
3129
|
+
label: cut()
|
|
3130
|
+
}, {
|
|
3131
|
+
command: 'Chat.handleInputCopy',
|
|
3132
|
+
flags: None,
|
|
3133
|
+
id: 'copy',
|
|
3134
|
+
label: copy()
|
|
3135
|
+
}, {
|
|
3136
|
+
command: 'Chat.handleInputPaste',
|
|
3137
|
+
flags: None,
|
|
3138
|
+
id: 'copy',
|
|
3139
|
+
label: paste()
|
|
3140
|
+
}];
|
|
3141
|
+
};
|
|
3142
|
+
|
|
3143
|
+
const getMenuEntriesChatInput = () => {
|
|
3144
|
+
return [{
|
|
3145
|
+
command: 'Chat.handleInputCut',
|
|
3146
|
+
flags: None,
|
|
3147
|
+
id: 'cut',
|
|
3148
|
+
label: cut()
|
|
3149
|
+
}, {
|
|
3150
|
+
command: 'Chat.handleInputCopy',
|
|
3151
|
+
flags: None,
|
|
3152
|
+
id: 'copy',
|
|
3153
|
+
label: copy()
|
|
3154
|
+
}, {
|
|
3155
|
+
command: 'Chat.handleInputPaste',
|
|
3156
|
+
flags: None,
|
|
3157
|
+
id: 'copy',
|
|
3158
|
+
label: paste()
|
|
3159
|
+
}];
|
|
3160
|
+
};
|
|
3161
|
+
|
|
3162
|
+
const getMenuEntriesChatList = (sessionId = '') => {
|
|
3163
|
+
return [{
|
|
3164
|
+
args: [sessionId],
|
|
3031
3165
|
command: 'Chat.handleClickRename',
|
|
3032
3166
|
flags: None,
|
|
3033
3167
|
id: 'rename',
|
|
3034
3168
|
label: rename()
|
|
3035
3169
|
}, {
|
|
3036
|
-
|
|
3170
|
+
args: [sessionId],
|
|
3171
|
+
command: 'Chat.handleClickDelete',
|
|
3037
3172
|
flags: None,
|
|
3038
3173
|
id: 'archive',
|
|
3039
3174
|
label: archive()
|
|
3040
3175
|
}];
|
|
3041
3176
|
};
|
|
3042
3177
|
|
|
3178
|
+
const Composer = 'composer';
|
|
3179
|
+
const Search = 'search';
|
|
3180
|
+
const ComposerDropTarget = 'composer-drop-target';
|
|
3181
|
+
const AddContext = 'add-context';
|
|
3182
|
+
const Dictate = 'dictate';
|
|
3183
|
+
const Send = 'send';
|
|
3184
|
+
const Back = 'back';
|
|
3185
|
+
const Model = 'model';
|
|
3186
|
+
const ModelPickerToggle = 'model-picker-toggle';
|
|
3187
|
+
const ModelPickerSearch = 'model-picker-search';
|
|
3188
|
+
const ModelPickerSettings = 'model-picker-settings';
|
|
3189
|
+
const RunMode = 'runMode';
|
|
3190
|
+
const ToggleChatFocus = 'toggle-chat-focus';
|
|
3191
|
+
const ToggleSearch = 'toggle-search';
|
|
3192
|
+
const ChatList$1 = 'chat-list';
|
|
3193
|
+
const CreateProject = 'create-project';
|
|
3194
|
+
const CreateSession = 'create-session';
|
|
3195
|
+
const CreateSessionInProjectPrefix = 'create-session-in-project:';
|
|
3196
|
+
const SessionDebug = 'session-debug';
|
|
3197
|
+
const Settings = 'settings';
|
|
3198
|
+
const Login = 'login';
|
|
3199
|
+
const Logout = 'logout';
|
|
3200
|
+
const CloseChat = 'close-chat';
|
|
3201
|
+
const SessionDelete = 'SessionDelete';
|
|
3202
|
+
const ProjectPrefix = 'project:';
|
|
3203
|
+
const SessionPrefix = 'session:';
|
|
3204
|
+
const RenamePrefix = 'session-rename:';
|
|
3205
|
+
const ModelPickerItemPrefix = 'model-picker-item:';
|
|
3206
|
+
const getProjectInputName = projectId => {
|
|
3207
|
+
return `${ProjectPrefix}${projectId}`;
|
|
3208
|
+
};
|
|
3209
|
+
const getCreateSessionInProjectInputName = projectId => {
|
|
3210
|
+
return `${CreateSessionInProjectPrefix}${projectId}`;
|
|
3211
|
+
};
|
|
3212
|
+
const isCreateSessionInProjectInputName = name => {
|
|
3213
|
+
return name.startsWith(CreateSessionInProjectPrefix);
|
|
3214
|
+
};
|
|
3215
|
+
const getProjectIdFromCreateSessionInProjectInputName = name => {
|
|
3216
|
+
return name.slice(CreateSessionInProjectPrefix.length);
|
|
3217
|
+
};
|
|
3218
|
+
const isProjectInputName = name => {
|
|
3219
|
+
return name.startsWith(ProjectPrefix);
|
|
3220
|
+
};
|
|
3221
|
+
const getProjectIdFromInputName = name => {
|
|
3222
|
+
return name.slice(ProjectPrefix.length);
|
|
3223
|
+
};
|
|
3224
|
+
const getSessionInputName = sessionId => {
|
|
3225
|
+
return `${SessionPrefix}${sessionId}`;
|
|
3226
|
+
};
|
|
3227
|
+
const isSessionInputName = name => {
|
|
3228
|
+
return name.startsWith(SessionPrefix);
|
|
3229
|
+
};
|
|
3230
|
+
const getSessionIdFromInputName = name => {
|
|
3231
|
+
return name.slice(SessionPrefix.length);
|
|
3232
|
+
};
|
|
3233
|
+
const isRenameInputName = name => {
|
|
3234
|
+
return name.startsWith(RenamePrefix);
|
|
3235
|
+
};
|
|
3236
|
+
const getRenameIdFromInputName = name => {
|
|
3237
|
+
return name.slice(RenamePrefix.length);
|
|
3238
|
+
};
|
|
3239
|
+
const getModelPickerItemInputName = modelId => {
|
|
3240
|
+
return `${ModelPickerItemPrefix}${modelId}`;
|
|
3241
|
+
};
|
|
3242
|
+
const isModelPickerItemInputName = name => {
|
|
3243
|
+
return name.startsWith(ModelPickerItemPrefix);
|
|
3244
|
+
};
|
|
3245
|
+
const getModelIdFromModelPickerItemInputName = name => {
|
|
3246
|
+
return name.slice(ModelPickerItemPrefix.length);
|
|
3247
|
+
};
|
|
3248
|
+
|
|
3249
|
+
const menuEntryAddProject = {
|
|
3250
|
+
args: [CreateProject],
|
|
3251
|
+
command: 'Chat.handleClick',
|
|
3252
|
+
flags: None,
|
|
3253
|
+
id: 'addProject',
|
|
3254
|
+
label: addProject()
|
|
3255
|
+
};
|
|
3256
|
+
const getMenuEntriesChatProjectList = (projectId = '') => {
|
|
3257
|
+
if (!projectId) {
|
|
3258
|
+
return [menuEntryAddProject];
|
|
3259
|
+
}
|
|
3260
|
+
return [{
|
|
3261
|
+
args: [getCreateSessionInProjectInputName(projectId)],
|
|
3262
|
+
command: 'Chat.handleClick',
|
|
3263
|
+
flags: None,
|
|
3264
|
+
id: 'newChat',
|
|
3265
|
+
label: newChat()
|
|
3266
|
+
}, menuEntryAddProject];
|
|
3267
|
+
};
|
|
3268
|
+
|
|
3043
3269
|
const MenuChatList = 2178;
|
|
3270
|
+
const MenuChatHeader = 2179;
|
|
3271
|
+
const MenuChatInput = 2180;
|
|
3272
|
+
const MenuChatProjectList = 2181;
|
|
3044
3273
|
const getMenuEntryIds = () => {
|
|
3045
|
-
return [Chat$1, MenuChatList];
|
|
3274
|
+
return [Chat$1, MenuChatList, MenuChatHeader, MenuChatInput, MenuChatProjectList];
|
|
3046
3275
|
};
|
|
3047
3276
|
|
|
3048
3277
|
const menuEntrySeparator = {
|
|
@@ -3115,10 +3344,16 @@ const menuEntryDelete = {
|
|
|
3115
3344
|
const getMenuEntriesFile = () => {
|
|
3116
3345
|
return [menuEntryCopyAsE2eTest, menuEntryOpenContainingFolder, menuEntryOpenInIntegratedTerminal, menuEntrySeparator, menuEntryCut, menuEntryCopy, menuEntryPaste, menuEntrySeparator, menuEntryCopyPath, menuEntryCopyRelativePath, menuEntrySeparator, menuEntryRename, menuEntryDelete];
|
|
3117
3346
|
};
|
|
3118
|
-
const getMenuEntries = menuId => {
|
|
3119
|
-
switch (menuId) {
|
|
3347
|
+
const getMenuEntries = (menuId, props) => {
|
|
3348
|
+
switch (props.menuId) {
|
|
3349
|
+
case MenuChatHeader:
|
|
3350
|
+
return getMenuEntriesChatHeader();
|
|
3351
|
+
case MenuChatInput:
|
|
3352
|
+
return getMenuEntriesChatInput();
|
|
3120
3353
|
case MenuChatList:
|
|
3121
3354
|
return getMenuEntriesChatList();
|
|
3355
|
+
case MenuChatProjectList:
|
|
3356
|
+
return getMenuEntriesChatProjectList(props.projectId);
|
|
3122
3357
|
default:
|
|
3123
3358
|
return getMenuEntriesFile();
|
|
3124
3359
|
}
|
|
@@ -3132,6 +3367,10 @@ const getSelectedSessionId = state => {
|
|
|
3132
3367
|
return state.selectedSessionId;
|
|
3133
3368
|
};
|
|
3134
3369
|
|
|
3370
|
+
const handleChatDetailWelcomeContextMenu = async state => {
|
|
3371
|
+
return state;
|
|
3372
|
+
};
|
|
3373
|
+
|
|
3135
3374
|
const handleChatHeaderContextMenu = async state => {
|
|
3136
3375
|
return state;
|
|
3137
3376
|
};
|
|
@@ -3172,17 +3411,13 @@ const handleChatListContextMenu = async (state, eventX, eventY) => {
|
|
|
3172
3411
|
if (!item) {
|
|
3173
3412
|
return state;
|
|
3174
3413
|
}
|
|
3175
|
-
await showContextMenu2(uid,
|
|
3176
|
-
menuId:
|
|
3414
|
+
await showContextMenu2(uid, MenuChatList, eventX, eventY, {
|
|
3415
|
+
menuId: MenuChatList,
|
|
3177
3416
|
sessionId: item.id
|
|
3178
3417
|
});
|
|
3179
3418
|
return state;
|
|
3180
3419
|
};
|
|
3181
3420
|
|
|
3182
|
-
const handleChatWelcomeContextMenu = async state => {
|
|
3183
|
-
return state;
|
|
3184
|
-
};
|
|
3185
|
-
|
|
3186
3421
|
const generateSessionId = () => {
|
|
3187
3422
|
return crypto.randomUUID();
|
|
3188
3423
|
};
|
|
@@ -7051,7 +7286,8 @@ const focusInput = state => {
|
|
|
7051
7286
|
return {
|
|
7052
7287
|
...state,
|
|
7053
7288
|
focus: 'composer',
|
|
7054
|
-
focused: true
|
|
7289
|
+
focused: true,
|
|
7290
|
+
listFocusedIndex: -1
|
|
7055
7291
|
};
|
|
7056
7292
|
};
|
|
7057
7293
|
|
|
@@ -7776,76 +8012,6 @@ const handleClickSend = async state => {
|
|
|
7776
8012
|
return handleSubmit(submitState);
|
|
7777
8013
|
};
|
|
7778
8014
|
|
|
7779
|
-
const Composer = 'composer';
|
|
7780
|
-
const Search = 'search';
|
|
7781
|
-
const ComposerDropTarget = 'composer-drop-target';
|
|
7782
|
-
const AddContext = 'add-context';
|
|
7783
|
-
const Dictate = 'dictate';
|
|
7784
|
-
const Send = 'send';
|
|
7785
|
-
const Back = 'back';
|
|
7786
|
-
const Model = 'model';
|
|
7787
|
-
const ModelPickerToggle = 'model-picker-toggle';
|
|
7788
|
-
const ModelPickerSearch = 'model-picker-search';
|
|
7789
|
-
const ModelPickerSettings = 'model-picker-settings';
|
|
7790
|
-
const RunMode = 'runMode';
|
|
7791
|
-
const ToggleChatFocus = 'toggle-chat-focus';
|
|
7792
|
-
const ToggleSearch = 'toggle-search';
|
|
7793
|
-
const CreateProject = 'create-project';
|
|
7794
|
-
const CreateSession = 'create-session';
|
|
7795
|
-
const CreateSessionInProjectPrefix = 'create-session-in-project:';
|
|
7796
|
-
const SessionDebug = 'session-debug';
|
|
7797
|
-
const Settings = 'settings';
|
|
7798
|
-
const Login = 'login';
|
|
7799
|
-
const Logout = 'logout';
|
|
7800
|
-
const CloseChat = 'close-chat';
|
|
7801
|
-
const SessionDelete = 'SessionDelete';
|
|
7802
|
-
const ProjectPrefix = 'project:';
|
|
7803
|
-
const SessionPrefix = 'session:';
|
|
7804
|
-
const RenamePrefix = 'session-rename:';
|
|
7805
|
-
const ModelPickerItemPrefix = 'model-picker-item:';
|
|
7806
|
-
const getProjectInputName = projectId => {
|
|
7807
|
-
return `${ProjectPrefix}${projectId}`;
|
|
7808
|
-
};
|
|
7809
|
-
const getCreateSessionInProjectInputName = projectId => {
|
|
7810
|
-
return `${CreateSessionInProjectPrefix}${projectId}`;
|
|
7811
|
-
};
|
|
7812
|
-
const isCreateSessionInProjectInputName = name => {
|
|
7813
|
-
return name.startsWith(CreateSessionInProjectPrefix);
|
|
7814
|
-
};
|
|
7815
|
-
const getProjectIdFromCreateSessionInProjectInputName = name => {
|
|
7816
|
-
return name.slice(CreateSessionInProjectPrefix.length);
|
|
7817
|
-
};
|
|
7818
|
-
const isProjectInputName = name => {
|
|
7819
|
-
return name.startsWith(ProjectPrefix);
|
|
7820
|
-
};
|
|
7821
|
-
const getProjectIdFromInputName = name => {
|
|
7822
|
-
return name.slice(ProjectPrefix.length);
|
|
7823
|
-
};
|
|
7824
|
-
const getSessionInputName = sessionId => {
|
|
7825
|
-
return `${SessionPrefix}${sessionId}`;
|
|
7826
|
-
};
|
|
7827
|
-
const isSessionInputName = name => {
|
|
7828
|
-
return name.startsWith(SessionPrefix);
|
|
7829
|
-
};
|
|
7830
|
-
const getSessionIdFromInputName = name => {
|
|
7831
|
-
return name.slice(SessionPrefix.length);
|
|
7832
|
-
};
|
|
7833
|
-
const isRenameInputName = name => {
|
|
7834
|
-
return name.startsWith(RenamePrefix);
|
|
7835
|
-
};
|
|
7836
|
-
const getRenameIdFromInputName = name => {
|
|
7837
|
-
return name.slice(RenamePrefix.length);
|
|
7838
|
-
};
|
|
7839
|
-
const getModelPickerItemInputName = modelId => {
|
|
7840
|
-
return `${ModelPickerItemPrefix}${modelId}`;
|
|
7841
|
-
};
|
|
7842
|
-
const isModelPickerItemInputName = name => {
|
|
7843
|
-
return name.startsWith(ModelPickerItemPrefix);
|
|
7844
|
-
};
|
|
7845
|
-
const getModelIdFromModelPickerItemInputName = name => {
|
|
7846
|
-
return name.slice(ModelPickerItemPrefix.length);
|
|
7847
|
-
};
|
|
7848
|
-
|
|
7849
8015
|
const OpenApiApiKeyInput = 'open-api-api-key';
|
|
7850
8016
|
const SaveOpenApiApiKey = 'save-openapi-api-key';
|
|
7851
8017
|
const OpenOpenApiApiKeySettings = 'open-openapi-api-key-settings';
|
|
@@ -7954,11 +8120,34 @@ const selectListIndex = async (state, index) => {
|
|
|
7954
8120
|
return state;
|
|
7955
8121
|
}
|
|
7956
8122
|
const session = visibleSessions[index];
|
|
7957
|
-
|
|
8123
|
+
const nextState = await selectSession(state, session.id);
|
|
8124
|
+
return {
|
|
8125
|
+
...nextState,
|
|
8126
|
+
focus: 'list',
|
|
8127
|
+
focused: true,
|
|
8128
|
+
listFocusedIndex: index
|
|
8129
|
+
};
|
|
7958
8130
|
};
|
|
7959
8131
|
|
|
7960
8132
|
const handleClickList = async (state, eventX, eventY) => {
|
|
7961
8133
|
const index = getListIndex(state, eventX, eventY);
|
|
8134
|
+
if (index === -1) {
|
|
8135
|
+
return {
|
|
8136
|
+
...state,
|
|
8137
|
+
focus: 'list',
|
|
8138
|
+
focused: true,
|
|
8139
|
+
listFocusedIndex: -1
|
|
8140
|
+
};
|
|
8141
|
+
}
|
|
8142
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
8143
|
+
if (index >= visibleSessions.length) {
|
|
8144
|
+
return {
|
|
8145
|
+
...state,
|
|
8146
|
+
focus: 'list',
|
|
8147
|
+
focused: true,
|
|
8148
|
+
listFocusedIndex: -1
|
|
8149
|
+
};
|
|
8150
|
+
}
|
|
7962
8151
|
return selectListIndex(state, index);
|
|
7963
8152
|
};
|
|
7964
8153
|
|
|
@@ -8241,21 +8430,37 @@ const handleInputFocus = async (state, name) => {
|
|
|
8241
8430
|
return {
|
|
8242
8431
|
...state,
|
|
8243
8432
|
focus: 'send-button',
|
|
8244
|
-
focused: true
|
|
8433
|
+
focused: true,
|
|
8434
|
+
listFocusedIndex: -1
|
|
8435
|
+
};
|
|
8436
|
+
}
|
|
8437
|
+
if (name === ChatList$1) {
|
|
8438
|
+
return {
|
|
8439
|
+
...state,
|
|
8440
|
+
focus: 'list',
|
|
8441
|
+
focused: true,
|
|
8442
|
+
listFocusedIndex: -1
|
|
8245
8443
|
};
|
|
8246
8444
|
}
|
|
8247
8445
|
if (isSessionInputName(name) || name === SessionDelete) {
|
|
8446
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
8447
|
+
const sessionId = isSessionInputName(name) ? getSessionIdFromInputName(name) : '';
|
|
8448
|
+
const focusedIndex = sessionId === '' ? -1 : visibleSessions.findIndex(session => {
|
|
8449
|
+
return session.id === sessionId;
|
|
8450
|
+
});
|
|
8248
8451
|
return {
|
|
8249
8452
|
...state,
|
|
8250
8453
|
focus: 'list',
|
|
8251
|
-
focused: true
|
|
8454
|
+
focused: true,
|
|
8455
|
+
listFocusedIndex: focusedIndex
|
|
8252
8456
|
};
|
|
8253
8457
|
}
|
|
8254
8458
|
if (name === CreateSession || name === SessionDebug || name === Settings || name === CloseChat || name === Back) {
|
|
8255
8459
|
return {
|
|
8256
8460
|
...state,
|
|
8257
8461
|
focus: 'header',
|
|
8258
|
-
focused: true
|
|
8462
|
+
focused: true,
|
|
8463
|
+
listFocusedIndex: -1
|
|
8259
8464
|
};
|
|
8260
8465
|
}
|
|
8261
8466
|
return {
|
|
@@ -8308,6 +8513,18 @@ const handleKeyDown = async (state, key, shiftKey) => {
|
|
|
8308
8513
|
sessions,
|
|
8309
8514
|
viewMode
|
|
8310
8515
|
} = state;
|
|
8516
|
+
if (state.focus === 'list' && viewMode === 'list') {
|
|
8517
|
+
switch (key) {
|
|
8518
|
+
case 'ArrowDown':
|
|
8519
|
+
return chatListFocusNext(state);
|
|
8520
|
+
case 'ArrowUp':
|
|
8521
|
+
return chatListFocusPrevious(state);
|
|
8522
|
+
case 'End':
|
|
8523
|
+
return chatListFocusLast(state);
|
|
8524
|
+
case 'Home':
|
|
8525
|
+
return chatListFocusFirst(state);
|
|
8526
|
+
}
|
|
8527
|
+
}
|
|
8311
8528
|
if (key !== 'Enter' || shiftKey) {
|
|
8312
8529
|
return state;
|
|
8313
8530
|
}
|
|
@@ -8356,7 +8573,50 @@ const handleNewline = async state => {
|
|
|
8356
8573
|
return handleInput(state, Composer, `${composerValue}\n`);
|
|
8357
8574
|
};
|
|
8358
8575
|
|
|
8359
|
-
const
|
|
8576
|
+
const getProjectRowIds = (projects, sessions, projectExpandedIds) => {
|
|
8577
|
+
const blankProjectId = projects.find(project => project.name === '_blank')?.id || projects[0]?.id || '';
|
|
8578
|
+
const projectRowIds = [];
|
|
8579
|
+
for (const project of projects) {
|
|
8580
|
+
projectRowIds.push(project.id);
|
|
8581
|
+
if (!projectExpandedIds.includes(project.id)) {
|
|
8582
|
+
continue;
|
|
8583
|
+
}
|
|
8584
|
+
for (const session of sessions) {
|
|
8585
|
+
const sessionProjectId = session.projectId || blankProjectId;
|
|
8586
|
+
if (sessionProjectId === project.id) {
|
|
8587
|
+
projectRowIds.push(project.id);
|
|
8588
|
+
}
|
|
8589
|
+
}
|
|
8590
|
+
}
|
|
8591
|
+
return projectRowIds;
|
|
8592
|
+
};
|
|
8593
|
+
const getProjectIdAtPosition = (state, eventY) => {
|
|
8594
|
+
const {
|
|
8595
|
+
headerHeight,
|
|
8596
|
+
listItemHeight,
|
|
8597
|
+
projectExpandedIds,
|
|
8598
|
+
projectListScrollTop,
|
|
8599
|
+
projects,
|
|
8600
|
+
sessions,
|
|
8601
|
+
y
|
|
8602
|
+
} = state;
|
|
8603
|
+
const relativeY = eventY - y - headerHeight + projectListScrollTop;
|
|
8604
|
+
if (relativeY < 0) {
|
|
8605
|
+
return '';
|
|
8606
|
+
}
|
|
8607
|
+
const index = Math.floor(relativeY / listItemHeight);
|
|
8608
|
+
const projectRowIds = getProjectRowIds(projects, sessions, projectExpandedIds);
|
|
8609
|
+
return projectRowIds[index] || '';
|
|
8610
|
+
};
|
|
8611
|
+
const handleProjectListContextMenu = async (state, button, eventX, eventY) => {
|
|
8612
|
+
const {
|
|
8613
|
+
uid
|
|
8614
|
+
} = state;
|
|
8615
|
+
const projectId = getProjectIdAtPosition(state, eventY);
|
|
8616
|
+
await showContextMenu2(uid, MenuChatProjectList, eventX, eventY, {
|
|
8617
|
+
menuId: MenuChatProjectList,
|
|
8618
|
+
projectId
|
|
8619
|
+
});
|
|
8360
8620
|
return state;
|
|
8361
8621
|
};
|
|
8362
8622
|
|
|
@@ -9108,10 +9368,24 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
|
|
|
9108
9368
|
align-items:center;
|
|
9109
9369
|
}
|
|
9110
9370
|
|
|
9371
|
+
.ChatListItemFocused{
|
|
9372
|
+
background: var(--vscode-list-activeSelectionBackground);
|
|
9373
|
+
color: var(--vscode-list-activeSelectionForeground);
|
|
9374
|
+
}
|
|
9375
|
+
|
|
9111
9376
|
.ChatMessageContent p + p{
|
|
9112
9377
|
margin-top: 0.75em;
|
|
9113
9378
|
}
|
|
9114
9379
|
|
|
9380
|
+
.MissingApiKeyForm{
|
|
9381
|
+
padding-top: 10px;
|
|
9382
|
+
}
|
|
9383
|
+
|
|
9384
|
+
.ChatHeaderLabel{
|
|
9385
|
+
margin: 0;
|
|
9386
|
+
font-size: 14px;
|
|
9387
|
+
}
|
|
9388
|
+
|
|
9115
9389
|
.ChatListItemStatusRow{
|
|
9116
9390
|
width: 16px;
|
|
9117
9391
|
min-width: 16px;
|
|
@@ -9134,6 +9408,8 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
|
|
|
9134
9408
|
|
|
9135
9409
|
.ChatListItemStatusFinished{
|
|
9136
9410
|
color: var(--vscode-testing-iconPassed);
|
|
9411
|
+
}
|
|
9412
|
+
|
|
9137
9413
|
.ChatListItem .SessionArchiveButton{
|
|
9138
9414
|
opacity: 0;
|
|
9139
9415
|
}
|
|
@@ -9142,6 +9418,13 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
|
|
|
9142
9418
|
.ChatListItem:focus-within .SessionArchiveButton{
|
|
9143
9419
|
opacity: 1;
|
|
9144
9420
|
}
|
|
9421
|
+
|
|
9422
|
+
.ChatHeaderLabel{
|
|
9423
|
+
white-space: nowrap;
|
|
9424
|
+
overflow: hidden;
|
|
9425
|
+
text-overflow: ellipsis;
|
|
9426
|
+
}
|
|
9427
|
+
|
|
9145
9428
|
`;
|
|
9146
9429
|
return `${baseCss}
|
|
9147
9430
|
|
|
@@ -9176,7 +9459,11 @@ const renderCss = (oldState, newState) => {
|
|
|
9176
9459
|
return [SetCss, uid, css];
|
|
9177
9460
|
};
|
|
9178
9461
|
|
|
9179
|
-
const getFocusSelector =
|
|
9462
|
+
const getFocusSelector = state => {
|
|
9463
|
+
const {
|
|
9464
|
+
focus,
|
|
9465
|
+
listFocusedIndex
|
|
9466
|
+
} = state;
|
|
9180
9467
|
switch (focus) {
|
|
9181
9468
|
case 'composer':
|
|
9182
9469
|
case 'input':
|
|
@@ -9184,7 +9471,17 @@ const getFocusSelector = focus => {
|
|
|
9184
9471
|
case 'header':
|
|
9185
9472
|
return '[name="create-session"]';
|
|
9186
9473
|
case 'list':
|
|
9187
|
-
|
|
9474
|
+
{
|
|
9475
|
+
if (listFocusedIndex === -1) {
|
|
9476
|
+
return `[name="${ChatList$1}"]`;
|
|
9477
|
+
}
|
|
9478
|
+
const visibleSessions = getVisibleSessions(state.sessions, state.selectedProjectId);
|
|
9479
|
+
const session = visibleSessions[listFocusedIndex];
|
|
9480
|
+
if (!session) {
|
|
9481
|
+
return `[name="${ChatList$1}"]`;
|
|
9482
|
+
}
|
|
9483
|
+
return `[name="${getSessionInputName(session.id)}"]`;
|
|
9484
|
+
}
|
|
9188
9485
|
case 'send-button':
|
|
9189
9486
|
return '[name="send"]';
|
|
9190
9487
|
default:
|
|
@@ -9192,7 +9489,7 @@ const getFocusSelector = focus => {
|
|
|
9192
9489
|
}
|
|
9193
9490
|
};
|
|
9194
9491
|
const renderFocus = (oldState, newState) => {
|
|
9195
|
-
const selector = getFocusSelector(newState
|
|
9492
|
+
const selector = getFocusSelector(newState);
|
|
9196
9493
|
return [FocusSelector, selector];
|
|
9197
9494
|
};
|
|
9198
9495
|
|
|
@@ -9225,6 +9522,7 @@ const ChatTodoListItemInProgress = 'ChatTodoListItemInProgress';
|
|
|
9225
9522
|
const ChatTodoListItemCompleted = 'ChatTodoListItemCompleted';
|
|
9226
9523
|
const Chat = 'Chat';
|
|
9227
9524
|
const ChatHeader = 'ChatHeader';
|
|
9525
|
+
const ChatHeaderLabel = 'ChatHeaderLabel';
|
|
9228
9526
|
const Button = 'Button';
|
|
9229
9527
|
const ButtonPrimary = 'ButtonPrimary';
|
|
9230
9528
|
const ButtonSecondary = 'ButtonSecondary';
|
|
@@ -9241,6 +9539,7 @@ const LabelDetail = 'LabelDetail';
|
|
|
9241
9539
|
const ChatList = 'ChatList';
|
|
9242
9540
|
const ChatListEmpty = 'ChatListEmpty';
|
|
9243
9541
|
const ChatListItem = 'ChatListItem';
|
|
9542
|
+
const ChatListItemFocused = 'ChatListItemFocused';
|
|
9244
9543
|
const ChatListItemStatusRow = 'ChatListItemStatusRow';
|
|
9245
9544
|
const ChatListItemStatusIcon = 'ChatListItemStatusIcon';
|
|
9246
9545
|
const ChatListItemStatusStopped = 'ChatListItemStatusStopped';
|
|
@@ -9267,6 +9566,7 @@ const MarkdownMathBlock = 'MarkdownMathBlock';
|
|
|
9267
9566
|
const MarkdownTable = 'MarkdownTable';
|
|
9268
9567
|
const ChatTableWrapper = 'ChatTableWrapper';
|
|
9269
9568
|
const Message = 'Message';
|
|
9569
|
+
const MissingApiKeyForm = 'MissingApiKeyForm';
|
|
9270
9570
|
const ChatMessageContent = 'ChatMessageContent';
|
|
9271
9571
|
const ChatToolCalls = 'ChatToolCalls';
|
|
9272
9572
|
const ChatToolCallsLabel = 'ChatToolCallsLabel';
|
|
@@ -9497,6 +9797,20 @@ const getAddContextButtonDom = () => {
|
|
|
9497
9797
|
type: Text
|
|
9498
9798
|
}];
|
|
9499
9799
|
};
|
|
9800
|
+
const getBackToChatsButtonDom = () => {
|
|
9801
|
+
return [{
|
|
9802
|
+
childCount: 1,
|
|
9803
|
+
className: mergeClassNames(Button, ButtonSecondary),
|
|
9804
|
+
inputType: 'button',
|
|
9805
|
+
name: Back,
|
|
9806
|
+
onClick: HandleClickBack,
|
|
9807
|
+
title: backToChatList(),
|
|
9808
|
+
type: Button$1
|
|
9809
|
+
}, {
|
|
9810
|
+
text: backToChatList(),
|
|
9811
|
+
type: Text
|
|
9812
|
+
}];
|
|
9813
|
+
};
|
|
9500
9814
|
|
|
9501
9815
|
const clampToPercentage = (tokensUsed, tokensMax) => {
|
|
9502
9816
|
if (tokensMax <= 0) {
|
|
@@ -9533,9 +9847,9 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
|
|
|
9533
9847
|
}, text(usageLabel)];
|
|
9534
9848
|
};
|
|
9535
9849
|
|
|
9536
|
-
const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled = false) => {
|
|
9850
|
+
const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled = false, showBackToChatsButton = false) => {
|
|
9537
9851
|
const isSendDisabled = composerValue.trim() === '';
|
|
9538
|
-
const controlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (showRunMode ? 1 : 0) + (addContextButtonEnabled ? 1 : 0);
|
|
9852
|
+
const controlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (showRunMode ? 1 : 0) + (addContextButtonEnabled ? 1 : 0) + (showBackToChatsButton ? 1 : 0);
|
|
9539
9853
|
const hasTodoList = todoListToolEnabled && todoListItems.length > 0;
|
|
9540
9854
|
const todoHeaderText = `Todos (${todoListItems.filter(item => item.status === 'completed').length}/${todoListItems.length})`;
|
|
9541
9855
|
const getTodoItemClassName = status => {
|
|
@@ -9589,7 +9903,7 @@ const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchVal
|
|
|
9589
9903
|
className: ChatSendAreaBottom,
|
|
9590
9904
|
onContextMenu: HandleContextMenuChatSendAreaBottom,
|
|
9591
9905
|
type: Div
|
|
9592
|
-
}, ...(newChatModelPickerEnabled ? getChatModelPickerVirtualDom(models, selectedModelId, modelPickerOpen, modelPickerSearchValue) : getChatSelectVirtualDom(models, selectedModelId)), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
9906
|
+
}, ...(newChatModelPickerEnabled ? getChatModelPickerVirtualDom(models, selectedModelId, modelPickerOpen, modelPickerSearchValue) : getChatSelectVirtualDom(models, selectedModelId)), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...(showBackToChatsButton ? getBackToChatsButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
9593
9907
|
};
|
|
9594
9908
|
|
|
9595
9909
|
const getImageAltText = alt => {
|
|
@@ -10001,6 +10315,7 @@ const getMissingApiKeyDom = ({
|
|
|
10001
10315
|
inputPattern,
|
|
10002
10316
|
inputRequired = false,
|
|
10003
10317
|
openSettingsButtonName,
|
|
10318
|
+
openSettingsUrl,
|
|
10004
10319
|
placeholder,
|
|
10005
10320
|
saveButtonDisabled = false,
|
|
10006
10321
|
saveButtonName,
|
|
@@ -10008,10 +10323,14 @@ const getMissingApiKeyDom = ({
|
|
|
10008
10323
|
}) => {
|
|
10009
10324
|
return [{
|
|
10010
10325
|
childCount: 2,
|
|
10326
|
+
className: MissingApiKeyForm,
|
|
10011
10327
|
method: 'GET',
|
|
10012
10328
|
onSubmit: HandleMissingApiKeySubmit,
|
|
10013
10329
|
type: Form
|
|
10014
10330
|
}, {
|
|
10331
|
+
autocapitalize: 'off',
|
|
10332
|
+
autocomplete: 'off',
|
|
10333
|
+
autocorrect: 'off',
|
|
10015
10334
|
childCount: 0,
|
|
10016
10335
|
className: InputBox,
|
|
10017
10336
|
name: inputName,
|
|
@@ -10021,6 +10340,7 @@ const getMissingApiKeyDom = ({
|
|
|
10021
10340
|
} : {}),
|
|
10022
10341
|
placeholder,
|
|
10023
10342
|
required: inputRequired,
|
|
10343
|
+
spellcheck: false,
|
|
10024
10344
|
type: Input
|
|
10025
10345
|
}, {
|
|
10026
10346
|
childCount: 2,
|
|
@@ -10036,10 +10356,11 @@ const getMissingApiKeyDom = ({
|
|
|
10036
10356
|
}, text(saveButtonText), {
|
|
10037
10357
|
childCount: 1,
|
|
10038
10358
|
className: mergeClassNames(Button, ButtonSecondary),
|
|
10039
|
-
|
|
10359
|
+
href: openSettingsUrl,
|
|
10040
10360
|
name: openSettingsButtonName,
|
|
10041
|
-
|
|
10042
|
-
|
|
10361
|
+
rel: 'noopener noreferrer',
|
|
10362
|
+
target: '_blank',
|
|
10363
|
+
type: A
|
|
10043
10364
|
}, text(getApiKeyText)];
|
|
10044
10365
|
};
|
|
10045
10366
|
|
|
@@ -10050,6 +10371,7 @@ const getMissingOpenApiApiKeyDom = () => {
|
|
|
10050
10371
|
inputPattern: '^sk-.+',
|
|
10051
10372
|
inputRequired: true,
|
|
10052
10373
|
openSettingsButtonName: OpenOpenApiApiKeyWebsite,
|
|
10374
|
+
openSettingsUrl: 'https://platform.openai.com/api-keys',
|
|
10053
10375
|
placeholder: openApiApiKeyPlaceholder(),
|
|
10054
10376
|
saveButtonName: SaveOpenApiApiKey
|
|
10055
10377
|
});
|
|
@@ -10061,6 +10383,7 @@ const getMissingOpenRouterApiKeyDom = (openRouterApiKeyState = 'idle') => {
|
|
|
10061
10383
|
getApiKeyText: getOpenRouterApiKey(),
|
|
10062
10384
|
inputName: OpenRouterApiKeyInput,
|
|
10063
10385
|
openSettingsButtonName: OpenOpenRouterApiKeySettings,
|
|
10386
|
+
openSettingsUrl: 'https://openrouter.ai/settings/keys',
|
|
10064
10387
|
placeholder: openRouterApiKeyPlaceholder(),
|
|
10065
10388
|
saveButtonDisabled: isSaving,
|
|
10066
10389
|
saveButtonName: SaveOpenRouterApiKey,
|
|
@@ -11066,7 +11389,7 @@ const getChatModeChatFocusVirtualDom = ({
|
|
|
11066
11389
|
onDragEnter: HandleDragEnterChatView,
|
|
11067
11390
|
onDragOver: HandleDragOverChatView,
|
|
11068
11391
|
type: Div
|
|
11069
|
-
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
11392
|
+
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled, true), ...(isDropOverlayVisible ? [{
|
|
11070
11393
|
childCount: 1,
|
|
11071
11394
|
className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
|
|
11072
11395
|
name: ComposerDropTarget,
|
|
@@ -11180,8 +11503,8 @@ const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false, a
|
|
|
11180
11503
|
type: Div
|
|
11181
11504
|
}, ...getBackButtonVirtualDom(), {
|
|
11182
11505
|
childCount: 1,
|
|
11183
|
-
className:
|
|
11184
|
-
type:
|
|
11506
|
+
className: ChatHeaderLabel,
|
|
11507
|
+
type: H2
|
|
11185
11508
|
}, text(selectedSessionTitle), ...getChatHeaderActionsDom('detail', authEnabled, authStatus), ...(hasAuthError ? [{
|
|
11186
11509
|
childCount: 1,
|
|
11187
11510
|
className: ChatAuthError,
|
|
@@ -11258,8 +11581,8 @@ const getChatHeaderListModeDom = (authEnabled = false, authStatus = 'signed-out'
|
|
|
11258
11581
|
type: Div
|
|
11259
11582
|
}, {
|
|
11260
11583
|
childCount: 1,
|
|
11261
|
-
className:
|
|
11262
|
-
type:
|
|
11584
|
+
className: ChatHeaderLabel,
|
|
11585
|
+
type: H2
|
|
11263
11586
|
}, text(chats()), ...getChatHeaderActionsDom('list', authEnabled, authStatus, searchEnabled), ...(hasSearchField ? [{
|
|
11264
11587
|
childCount: 1,
|
|
11265
11588
|
className: SearchFieldContainer,
|
|
@@ -11303,8 +11626,8 @@ const getSessionStatusClassName = session => {
|
|
|
11303
11626
|
}
|
|
11304
11627
|
return ChatListItemStatusStopped;
|
|
11305
11628
|
};
|
|
11306
|
-
const getSessionDom = session => {
|
|
11307
|
-
const sessionClassName = ChatListItem;
|
|
11629
|
+
const getSessionDom = (session, focused = false) => {
|
|
11630
|
+
const sessionClassName = focused ? mergeClassNames(ChatListItem, ChatListItemFocused) : ChatListItem;
|
|
11308
11631
|
const sessionStatusClassName = getSessionStatusClassName(session);
|
|
11309
11632
|
return [{
|
|
11310
11633
|
childCount: 3,
|
|
@@ -11323,6 +11646,8 @@ const getSessionDom = session => {
|
|
|
11323
11646
|
className: ChatListItemLabel,
|
|
11324
11647
|
name: getSessionInputName(session.id),
|
|
11325
11648
|
onContextMenu: HandleListContextMenu,
|
|
11649
|
+
onFocus: HandleFocus,
|
|
11650
|
+
tabIndex: 0,
|
|
11326
11651
|
type: Div
|
|
11327
11652
|
}, text(session.title), {
|
|
11328
11653
|
childCount: 1,
|
|
@@ -11344,18 +11669,22 @@ const getSessionDom = session => {
|
|
|
11344
11669
|
}];
|
|
11345
11670
|
};
|
|
11346
11671
|
|
|
11347
|
-
const getChatListDom = (sessions, selectedSessionId, chatListScrollTop = 0) => {
|
|
11672
|
+
const getChatListDom = (sessions, selectedSessionId, listFocusedIndex, chatListScrollTop = 0) => {
|
|
11348
11673
|
if (sessions.length === 0) {
|
|
11349
11674
|
return getEmptyChatSessionsDom();
|
|
11350
11675
|
}
|
|
11351
11676
|
return [{
|
|
11352
11677
|
childCount: sessions.length,
|
|
11353
11678
|
className: ChatList,
|
|
11679
|
+
name: ChatList$1,
|
|
11354
11680
|
onClick: HandleClickList,
|
|
11681
|
+
onContextMenu: HandleListContextMenu,
|
|
11682
|
+
onFocus: HandleFocus,
|
|
11355
11683
|
onScroll: HandleChatListScroll,
|
|
11356
11684
|
scrollTop: chatListScrollTop,
|
|
11685
|
+
tabIndex: 0,
|
|
11357
11686
|
type: Ul
|
|
11358
|
-
}, ...sessions.flatMap(getSessionDom)];
|
|
11687
|
+
}, ...sessions.flatMap((session, index) => getSessionDom(session, index === listFocusedIndex))];
|
|
11359
11688
|
};
|
|
11360
11689
|
|
|
11361
11690
|
const getChatModeListVirtualDom = ({
|
|
@@ -11371,6 +11700,7 @@ const getChatModeListVirtualDom = ({
|
|
|
11371
11700
|
composerHeight = 28,
|
|
11372
11701
|
composerLineHeight = 20,
|
|
11373
11702
|
composerValue,
|
|
11703
|
+
listFocusedIndex = -1,
|
|
11374
11704
|
modelPickerOpen = false,
|
|
11375
11705
|
modelPickerSearchValue = '',
|
|
11376
11706
|
models,
|
|
@@ -11399,7 +11729,7 @@ const getChatModeListVirtualDom = ({
|
|
|
11399
11729
|
onDragEnter: HandleDragEnterChatView,
|
|
11400
11730
|
onDragOver: HandleDragOverChatView,
|
|
11401
11731
|
type: Div
|
|
11402
|
-
}, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
11732
|
+
}, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, listFocusedIndex, chatListScrollTop), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
11403
11733
|
childCount: 1,
|
|
11404
11734
|
className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
|
|
11405
11735
|
name: ComposerDropTarget,
|
|
@@ -11506,6 +11836,7 @@ const getChatVirtualDom = options => {
|
|
|
11506
11836
|
composerHeight,
|
|
11507
11837
|
composerLineHeight,
|
|
11508
11838
|
composerValue,
|
|
11839
|
+
listFocusedIndex = -1,
|
|
11509
11840
|
messagesScrollTop,
|
|
11510
11841
|
modelPickerOpen = false,
|
|
11511
11842
|
modelPickerSearchValue = '',
|
|
@@ -11626,6 +11957,7 @@ const getChatVirtualDom = options => {
|
|
|
11626
11957
|
composerHeight,
|
|
11627
11958
|
composerLineHeight,
|
|
11628
11959
|
composerValue,
|
|
11960
|
+
listFocusedIndex,
|
|
11629
11961
|
modelPickerOpen,
|
|
11630
11962
|
modelPickerSearchValue,
|
|
11631
11963
|
models,
|
|
@@ -11665,6 +11997,7 @@ const renderItems = (oldState, newState) => {
|
|
|
11665
11997
|
composerLineHeight,
|
|
11666
11998
|
composerValue,
|
|
11667
11999
|
initial,
|
|
12000
|
+
listFocusedIndex,
|
|
11668
12001
|
messagesScrollTop,
|
|
11669
12002
|
modelPickerOpen,
|
|
11670
12003
|
modelPickerSearchValue,
|
|
@@ -11711,6 +12044,7 @@ const renderItems = (oldState, newState) => {
|
|
|
11711
12044
|
composerHeight,
|
|
11712
12045
|
composerLineHeight,
|
|
11713
12046
|
composerValue,
|
|
12047
|
+
listFocusedIndex,
|
|
11714
12048
|
messagesScrollTop,
|
|
11715
12049
|
modelPickerOpen,
|
|
11716
12050
|
modelPickerSearchValue,
|
|
@@ -11971,7 +12305,8 @@ const renderEventListeners = () => {
|
|
|
11971
12305
|
preventDefault: true
|
|
11972
12306
|
}, {
|
|
11973
12307
|
name: HandleChatWelcomeContextMenu,
|
|
11974
|
-
params: ['
|
|
12308
|
+
params: ['handleChatDetailWelcomeContextMenu'],
|
|
12309
|
+
preventDefault: true
|
|
11975
12310
|
}, {
|
|
11976
12311
|
name: HandleChatHeaderContextMenu,
|
|
11977
12312
|
params: ['handleChatHeaderContextMenu'],
|
|
@@ -12233,6 +12568,10 @@ const useMockApi = (state, value, mockApiCommandId = defaultMockApiCommandId) =>
|
|
|
12233
12568
|
};
|
|
12234
12569
|
|
|
12235
12570
|
const commandMap = {
|
|
12571
|
+
'Chat.chatListFocusFirst': wrapCommand(chatListFocusFirst),
|
|
12572
|
+
'Chat.chatListFocusLast': wrapCommand(chatListFocusLast),
|
|
12573
|
+
'Chat.chatListFocusNext': wrapCommand(chatListFocusNext),
|
|
12574
|
+
'Chat.chatListFocusPrevious': wrapCommand(chatListFocusPrevious),
|
|
12236
12575
|
'Chat.clearInput': wrapCommand(clearInput),
|
|
12237
12576
|
'Chat.copyInput': wrapCommand(copyInput),
|
|
12238
12577
|
'Chat.create': create,
|
|
@@ -12247,11 +12586,11 @@ const commandMap = {
|
|
|
12247
12586
|
'Chat.getMenuEntryIds': getMenuEntryIds,
|
|
12248
12587
|
'Chat.getQuickPickMenuEntries': getQuickPickMenuEntries,
|
|
12249
12588
|
'Chat.getSelectedSessionId': wrapGetter(getSelectedSessionId),
|
|
12589
|
+
'Chat.handleChatDetailWelcomeContextMenu': wrapCommand(handleChatDetailWelcomeContextMenu),
|
|
12250
12590
|
'Chat.handleChatHeaderContextMenu': wrapCommand(handleChatHeaderContextMenu),
|
|
12251
12591
|
'Chat.handleChatInputContextMenu': wrapCommand(handleChatInputContextMenu),
|
|
12252
12592
|
'Chat.handleChatListContextMenu': wrapCommand(handleChatListContextMenu),
|
|
12253
12593
|
'Chat.handleChatListScroll': wrapCommand(handleChatListScroll),
|
|
12254
|
-
'Chat.handleChatWelcomeContextMenu': wrapCommand(handleChatWelcomeContextMenu),
|
|
12255
12594
|
'Chat.handleClick': wrapCommand(handleClick),
|
|
12256
12595
|
'Chat.handleClickBack': wrapCommand(handleClickBack),
|
|
12257
12596
|
'Chat.handleClickClose': handleClickClose,
|