@lvce-editor/chat-view 6.10.0 → 6.13.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 +896 -467
- package/package.json +1 -1
|
@@ -1664,6 +1664,10 @@ const createDefaultState = () => {
|
|
|
1664
1664
|
chatMessageFontFamily: 'system-ui',
|
|
1665
1665
|
chatMessageFontSize,
|
|
1666
1666
|
chatMessageLineHeight,
|
|
1667
|
+
chatSendAreaPaddingBottom: 10,
|
|
1668
|
+
chatSendAreaPaddingLeft: 8,
|
|
1669
|
+
chatSendAreaPaddingRight: 8,
|
|
1670
|
+
chatSendAreaPaddingTop: 10,
|
|
1667
1671
|
composerDropActive: false,
|
|
1668
1672
|
composerDropEnabled: true,
|
|
1669
1673
|
composerFontFamily: 'system-ui',
|
|
@@ -1710,6 +1714,7 @@ const createDefaultState = () => {
|
|
|
1710
1714
|
}],
|
|
1711
1715
|
questionToolEnabled: false,
|
|
1712
1716
|
renamingSessionId: '',
|
|
1717
|
+
runMode: 'local',
|
|
1713
1718
|
selectedModelId: defaultModelId,
|
|
1714
1719
|
selectedProjectId: defaultProjectId,
|
|
1715
1720
|
selectedSessionId: defaultSessionId,
|
|
@@ -1719,7 +1724,13 @@ const createDefaultState = () => {
|
|
|
1719
1724
|
projectId: defaultProjectId,
|
|
1720
1725
|
title: defaultSessionTitle()
|
|
1721
1726
|
}],
|
|
1727
|
+
showRunMode: false,
|
|
1722
1728
|
streamingEnabled: true,
|
|
1729
|
+
textAreaPaddingBottom: 0,
|
|
1730
|
+
textAreaPaddingLeft: 12,
|
|
1731
|
+
textAreaPaddingRight: 12,
|
|
1732
|
+
textAreaPaddingTop: 0,
|
|
1733
|
+
todoListToolEnabled: false,
|
|
1723
1734
|
tokensMax: 0,
|
|
1724
1735
|
tokensUsed: 0,
|
|
1725
1736
|
uid: 0,
|
|
@@ -2513,7 +2524,7 @@ const getRenderHtmlCss = (sessions, selectedSessionId) => {
|
|
|
2513
2524
|
const isEqual$1 = (oldState, newState) => {
|
|
2514
2525
|
const oldRenderHtmlCss = getRenderHtmlCss(oldState.sessions, oldState.selectedSessionId);
|
|
2515
2526
|
const newRenderHtmlCss = getRenderHtmlCss(newState.sessions, newState.selectedSessionId);
|
|
2516
|
-
return oldState.initial === newState.initial && oldState.chatMessageFontFamily === newState.chatMessageFontFamily && oldState.chatMessageFontSize === newState.chatMessageFontSize && oldState.chatMessageLineHeight === newState.chatMessageLineHeight && oldState.composerHeight === newState.composerHeight && oldState.composerLineHeight === newState.composerLineHeight && oldState.composerFontFamily === newState.composerFontFamily && oldState.composerFontSize === newState.composerFontSize && oldState.listItemHeight === newState.listItemHeight && oldRenderHtmlCss === newRenderHtmlCss;
|
|
2527
|
+
return oldState.initial === newState.initial && oldState.chatMessageFontFamily === newState.chatMessageFontFamily && oldState.chatMessageFontSize === newState.chatMessageFontSize && oldState.chatMessageLineHeight === newState.chatMessageLineHeight && oldState.chatSendAreaPaddingTop === newState.chatSendAreaPaddingTop && oldState.chatSendAreaPaddingLeft === newState.chatSendAreaPaddingLeft && oldState.chatSendAreaPaddingRight === newState.chatSendAreaPaddingRight && oldState.chatSendAreaPaddingBottom === newState.chatSendAreaPaddingBottom && oldState.composerHeight === newState.composerHeight && oldState.composerLineHeight === newState.composerLineHeight && oldState.composerFontFamily === newState.composerFontFamily && oldState.composerFontSize === newState.composerFontSize && oldState.listItemHeight === newState.listItemHeight && oldState.textAreaPaddingTop === newState.textAreaPaddingTop && oldState.textAreaPaddingLeft === newState.textAreaPaddingLeft && oldState.textAreaPaddingRight === newState.textAreaPaddingRight && oldState.textAreaPaddingBottom === newState.textAreaPaddingBottom && oldRenderHtmlCss === newRenderHtmlCss;
|
|
2517
2528
|
};
|
|
2518
2529
|
|
|
2519
2530
|
const diffFocus = (oldState, newState) => {
|
|
@@ -2535,7 +2546,7 @@ const isEqualProjectExpandedIds = (a, b) => {
|
|
|
2535
2546
|
return true;
|
|
2536
2547
|
};
|
|
2537
2548
|
const isEqual = (oldState, newState) => {
|
|
2538
|
-
return 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 && 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.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;
|
|
2549
|
+
return 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 && 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;
|
|
2539
2550
|
};
|
|
2540
2551
|
|
|
2541
2552
|
const diffScrollTop = (oldState, newState) => {
|
|
@@ -3126,12 +3137,14 @@ const selectProject = async (state, projectId) => {
|
|
|
3126
3137
|
};
|
|
3127
3138
|
};
|
|
3128
3139
|
|
|
3140
|
+
const fileSchemeRegex = /^file:\/\//;
|
|
3141
|
+
const trailingSlashesRegex$4 = /\/+$/;
|
|
3129
3142
|
const getProjectName = (uri, fallbackIndex) => {
|
|
3130
3143
|
if (!uri) {
|
|
3131
3144
|
return `Project ${fallbackIndex}`;
|
|
3132
3145
|
}
|
|
3133
|
-
const withoutScheme = uri.replace(
|
|
3134
|
-
const normalized = withoutScheme.replace(
|
|
3146
|
+
const withoutScheme = uri.replace(fileSchemeRegex, '');
|
|
3147
|
+
const normalized = withoutScheme.replace(trailingSlashesRegex$4, '');
|
|
3135
3148
|
const lastSegment = normalized.split('/').pop();
|
|
3136
3149
|
if (!lastSegment) {
|
|
3137
3150
|
return `Project ${fallbackIndex}`;
|
|
@@ -3194,6 +3207,7 @@ const update = async settings => {
|
|
|
3194
3207
|
await invoke$1('Preferences.update', settings);
|
|
3195
3208
|
};
|
|
3196
3209
|
|
|
3210
|
+
const trailingSlashesRegex$3 = /\/+$/;
|
|
3197
3211
|
const isLoginResponse = value => {
|
|
3198
3212
|
if (!value || typeof value !== 'object') {
|
|
3199
3213
|
return false;
|
|
@@ -3201,7 +3215,7 @@ const isLoginResponse = value => {
|
|
|
3201
3215
|
return true;
|
|
3202
3216
|
};
|
|
3203
3217
|
const trimTrailingSlashes = value => {
|
|
3204
|
-
return value.replace(
|
|
3218
|
+
return value.replace(trailingSlashesRegex$3, '');
|
|
3205
3219
|
};
|
|
3206
3220
|
const handleClickLogin = async state => {
|
|
3207
3221
|
if (!state.backendUrl) {
|
|
@@ -4001,6 +4015,8 @@ const getTextContent = content => {
|
|
|
4001
4015
|
|
|
4002
4016
|
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
|
|
4003
4017
|
|
|
4018
|
+
const errorPrefixRegex = /^Error:\s*/;
|
|
4019
|
+
const notFoundErrorRegex = /not[\s_-]?found|enoent/i;
|
|
4004
4020
|
const getOpenAiTools = tools => {
|
|
4005
4021
|
return tools.map(tool => {
|
|
4006
4022
|
if (!tool || typeof tool !== 'object') {
|
|
@@ -4066,7 +4082,7 @@ const getStreamChunkText = content => {
|
|
|
4066
4082
|
}).join('');
|
|
4067
4083
|
};
|
|
4068
4084
|
const getShortToolErrorMessage = error => {
|
|
4069
|
-
const trimmed = error.trim().replace(
|
|
4085
|
+
const trimmed = error.trim().replace(errorPrefixRegex, '');
|
|
4070
4086
|
const firstLine = trimmed.split('\n')[0];
|
|
4071
4087
|
if (firstLine.length <= 80) {
|
|
4072
4088
|
return firstLine;
|
|
@@ -4098,7 +4114,7 @@ const getToolCallExecutionStatus = content => {
|
|
|
4098
4114
|
const rawStack = Reflect.get(parsed, 'errorStack') ?? Reflect.get(parsed, 'stack');
|
|
4099
4115
|
const errorStack = typeof rawStack === 'string' && rawStack.trim() ? rawStack : undefined;
|
|
4100
4116
|
const errorMessage = getShortToolErrorMessage(rawError);
|
|
4101
|
-
if (
|
|
4117
|
+
if (notFoundErrorRegex.test(errorMessage)) {
|
|
4102
4118
|
return {
|
|
4103
4119
|
...(errorStack ? {
|
|
4104
4120
|
errorStack
|
|
@@ -5086,13 +5102,15 @@ const getOpenApiModelId = selectedModelId => {
|
|
|
5086
5102
|
return selectedModelId;
|
|
5087
5103
|
};
|
|
5088
5104
|
|
|
5105
|
+
const trailingSlashesRegex$2 = /\/+$/;
|
|
5089
5106
|
const getOpenRouterApiEndpoint = openRouterApiBaseUrl => {
|
|
5090
|
-
const trimmedBaseUrl = openRouterApiBaseUrl.replace(
|
|
5107
|
+
const trimmedBaseUrl = openRouterApiBaseUrl.replace(trailingSlashesRegex$2, '');
|
|
5091
5108
|
return `${trimmedBaseUrl}/chat/completions`;
|
|
5092
5109
|
};
|
|
5093
5110
|
|
|
5111
|
+
const trailingSlashesRegex$1 = /\/+$/;
|
|
5094
5112
|
const getOpenRouterKeyEndpoint = openRouterApiBaseUrl => {
|
|
5095
|
-
const trimmedBaseUrl = openRouterApiBaseUrl.replace(
|
|
5113
|
+
const trimmedBaseUrl = openRouterApiBaseUrl.replace(trailingSlashesRegex$1, '');
|
|
5096
5114
|
return `${trimmedBaseUrl}/auth/key`;
|
|
5097
5115
|
};
|
|
5098
5116
|
|
|
@@ -5478,8 +5496,9 @@ const getAll = () => {
|
|
|
5478
5496
|
|
|
5479
5497
|
/* eslint-disable prefer-destructuring */
|
|
5480
5498
|
|
|
5499
|
+
const trailingSlashesRegex = /\/+$/;
|
|
5481
5500
|
const getBackendCompletionsEndpoint = backendUrl => {
|
|
5482
|
-
const trimmedBackendUrl = backendUrl.replace(
|
|
5501
|
+
const trimmedBackendUrl = backendUrl.replace(trailingSlashesRegex, '');
|
|
5483
5502
|
return `${trimmedBackendUrl}/v1/chat/completions`;
|
|
5484
5503
|
};
|
|
5485
5504
|
const getEffectiveBackendModelId = selectedModelId => {
|
|
@@ -6254,21 +6273,25 @@ const parseInlineNodes = value => {
|
|
|
6254
6273
|
};
|
|
6255
6274
|
|
|
6256
6275
|
const markdownMathBlockDelimiter = '$$';
|
|
6276
|
+
const escapedNewlineRegex = /\\r\\n|\\n/g;
|
|
6277
|
+
const lineBreakRegex = /\r?\n/;
|
|
6278
|
+
const tableDelimiterRegex = /\|\s*[-:]{3,}/;
|
|
6279
|
+
const inlineTableCellRegex = /\|\s+\|/g;
|
|
6257
6280
|
const normalizeEscapedNewlines = value => {
|
|
6258
6281
|
if (value.includes('\\n')) {
|
|
6259
|
-
return value.replaceAll(
|
|
6282
|
+
return value.replaceAll(escapedNewlineRegex, '\n');
|
|
6260
6283
|
}
|
|
6261
6284
|
return value;
|
|
6262
6285
|
};
|
|
6263
6286
|
const normalizeInlineTables = value => {
|
|
6264
|
-
return value.split(
|
|
6287
|
+
return value.split(lineBreakRegex).map(line => {
|
|
6265
6288
|
if (!line.includes('|')) {
|
|
6266
6289
|
return line;
|
|
6267
6290
|
}
|
|
6268
|
-
if (
|
|
6291
|
+
if (!tableDelimiterRegex.test(line)) {
|
|
6269
6292
|
return line;
|
|
6270
6293
|
}
|
|
6271
|
-
return line.replaceAll(
|
|
6294
|
+
return line.replaceAll(inlineTableCellRegex, '|\n|');
|
|
6272
6295
|
}).join('\n');
|
|
6273
6296
|
};
|
|
6274
6297
|
const parseHeadingLine = line => {
|
|
@@ -6347,6 +6370,33 @@ const parseBlockQuoteLine = line => {
|
|
|
6347
6370
|
}
|
|
6348
6371
|
return content;
|
|
6349
6372
|
};
|
|
6373
|
+
const isThematicBreakLine = line => {
|
|
6374
|
+
const trimmedStart = line.trimStart();
|
|
6375
|
+
const leadingSpaces = line.length - trimmedStart.length;
|
|
6376
|
+
if (leadingSpaces > 3) {
|
|
6377
|
+
return false;
|
|
6378
|
+
}
|
|
6379
|
+
const trimmed = trimmedStart.trimEnd();
|
|
6380
|
+
if (!trimmed) {
|
|
6381
|
+
return false;
|
|
6382
|
+
}
|
|
6383
|
+
const marker = trimmed[0];
|
|
6384
|
+
if (marker !== '-' && marker !== '_' && marker !== '*') {
|
|
6385
|
+
return false;
|
|
6386
|
+
}
|
|
6387
|
+
let markerCount = 0;
|
|
6388
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
6389
|
+
const char = trimmed[i];
|
|
6390
|
+
if (char === marker) {
|
|
6391
|
+
markerCount++;
|
|
6392
|
+
continue;
|
|
6393
|
+
}
|
|
6394
|
+
if (char !== ' ') {
|
|
6395
|
+
return false;
|
|
6396
|
+
}
|
|
6397
|
+
}
|
|
6398
|
+
return markerCount >= 3;
|
|
6399
|
+
};
|
|
6350
6400
|
const isTableRow = line => {
|
|
6351
6401
|
const trimmed = line.trim();
|
|
6352
6402
|
if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) {
|
|
@@ -6360,7 +6410,7 @@ const getTableCells = line => {
|
|
|
6360
6410
|
};
|
|
6361
6411
|
const scanBlockTokens = rawMessage => {
|
|
6362
6412
|
const normalizedMessage = normalizeInlineTables(normalizeEscapedNewlines(rawMessage));
|
|
6363
|
-
const lines = normalizedMessage.split(
|
|
6413
|
+
const lines = normalizedMessage.split(lineBreakRegex);
|
|
6364
6414
|
const tokens = [];
|
|
6365
6415
|
for (let i = 0; i < lines.length; i++) {
|
|
6366
6416
|
const line = lines[i];
|
|
@@ -6426,6 +6476,12 @@ const scanBlockTokens = rawMessage => {
|
|
|
6426
6476
|
});
|
|
6427
6477
|
continue;
|
|
6428
6478
|
}
|
|
6479
|
+
if (isThematicBreakLine(line)) {
|
|
6480
|
+
tokens.push({
|
|
6481
|
+
type: 'thematic-break'
|
|
6482
|
+
});
|
|
6483
|
+
continue;
|
|
6484
|
+
}
|
|
6429
6485
|
const ordered = parseOrderedListItemLine(line);
|
|
6430
6486
|
if (ordered) {
|
|
6431
6487
|
tokens.push({
|
|
@@ -6571,6 +6627,14 @@ const parseBlockTokens = tokens => {
|
|
|
6571
6627
|
});
|
|
6572
6628
|
continue;
|
|
6573
6629
|
}
|
|
6630
|
+
if (token.type === 'thematic-break') {
|
|
6631
|
+
flushList();
|
|
6632
|
+
flushParagraph();
|
|
6633
|
+
nodes.push({
|
|
6634
|
+
type: 'thematic-break'
|
|
6635
|
+
});
|
|
6636
|
+
continue;
|
|
6637
|
+
}
|
|
6574
6638
|
if (token.type === 'blockquote-line') {
|
|
6575
6639
|
flushList();
|
|
6576
6640
|
flushParagraph();
|
|
@@ -6944,12 +7008,16 @@ const executeSlashCommand = async (state, command) => {
|
|
|
6944
7008
|
});
|
|
6945
7009
|
};
|
|
6946
7010
|
|
|
7011
|
+
const defaultSessionTitleRegex = /^Chat \d+$/;
|
|
6947
7012
|
const isDefaultSessionTitle = title => {
|
|
6948
|
-
return
|
|
7013
|
+
return defaultSessionTitleRegex.test(title);
|
|
6949
7014
|
};
|
|
6950
7015
|
|
|
7016
|
+
const titlePrefixRegex = /^title:\s*/i;
|
|
7017
|
+
const wrappedQuotesAndWhitespaceRegex = /^['"`\s]+|['"`\s]+$/g;
|
|
7018
|
+
const consecutiveWhitespaceRegex = /\s+/g;
|
|
6951
7019
|
const sanitizeGeneratedTitle = value => {
|
|
6952
|
-
return value.replace(
|
|
7020
|
+
return value.replace(titlePrefixRegex, '').replaceAll(wrappedQuotesAndWhitespaceRegex, '').replaceAll(consecutiveWhitespaceRegex, ' ').trim().slice(0, 80);
|
|
6953
7021
|
};
|
|
6954
7022
|
|
|
6955
7023
|
const getAiSessionTitle = async (state, userText, assistantText) => {
|
|
@@ -7020,6 +7088,8 @@ Assistant: ${assistantText}`;
|
|
|
7020
7088
|
return title && !isDefaultSessionTitle(title) ? title : '';
|
|
7021
7089
|
};
|
|
7022
7090
|
|
|
7091
|
+
const windowsAbsolutePathRegex = /^[a-zA-Z]:[\\/]/;
|
|
7092
|
+
const pathSeparatorRegex$1 = /[\\/]/;
|
|
7023
7093
|
const isPathTraversalAttempt = path => {
|
|
7024
7094
|
if (!path) {
|
|
7025
7095
|
return false;
|
|
@@ -7030,15 +7100,16 @@ const isPathTraversalAttempt = path => {
|
|
|
7030
7100
|
if (path.startsWith('file://')) {
|
|
7031
7101
|
return true;
|
|
7032
7102
|
}
|
|
7033
|
-
if (
|
|
7103
|
+
if (windowsAbsolutePathRegex.test(path)) {
|
|
7034
7104
|
return true;
|
|
7035
7105
|
}
|
|
7036
|
-
const segments = path.split(
|
|
7106
|
+
const segments = path.split(pathSeparatorRegex$1);
|
|
7037
7107
|
return segments.includes('..');
|
|
7038
7108
|
};
|
|
7039
7109
|
|
|
7110
|
+
const pathSeparatorRegex = /[\\/]/;
|
|
7040
7111
|
const normalizeRelativePath = path => {
|
|
7041
|
-
const segments = path.split(
|
|
7112
|
+
const segments = path.split(pathSeparatorRegex).filter(segment => segment && segment !== '.');
|
|
7042
7113
|
if (segments.length === 0) {
|
|
7043
7114
|
return '.';
|
|
7044
7115
|
}
|
|
@@ -7046,13 +7117,14 @@ const normalizeRelativePath = path => {
|
|
|
7046
7117
|
};
|
|
7047
7118
|
|
|
7048
7119
|
const mentionRegex = /(^|\s)@([^\s]+)/g;
|
|
7120
|
+
const trailingPunctuationRegex = /[),.;:!?]+$/g;
|
|
7049
7121
|
const maxMentionCount = 5;
|
|
7050
7122
|
const parseMentionedPaths = value => {
|
|
7051
7123
|
const matches = value.matchAll(mentionRegex);
|
|
7052
7124
|
const paths = [];
|
|
7053
7125
|
for (const match of matches) {
|
|
7054
7126
|
const rawPath = match[2] || '';
|
|
7055
|
-
const cleanedPath = rawPath.replaceAll(
|
|
7127
|
+
const cleanedPath = rawPath.replaceAll(trailingPunctuationRegex, '');
|
|
7056
7128
|
if (!cleanedPath || isPathTraversalAttempt(cleanedPath)) {
|
|
7057
7129
|
continue;
|
|
7058
7130
|
}
|
|
@@ -7115,12 +7187,38 @@ const getSseEventType = value => {
|
|
|
7115
7187
|
return value && typeof value === 'object' && Reflect.get(value, 'type') === 'response.completed' ? 'sse-response-completed' : 'sse-response-part';
|
|
7116
7188
|
};
|
|
7117
7189
|
|
|
7190
|
+
const getMessageById = (messages, messageId) => {
|
|
7191
|
+
return messages.find(message => message.id === messageId);
|
|
7192
|
+
};
|
|
7193
|
+
|
|
7194
|
+
const getNextHandleTextChunkState = (latestState, parsedMessages, sessions) => {
|
|
7195
|
+
return {
|
|
7196
|
+
...latestState,
|
|
7197
|
+
...(latestState.messagesAutoScrollEnabled ? {
|
|
7198
|
+
messagesScrollTop: getNextAutoScrollTop(latestState.messagesScrollTop)
|
|
7199
|
+
} : {}),
|
|
7200
|
+
parsedMessages,
|
|
7201
|
+
sessions
|
|
7202
|
+
};
|
|
7203
|
+
};
|
|
7204
|
+
|
|
7205
|
+
const getSelectedSession = (sessions, selectedSessionId) => {
|
|
7206
|
+
return sessions.find(session => session.id === selectedSessionId);
|
|
7207
|
+
};
|
|
7208
|
+
|
|
7209
|
+
const setAndRerenderHandleTextChunkState = async (uid, previousState, nextState) => {
|
|
7210
|
+
set$1(uid, previousState, nextState);
|
|
7211
|
+
// @ts-ignore
|
|
7212
|
+
await invoke$1('Chat.rerender');
|
|
7213
|
+
};
|
|
7214
|
+
|
|
7118
7215
|
const getToolCallMergeKey = toolCall => {
|
|
7119
7216
|
if (toolCall.id) {
|
|
7120
7217
|
return `id:${toolCall.id}`;
|
|
7121
7218
|
}
|
|
7122
7219
|
return `value:${toolCall.name}:${toolCall.arguments}`;
|
|
7123
7220
|
};
|
|
7221
|
+
|
|
7124
7222
|
const mergeToolCalls = (existing = [], incoming) => {
|
|
7125
7223
|
if (incoming.length === 0) {
|
|
7126
7224
|
return existing;
|
|
@@ -7142,8 +7240,9 @@ const mergeToolCalls = (existing = [], incoming) => {
|
|
|
7142
7240
|
}
|
|
7143
7241
|
return merged;
|
|
7144
7242
|
};
|
|
7145
|
-
|
|
7146
|
-
|
|
7243
|
+
|
|
7244
|
+
const updateMessageToolCallsInSelectedSession = (sessions, parsedMessages, selectedSessionId, messageId, toolCalls) => {
|
|
7245
|
+
let nextParsedMessages = parsedMessages;
|
|
7147
7246
|
const updatedSessions = sessions.map(session => {
|
|
7148
7247
|
if (session.id !== selectedSessionId) {
|
|
7149
7248
|
return session;
|
|
@@ -7154,26 +7253,47 @@ const updateMessageTextInSelectedSession = async (sessions, parsedMessages, sele
|
|
|
7154
7253
|
if (message.id !== messageId) {
|
|
7155
7254
|
return message;
|
|
7156
7255
|
}
|
|
7157
|
-
updatedMessage = {
|
|
7256
|
+
const updatedMessage = {
|
|
7158
7257
|
...message,
|
|
7159
|
-
|
|
7160
|
-
text
|
|
7258
|
+
toolCalls: mergeToolCalls(message.toolCalls, toolCalls)
|
|
7161
7259
|
};
|
|
7260
|
+
nextParsedMessages = copyParsedMessageContent(nextParsedMessages, message.id, updatedMessage.id);
|
|
7162
7261
|
return updatedMessage;
|
|
7163
7262
|
})
|
|
7164
7263
|
};
|
|
7165
7264
|
});
|
|
7166
|
-
let nextParsedMessages = parsedMessages;
|
|
7167
|
-
if (updatedMessage) {
|
|
7168
|
-
nextParsedMessages = await parseAndStoreMessageContent(parsedMessages, updatedMessage);
|
|
7169
|
-
}
|
|
7170
7265
|
return {
|
|
7171
7266
|
parsedMessages: nextParsedMessages,
|
|
7172
7267
|
sessions: updatedSessions
|
|
7173
7268
|
};
|
|
7174
7269
|
};
|
|
7175
|
-
|
|
7176
|
-
|
|
7270
|
+
|
|
7271
|
+
const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls, handleTextChunkState) => {
|
|
7272
|
+
const selectedSession = getSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.selectedSessionId);
|
|
7273
|
+
if (!selectedSession) {
|
|
7274
|
+
return {
|
|
7275
|
+
latestState: handleTextChunkState.latestState,
|
|
7276
|
+
previousState: handleTextChunkState.previousState
|
|
7277
|
+
};
|
|
7278
|
+
}
|
|
7279
|
+
const assistantMessage = getMessageById(selectedSession.messages, assistantMessageId);
|
|
7280
|
+
if (!assistantMessage) {
|
|
7281
|
+
return {
|
|
7282
|
+
latestState: handleTextChunkState.latestState,
|
|
7283
|
+
previousState: handleTextChunkState.previousState
|
|
7284
|
+
};
|
|
7285
|
+
}
|
|
7286
|
+
const updated = updateMessageToolCallsInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, toolCalls);
|
|
7287
|
+
const nextState = getNextHandleTextChunkState(handleTextChunkState.latestState, updated.parsedMessages, updated.sessions);
|
|
7288
|
+
await setAndRerenderHandleTextChunkState(uid, handleTextChunkState.previousState, nextState);
|
|
7289
|
+
return {
|
|
7290
|
+
latestState: nextState,
|
|
7291
|
+
previousState: nextState
|
|
7292
|
+
};
|
|
7293
|
+
};
|
|
7294
|
+
|
|
7295
|
+
const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress) => {
|
|
7296
|
+
let updatedMessage;
|
|
7177
7297
|
const updatedSessions = sessions.map(session => {
|
|
7178
7298
|
if (session.id !== selectedSessionId) {
|
|
7179
7299
|
return session;
|
|
@@ -7184,15 +7304,19 @@ const updateMessageToolCallsInSelectedSession = (sessions, parsedMessages, selec
|
|
|
7184
7304
|
if (message.id !== messageId) {
|
|
7185
7305
|
return message;
|
|
7186
7306
|
}
|
|
7187
|
-
|
|
7307
|
+
updatedMessage = {
|
|
7188
7308
|
...message,
|
|
7189
|
-
|
|
7309
|
+
inProgress,
|
|
7310
|
+
text
|
|
7190
7311
|
};
|
|
7191
|
-
nextParsedMessages = copyParsedMessageContent(nextParsedMessages, message.id, updatedMessage.id);
|
|
7192
7312
|
return updatedMessage;
|
|
7193
7313
|
})
|
|
7194
7314
|
};
|
|
7195
7315
|
});
|
|
7316
|
+
let nextParsedMessages = parsedMessages;
|
|
7317
|
+
if (updatedMessage) {
|
|
7318
|
+
nextParsedMessages = await parseAndStoreMessageContent(parsedMessages, updatedMessage);
|
|
7319
|
+
}
|
|
7196
7320
|
return {
|
|
7197
7321
|
parsedMessages: nextParsedMessages,
|
|
7198
7322
|
sessions: updatedSessions
|
|
@@ -7231,38 +7355,6 @@ const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTex
|
|
|
7231
7355
|
previousState: nextState
|
|
7232
7356
|
};
|
|
7233
7357
|
};
|
|
7234
|
-
const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls, handleTextChunkState) => {
|
|
7235
|
-
const selectedSession = handleTextChunkState.latestState.sessions.find(session => session.id === handleTextChunkState.latestState.selectedSessionId);
|
|
7236
|
-
if (!selectedSession) {
|
|
7237
|
-
return {
|
|
7238
|
-
latestState: handleTextChunkState.latestState,
|
|
7239
|
-
previousState: handleTextChunkState.previousState
|
|
7240
|
-
};
|
|
7241
|
-
}
|
|
7242
|
-
const assistantMessage = selectedSession.messages.find(message => message.id === assistantMessageId);
|
|
7243
|
-
if (!assistantMessage) {
|
|
7244
|
-
return {
|
|
7245
|
-
latestState: handleTextChunkState.latestState,
|
|
7246
|
-
previousState: handleTextChunkState.previousState
|
|
7247
|
-
};
|
|
7248
|
-
}
|
|
7249
|
-
const updated = updateMessageToolCallsInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, toolCalls);
|
|
7250
|
-
const nextState = {
|
|
7251
|
-
...handleTextChunkState.latestState,
|
|
7252
|
-
...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
|
|
7253
|
-
messagesScrollTop: getNextAutoScrollTop(handleTextChunkState.latestState.messagesScrollTop)
|
|
7254
|
-
} : {}),
|
|
7255
|
-
parsedMessages: updated.parsedMessages,
|
|
7256
|
-
sessions: updated.sessions
|
|
7257
|
-
};
|
|
7258
|
-
set$1(uid, handleTextChunkState.previousState, nextState);
|
|
7259
|
-
// @ts-ignore
|
|
7260
|
-
await invoke$1('Chat.rerender');
|
|
7261
|
-
return {
|
|
7262
|
-
latestState: nextState,
|
|
7263
|
-
previousState: nextState
|
|
7264
|
-
};
|
|
7265
|
-
};
|
|
7266
7358
|
|
|
7267
7359
|
const hasLegacyStreamingToolCalls = parsed => {
|
|
7268
7360
|
if (!parsed || typeof parsed !== 'object') {
|
|
@@ -7580,6 +7672,7 @@ const Dictate = 'dictate';
|
|
|
7580
7672
|
const Send = 'send';
|
|
7581
7673
|
const Back = 'back';
|
|
7582
7674
|
const Model = 'model';
|
|
7675
|
+
const RunMode = 'runMode';
|
|
7583
7676
|
const ToggleChatFocus = 'toggle-chat-focus';
|
|
7584
7677
|
const CreateProject = 'create-project';
|
|
7585
7678
|
const CreateSession = 'create-session';
|
|
@@ -8097,6 +8190,19 @@ const handleProjectListContextMenu = async state => {
|
|
|
8097
8190
|
return state;
|
|
8098
8191
|
};
|
|
8099
8192
|
|
|
8193
|
+
const isRunMode = value => {
|
|
8194
|
+
return value === 'local' || value === 'background' || value === 'cloud';
|
|
8195
|
+
};
|
|
8196
|
+
const handleRunModeChange = async (state, value) => {
|
|
8197
|
+
if (!isRunMode(value)) {
|
|
8198
|
+
return state;
|
|
8199
|
+
}
|
|
8200
|
+
return {
|
|
8201
|
+
...state,
|
|
8202
|
+
runMode: value
|
|
8203
|
+
};
|
|
8204
|
+
};
|
|
8205
|
+
|
|
8100
8206
|
const handleChatListScroll = async (state, chatListScrollTop) => {
|
|
8101
8207
|
if (state.chatListScrollTop === chatListScrollTop) {
|
|
8102
8208
|
return state;
|
|
@@ -8338,6 +8444,15 @@ const loadStreamingEnabled = async () => {
|
|
|
8338
8444
|
}
|
|
8339
8445
|
};
|
|
8340
8446
|
|
|
8447
|
+
const loadTodoListToolEnabled = async () => {
|
|
8448
|
+
try {
|
|
8449
|
+
const savedTodoListToolEnabled = await get('chatView.todoListToolEnabled');
|
|
8450
|
+
return typeof savedTodoListToolEnabled === 'boolean' ? savedTodoListToolEnabled : false;
|
|
8451
|
+
} catch {
|
|
8452
|
+
return false;
|
|
8453
|
+
}
|
|
8454
|
+
};
|
|
8455
|
+
|
|
8341
8456
|
const loadUseChatCoordinatorWorker = async () => {
|
|
8342
8457
|
try {
|
|
8343
8458
|
const savedUseChatCoordinatorWorker = await get('chatView.useChatCoordinatorWorker');
|
|
@@ -8384,7 +8499,7 @@ const loadVoiceDictationEnabled = async () => {
|
|
|
8384
8499
|
};
|
|
8385
8500
|
|
|
8386
8501
|
const loadPreferences = async () => {
|
|
8387
|
-
const [aiSessionTitleGenerationEnabled, authAccessToken, authEnabled, authRefreshToken, backendUrl, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatNetworkWorkerForRequests, useChatToolWorker, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadBackendAccessToken(), loadAuthEnabled(), loadBackendRefreshToken(), loadBackendUrl(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatNetworkWorkerForRequests(), loadUseChatToolWorker(), loadVoiceDictationEnabled()]);
|
|
8502
|
+
const [aiSessionTitleGenerationEnabled, authAccessToken, authEnabled, authRefreshToken, backendUrl, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, todoListToolEnabled, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatNetworkWorkerForRequests, useChatToolWorker, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadBackendAccessToken(), loadAuthEnabled(), loadBackendRefreshToken(), loadBackendUrl(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadTodoListToolEnabled(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatNetworkWorkerForRequests(), loadUseChatToolWorker(), loadVoiceDictationEnabled()]);
|
|
8388
8503
|
return {
|
|
8389
8504
|
aiSessionTitleGenerationEnabled,
|
|
8390
8505
|
authAccessToken,
|
|
@@ -8397,6 +8512,7 @@ const loadPreferences = async () => {
|
|
|
8397
8512
|
openRouterApiKey,
|
|
8398
8513
|
passIncludeObfuscation,
|
|
8399
8514
|
streamingEnabled,
|
|
8515
|
+
todoListToolEnabled,
|
|
8400
8516
|
useChatCoordinatorWorker,
|
|
8401
8517
|
useChatMathWorker,
|
|
8402
8518
|
useChatNetworkWorkerForRequests,
|
|
@@ -8542,6 +8658,7 @@ const loadContent = async (state, savedState) => {
|
|
|
8542
8658
|
openRouterApiKey,
|
|
8543
8659
|
passIncludeObfuscation,
|
|
8544
8660
|
streamingEnabled,
|
|
8661
|
+
todoListToolEnabled,
|
|
8545
8662
|
useChatCoordinatorWorker,
|
|
8546
8663
|
useChatMathWorker,
|
|
8547
8664
|
useChatNetworkWorkerForRequests,
|
|
@@ -8624,6 +8741,7 @@ const loadContent = async (state, savedState) => {
|
|
|
8624
8741
|
selectedSessionId,
|
|
8625
8742
|
sessions,
|
|
8626
8743
|
streamingEnabled,
|
|
8744
|
+
todoListToolEnabled,
|
|
8627
8745
|
useChatCoordinatorWorker,
|
|
8628
8746
|
useChatMathWorker,
|
|
8629
8747
|
useChatNetworkWorkerForRequests,
|
|
@@ -8740,301 +8858,184 @@ const registerMockResponse = (state, mockResponse) => {
|
|
|
8740
8858
|
return state;
|
|
8741
8859
|
};
|
|
8742
8860
|
|
|
8743
|
-
const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, renderHtmlCss) => {
|
|
8861
|
+
const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss) => {
|
|
8744
8862
|
const baseCss = `:root {
|
|
8745
8863
|
--ChatInputBoxHeight: ${composerHeight}px;
|
|
8864
|
+
--ChatTextAreaHeight: ${composerHeight}px;
|
|
8865
|
+
--ChatSendAreaHeight: ${composerHeight + 62}px;
|
|
8866
|
+
--ChatTextAreaPaddingTop: ${textAreaPaddingTop}px;
|
|
8867
|
+
--ChatTextAreaPaddingLeft: ${textAreaPaddingLeft}px;
|
|
8868
|
+
--ChatTextAreaPaddingRight: ${textAreaPaddingRight}px;
|
|
8869
|
+
--ChatTextAreaPaddingBottom: ${textAreaPaddingBottom}px;
|
|
8870
|
+
--ChatSendAreaPaddingTop: ${chatSendAreaPaddingTop}px;
|
|
8871
|
+
--ChatSendAreaPaddingLeft: ${chatSendAreaPaddingLeft}px;
|
|
8872
|
+
--ChatSendAreaPaddingRight: ${chatSendAreaPaddingRight}px;
|
|
8873
|
+
--ChatSendAreaPaddingBottom: ${chatSendAreaPaddingBottom}px;
|
|
8746
8874
|
--ChatListItemHeight: ${listItemHeight}px;
|
|
8747
8875
|
--ChatMessageFontSize: ${chatMessageFontSize}px;
|
|
8748
8876
|
--ChatMessageLineHeight: ${chatMessageLineHeight}px;
|
|
8749
8877
|
--ChatMessageFontFamily: ${chatMessageFontFamily};
|
|
8750
|
-
}
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
background: linear-gradient(180deg, var(--ColorViewBackground, #1d2229) 0%, #1f252d 100%);
|
|
8754
|
-
display: grid;
|
|
8755
|
-
grid-template-columns: 320px 1fr;
|
|
8756
|
-
grid-template-rows: auto 1fr auto;
|
|
8757
|
-
}
|
|
8878
|
+
}`;
|
|
8879
|
+
if (!renderHtmlCss.trim()) {
|
|
8880
|
+
return `${baseCss}
|
|
8758
8881
|
|
|
8759
|
-
.
|
|
8760
|
-
|
|
8882
|
+
.ChatTodoList {
|
|
8883
|
+
background: var(--vscode-editorWidget-background);
|
|
8884
|
+
border: 1px solid var(--vscode-editorWidget-border);
|
|
8885
|
+
border-radius: 6px;
|
|
8886
|
+
margin-bottom: 8px;
|
|
8887
|
+
overflow: hidden;
|
|
8761
8888
|
}
|
|
8762
8889
|
|
|
8763
|
-
.
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
grid-column: 1;
|
|
8770
|
-
grid-row: 2 / 4;
|
|
8771
|
-
min-height: 0;
|
|
8890
|
+
.ChatTodoListHeader {
|
|
8891
|
+
border-bottom: 1px solid var(--vscode-editorWidget-border);
|
|
8892
|
+
color: var(--vscode-descriptionForeground);
|
|
8893
|
+
font-size: 12px;
|
|
8894
|
+
line-height: 18px;
|
|
8895
|
+
padding: 6px 10px;
|
|
8772
8896
|
}
|
|
8773
8897
|
|
|
8774
|
-
.
|
|
8775
|
-
|
|
8898
|
+
.ChatTodoListItems {
|
|
8899
|
+
list-style: none;
|
|
8900
|
+
margin: 0;
|
|
8901
|
+
max-height: 180px;
|
|
8776
8902
|
overflow: auto;
|
|
8777
|
-
padding:
|
|
8778
|
-
scrollbar-color: color-mix(in srgb, var(--ColorScrollBarSliderBackground, #4b5563) 78%, transparent)
|
|
8779
|
-
color-mix(in srgb, var(--ColorSideBarBackground, #232b35) 92%, transparent);
|
|
8780
|
-
scrollbar-width: thin;
|
|
8903
|
+
padding: 4px 0;
|
|
8781
8904
|
}
|
|
8782
8905
|
|
|
8783
|
-
.
|
|
8784
|
-
height: 10px;
|
|
8785
|
-
width: 10px;
|
|
8786
|
-
}
|
|
8787
|
-
|
|
8788
|
-
.Chat.ChatFocus .ProjectList::-webkit-scrollbar-track {
|
|
8789
|
-
background: color-mix(in srgb, var(--ColorSideBarBackground, #232b35) 94%, transparent);
|
|
8790
|
-
border-radius: 999px;
|
|
8791
|
-
}
|
|
8792
|
-
|
|
8793
|
-
.Chat.ChatFocus .ProjectList::-webkit-scrollbar-thumb {
|
|
8794
|
-
background: color-mix(in srgb, var(--ColorScrollBarSliderBackground, #4b5563) 70%, transparent);
|
|
8795
|
-
border: 2px solid color-mix(in srgb, var(--ColorSideBarBackground, #232b35) 94%, transparent);
|
|
8796
|
-
border-radius: 999px;
|
|
8797
|
-
}
|
|
8798
|
-
|
|
8799
|
-
.Chat.ChatFocus .ProjectList::-webkit-scrollbar-thumb:hover {
|
|
8800
|
-
background: color-mix(in srgb, var(--ColorScrollBarSliderHoverBackground, #667284) 80%, transparent);
|
|
8801
|
-
}
|
|
8802
|
-
|
|
8803
|
-
.ProjectListGroup {
|
|
8804
|
-
border: 1px solid transparent;
|
|
8805
|
-
border-radius: 8px;
|
|
8806
|
-
margin-bottom: 6px;
|
|
8807
|
-
overflow: hidden;
|
|
8808
|
-
}
|
|
8809
|
-
|
|
8810
|
-
.ProjectListItem {
|
|
8811
|
-
align-items: center;
|
|
8812
|
-
display: flex;
|
|
8813
|
-
gap: 6px;
|
|
8814
|
-
min-height: calc(var(--ChatListItemHeight) - 2px);
|
|
8815
|
-
}
|
|
8816
|
-
|
|
8817
|
-
.ProjectListItemLabel {
|
|
8906
|
+
.ChatTodoListItem {
|
|
8818
8907
|
align-items: center;
|
|
8819
|
-
|
|
8820
|
-
color: var(--ColorForeground, #d5dbe3);
|
|
8821
|
-
cursor: pointer;
|
|
8908
|
+
color: var(--vscode-foreground);
|
|
8822
8909
|
display: flex;
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
overflow: hidden;
|
|
8910
|
+
font-size: 12px;
|
|
8911
|
+
line-height: 18px;
|
|
8912
|
+
min-height: 24px;
|
|
8827
8913
|
padding: 0 10px;
|
|
8828
|
-
text-overflow: ellipsis;
|
|
8829
|
-
transition: background-color 80ms ease, color 80ms ease;
|
|
8830
|
-
white-space: nowrap;
|
|
8831
8914
|
}
|
|
8832
8915
|
|
|
8833
|
-
.
|
|
8834
|
-
color:
|
|
8916
|
+
.ChatTodoListItem::before {
|
|
8917
|
+
color: var(--vscode-descriptionForeground);
|
|
8918
|
+
content: "○";
|
|
8835
8919
|
display: inline-block;
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
margin-right: 4px;
|
|
8839
|
-
text-align: center;
|
|
8840
|
-
width: 12px;
|
|
8920
|
+
margin-right: 8px;
|
|
8921
|
+
width: 1em;
|
|
8841
8922
|
}
|
|
8842
8923
|
|
|
8843
|
-
.
|
|
8844
|
-
|
|
8924
|
+
.ChatTodoListItemTodo::before {
|
|
8925
|
+
content: "○";
|
|
8845
8926
|
}
|
|
8846
8927
|
|
|
8847
|
-
.
|
|
8848
|
-
|
|
8849
|
-
background: color-mix(in srgb, var(--ColorListHoverBackground, #38414b) 50%, transparent);
|
|
8928
|
+
.ChatTodoListItem.todo::before {
|
|
8929
|
+
content: "○";
|
|
8850
8930
|
}
|
|
8851
8931
|
|
|
8852
|
-
.
|
|
8853
|
-
color: var(--
|
|
8932
|
+
.ChatTodoListItemInProgress::before {
|
|
8933
|
+
color: var(--vscode-textLink-foreground);
|
|
8934
|
+
content: "◐";
|
|
8854
8935
|
}
|
|
8855
8936
|
|
|
8856
|
-
.
|
|
8857
|
-
|
|
8858
|
-
|
|
8937
|
+
.ChatTodoListItem.inProgress::before {
|
|
8938
|
+
color: var(--vscode-textLink-foreground);
|
|
8939
|
+
content: "◐";
|
|
8859
8940
|
}
|
|
8860
8941
|
|
|
8861
|
-
.
|
|
8862
|
-
|
|
8863
|
-
background: color-mix(in srgb, var(--ColorButtonSecondaryBackground, #3a434f) 76%, transparent);
|
|
8864
|
-
border: 0;
|
|
8865
|
-
border-radius: 5px;
|
|
8866
|
-
color: var(--ColorForeground, #d0d8e2);
|
|
8867
|
-
cursor: pointer;
|
|
8868
|
-
display: inline-flex;
|
|
8869
|
-
font-size: 13px;
|
|
8870
|
-
font-weight: 500;
|
|
8871
|
-
height: 18px;
|
|
8872
|
-
justify-content: center;
|
|
8873
|
-
opacity: 0;
|
|
8874
|
-
padding: 0;
|
|
8875
|
-
transition: opacity 90ms ease, background-color 90ms ease;
|
|
8876
|
-
visibility: hidden;
|
|
8877
|
-
width: 18px;
|
|
8942
|
+
.ChatTodoListItemCompleted {
|
|
8943
|
+
color: var(--vscode-disabledForeground);
|
|
8878
8944
|
}
|
|
8879
8945
|
|
|
8880
|
-
.
|
|
8881
|
-
|
|
8882
|
-
opacity: 1;
|
|
8883
|
-
visibility: visible;
|
|
8946
|
+
.ChatTodoListItem.completed {
|
|
8947
|
+
color: var(--vscode-disabledForeground);
|
|
8884
8948
|
}
|
|
8885
8949
|
|
|
8886
|
-
.
|
|
8887
|
-
|
|
8888
|
-
|
|
8950
|
+
.ChatTodoListItemCompleted::before {
|
|
8951
|
+
color: var(--vscode-testing-iconPassed);
|
|
8952
|
+
content: "✓";
|
|
8889
8953
|
}
|
|
8890
8954
|
|
|
8891
|
-
.
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
}
|
|
8955
|
+
.ChatTodoListItem.completed::before {
|
|
8956
|
+
color: var(--vscode-testing-iconPassed);
|
|
8957
|
+
content: "✓";
|
|
8958
|
+
}`;
|
|
8959
|
+
}
|
|
8960
|
+
return `${baseCss}
|
|
8896
8961
|
|
|
8897
|
-
.
|
|
8962
|
+
.ChatTodoList {
|
|
8963
|
+
background: var(--vscode-editorWidget-background);
|
|
8964
|
+
border: 1px solid var(--vscode-editorWidget-border);
|
|
8898
8965
|
border-radius: 6px;
|
|
8899
|
-
|
|
8900
|
-
cursor: pointer;
|
|
8901
|
-
display: block;
|
|
8902
|
-
flex: 1;
|
|
8903
|
-
font-size: 12.5px;
|
|
8966
|
+
margin-bottom: 8px;
|
|
8904
8967
|
overflow: hidden;
|
|
8905
|
-
padding: 0 10px 0 28px;
|
|
8906
|
-
text-overflow: ellipsis;
|
|
8907
|
-
transition: background-color 80ms ease, color 80ms ease;
|
|
8908
|
-
white-space: nowrap;
|
|
8909
|
-
}
|
|
8910
|
-
|
|
8911
|
-
.ProjectSessionItemSelected {
|
|
8912
|
-
background: color-mix(in srgb, var(--ColorListInactiveSelectionBackground, #353f4a) 86%, #2c3540 14%);
|
|
8913
|
-
}
|
|
8914
|
-
|
|
8915
|
-
.ProjectSessionItem:not(.ProjectSessionItemSelected):hover,
|
|
8916
|
-
.ProjectSessionItem:not(.ProjectSessionItemSelected):focus-within {
|
|
8917
|
-
background: color-mix(in srgb, var(--ColorListHoverBackground, #38414c) 46%, transparent);
|
|
8918
|
-
}
|
|
8919
|
-
|
|
8920
|
-
.ProjectSessionItemSelected .ProjectSessionItemLabel {
|
|
8921
|
-
color: var(--ColorListInactiveSelectionForeground, #f2f6fc);
|
|
8922
|
-
}
|
|
8923
|
-
|
|
8924
|
-
.Chat.ChatFocus .ProjectAddButton {
|
|
8925
|
-
background: color-mix(in srgb, var(--ColorButtonSecondaryBackground, #21252c) 72%, transparent);
|
|
8926
|
-
border: 0;
|
|
8927
|
-
border-top: 1px solid color-mix(in srgb, var(--ColorBorder, #3a3d41) 70%, transparent);
|
|
8928
|
-
color: var(--ColorForeground, #d2d9e2);
|
|
8929
|
-
cursor: pointer;
|
|
8930
|
-
font-size: 12.5px;
|
|
8931
|
-
letter-spacing: 0.01em;
|
|
8932
|
-
margin-top: auto;
|
|
8933
|
-
min-height: var(--ChatListItemHeight);
|
|
8934
|
-
padding: 0 12px;
|
|
8935
|
-
text-align: left;
|
|
8936
|
-
transition: background-color 80ms ease;
|
|
8937
8968
|
}
|
|
8938
8969
|
|
|
8939
|
-
.
|
|
8940
|
-
|
|
8941
|
-
|
|
8970
|
+
.ChatTodoListHeader {
|
|
8971
|
+
border-bottom: 1px solid var(--vscode-editorWidget-border);
|
|
8972
|
+
color: var(--vscode-descriptionForeground);
|
|
8973
|
+
font-size: 12px;
|
|
8974
|
+
line-height: 18px;
|
|
8975
|
+
padding: 6px 10px;
|
|
8942
8976
|
}
|
|
8943
8977
|
|
|
8944
|
-
.
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
.Chat.ChatFocus .ChatList,
|
|
8951
|
-
.Chat.ChatFocus .ChatListEmpty {
|
|
8952
|
-
display: none;
|
|
8953
|
-
}
|
|
8954
|
-
|
|
8955
|
-
.Chat.ChatFocus .ChatMessages {
|
|
8956
|
-
grid-column: 2;
|
|
8957
|
-
grid-row: 2;
|
|
8978
|
+
.ChatTodoListItems {
|
|
8979
|
+
list-style: none;
|
|
8980
|
+
margin: 0;
|
|
8981
|
+
max-height: 180px;
|
|
8982
|
+
overflow: auto;
|
|
8983
|
+
padding: 4px 0;
|
|
8958
8984
|
}
|
|
8959
8985
|
|
|
8960
|
-
.
|
|
8961
|
-
|
|
8962
|
-
|
|
8986
|
+
.ChatTodoListItem {
|
|
8987
|
+
align-items: center;
|
|
8988
|
+
color: var(--vscode-foreground);
|
|
8989
|
+
display: flex;
|
|
8990
|
+
font-size: 12px;
|
|
8991
|
+
line-height: 18px;
|
|
8992
|
+
min-height: 24px;
|
|
8993
|
+
padding: 0 10px;
|
|
8963
8994
|
}
|
|
8964
8995
|
|
|
8965
|
-
.
|
|
8996
|
+
.ChatTodoListItem::before {
|
|
8997
|
+
color: var(--vscode-descriptionForeground);
|
|
8998
|
+
content: "○";
|
|
8966
8999
|
display: inline-block;
|
|
8967
|
-
|
|
8968
|
-
|
|
9000
|
+
margin-right: 8px;
|
|
9001
|
+
width: 1em;
|
|
8969
9002
|
}
|
|
8970
9003
|
|
|
8971
|
-
.
|
|
8972
|
-
|
|
8973
|
-
margin: 8px 0;
|
|
8974
|
-
padding-left: 12px;
|
|
9004
|
+
.ChatTodoListItemTodo::before {
|
|
9005
|
+
content: "○";
|
|
8975
9006
|
}
|
|
8976
9007
|
|
|
8977
|
-
.
|
|
8978
|
-
|
|
8979
|
-
overflow-x: auto;
|
|
8980
|
-
overflow-y: hidden;
|
|
9008
|
+
.ChatTodoListItem.todo::before {
|
|
9009
|
+
content: "○";
|
|
8981
9010
|
}
|
|
8982
9011
|
|
|
8983
|
-
.
|
|
8984
|
-
|
|
9012
|
+
.ChatTodoListItemInProgress::before {
|
|
9013
|
+
color: var(--vscode-textLink-foreground);
|
|
9014
|
+
content: "◐";
|
|
8985
9015
|
}
|
|
8986
9016
|
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
9017
|
+
.ChatTodoListItem.inProgress::before {
|
|
9018
|
+
color: var(--vscode-textLink-foreground);
|
|
9019
|
+
content: "◐";
|
|
8990
9020
|
}
|
|
8991
9021
|
|
|
8992
|
-
.
|
|
8993
|
-
color: var(--
|
|
9022
|
+
.ChatTodoListItemCompleted {
|
|
9023
|
+
color: var(--vscode-disabledForeground);
|
|
8994
9024
|
}
|
|
8995
9025
|
|
|
8996
|
-
.
|
|
8997
|
-
|
|
8998
|
-
color: var(--ColorChartsBlue, #8caaee);
|
|
9026
|
+
.ChatTodoListItem.completed {
|
|
9027
|
+
color: var(--vscode-disabledForeground);
|
|
8999
9028
|
}
|
|
9000
9029
|
|
|
9001
|
-
.
|
|
9002
|
-
|
|
9003
|
-
|
|
9030
|
+
.ChatTodoListItemCompleted::before {
|
|
9031
|
+
color: var(--vscode-testing-iconPassed);
|
|
9032
|
+
content: "✓";
|
|
9004
9033
|
}
|
|
9005
9034
|
|
|
9006
|
-
.
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
}
|
|
9010
|
-
|
|
9011
|
-
.ChatToolCallQuestionText {
|
|
9012
|
-
margin-bottom: 6px;
|
|
9013
|
-
}
|
|
9014
|
-
|
|
9015
|
-
.ChatToolCallQuestionOptions {
|
|
9016
|
-
display: flex;
|
|
9017
|
-
flex-wrap: wrap;
|
|
9018
|
-
gap: 6px;
|
|
9019
|
-
}
|
|
9020
|
-
|
|
9021
|
-
.ChatToolCallQuestionOption {
|
|
9022
|
-
background: color-mix(in srgb, var(--ColorBadgeBackground, #2f3640) 70%, transparent);
|
|
9023
|
-
border: 1px solid color-mix(in srgb, var(--ColorBorder, #3a3d41) 70%, transparent);
|
|
9024
|
-
border-radius: 999px;
|
|
9025
|
-
color: var(--ColorForeground, #d5dbe3);
|
|
9026
|
-
display: inline-block;
|
|
9027
|
-
max-width: 100%;
|
|
9028
|
-
overflow: hidden;
|
|
9029
|
-
padding: 2px 8px;
|
|
9030
|
-
text-overflow: ellipsis;
|
|
9031
|
-
white-space: nowrap;
|
|
9035
|
+
.ChatTodoListItem.completed::before {
|
|
9036
|
+
color: var(--vscode-testing-iconPassed);
|
|
9037
|
+
content: "✓";
|
|
9032
9038
|
}
|
|
9033
|
-
`;
|
|
9034
|
-
if (!renderHtmlCss.trim()) {
|
|
9035
|
-
return baseCss;
|
|
9036
|
-
}
|
|
9037
|
-
return `${baseCss}
|
|
9038
9039
|
|
|
9039
9040
|
/* render_html tool css */
|
|
9040
9041
|
${renderHtmlCss}`;
|
|
@@ -9048,14 +9049,22 @@ const renderCss = (oldState, newState) => {
|
|
|
9048
9049
|
chatMessageFontFamily,
|
|
9049
9050
|
chatMessageFontSize,
|
|
9050
9051
|
chatMessageLineHeight,
|
|
9052
|
+
chatSendAreaPaddingBottom,
|
|
9053
|
+
chatSendAreaPaddingLeft,
|
|
9054
|
+
chatSendAreaPaddingRight,
|
|
9055
|
+
chatSendAreaPaddingTop,
|
|
9051
9056
|
composerHeight,
|
|
9052
9057
|
listItemHeight,
|
|
9053
9058
|
selectedSessionId,
|
|
9054
9059
|
sessions,
|
|
9060
|
+
textAreaPaddingBottom,
|
|
9061
|
+
textAreaPaddingLeft,
|
|
9062
|
+
textAreaPaddingRight,
|
|
9063
|
+
textAreaPaddingTop,
|
|
9055
9064
|
uid
|
|
9056
9065
|
} = newState;
|
|
9057
9066
|
const renderHtmlCss = getRenderHtmlCss(sessions, selectedSessionId);
|
|
9058
|
-
const css = getCss(composerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, renderHtmlCss);
|
|
9067
|
+
const css = getCss(composerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss);
|
|
9059
9068
|
return [SetCss, uid, css];
|
|
9060
9069
|
};
|
|
9061
9070
|
|
|
@@ -9093,6 +9102,13 @@ const ChatViewDropOverlayActive = 'ChatViewDropOverlayActive';
|
|
|
9093
9102
|
const SendButtonDisabled = 'SendButtonDisabled';
|
|
9094
9103
|
const ChatSendAreaBottom = 'ChatSendAreaBottom';
|
|
9095
9104
|
const ChatSendAreaContent = 'ChatSendAreaContent';
|
|
9105
|
+
const ChatTodoList = 'ChatTodoList';
|
|
9106
|
+
const ChatTodoListHeader = 'ChatTodoListHeader';
|
|
9107
|
+
const ChatTodoListItems = 'ChatTodoListItems';
|
|
9108
|
+
const ChatTodoListItem = 'ChatTodoListItem';
|
|
9109
|
+
const ChatTodoListItemTodo = 'ChatTodoListItemTodo';
|
|
9110
|
+
const ChatTodoListItemInProgress = 'ChatTodoListItemInProgress';
|
|
9111
|
+
const ChatTodoListItemCompleted = 'ChatTodoListItemCompleted';
|
|
9096
9112
|
const Chat = 'Chat';
|
|
9097
9113
|
const ChatHeader = 'ChatHeader';
|
|
9098
9114
|
const Button = 'Button';
|
|
@@ -9134,6 +9150,7 @@ const ChatMessageContent = 'ChatMessageContent';
|
|
|
9134
9150
|
const ChatToolCalls = 'ChatToolCalls';
|
|
9135
9151
|
const ChatToolCallsLabel = 'ChatToolCallsLabel';
|
|
9136
9152
|
const ChatToolCallReadFileLink = 'ChatToolCallReadFileLink';
|
|
9153
|
+
const ChatToolCallFileName = 'ChatToolCallFileName';
|
|
9137
9154
|
const ChatToolCallQuestionOption = 'ChatToolCallQuestionOption';
|
|
9138
9155
|
const ChatToolCallQuestionOptions = 'ChatToolCallQuestionOptions';
|
|
9139
9156
|
const ChatToolCallQuestionText = 'ChatToolCallQuestionText';
|
|
@@ -9193,6 +9210,7 @@ const HandleProjectListScroll = 32;
|
|
|
9193
9210
|
const HandleProjectListContextMenu = 33;
|
|
9194
9211
|
const HandleClickDictationButton = 34;
|
|
9195
9212
|
const HandleMissingApiKeySubmit = 35;
|
|
9213
|
+
const HandleRunModeChange = 36;
|
|
9196
9214
|
|
|
9197
9215
|
const getModelLabel = model => {
|
|
9198
9216
|
if (model.provider === 'openRouter') {
|
|
@@ -9226,6 +9244,28 @@ const getChatSelectVirtualDom = (models, selectedModelId) => {
|
|
|
9226
9244
|
}, ...modelOptions];
|
|
9227
9245
|
};
|
|
9228
9246
|
|
|
9247
|
+
const getRunModeOptionDom = (runMode, selectedRunMode) => {
|
|
9248
|
+
return [{
|
|
9249
|
+
childCount: 1,
|
|
9250
|
+
selected: runMode === selectedRunMode,
|
|
9251
|
+
type: Option$1,
|
|
9252
|
+
value: runMode
|
|
9253
|
+
}, text(runMode)];
|
|
9254
|
+
};
|
|
9255
|
+
|
|
9256
|
+
const runModes = ['local', 'background', 'cloud'];
|
|
9257
|
+
const getRunModeSelectVirtualDom = selectedRunMode => {
|
|
9258
|
+
const runModeOptions = runModes.flatMap(runMode => getRunModeOptionDom(runMode, selectedRunMode));
|
|
9259
|
+
return [{
|
|
9260
|
+
childCount: runModes.length,
|
|
9261
|
+
className: Select,
|
|
9262
|
+
name: RunMode,
|
|
9263
|
+
onInput: HandleRunModeChange,
|
|
9264
|
+
type: Select$1,
|
|
9265
|
+
value: selectedRunMode
|
|
9266
|
+
}, ...runModeOptions];
|
|
9267
|
+
};
|
|
9268
|
+
|
|
9229
9269
|
const getSendButtonClassName = isSendDisabled => {
|
|
9230
9270
|
return isSendDisabled ? `${IconButton} ${SendButtonDisabled}` : `${IconButton}`;
|
|
9231
9271
|
};
|
|
@@ -9293,19 +9333,48 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
|
|
|
9293
9333
|
}, text(usageLabel)];
|
|
9294
9334
|
};
|
|
9295
9335
|
|
|
9296
|
-
const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled = false) => {
|
|
9336
|
+
const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled = false) => {
|
|
9297
9337
|
const isSendDisabled = composerValue.trim() === '';
|
|
9298
|
-
const controlsCount = usageOverviewEnabled ?
|
|
9338
|
+
const controlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (showRunMode ? 1 : 0);
|
|
9339
|
+
const hasTodoList = todoListToolEnabled && todoListItems.length > 0;
|
|
9340
|
+
const todoHeaderText = `Todos (${todoListItems.filter(item => item.status === 'completed').length}/${todoListItems.length})`;
|
|
9341
|
+
const getTodoItemClassName = status => {
|
|
9342
|
+
if (status === 'completed') {
|
|
9343
|
+
return `${ChatTodoListItem} ${ChatTodoListItemCompleted} completed`;
|
|
9344
|
+
}
|
|
9345
|
+
if (status === 'inProgress') {
|
|
9346
|
+
return `${ChatTodoListItem} ${ChatTodoListItemInProgress} inProgress`;
|
|
9347
|
+
}
|
|
9348
|
+
return `${ChatTodoListItem} ${ChatTodoListItemTodo} todo`;
|
|
9349
|
+
};
|
|
9299
9350
|
return [{
|
|
9300
9351
|
childCount: 1,
|
|
9301
9352
|
className: ChatSendArea,
|
|
9302
9353
|
onSubmit: HandleSubmit,
|
|
9303
9354
|
type: Form
|
|
9304
9355
|
}, {
|
|
9305
|
-
childCount: 2,
|
|
9356
|
+
childCount: hasTodoList ? 3 : 2,
|
|
9306
9357
|
className: ChatSendAreaContent,
|
|
9307
9358
|
type: Div
|
|
9359
|
+
}, ...(hasTodoList ? [{
|
|
9360
|
+
childCount: 2,
|
|
9361
|
+
className: ChatTodoList,
|
|
9362
|
+
type: Div
|
|
9363
|
+
}, {
|
|
9364
|
+
childCount: 1,
|
|
9365
|
+
className: ChatTodoListHeader,
|
|
9366
|
+
type: Div
|
|
9367
|
+
}, {
|
|
9368
|
+
...text(todoHeaderText)
|
|
9308
9369
|
}, {
|
|
9370
|
+
childCount: todoListItems.length,
|
|
9371
|
+
className: ChatTodoListItems,
|
|
9372
|
+
type: Ul
|
|
9373
|
+
}, ...todoListItems.flatMap(item => [{
|
|
9374
|
+
childCount: 1,
|
|
9375
|
+
className: getTodoItemClassName(item.status),
|
|
9376
|
+
type: Li
|
|
9377
|
+
}, text(item.text)])] : []), {
|
|
9309
9378
|
childCount: 0,
|
|
9310
9379
|
className: MultilineInputBox,
|
|
9311
9380
|
name: Composer,
|
|
@@ -9318,7 +9387,7 @@ const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOvervie
|
|
|
9318
9387
|
childCount: voiceDictationEnabled ? controlsCount + 1 : controlsCount,
|
|
9319
9388
|
className: ChatSendAreaBottom,
|
|
9320
9389
|
type: Div
|
|
9321
|
-
}, ...getChatSelectVirtualDom(models, selectedModelId), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
9390
|
+
}, ...getChatSelectVirtualDom(models, selectedModelId), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
9322
9391
|
};
|
|
9323
9392
|
|
|
9324
9393
|
const getImageAltText = alt => {
|
|
@@ -9683,6 +9752,12 @@ const getMessageNodeDom = (node, useChatMathWorker = false) => {
|
|
|
9683
9752
|
if (node.type === 'math-block-dom') {
|
|
9684
9753
|
return node.dom;
|
|
9685
9754
|
}
|
|
9755
|
+
if (node.type === 'thematic-break') {
|
|
9756
|
+
return [{
|
|
9757
|
+
childCount: 0,
|
|
9758
|
+
type: Hr
|
|
9759
|
+
}];
|
|
9760
|
+
}
|
|
9686
9761
|
if (node.type === 'heading') {
|
|
9687
9762
|
return getHeadingDom(node, useChatMathWorker);
|
|
9688
9763
|
}
|
|
@@ -9817,22 +9892,88 @@ const getOpenRouterTooManyRequestsDom = () => {
|
|
|
9817
9892
|
})];
|
|
9818
9893
|
};
|
|
9819
9894
|
|
|
9820
|
-
const
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9895
|
+
const getToolCallStatusLabel = toolCall => {
|
|
9896
|
+
if (toolCall.status === 'not-found') {
|
|
9897
|
+
return ' (not-found)';
|
|
9898
|
+
}
|
|
9899
|
+
if (toolCall.status === 'error') {
|
|
9900
|
+
if (toolCall.errorMessage) {
|
|
9901
|
+
return ` (error: ${toolCall.errorMessage})`;
|
|
9902
|
+
}
|
|
9903
|
+
return ' (error)';
|
|
9904
|
+
}
|
|
9905
|
+
return '';
|
|
9827
9906
|
};
|
|
9828
9907
|
|
|
9829
|
-
const
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9908
|
+
const parseAskQuestionArguments = rawArguments => {
|
|
9909
|
+
let parsed;
|
|
9910
|
+
try {
|
|
9911
|
+
parsed = JSON.parse(rawArguments);
|
|
9912
|
+
} catch {
|
|
9913
|
+
return {
|
|
9914
|
+
answers: [],
|
|
9915
|
+
question: ''
|
|
9916
|
+
};
|
|
9833
9917
|
}
|
|
9834
|
-
|
|
9835
|
-
|
|
9918
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
9919
|
+
return {
|
|
9920
|
+
answers: [],
|
|
9921
|
+
question: ''
|
|
9922
|
+
};
|
|
9923
|
+
}
|
|
9924
|
+
const question = Reflect.get(parsed, 'question');
|
|
9925
|
+
const rawAnswers = Reflect.get(parsed, 'answers');
|
|
9926
|
+
const rawChoices = Reflect.get(parsed, 'choices');
|
|
9927
|
+
const rawOptions = Reflect.get(parsed, 'options');
|
|
9928
|
+
const arrayValue = Array.isArray(rawAnswers) ? rawAnswers : Array.isArray(rawChoices) ? rawChoices : Array.isArray(rawOptions) ? rawOptions : [];
|
|
9929
|
+
const answers = arrayValue.filter(value => typeof value === 'string');
|
|
9930
|
+
return {
|
|
9931
|
+
answers,
|
|
9932
|
+
question: typeof question === 'string' ? question : ''
|
|
9933
|
+
};
|
|
9934
|
+
};
|
|
9935
|
+
|
|
9936
|
+
const getToolCallAskQuestionVirtualDom = toolCall => {
|
|
9937
|
+
const parsed = parseAskQuestionArguments(toolCall.arguments);
|
|
9938
|
+
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
9939
|
+
const questionLabel = parsed.question.trim() ? parsed.question : '(empty question)';
|
|
9940
|
+
const answers = parsed.answers.length > 0 ? parsed.answers : ['(no answers)'];
|
|
9941
|
+
const childCount = 2;
|
|
9942
|
+
return [{
|
|
9943
|
+
childCount,
|
|
9944
|
+
className: ChatOrderedListItem,
|
|
9945
|
+
type: Li
|
|
9946
|
+
}, {
|
|
9947
|
+
childCount: 1,
|
|
9948
|
+
className: ChatToolCallQuestionText,
|
|
9949
|
+
type: Div
|
|
9950
|
+
}, text(`ask_question: ${questionLabel}${statusLabel}`), {
|
|
9951
|
+
childCount: answers.length,
|
|
9952
|
+
className: ChatToolCallQuestionOptions,
|
|
9953
|
+
type: Div
|
|
9954
|
+
}, ...answers.flatMap(answer => [{
|
|
9955
|
+
childCount: 1,
|
|
9956
|
+
className: ChatToolCallQuestionOption,
|
|
9957
|
+
type: Span
|
|
9958
|
+
}, text(answer.trim() ? answer : '(empty answer)')])];
|
|
9959
|
+
};
|
|
9960
|
+
|
|
9961
|
+
const RE_QUERY_OR_HASH = /[?#].*$/;
|
|
9962
|
+
const RE_TRAILING_SLASH = /\/$/;
|
|
9963
|
+
const getFileNameFromUri = uri => {
|
|
9964
|
+
const stripped = uri.replace(RE_QUERY_OR_HASH, '').replace(RE_TRAILING_SLASH, '');
|
|
9965
|
+
const slashIndex = Math.max(stripped.lastIndexOf('/'), stripped.lastIndexOf('\\\\'));
|
|
9966
|
+
const fileName = slashIndex === -1 ? stripped : stripped.slice(slashIndex + 1);
|
|
9967
|
+
return fileName || uri;
|
|
9968
|
+
};
|
|
9969
|
+
|
|
9970
|
+
const isCompleteJson = value => {
|
|
9971
|
+
const trimmed = value.trim();
|
|
9972
|
+
if (!trimmed) {
|
|
9973
|
+
return false;
|
|
9974
|
+
}
|
|
9975
|
+
let depth = 0;
|
|
9976
|
+
let inString = false;
|
|
9836
9977
|
let escaped = false;
|
|
9837
9978
|
for (const char of trimmed) {
|
|
9838
9979
|
if (inString) {
|
|
@@ -9896,6 +10037,66 @@ const getReadFileTarget = rawArguments => {
|
|
|
9896
10037
|
};
|
|
9897
10038
|
};
|
|
9898
10039
|
|
|
10040
|
+
const getToolCallEditFileVirtualDom = toolCall => {
|
|
10041
|
+
const target = getReadFileTarget(toolCall.arguments);
|
|
10042
|
+
if (!target) {
|
|
10043
|
+
return [];
|
|
10044
|
+
}
|
|
10045
|
+
const fileName = getFileNameFromUri(target.title);
|
|
10046
|
+
const fileNameClickableProps = target.clickableUri ? {
|
|
10047
|
+
'data-uri': target.clickableUri,
|
|
10048
|
+
onClick: HandleClickReadFile
|
|
10049
|
+
} : {};
|
|
10050
|
+
return [{
|
|
10051
|
+
childCount: 3,
|
|
10052
|
+
className: ChatOrderedListItem,
|
|
10053
|
+
title: target.title,
|
|
10054
|
+
type: Li
|
|
10055
|
+
}, {
|
|
10056
|
+
childCount: 0,
|
|
10057
|
+
className: FileIcon,
|
|
10058
|
+
type: Div
|
|
10059
|
+
}, text('edit_file '), {
|
|
10060
|
+
childCount: 1,
|
|
10061
|
+
className: ChatToolCallReadFileLink,
|
|
10062
|
+
title: target.clickableUri,
|
|
10063
|
+
...fileNameClickableProps,
|
|
10064
|
+
type: Span
|
|
10065
|
+
}, {
|
|
10066
|
+
childCount: 1,
|
|
10067
|
+
className: ChatToolCallFileName,
|
|
10068
|
+
type: Span
|
|
10069
|
+
}, text(fileName)];
|
|
10070
|
+
};
|
|
10071
|
+
|
|
10072
|
+
const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
10073
|
+
if (!toolCall.result) {
|
|
10074
|
+
return [];
|
|
10075
|
+
}
|
|
10076
|
+
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
10077
|
+
const fileName = getFileNameFromUri(toolCall.result);
|
|
10078
|
+
return [{
|
|
10079
|
+
childCount: statusLabel ? 4 : 3,
|
|
10080
|
+
className: ChatOrderedListItem,
|
|
10081
|
+
title: toolCall.result,
|
|
10082
|
+
type: Li
|
|
10083
|
+
}, {
|
|
10084
|
+
childCount: 0,
|
|
10085
|
+
className: FileIcon,
|
|
10086
|
+
type: Div
|
|
10087
|
+
}, text('get_workspace_uri '), {
|
|
10088
|
+
childCount: 1,
|
|
10089
|
+
className: ChatToolCallReadFileLink,
|
|
10090
|
+
'data-uri': toolCall.result,
|
|
10091
|
+
onClick: HandleClickReadFile,
|
|
10092
|
+
type: Span
|
|
10093
|
+
}, {
|
|
10094
|
+
childCount: 1,
|
|
10095
|
+
className: ChatToolCallFileName,
|
|
10096
|
+
type: Span
|
|
10097
|
+
}, text(fileName), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
10098
|
+
};
|
|
10099
|
+
|
|
9899
10100
|
const getToolCallArgumentPreview = rawArguments => {
|
|
9900
10101
|
if (!rawArguments.trim()) {
|
|
9901
10102
|
return '""';
|
|
@@ -9923,69 +10124,33 @@ const getToolCallArgumentPreview = rawArguments => {
|
|
|
9923
10124
|
return rawArguments;
|
|
9924
10125
|
};
|
|
9925
10126
|
|
|
9926
|
-
const
|
|
9927
|
-
if (
|
|
9928
|
-
return '
|
|
9929
|
-
}
|
|
9930
|
-
if (toolCall.status === 'error') {
|
|
9931
|
-
if (toolCall.errorMessage) {
|
|
9932
|
-
return ` (error: ${toolCall.errorMessage})`;
|
|
9933
|
-
}
|
|
9934
|
-
return ' (error)';
|
|
10127
|
+
const getToolCallDisplayName = name => {
|
|
10128
|
+
if (name === 'getWorkspaceUri') {
|
|
10129
|
+
return 'get_workspace_uri';
|
|
9935
10130
|
}
|
|
9936
|
-
return
|
|
10131
|
+
return name;
|
|
9937
10132
|
};
|
|
9938
10133
|
|
|
9939
|
-
const
|
|
9940
|
-
let parsed;
|
|
10134
|
+
const hasIncompleteJsonArguments = rawArguments => {
|
|
9941
10135
|
try {
|
|
9942
|
-
|
|
10136
|
+
JSON.parse(rawArguments);
|
|
10137
|
+
return false;
|
|
9943
10138
|
} catch {
|
|
9944
|
-
return
|
|
9945
|
-
answers: [],
|
|
9946
|
-
question: ''
|
|
9947
|
-
};
|
|
9948
|
-
}
|
|
9949
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
9950
|
-
return {
|
|
9951
|
-
answers: [],
|
|
9952
|
-
question: ''
|
|
9953
|
-
};
|
|
10139
|
+
return true;
|
|
9954
10140
|
}
|
|
9955
|
-
const question = Reflect.get(parsed, 'question');
|
|
9956
|
-
const rawAnswers = Reflect.get(parsed, 'answers');
|
|
9957
|
-
const rawChoices = Reflect.get(parsed, 'choices');
|
|
9958
|
-
const rawOptions = Reflect.get(parsed, 'options');
|
|
9959
|
-
const arrayValue = Array.isArray(rawAnswers) ? rawAnswers : Array.isArray(rawChoices) ? rawChoices : Array.isArray(rawOptions) ? rawOptions : [];
|
|
9960
|
-
const answers = arrayValue.filter(value => typeof value === 'string');
|
|
9961
|
-
return {
|
|
9962
|
-
answers,
|
|
9963
|
-
question: typeof question === 'string' ? question : ''
|
|
9964
|
-
};
|
|
9965
10141
|
};
|
|
9966
|
-
|
|
9967
|
-
|
|
10142
|
+
|
|
10143
|
+
const getToolCallLabel = toolCall => {
|
|
10144
|
+
const displayName = getToolCallDisplayName(toolCall.name);
|
|
10145
|
+
if (toolCall.name === 'write_file' && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
10146
|
+
return `${displayName} (in progress)`;
|
|
10147
|
+
}
|
|
10148
|
+
const argumentPreview = getToolCallArgumentPreview(toolCall.arguments);
|
|
9968
10149
|
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
return
|
|
9973
|
-
childCount,
|
|
9974
|
-
className: ChatOrderedListItem,
|
|
9975
|
-
type: Li
|
|
9976
|
-
}, {
|
|
9977
|
-
childCount: 1,
|
|
9978
|
-
className: ChatToolCallQuestionText,
|
|
9979
|
-
type: Div
|
|
9980
|
-
}, text(`ask_question: ${questionLabel}${statusLabel}`), {
|
|
9981
|
-
childCount: answers.length,
|
|
9982
|
-
className: ChatToolCallQuestionOptions,
|
|
9983
|
-
type: Div
|
|
9984
|
-
}, ...answers.flatMap(answer => [{
|
|
9985
|
-
childCount: 1,
|
|
9986
|
-
className: ChatToolCallQuestionOption,
|
|
9987
|
-
type: Span
|
|
9988
|
-
}, text(answer.trim() ? answer : '(empty answer)')])];
|
|
10150
|
+
if (argumentPreview === '{}') {
|
|
10151
|
+
return `${displayName}${statusLabel}`;
|
|
10152
|
+
}
|
|
10153
|
+
return `${displayName} ${argumentPreview}${statusLabel}`;
|
|
9989
10154
|
};
|
|
9990
10155
|
|
|
9991
10156
|
const getToolCallReadFileVirtualDom = toolCall => {
|
|
@@ -10014,22 +10179,34 @@ const getToolCallReadFileVirtualDom = toolCall => {
|
|
|
10014
10179
|
className: ChatToolCallReadFileLink,
|
|
10015
10180
|
...fileNameClickableProps,
|
|
10016
10181
|
type: Span
|
|
10182
|
+
}, {
|
|
10183
|
+
childCount: 1,
|
|
10184
|
+
className: ChatToolCallFileName,
|
|
10185
|
+
type: Span
|
|
10017
10186
|
}, text(fileName), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
10018
10187
|
};
|
|
10019
10188
|
|
|
10020
10189
|
const maxHtmlLength = 40_000;
|
|
10021
10190
|
const tokenRegex = /<!--[\s\S]*?-->|<\/?[a-zA-Z][\w:-]*(?:\s[^<>]*?)?>|[^<]+/g;
|
|
10022
10191
|
const attributeRegex = /([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
10192
|
+
const scriptTagRegex = /<script\b[\s\S]*?<\/script>/gi;
|
|
10193
|
+
const styleTagRegex = /<style\b[\s\S]*?<\/style>/gi;
|
|
10194
|
+
const headTagRegex = /<head\b[\s\S]*?<\/head>/gi;
|
|
10195
|
+
const metaTagRegex = /<meta\b[^>]*>/gi;
|
|
10196
|
+
const linkTagRegex = /<link\b[^>]*>/gi;
|
|
10197
|
+
const tagPrefixRegex = /^<\/?\s*[a-zA-Z][\w:-]*/;
|
|
10198
|
+
const tagSuffixRegex = /\/?\s*>$/;
|
|
10199
|
+
const openTagNameRegex = /^<\s*([a-zA-Z][\w:-]*)/;
|
|
10023
10200
|
const inlineTags = new Set(['a', 'abbr', 'b', 'code', 'em', 'i', 'label', 'small', 'span', 'strong', 'sub', 'sup', 'u']);
|
|
10024
10201
|
const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
|
|
10025
10202
|
const sanitizeHtml = value => {
|
|
10026
|
-
return value.slice(0, maxHtmlLength).replaceAll(
|
|
10203
|
+
return value.slice(0, maxHtmlLength).replaceAll(scriptTagRegex, '').replaceAll(styleTagRegex, '').replaceAll(headTagRegex, '').replaceAll(metaTagRegex, '').replaceAll(linkTagRegex, '');
|
|
10027
10204
|
};
|
|
10028
10205
|
const decodeEntities = value => {
|
|
10029
10206
|
return value.replaceAll(' ', ' ').replaceAll('"', '"').replaceAll(''', "'").replaceAll('<', '<').replaceAll('>', '>').replaceAll('&', '&');
|
|
10030
10207
|
};
|
|
10031
10208
|
const parseAttributes = token => {
|
|
10032
|
-
const withoutTag = token.replace(
|
|
10209
|
+
const withoutTag = token.replace(tagPrefixRegex, '').replace(tagSuffixRegex, '').trim();
|
|
10033
10210
|
if (!withoutTag) {
|
|
10034
10211
|
return Object.create(null);
|
|
10035
10212
|
}
|
|
@@ -10076,7 +10253,7 @@ const parseHtml = value => {
|
|
|
10076
10253
|
continue;
|
|
10077
10254
|
}
|
|
10078
10255
|
if (token.startsWith('<')) {
|
|
10079
|
-
const openTagNameMatch =
|
|
10256
|
+
const openTagNameMatch = openTagNameRegex.exec(token);
|
|
10080
10257
|
if (!openTagNameMatch) {
|
|
10081
10258
|
continue;
|
|
10082
10259
|
}
|
|
@@ -10320,55 +10497,6 @@ const getToolCallRenderHtmlVirtualDom = toolCall => {
|
|
|
10320
10497
|
}, ...parsedHtml.virtualDom];
|
|
10321
10498
|
};
|
|
10322
10499
|
|
|
10323
|
-
const getToolCallDisplayName = name => {
|
|
10324
|
-
if (name === 'getWorkspaceUri') {
|
|
10325
|
-
return 'get_workspace_uri';
|
|
10326
|
-
}
|
|
10327
|
-
return name;
|
|
10328
|
-
};
|
|
10329
|
-
const hasIncompleteJsonArguments = rawArguments => {
|
|
10330
|
-
try {
|
|
10331
|
-
JSON.parse(rawArguments);
|
|
10332
|
-
return false;
|
|
10333
|
-
} catch {
|
|
10334
|
-
return true;
|
|
10335
|
-
}
|
|
10336
|
-
};
|
|
10337
|
-
const getToolCallLabel = toolCall => {
|
|
10338
|
-
const displayName = getToolCallDisplayName(toolCall.name);
|
|
10339
|
-
if (toolCall.name === 'write_file' && !toolCall.status && hasIncompleteJsonArguments(toolCall.arguments)) {
|
|
10340
|
-
return `${displayName} (in progress)`;
|
|
10341
|
-
}
|
|
10342
|
-
const argumentPreview = getToolCallArgumentPreview(toolCall.arguments);
|
|
10343
|
-
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
10344
|
-
if (argumentPreview === '{}') {
|
|
10345
|
-
return `${displayName}${statusLabel}`;
|
|
10346
|
-
}
|
|
10347
|
-
return `${displayName} ${argumentPreview}${statusLabel}`;
|
|
10348
|
-
};
|
|
10349
|
-
const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
|
|
10350
|
-
if (!toolCall.result) {
|
|
10351
|
-
return [];
|
|
10352
|
-
}
|
|
10353
|
-
const statusLabel = getToolCallStatusLabel(toolCall);
|
|
10354
|
-
const fileName = getFileNameFromUri(toolCall.result);
|
|
10355
|
-
return [{
|
|
10356
|
-
childCount: statusLabel ? 4 : 3,
|
|
10357
|
-
className: ChatOrderedListItem,
|
|
10358
|
-
title: toolCall.result,
|
|
10359
|
-
type: Li
|
|
10360
|
-
}, {
|
|
10361
|
-
childCount: 0,
|
|
10362
|
-
className: FileIcon,
|
|
10363
|
-
type: Div
|
|
10364
|
-
}, text('get_workspace_uri '), {
|
|
10365
|
-
childCount: 1,
|
|
10366
|
-
className: ChatToolCallReadFileLink,
|
|
10367
|
-
'data-uri': toolCall.result,
|
|
10368
|
-
onClick: HandleClickReadFile,
|
|
10369
|
-
type: Span
|
|
10370
|
-
}, text(fileName), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
10371
|
-
};
|
|
10372
10500
|
const parseWriteFileLineCounts = rawResult => {
|
|
10373
10501
|
if (!rawResult) {
|
|
10374
10502
|
return {
|
|
@@ -10398,6 +10526,7 @@ const parseWriteFileLineCounts = rawResult => {
|
|
|
10398
10526
|
linesDeleted: typeof linesDeleted === 'number' ? Math.max(0, linesDeleted) : 0
|
|
10399
10527
|
};
|
|
10400
10528
|
};
|
|
10529
|
+
|
|
10401
10530
|
const getToolCallWriteFileVirtualDom = toolCall => {
|
|
10402
10531
|
const target = getReadFileTarget(toolCall.arguments);
|
|
10403
10532
|
if (!target) {
|
|
@@ -10427,6 +10556,10 @@ const getToolCallWriteFileVirtualDom = toolCall => {
|
|
|
10427
10556
|
className: ChatToolCallReadFileLink,
|
|
10428
10557
|
...fileNameClickableProps,
|
|
10429
10558
|
type: Span
|
|
10559
|
+
}, {
|
|
10560
|
+
childCount: 1,
|
|
10561
|
+
className: ChatToolCallFileName,
|
|
10562
|
+
type: Span
|
|
10430
10563
|
}, text(fileName), {
|
|
10431
10564
|
childCount: 1,
|
|
10432
10565
|
className: Insertion,
|
|
@@ -10437,33 +10570,7 @@ const getToolCallWriteFileVirtualDom = toolCall => {
|
|
|
10437
10570
|
type: Span
|
|
10438
10571
|
}, text(` -${linesDeleted}`), ...(statusLabel ? [text(statusLabel)] : [])];
|
|
10439
10572
|
};
|
|
10440
|
-
|
|
10441
|
-
const target = getReadFileTarget(toolCall.arguments);
|
|
10442
|
-
if (!target) {
|
|
10443
|
-
return [];
|
|
10444
|
-
}
|
|
10445
|
-
const fileName = getFileNameFromUri(target.title);
|
|
10446
|
-
const fileNameClickableProps = target.clickableUri ? {
|
|
10447
|
-
'data-uri': target.clickableUri,
|
|
10448
|
-
onClick: HandleClickReadFile
|
|
10449
|
-
} : {};
|
|
10450
|
-
return [{
|
|
10451
|
-
childCount: 3,
|
|
10452
|
-
className: ChatOrderedListItem,
|
|
10453
|
-
title: target.title,
|
|
10454
|
-
type: Li
|
|
10455
|
-
}, {
|
|
10456
|
-
childCount: 0,
|
|
10457
|
-
className: FileIcon,
|
|
10458
|
-
type: Div
|
|
10459
|
-
}, text('edit_file '), {
|
|
10460
|
-
childCount: 1,
|
|
10461
|
-
className: ChatToolCallReadFileLink,
|
|
10462
|
-
title: target.clickableUri,
|
|
10463
|
-
...fileNameClickableProps,
|
|
10464
|
-
type: Span
|
|
10465
|
-
}, text(fileName)];
|
|
10466
|
-
};
|
|
10573
|
+
|
|
10467
10574
|
const getToolCallDom = toolCall => {
|
|
10468
10575
|
if (toolCall.name === 'getWorkspaceUri') {
|
|
10469
10576
|
const virtualDom = getToolCallGetWorkspaceUriVirtualDom(toolCall);
|
|
@@ -10598,9 +10705,9 @@ const getDisplayMessages = (messages, parsedMessages) => {
|
|
|
10598
10705
|
}
|
|
10599
10706
|
return displayMessages;
|
|
10600
10707
|
};
|
|
10601
|
-
const getMessagesDom = (messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput = '', openRouterApiKeyState = 'idle', messagesScrollTop = 0, useChatMathWorker = false) => {
|
|
10708
|
+
const getMessagesDom = (messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput = '', openRouterApiKeyState = 'idle', messagesScrollTop = 0, useChatMathWorker = false, hideWelcomeMessage = false) => {
|
|
10602
10709
|
if (messages.length === 0) {
|
|
10603
|
-
return getEmptyMessagesDom();
|
|
10710
|
+
return hideWelcomeMessage ? [] : getEmptyMessagesDom();
|
|
10604
10711
|
}
|
|
10605
10712
|
const displayMessages = getDisplayMessages(messages, parsedMessages);
|
|
10606
10713
|
return [{
|
|
@@ -10698,7 +10805,40 @@ const getProjectListDom = (projects, sessions, projectExpandedIds, selectedProje
|
|
|
10698
10805
|
}, text('+ Add Project')];
|
|
10699
10806
|
};
|
|
10700
10807
|
|
|
10701
|
-
const getChatModeChatFocusVirtualDom = (
|
|
10808
|
+
const getChatModeChatFocusVirtualDom = ({
|
|
10809
|
+
authEnabled = false,
|
|
10810
|
+
authErrorMessage = '',
|
|
10811
|
+
authStatus = 'signed-out',
|
|
10812
|
+
composerDropActive = false,
|
|
10813
|
+
composerDropEnabled = true,
|
|
10814
|
+
composerFontFamily = 'system-ui',
|
|
10815
|
+
composerFontSize = 13,
|
|
10816
|
+
composerHeight = 28,
|
|
10817
|
+
composerLineHeight = 20,
|
|
10818
|
+
composerValue,
|
|
10819
|
+
messagesScrollTop = 0,
|
|
10820
|
+
models,
|
|
10821
|
+
openApiApiKeyInput,
|
|
10822
|
+
openRouterApiKeyInput,
|
|
10823
|
+
openRouterApiKeyState = 'idle',
|
|
10824
|
+
parsedMessages = [],
|
|
10825
|
+
projectExpandedIds = [],
|
|
10826
|
+
projectListScrollTop = 0,
|
|
10827
|
+
projects = [],
|
|
10828
|
+
runMode,
|
|
10829
|
+
selectedModelId,
|
|
10830
|
+
selectedProjectId = '',
|
|
10831
|
+
selectedSessionId,
|
|
10832
|
+
sessions,
|
|
10833
|
+
showRunMode,
|
|
10834
|
+
todoListItems,
|
|
10835
|
+
todoListToolEnabled,
|
|
10836
|
+
tokensMax,
|
|
10837
|
+
tokensUsed,
|
|
10838
|
+
usageOverviewEnabled,
|
|
10839
|
+
useChatMathWorker = false,
|
|
10840
|
+
voiceDictationEnabled = false
|
|
10841
|
+
}) => {
|
|
10702
10842
|
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
10703
10843
|
const messages = selectedSession ? selectedSession.messages : [];
|
|
10704
10844
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
@@ -10708,7 +10848,7 @@ const getChatModeChatFocusVirtualDom = (sessions, selectedSessionId, composerVal
|
|
|
10708
10848
|
onDragEnter: HandleDragEnterChatView,
|
|
10709
10849
|
onDragOver: HandleDragOverChatView,
|
|
10710
10850
|
type: Div
|
|
10711
|
-
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
10851
|
+
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
10712
10852
|
childCount: 1,
|
|
10713
10853
|
className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
|
|
10714
10854
|
name: ComposerDropTarget,
|
|
@@ -10824,7 +10964,36 @@ const getChatHeaderDomDetailMode = (selectedSessionTitle, authEnabled = false, a
|
|
|
10824
10964
|
}, text(authErrorMessage)] : [])];
|
|
10825
10965
|
};
|
|
10826
10966
|
|
|
10827
|
-
const getChatModeDetailVirtualDom = (
|
|
10967
|
+
const getChatModeDetailVirtualDom = ({
|
|
10968
|
+
authEnabled = false,
|
|
10969
|
+
authErrorMessage = '',
|
|
10970
|
+
authStatus = 'signed-out',
|
|
10971
|
+
composerDropActive = false,
|
|
10972
|
+
composerDropEnabled = true,
|
|
10973
|
+
composerFontFamily = 'system-ui',
|
|
10974
|
+
composerFontSize = 13,
|
|
10975
|
+
composerHeight = 28,
|
|
10976
|
+
composerLineHeight = 20,
|
|
10977
|
+
composerValue,
|
|
10978
|
+
messagesScrollTop = 0,
|
|
10979
|
+
models,
|
|
10980
|
+
openApiApiKeyInput,
|
|
10981
|
+
openRouterApiKeyInput,
|
|
10982
|
+
openRouterApiKeyState = 'idle',
|
|
10983
|
+
parsedMessages = [],
|
|
10984
|
+
runMode,
|
|
10985
|
+
selectedModelId,
|
|
10986
|
+
selectedSessionId,
|
|
10987
|
+
sessions,
|
|
10988
|
+
showRunMode,
|
|
10989
|
+
todoListItems,
|
|
10990
|
+
todoListToolEnabled,
|
|
10991
|
+
tokensMax,
|
|
10992
|
+
tokensUsed,
|
|
10993
|
+
usageOverviewEnabled,
|
|
10994
|
+
useChatMathWorker = false,
|
|
10995
|
+
voiceDictationEnabled = false
|
|
10996
|
+
}) => {
|
|
10828
10997
|
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
10829
10998
|
const selectedSessionTitle = selectedSession?.title || chatTitle();
|
|
10830
10999
|
const messages = selectedSession ? selectedSession.messages : [];
|
|
@@ -10835,7 +11004,7 @@ const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue,
|
|
|
10835
11004
|
onDragEnter: HandleDragEnterChatView,
|
|
10836
11005
|
onDragOver: HandleDragOverChatView,
|
|
10837
11006
|
type: Div
|
|
10838
|
-
}, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, authStatus, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
11007
|
+
}, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, authStatus, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
10839
11008
|
childCount: 1,
|
|
10840
11009
|
className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
|
|
10841
11010
|
name: ComposerDropTarget,
|
|
@@ -10883,7 +11052,7 @@ const getSessionDom = session => {
|
|
|
10883
11052
|
return [{
|
|
10884
11053
|
childCount: 2,
|
|
10885
11054
|
className: sessionClassName,
|
|
10886
|
-
type:
|
|
11055
|
+
type: Li
|
|
10887
11056
|
}, {
|
|
10888
11057
|
childCount: 1,
|
|
10889
11058
|
className: ChatListItemLabel,
|
|
@@ -10917,11 +11086,35 @@ const getChatListDom = (sessions, selectedSessionId, chatListScrollTop = 0) => {
|
|
|
10917
11086
|
onClick: HandleClickList,
|
|
10918
11087
|
onScroll: HandleChatListScroll,
|
|
10919
11088
|
scrollTop: chatListScrollTop,
|
|
10920
|
-
type:
|
|
11089
|
+
type: Ul
|
|
10921
11090
|
}, ...sessions.flatMap(getSessionDom)];
|
|
10922
11091
|
};
|
|
10923
11092
|
|
|
10924
|
-
const getChatModeListVirtualDom = (
|
|
11093
|
+
const getChatModeListVirtualDom = ({
|
|
11094
|
+
authEnabled = false,
|
|
11095
|
+
authErrorMessage = '',
|
|
11096
|
+
authStatus = 'signed-out',
|
|
11097
|
+
chatListScrollTop = 0,
|
|
11098
|
+
composerDropActive = false,
|
|
11099
|
+
composerDropEnabled = true,
|
|
11100
|
+
composerFontFamily = 'system-ui',
|
|
11101
|
+
composerFontSize = 13,
|
|
11102
|
+
composerHeight = 28,
|
|
11103
|
+
composerLineHeight = 20,
|
|
11104
|
+
composerValue,
|
|
11105
|
+
models,
|
|
11106
|
+
runMode,
|
|
11107
|
+
selectedModelId,
|
|
11108
|
+
selectedSessionId,
|
|
11109
|
+
sessions,
|
|
11110
|
+
showRunMode,
|
|
11111
|
+
todoListItems,
|
|
11112
|
+
todoListToolEnabled,
|
|
11113
|
+
tokensMax,
|
|
11114
|
+
tokensUsed,
|
|
11115
|
+
usageOverviewEnabled,
|
|
11116
|
+
voiceDictationEnabled = false
|
|
11117
|
+
}) => {
|
|
10925
11118
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
10926
11119
|
return [{
|
|
10927
11120
|
childCount: isDropOverlayVisible ? 4 : 3,
|
|
@@ -10929,7 +11122,7 @@ const getChatModeListVirtualDom = (sessions, selectedSessionId, composerValue, m
|
|
|
10929
11122
|
onDragEnter: HandleDragEnterChatView,
|
|
10930
11123
|
onDragOver: HandleDragOverChatView,
|
|
10931
11124
|
type: Div
|
|
10932
|
-
}, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage), ...getChatListDom(sessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
11125
|
+
}, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage), ...getChatListDom(sessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
10933
11126
|
childCount: 1,
|
|
10934
11127
|
className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
|
|
10935
11128
|
name: ComposerDropTarget,
|
|
@@ -10950,6 +11143,62 @@ const getChatModeUnsupportedVirtualDom = () => {
|
|
|
10950
11143
|
}, text(unknownViewMode())];
|
|
10951
11144
|
};
|
|
10952
11145
|
|
|
11146
|
+
const isTodoStatus = status => {
|
|
11147
|
+
return status === 'todo' || status === 'inProgress' || status === 'completed';
|
|
11148
|
+
};
|
|
11149
|
+
const parseTodoListArguments = rawArguments => {
|
|
11150
|
+
let parsed;
|
|
11151
|
+
try {
|
|
11152
|
+
parsed = JSON.parse(rawArguments);
|
|
11153
|
+
} catch {
|
|
11154
|
+
return [];
|
|
11155
|
+
}
|
|
11156
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
11157
|
+
return [];
|
|
11158
|
+
}
|
|
11159
|
+
const rawTodos = Reflect.get(parsed, 'todos');
|
|
11160
|
+
if (!Array.isArray(rawTodos)) {
|
|
11161
|
+
return [];
|
|
11162
|
+
}
|
|
11163
|
+
const todos = [];
|
|
11164
|
+
for (const rawTodo of rawTodos) {
|
|
11165
|
+
if (!rawTodo || typeof rawTodo !== 'object') {
|
|
11166
|
+
continue;
|
|
11167
|
+
}
|
|
11168
|
+
const text = Reflect.get(rawTodo, 'text');
|
|
11169
|
+
const status = Reflect.get(rawTodo, 'status');
|
|
11170
|
+
if (typeof text !== 'string' || !isTodoStatus(status)) {
|
|
11171
|
+
continue;
|
|
11172
|
+
}
|
|
11173
|
+
todos.push({
|
|
11174
|
+
status,
|
|
11175
|
+
text
|
|
11176
|
+
});
|
|
11177
|
+
}
|
|
11178
|
+
return todos;
|
|
11179
|
+
};
|
|
11180
|
+
|
|
11181
|
+
const getTodoListItems = (sessions, selectedSessionId) => {
|
|
11182
|
+
const selectedSession = sessions.find(session => session.id === selectedSessionId);
|
|
11183
|
+
if (!selectedSession) {
|
|
11184
|
+
return [];
|
|
11185
|
+
}
|
|
11186
|
+
let todoItems = [];
|
|
11187
|
+
for (const message of selectedSession.messages) {
|
|
11188
|
+
if (message.role !== 'assistant' || !message.toolCalls) {
|
|
11189
|
+
continue;
|
|
11190
|
+
}
|
|
11191
|
+
for (const toolCall of message.toolCalls) {
|
|
11192
|
+
if (toolCall.name !== 'todo_list') {
|
|
11193
|
+
continue;
|
|
11194
|
+
}
|
|
11195
|
+
const parsedTodos = parseTodoListArguments(toolCall.arguments);
|
|
11196
|
+
todoItems = parsedTodos;
|
|
11197
|
+
}
|
|
11198
|
+
}
|
|
11199
|
+
return todoItems;
|
|
11200
|
+
};
|
|
11201
|
+
|
|
10953
11202
|
const getFallbackParsedMessages = sessions => {
|
|
10954
11203
|
const parsedMessages = [];
|
|
10955
11204
|
for (const session of sessions) {
|
|
@@ -10966,15 +11215,137 @@ const getFallbackParsedMessages = sessions => {
|
|
|
10966
11215
|
}
|
|
10967
11216
|
return parsedMessages;
|
|
10968
11217
|
};
|
|
10969
|
-
const getChatVirtualDom =
|
|
10970
|
-
const
|
|
11218
|
+
const getChatVirtualDom = options => {
|
|
11219
|
+
const {
|
|
11220
|
+
authEnabled = false,
|
|
11221
|
+
authErrorMessage = '',
|
|
11222
|
+
authStatus = 'signed-out',
|
|
11223
|
+
chatListScrollTop,
|
|
11224
|
+
composerDropActive = false,
|
|
11225
|
+
composerDropEnabled = true,
|
|
11226
|
+
composerFontFamily,
|
|
11227
|
+
composerFontSize,
|
|
11228
|
+
composerHeight,
|
|
11229
|
+
composerLineHeight,
|
|
11230
|
+
composerValue,
|
|
11231
|
+
messagesScrollTop,
|
|
11232
|
+
models,
|
|
11233
|
+
openApiApiKeyInput,
|
|
11234
|
+
openRouterApiKeyInput,
|
|
11235
|
+
openRouterApiKeyState,
|
|
11236
|
+
parsedMessages: parsedMessagesInput,
|
|
11237
|
+
projectExpandedIds = [],
|
|
11238
|
+
projectListScrollTop = 0,
|
|
11239
|
+
projects = [],
|
|
11240
|
+
runMode,
|
|
11241
|
+
selectedModelId,
|
|
11242
|
+
selectedProjectId = '',
|
|
11243
|
+
selectedSessionId,
|
|
11244
|
+
sessions,
|
|
11245
|
+
showRunMode,
|
|
11246
|
+
todoListToolEnabled,
|
|
11247
|
+
tokensMax,
|
|
11248
|
+
tokensUsed,
|
|
11249
|
+
usageOverviewEnabled,
|
|
11250
|
+
useChatMathWorker = false,
|
|
11251
|
+
viewMode,
|
|
11252
|
+
voiceDictationEnabled = false
|
|
11253
|
+
} = options;
|
|
11254
|
+
const parsedMessages = parsedMessagesInput ?? getFallbackParsedMessages(sessions);
|
|
11255
|
+
const todoListItems = getTodoListItems(sessions, selectedSessionId);
|
|
10971
11256
|
switch (viewMode) {
|
|
10972
11257
|
case 'chat-focus':
|
|
10973
|
-
return getChatModeChatFocusVirtualDom(
|
|
11258
|
+
return getChatModeChatFocusVirtualDom({
|
|
11259
|
+
authEnabled,
|
|
11260
|
+
authErrorMessage,
|
|
11261
|
+
authStatus,
|
|
11262
|
+
composerDropActive,
|
|
11263
|
+
composerDropEnabled,
|
|
11264
|
+
composerFontFamily,
|
|
11265
|
+
composerFontSize,
|
|
11266
|
+
composerHeight,
|
|
11267
|
+
composerLineHeight,
|
|
11268
|
+
composerValue,
|
|
11269
|
+
messagesScrollTop,
|
|
11270
|
+
models,
|
|
11271
|
+
openApiApiKeyInput,
|
|
11272
|
+
openRouterApiKeyInput,
|
|
11273
|
+
openRouterApiKeyState,
|
|
11274
|
+
parsedMessages,
|
|
11275
|
+
projectExpandedIds,
|
|
11276
|
+
projectListScrollTop,
|
|
11277
|
+
projects,
|
|
11278
|
+
runMode,
|
|
11279
|
+
selectedModelId,
|
|
11280
|
+
selectedProjectId,
|
|
11281
|
+
selectedSessionId,
|
|
11282
|
+
sessions,
|
|
11283
|
+
showRunMode,
|
|
11284
|
+
todoListItems,
|
|
11285
|
+
todoListToolEnabled,
|
|
11286
|
+
tokensMax,
|
|
11287
|
+
tokensUsed,
|
|
11288
|
+
usageOverviewEnabled,
|
|
11289
|
+
useChatMathWorker,
|
|
11290
|
+
voiceDictationEnabled
|
|
11291
|
+
});
|
|
10974
11292
|
case 'detail':
|
|
10975
|
-
return getChatModeDetailVirtualDom(
|
|
11293
|
+
return getChatModeDetailVirtualDom({
|
|
11294
|
+
authEnabled,
|
|
11295
|
+
authErrorMessage,
|
|
11296
|
+
authStatus,
|
|
11297
|
+
composerDropActive,
|
|
11298
|
+
composerDropEnabled,
|
|
11299
|
+
composerFontFamily,
|
|
11300
|
+
composerFontSize,
|
|
11301
|
+
composerHeight,
|
|
11302
|
+
composerLineHeight,
|
|
11303
|
+
composerValue,
|
|
11304
|
+
messagesScrollTop,
|
|
11305
|
+
models,
|
|
11306
|
+
openApiApiKeyInput,
|
|
11307
|
+
openRouterApiKeyInput,
|
|
11308
|
+
openRouterApiKeyState,
|
|
11309
|
+
parsedMessages,
|
|
11310
|
+
runMode,
|
|
11311
|
+
selectedModelId,
|
|
11312
|
+
selectedSessionId,
|
|
11313
|
+
sessions,
|
|
11314
|
+
showRunMode,
|
|
11315
|
+
todoListItems,
|
|
11316
|
+
todoListToolEnabled,
|
|
11317
|
+
tokensMax,
|
|
11318
|
+
tokensUsed,
|
|
11319
|
+
usageOverviewEnabled,
|
|
11320
|
+
useChatMathWorker,
|
|
11321
|
+
voiceDictationEnabled
|
|
11322
|
+
});
|
|
10976
11323
|
case 'list':
|
|
10977
|
-
return getChatModeListVirtualDom(
|
|
11324
|
+
return getChatModeListVirtualDom({
|
|
11325
|
+
authEnabled,
|
|
11326
|
+
authErrorMessage,
|
|
11327
|
+
authStatus,
|
|
11328
|
+
chatListScrollTop,
|
|
11329
|
+
composerDropActive,
|
|
11330
|
+
composerDropEnabled,
|
|
11331
|
+
composerFontFamily,
|
|
11332
|
+
composerFontSize,
|
|
11333
|
+
composerHeight,
|
|
11334
|
+
composerLineHeight,
|
|
11335
|
+
composerValue,
|
|
11336
|
+
models,
|
|
11337
|
+
runMode,
|
|
11338
|
+
selectedModelId,
|
|
11339
|
+
selectedSessionId,
|
|
11340
|
+
sessions,
|
|
11341
|
+
showRunMode,
|
|
11342
|
+
todoListItems,
|
|
11343
|
+
todoListToolEnabled,
|
|
11344
|
+
tokensMax,
|
|
11345
|
+
tokensUsed,
|
|
11346
|
+
usageOverviewEnabled,
|
|
11347
|
+
voiceDictationEnabled
|
|
11348
|
+
});
|
|
10978
11349
|
default:
|
|
10979
11350
|
return getChatModeUnsupportedVirtualDom();
|
|
10980
11351
|
}
|
|
@@ -11003,10 +11374,13 @@ const renderItems = (oldState, newState) => {
|
|
|
11003
11374
|
projectExpandedIds,
|
|
11004
11375
|
projectListScrollTop,
|
|
11005
11376
|
projects,
|
|
11377
|
+
runMode,
|
|
11006
11378
|
selectedModelId,
|
|
11007
11379
|
selectedProjectId,
|
|
11008
11380
|
selectedSessionId,
|
|
11009
11381
|
sessions,
|
|
11382
|
+
showRunMode,
|
|
11383
|
+
todoListToolEnabled,
|
|
11010
11384
|
tokensMax,
|
|
11011
11385
|
tokensUsed,
|
|
11012
11386
|
uid,
|
|
@@ -11018,7 +11392,41 @@ const renderItems = (oldState, newState) => {
|
|
|
11018
11392
|
if (initial) {
|
|
11019
11393
|
return [SetDom2, uid, []];
|
|
11020
11394
|
}
|
|
11021
|
-
const dom = getChatVirtualDom(
|
|
11395
|
+
const dom = getChatVirtualDom({
|
|
11396
|
+
authEnabled,
|
|
11397
|
+
authErrorMessage,
|
|
11398
|
+
authStatus,
|
|
11399
|
+
chatListScrollTop,
|
|
11400
|
+
composerDropActive,
|
|
11401
|
+
composerDropEnabled,
|
|
11402
|
+
composerFontFamily,
|
|
11403
|
+
composerFontSize,
|
|
11404
|
+
composerHeight,
|
|
11405
|
+
composerLineHeight,
|
|
11406
|
+
composerValue,
|
|
11407
|
+
messagesScrollTop,
|
|
11408
|
+
models,
|
|
11409
|
+
openApiApiKeyInput,
|
|
11410
|
+
openRouterApiKeyInput,
|
|
11411
|
+
openRouterApiKeyState,
|
|
11412
|
+
parsedMessages,
|
|
11413
|
+
projectExpandedIds,
|
|
11414
|
+
projectListScrollTop,
|
|
11415
|
+
projects,
|
|
11416
|
+
runMode,
|
|
11417
|
+
selectedModelId,
|
|
11418
|
+
selectedProjectId,
|
|
11419
|
+
selectedSessionId,
|
|
11420
|
+
sessions,
|
|
11421
|
+
showRunMode,
|
|
11422
|
+
todoListToolEnabled,
|
|
11423
|
+
tokensMax,
|
|
11424
|
+
tokensUsed,
|
|
11425
|
+
usageOverviewEnabled,
|
|
11426
|
+
useChatMathWorker,
|
|
11427
|
+
viewMode,
|
|
11428
|
+
voiceDictationEnabled
|
|
11429
|
+
});
|
|
11022
11430
|
return [SetDom2, uid, dom];
|
|
11023
11431
|
};
|
|
11024
11432
|
|
|
@@ -11222,6 +11630,9 @@ const renderEventListeners = () => {
|
|
|
11222
11630
|
}, {
|
|
11223
11631
|
name: HandleModelChange,
|
|
11224
11632
|
params: ['handleModelChange', TargetValue]
|
|
11633
|
+
}, {
|
|
11634
|
+
name: HandleRunModeChange,
|
|
11635
|
+
params: ['handleRunModeChange', TargetValue]
|
|
11225
11636
|
}, {
|
|
11226
11637
|
name: HandleChatListScroll,
|
|
11227
11638
|
params: ['handleChatListScroll', 'event.target.scrollTop']
|
|
@@ -11247,7 +11658,8 @@ const renderEventListeners = () => {
|
|
|
11247
11658
|
params: ['handleKeyDown', Key, ShiftKey]
|
|
11248
11659
|
}, {
|
|
11249
11660
|
name: HandleSubmit,
|
|
11250
|
-
params: ['handleSubmit']
|
|
11661
|
+
params: ['handleSubmit'],
|
|
11662
|
+
preventDefault: true
|
|
11251
11663
|
}, {
|
|
11252
11664
|
name: HandleMissingApiKeySubmit,
|
|
11253
11665
|
params: ['handleMissingApiKeySubmit', 'event.submitter?.name || ""'],
|
|
@@ -11367,6 +11779,13 @@ const setQuestionToolEnabled = (state, questionToolEnabled) => {
|
|
|
11367
11779
|
};
|
|
11368
11780
|
};
|
|
11369
11781
|
|
|
11782
|
+
const setShowRunMode = (state, showRunMode) => {
|
|
11783
|
+
return {
|
|
11784
|
+
...state,
|
|
11785
|
+
showRunMode
|
|
11786
|
+
};
|
|
11787
|
+
};
|
|
11788
|
+
|
|
11370
11789
|
const setStreamingEnabled = (state, streamingEnabled) => {
|
|
11371
11790
|
return {
|
|
11372
11791
|
...state,
|
|
@@ -11374,6 +11793,13 @@ const setStreamingEnabled = (state, streamingEnabled) => {
|
|
|
11374
11793
|
};
|
|
11375
11794
|
};
|
|
11376
11795
|
|
|
11796
|
+
const setTodoListToolEnabled = (state, todoListToolEnabled) => {
|
|
11797
|
+
return {
|
|
11798
|
+
...state,
|
|
11799
|
+
todoListToolEnabled
|
|
11800
|
+
};
|
|
11801
|
+
};
|
|
11802
|
+
|
|
11377
11803
|
const setUseChatCoordinatorWorker = async (state, useChatCoordinatorWorker, persist = true) => {
|
|
11378
11804
|
if (persist) {
|
|
11379
11805
|
await update({
|
|
@@ -11463,6 +11889,7 @@ const commandMap = {
|
|
|
11463
11889
|
'Chat.handleModelChange': wrapCommand(handleModelChange),
|
|
11464
11890
|
'Chat.handleProjectListContextMenu': wrapCommand(handleProjectListContextMenu),
|
|
11465
11891
|
'Chat.handleProjectListScroll': wrapCommand(handleProjectListScroll),
|
|
11892
|
+
'Chat.handleRunModeChange': wrapCommand(handleRunModeChange),
|
|
11466
11893
|
'Chat.handleSubmit': wrapCommand(handleSubmit),
|
|
11467
11894
|
'Chat.initialize': initialize,
|
|
11468
11895
|
'Chat.loadContent': wrapCommand(loadContent),
|
|
@@ -11489,7 +11916,9 @@ const commandMap = {
|
|
|
11489
11916
|
'Chat.setEmitStreamingFunctionCallEvents': wrapCommand(setEmitStreamingFunctionCallEvents),
|
|
11490
11917
|
'Chat.setOpenRouterApiKey': wrapCommand(setOpenRouterApiKey),
|
|
11491
11918
|
'Chat.setQuestionToolEnabled': wrapCommand(setQuestionToolEnabled),
|
|
11919
|
+
'Chat.setShowRunMode': wrapCommand(setShowRunMode),
|
|
11492
11920
|
'Chat.setStreamingEnabled': wrapCommand(setStreamingEnabled),
|
|
11921
|
+
'Chat.setTodoListToolEnabled': wrapCommand(setTodoListToolEnabled),
|
|
11493
11922
|
'Chat.setUseChatCoordinatorWorker': wrapCommand(setUseChatCoordinatorWorker),
|
|
11494
11923
|
'Chat.setUseChatMathWorker': wrapCommand(setUseChatMathWorker),
|
|
11495
11924
|
'Chat.setUseChatNetworkWorkerForRequests': wrapCommand(setUseChatNetworkWorkerForRequests),
|