@lvce-editor/chat-view 5.4.0 → 6.1.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 +640 -366
- package/package.json +1 -1
|
@@ -476,7 +476,7 @@ const register = commandMap => {
|
|
|
476
476
|
const getCommand = key => {
|
|
477
477
|
return commands[key];
|
|
478
478
|
};
|
|
479
|
-
const execute = (command, ...args) => {
|
|
479
|
+
const execute$1 = (command, ...args) => {
|
|
480
480
|
const fn = getCommand(command);
|
|
481
481
|
if (!fn) {
|
|
482
482
|
throw new CommandNotFoundError(command);
|
|
@@ -896,7 +896,7 @@ const logError = () => {
|
|
|
896
896
|
};
|
|
897
897
|
const handleMessage = event => {
|
|
898
898
|
const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
|
|
899
|
-
const actualExecute = event?.target?.execute || execute;
|
|
899
|
+
const actualExecute = event?.target?.execute || execute$1;
|
|
900
900
|
return handleJsonRpcMessage(event.target, event.data, actualExecute, event.target._resolve, preparePrettyError, logError, actualRequiresSocket);
|
|
901
901
|
};
|
|
902
902
|
|
|
@@ -1027,7 +1027,7 @@ const createMockRpc = ({
|
|
|
1027
1027
|
};
|
|
1028
1028
|
|
|
1029
1029
|
const rpcs = Object.create(null);
|
|
1030
|
-
const set$
|
|
1030
|
+
const set$8 = (id, rpc) => {
|
|
1031
1031
|
rpcs[id] = rpc;
|
|
1032
1032
|
};
|
|
1033
1033
|
const get$2 = id => {
|
|
@@ -1060,7 +1060,7 @@ const create$2 = rpcId => {
|
|
|
1060
1060
|
const mockRpc = createMockRpc({
|
|
1061
1061
|
commandMap
|
|
1062
1062
|
});
|
|
1063
|
-
set$
|
|
1063
|
+
set$8(rpcId, mockRpc);
|
|
1064
1064
|
// @ts-ignore
|
|
1065
1065
|
mockRpc[Symbol.dispose] = () => {
|
|
1066
1066
|
remove(rpcId);
|
|
@@ -1069,20 +1069,20 @@ const create$2 = rpcId => {
|
|
|
1069
1069
|
return mockRpc;
|
|
1070
1070
|
},
|
|
1071
1071
|
set(rpc) {
|
|
1072
|
-
set$
|
|
1072
|
+
set$8(rpcId, rpc);
|
|
1073
1073
|
}
|
|
1074
1074
|
};
|
|
1075
1075
|
};
|
|
1076
1076
|
|
|
1077
1077
|
const {
|
|
1078
|
-
invoke: invoke$
|
|
1079
|
-
set: set$
|
|
1078
|
+
invoke: invoke$5,
|
|
1079
|
+
set: set$7
|
|
1080
1080
|
} = create$2(6007);
|
|
1081
1081
|
const getMathBlockDom = async node => {
|
|
1082
|
-
return invoke$
|
|
1082
|
+
return invoke$5('ChatMath.getMathBlockDom', node);
|
|
1083
1083
|
};
|
|
1084
1084
|
const getMathInlineDom = async node => {
|
|
1085
|
-
return invoke$
|
|
1085
|
+
return invoke$5('ChatMath.getMathInlineDom', node);
|
|
1086
1086
|
};
|
|
1087
1087
|
|
|
1088
1088
|
const Button$2 = 'button';
|
|
@@ -1158,6 +1158,7 @@ const RestoreFocus = 6;
|
|
|
1158
1158
|
|
|
1159
1159
|
const ChatNetworkWorker = 6002;
|
|
1160
1160
|
const ExtensionHostWorker = 44;
|
|
1161
|
+
const OpenerWorker = 4561;
|
|
1161
1162
|
const RendererWorker = 1;
|
|
1162
1163
|
|
|
1163
1164
|
const FocusSelector = 'Viewlet.focusSelector';
|
|
@@ -1171,20 +1172,33 @@ const SetPatches = 'Viewlet.setPatches';
|
|
|
1171
1172
|
const FocusChatInput = 8000;
|
|
1172
1173
|
|
|
1173
1174
|
const {
|
|
1174
|
-
invoke: invoke$
|
|
1175
|
-
set: set$
|
|
1175
|
+
invoke: invoke$4,
|
|
1176
|
+
set: set$6
|
|
1176
1177
|
} = create$2(ChatNetworkWorker);
|
|
1177
1178
|
|
|
1179
|
+
const {
|
|
1180
|
+
invoke: invoke$3,
|
|
1181
|
+
set: set$5
|
|
1182
|
+
} = create$2(6005);
|
|
1183
|
+
|
|
1178
1184
|
const {
|
|
1179
1185
|
invoke: invoke$2,
|
|
1180
|
-
set: set$
|
|
1186
|
+
set: set$4
|
|
1181
1187
|
} = create$2(ExtensionHostWorker);
|
|
1182
1188
|
|
|
1189
|
+
const {
|
|
1190
|
+
set: set$3
|
|
1191
|
+
} = create$2(OpenerWorker);
|
|
1192
|
+
|
|
1183
1193
|
const {
|
|
1184
1194
|
invoke: invoke$1,
|
|
1185
1195
|
invokeAndTransfer,
|
|
1186
1196
|
set: set$2
|
|
1187
1197
|
} = create$2(RendererWorker);
|
|
1198
|
+
const sendMessagePortToOpenerWorker$1 = async (port, rpcId) => {
|
|
1199
|
+
const command = 'HandleMessagePort.handleMessagePort';
|
|
1200
|
+
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToOpenerWorker', port, command, rpcId);
|
|
1201
|
+
};
|
|
1188
1202
|
const sendMessagePortToChatMathWorker$1 = async (port, rpcId) => {
|
|
1189
1203
|
const command = 'HandleMessagePort.handleMessagePort';
|
|
1190
1204
|
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatMathWorker', port, command, rpcId);
|
|
@@ -1199,6 +1213,9 @@ const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
|
|
|
1199
1213
|
const sendMessagePortToChatNetworkWorker = async port => {
|
|
1200
1214
|
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatNetworkWorker', port, 'HandleMessagePort.handleMessagePort');
|
|
1201
1215
|
};
|
|
1216
|
+
const sendMessagePortToChatToolWorker = async port => {
|
|
1217
|
+
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatToolWorker', port, 'HandleMessagePort.handleMessagePort');
|
|
1218
|
+
};
|
|
1202
1219
|
const writeFile = async (uri, text) => {
|
|
1203
1220
|
await invoke$1('FileSystem.writeFile', uri, text);
|
|
1204
1221
|
};
|
|
@@ -1604,6 +1621,7 @@ const createDefaultState = () => {
|
|
|
1604
1621
|
lastSubmittedSessionId: '',
|
|
1605
1622
|
listItemHeight: 40,
|
|
1606
1623
|
maxComposerRows: 5,
|
|
1624
|
+
messagesAutoScrollEnabled: true,
|
|
1607
1625
|
messagesScrollTop: 0,
|
|
1608
1626
|
mockAiResponseDelay: 800,
|
|
1609
1627
|
mockApiCommandId: '',
|
|
@@ -1643,9 +1661,10 @@ const createDefaultState = () => {
|
|
|
1643
1661
|
tokensUsed: 0,
|
|
1644
1662
|
uid: 0,
|
|
1645
1663
|
usageOverviewEnabled: false,
|
|
1646
|
-
useChatCoordinatorWorker:
|
|
1664
|
+
useChatCoordinatorWorker: true,
|
|
1647
1665
|
useChatMathWorker: true,
|
|
1648
1666
|
useChatNetworkWorkerForRequests: false,
|
|
1667
|
+
useChatToolWorker: false,
|
|
1649
1668
|
useMockApi: false,
|
|
1650
1669
|
viewMode: 'list',
|
|
1651
1670
|
voiceDictationEnabled: false,
|
|
@@ -3104,6 +3123,10 @@ const getAiResponse$1 = async options => {
|
|
|
3104
3123
|
return invoke('ChatCoordinator.getAiResponse', options);
|
|
3105
3124
|
};
|
|
3106
3125
|
|
|
3126
|
+
const execute = async (name, rawArguments, options) => {
|
|
3127
|
+
return invoke$3('ChatTool.execute', name, rawArguments, options);
|
|
3128
|
+
};
|
|
3129
|
+
|
|
3107
3130
|
const getToolErrorPayload = error => {
|
|
3108
3131
|
const rawStack = error && typeof error === 'object' ? Reflect.get(error, 'stack') : undefined;
|
|
3109
3132
|
return {
|
|
@@ -3282,6 +3305,12 @@ const parseToolArguments = rawArguments => {
|
|
|
3282
3305
|
};
|
|
3283
3306
|
|
|
3284
3307
|
const executeChatTool = async (name, rawArguments, options) => {
|
|
3308
|
+
if (options.useChatToolWorker) {
|
|
3309
|
+
return execute(name, rawArguments, {
|
|
3310
|
+
assetDir: options.assetDir,
|
|
3311
|
+
platform: options.platform
|
|
3312
|
+
});
|
|
3313
|
+
}
|
|
3285
3314
|
const args = parseToolArguments(rawArguments);
|
|
3286
3315
|
if (name === 'read_file') {
|
|
3287
3316
|
return executeReadFileTool(args);
|
|
@@ -3870,10 +3899,10 @@ const getOpenApiApiEndpoint = openApiApiBaseUrl => {
|
|
|
3870
3899
|
};
|
|
3871
3900
|
|
|
3872
3901
|
const makeApiRequest = async options => {
|
|
3873
|
-
return invoke$
|
|
3902
|
+
return invoke$4('ChatNetwork.makeApiRequest', options);
|
|
3874
3903
|
};
|
|
3875
3904
|
const makeStreamingApiRequest = async options => {
|
|
3876
|
-
return invoke$
|
|
3905
|
+
return invoke$4('ChatNetwork.makeStreamingApiRequest', options);
|
|
3877
3906
|
};
|
|
3878
3907
|
|
|
3879
3908
|
const getTextContent = content => {
|
|
@@ -4503,6 +4532,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4503
4532
|
onToolCallsChunk,
|
|
4504
4533
|
stream,
|
|
4505
4534
|
useChatNetworkWorkerForRequests = false,
|
|
4535
|
+
useChatToolWorker = false,
|
|
4506
4536
|
webSearchEnabled = false
|
|
4507
4537
|
} = options ?? {
|
|
4508
4538
|
stream: false
|
|
@@ -4608,7 +4638,11 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4608
4638
|
openAiInput.length = 0;
|
|
4609
4639
|
const executedToolCalls = [];
|
|
4610
4640
|
for (const toolCall of streamResult.responseFunctionCalls) {
|
|
4611
|
-
const content = await executeChatTool(toolCall.name, toolCall.arguments
|
|
4641
|
+
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
4642
|
+
assetDir,
|
|
4643
|
+
platform,
|
|
4644
|
+
useChatToolWorker
|
|
4645
|
+
});
|
|
4612
4646
|
const executionStatus = getToolCallExecutionStatus(content);
|
|
4613
4647
|
executedToolCalls.push({
|
|
4614
4648
|
arguments: toolCall.arguments,
|
|
@@ -4749,7 +4783,11 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4749
4783
|
openAiInput.length = 0;
|
|
4750
4784
|
const executedToolCalls = [];
|
|
4751
4785
|
for (const toolCall of responseFunctionCalls) {
|
|
4752
|
-
const content = await executeChatTool(toolCall.name, toolCall.arguments
|
|
4786
|
+
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
4787
|
+
assetDir,
|
|
4788
|
+
platform,
|
|
4789
|
+
useChatToolWorker
|
|
4790
|
+
});
|
|
4753
4791
|
const executionStatus = getToolCallExecutionStatus(content);
|
|
4754
4792
|
executedToolCalls.push({
|
|
4755
4793
|
arguments: toolCall.arguments,
|
|
@@ -4817,7 +4855,11 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
|
|
|
4817
4855
|
}
|
|
4818
4856
|
const name = Reflect.get(toolFunction, 'name');
|
|
4819
4857
|
const rawArguments = Reflect.get(toolFunction, 'arguments');
|
|
4820
|
-
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments
|
|
4858
|
+
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
|
|
4859
|
+
assetDir,
|
|
4860
|
+
platform,
|
|
4861
|
+
useChatToolWorker
|
|
4862
|
+
}) : '{}';
|
|
4821
4863
|
if (typeof name === 'string') {
|
|
4822
4864
|
const executionStatus = getToolCallExecutionStatus(content);
|
|
4823
4865
|
executedToolCalls.push({
|
|
@@ -5065,7 +5107,7 @@ const getOpenRouterLimitInfo = async (openRouterApiKey, openRouterApiBaseUrl, us
|
|
|
5065
5107
|
}
|
|
5066
5108
|
return normalizedLimitInfo;
|
|
5067
5109
|
};
|
|
5068
|
-
const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false) => {
|
|
5110
|
+
const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false, useChatToolWorker = false) => {
|
|
5069
5111
|
const completionMessages = messages.map(message => ({
|
|
5070
5112
|
content: message.text,
|
|
5071
5113
|
role: message.role
|
|
@@ -5220,7 +5262,11 @@ const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, o
|
|
|
5220
5262
|
}
|
|
5221
5263
|
const name = Reflect.get(toolFunction, 'name');
|
|
5222
5264
|
const rawArguments = Reflect.get(toolFunction, 'arguments');
|
|
5223
|
-
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments
|
|
5265
|
+
const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
|
|
5266
|
+
assetDir,
|
|
5267
|
+
platform,
|
|
5268
|
+
useChatToolWorker
|
|
5269
|
+
}) : '{}';
|
|
5224
5270
|
completionMessages.push({
|
|
5225
5271
|
content,
|
|
5226
5272
|
role: 'tool',
|
|
@@ -5349,6 +5395,7 @@ const getAiResponse = async ({
|
|
|
5349
5395
|
streamingEnabled = true,
|
|
5350
5396
|
useChatCoordinatorWorker = false,
|
|
5351
5397
|
useChatNetworkWorkerForRequests = false,
|
|
5398
|
+
useChatToolWorker = false,
|
|
5352
5399
|
useMockApi,
|
|
5353
5400
|
userText,
|
|
5354
5401
|
webSearchEnabled = false
|
|
@@ -5374,6 +5421,7 @@ const getAiResponse = async ({
|
|
|
5374
5421
|
selectedModelId,
|
|
5375
5422
|
streamingEnabled,
|
|
5376
5423
|
useChatNetworkWorkerForRequests,
|
|
5424
|
+
useChatToolWorker,
|
|
5377
5425
|
useMockApi,
|
|
5378
5426
|
userText,
|
|
5379
5427
|
webSearchEnabled
|
|
@@ -5429,7 +5477,11 @@ const getAiResponse = async ({
|
|
|
5429
5477
|
}
|
|
5430
5478
|
openAiInput.length = 0;
|
|
5431
5479
|
for (const toolCall of result.responseFunctionCalls) {
|
|
5432
|
-
const content = await executeChatTool(toolCall.name, toolCall.arguments
|
|
5480
|
+
const content = await executeChatTool(toolCall.name, toolCall.arguments, {
|
|
5481
|
+
assetDir,
|
|
5482
|
+
platform,
|
|
5483
|
+
useChatToolWorker
|
|
5484
|
+
});
|
|
5433
5485
|
openAiInput.push({
|
|
5434
5486
|
call_id: toolCall.callId,
|
|
5435
5487
|
output: content,
|
|
@@ -5454,6 +5506,7 @@ const getAiResponse = async ({
|
|
|
5454
5506
|
} : {}),
|
|
5455
5507
|
stream: streamingEnabled,
|
|
5456
5508
|
useChatNetworkWorkerForRequests,
|
|
5509
|
+
useChatToolWorker,
|
|
5457
5510
|
webSearchEnabled
|
|
5458
5511
|
});
|
|
5459
5512
|
if (result.type === 'success') {
|
|
@@ -5480,7 +5533,7 @@ const getAiResponse = async ({
|
|
|
5480
5533
|
text = getOpenRouterErrorMessage(result);
|
|
5481
5534
|
}
|
|
5482
5535
|
} else if (openRouterApiKey) {
|
|
5483
|
-
const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests);
|
|
5536
|
+
const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests, useChatToolWorker);
|
|
5484
5537
|
if (result.type === 'success') {
|
|
5485
5538
|
const {
|
|
5486
5539
|
text: assistantText
|
|
@@ -5751,6 +5804,48 @@ const parseLinkToken = (value, start) => {
|
|
|
5751
5804
|
}
|
|
5752
5805
|
return undefined;
|
|
5753
5806
|
};
|
|
5807
|
+
const parseImageToken = (value, start) => {
|
|
5808
|
+
if (value[start] !== '!' || value[start + 1] !== '[') {
|
|
5809
|
+
return undefined;
|
|
5810
|
+
}
|
|
5811
|
+
const textEnd = value.indexOf(']', start + 2);
|
|
5812
|
+
if (textEnd === -1) {
|
|
5813
|
+
return undefined;
|
|
5814
|
+
}
|
|
5815
|
+
if (value[textEnd + 1] !== '(') {
|
|
5816
|
+
return undefined;
|
|
5817
|
+
}
|
|
5818
|
+
let depth = 1;
|
|
5819
|
+
let index = textEnd + 2;
|
|
5820
|
+
while (index < value.length) {
|
|
5821
|
+
const current = value[index];
|
|
5822
|
+
if (current === '\n') {
|
|
5823
|
+
return undefined;
|
|
5824
|
+
}
|
|
5825
|
+
if (current === '(') {
|
|
5826
|
+
depth++;
|
|
5827
|
+
} else if (current === ')') {
|
|
5828
|
+
depth--;
|
|
5829
|
+
if (depth === 0) {
|
|
5830
|
+
const alt = value.slice(start + 2, textEnd);
|
|
5831
|
+
const src = value.slice(textEnd + 2, index);
|
|
5832
|
+
if (!src) {
|
|
5833
|
+
return undefined;
|
|
5834
|
+
}
|
|
5835
|
+
return {
|
|
5836
|
+
length: index - start + 1,
|
|
5837
|
+
node: {
|
|
5838
|
+
alt,
|
|
5839
|
+
src: sanitizeUrl(src),
|
|
5840
|
+
type: 'image'
|
|
5841
|
+
}
|
|
5842
|
+
};
|
|
5843
|
+
}
|
|
5844
|
+
}
|
|
5845
|
+
index++;
|
|
5846
|
+
}
|
|
5847
|
+
return undefined;
|
|
5848
|
+
};
|
|
5754
5849
|
const parseBoldToken = (value, start) => {
|
|
5755
5850
|
if (value[start] !== '*' || value[start + 1] !== '*') {
|
|
5756
5851
|
return undefined;
|
|
@@ -5812,6 +5907,26 @@ const parseItalicToken = (value, start) => {
|
|
|
5812
5907
|
}
|
|
5813
5908
|
};
|
|
5814
5909
|
};
|
|
5910
|
+
const parseStrikethroughToken = (value, start) => {
|
|
5911
|
+
if (value[start] !== '~' || value[start + 1] !== '~') {
|
|
5912
|
+
return undefined;
|
|
5913
|
+
}
|
|
5914
|
+
const end = value.indexOf('~~', start + 2);
|
|
5915
|
+
if (end === -1) {
|
|
5916
|
+
return undefined;
|
|
5917
|
+
}
|
|
5918
|
+
const text = value.slice(start + 2, end);
|
|
5919
|
+
if (!text || text.includes('\n')) {
|
|
5920
|
+
return undefined;
|
|
5921
|
+
}
|
|
5922
|
+
return {
|
|
5923
|
+
length: end - start + 2,
|
|
5924
|
+
node: {
|
|
5925
|
+
children: parseInlineNodes(text),
|
|
5926
|
+
type: 'strikethrough'
|
|
5927
|
+
}
|
|
5928
|
+
};
|
|
5929
|
+
};
|
|
5815
5930
|
const parseMathToken = (value, start) => {
|
|
5816
5931
|
if (value[start] !== '$') {
|
|
5817
5932
|
return undefined;
|
|
@@ -5858,7 +5973,7 @@ const parseMathToken = (value, start) => {
|
|
|
5858
5973
|
return undefined;
|
|
5859
5974
|
};
|
|
5860
5975
|
const parseInlineToken = (value, start) => {
|
|
5861
|
-
return parseLinkToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseMathToken(value, start);
|
|
5976
|
+
return parseImageToken(value, start) || parseLinkToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseLinkToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseStrikethroughToken(value, start) || parseMathToken(value, start);
|
|
5862
5977
|
};
|
|
5863
5978
|
const parseInlineNodes = value => {
|
|
5864
5979
|
const nodes = [];
|
|
@@ -5894,105 +6009,311 @@ const parseInlineNodes = value => {
|
|
|
5894
6009
|
return nodes;
|
|
5895
6010
|
};
|
|
5896
6011
|
|
|
5897
|
-
const
|
|
5898
|
-
|
|
5899
|
-
|
|
6012
|
+
const markdownMathBlockDelimiter = '$$';
|
|
6013
|
+
const normalizeEscapedNewlines = value => {
|
|
6014
|
+
if (value.includes('\\n')) {
|
|
6015
|
+
return value.replaceAll(/\\r\\n|\\n/g, '\n');
|
|
5900
6016
|
}
|
|
6017
|
+
return value;
|
|
6018
|
+
};
|
|
6019
|
+
const normalizeInlineTables = value => {
|
|
6020
|
+
return value.split(/\r?\n/).map(line => {
|
|
6021
|
+
if (!line.includes('|')) {
|
|
6022
|
+
return line;
|
|
6023
|
+
}
|
|
6024
|
+
if (!/\|\s*[-:]{3,}/.test(line)) {
|
|
6025
|
+
return line;
|
|
6026
|
+
}
|
|
6027
|
+
return line.replaceAll(/\|\s+\|/g, '|\n|');
|
|
6028
|
+
}).join('\n');
|
|
6029
|
+
};
|
|
6030
|
+
const parseHeadingLine = line => {
|
|
6031
|
+
const trimmedStart = line.trimStart();
|
|
5901
6032
|
let index = 0;
|
|
5902
|
-
|
|
6033
|
+
while (index < trimmedStart.length && trimmedStart[index] === '#') {
|
|
5903
6034
|
index++;
|
|
5904
6035
|
}
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
dashCount++;
|
|
5908
|
-
index++;
|
|
6036
|
+
if (index === 0 || index > 6) {
|
|
6037
|
+
return undefined;
|
|
5909
6038
|
}
|
|
5910
|
-
if (
|
|
5911
|
-
return
|
|
6039
|
+
if (trimmedStart[index] !== ' ') {
|
|
6040
|
+
return undefined;
|
|
5912
6041
|
}
|
|
5913
|
-
|
|
6042
|
+
const text = trimmedStart.slice(index).trimStart();
|
|
6043
|
+
return {
|
|
6044
|
+
level: index,
|
|
6045
|
+
text
|
|
6046
|
+
};
|
|
6047
|
+
};
|
|
6048
|
+
const parseOrderedListItemLine = line => {
|
|
6049
|
+
let index = 0;
|
|
6050
|
+
while (index < line.length && line[index] === ' ') {
|
|
5914
6051
|
index++;
|
|
5915
6052
|
}
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
if (!token || token.type !== 'table-row-line') {
|
|
5920
|
-
return false;
|
|
6053
|
+
const firstDigit = index;
|
|
6054
|
+
while (index < line.length && line[index] >= '0' && line[index] <= '9') {
|
|
6055
|
+
index++;
|
|
5921
6056
|
}
|
|
5922
|
-
if (
|
|
5923
|
-
return
|
|
6057
|
+
if (index === firstDigit || line[index] !== '.') {
|
|
6058
|
+
return undefined;
|
|
6059
|
+
}
|
|
6060
|
+
index++;
|
|
6061
|
+
if (line[index] !== ' ') {
|
|
6062
|
+
return undefined;
|
|
6063
|
+
}
|
|
6064
|
+
while (index < line.length && line[index] === ' ') {
|
|
6065
|
+
index++;
|
|
5924
6066
|
}
|
|
5925
|
-
return token.cells.every(isTableSeparatorCell);
|
|
5926
|
-
};
|
|
5927
|
-
const toTableCell = value => {
|
|
5928
6067
|
return {
|
|
5929
|
-
|
|
5930
|
-
type: 'table-cell'
|
|
6068
|
+
text: line.slice(index)
|
|
5931
6069
|
};
|
|
5932
6070
|
};
|
|
5933
|
-
const
|
|
6071
|
+
const parseUnorderedListItemLine = line => {
|
|
6072
|
+
let indentation = 0;
|
|
6073
|
+
while (indentation < line.length && line[indentation] === ' ') {
|
|
6074
|
+
indentation++;
|
|
6075
|
+
}
|
|
6076
|
+
const marker = line[indentation];
|
|
6077
|
+
if (marker !== '-' && marker !== '*') {
|
|
6078
|
+
return undefined;
|
|
6079
|
+
}
|
|
6080
|
+
let index = indentation + 1;
|
|
6081
|
+
if (line[index] !== ' ') {
|
|
6082
|
+
return undefined;
|
|
6083
|
+
}
|
|
6084
|
+
while (index < line.length && line[index] === ' ') {
|
|
6085
|
+
index++;
|
|
6086
|
+
}
|
|
5934
6087
|
return {
|
|
5935
|
-
|
|
5936
|
-
|
|
6088
|
+
indentation,
|
|
6089
|
+
text: line.slice(index)
|
|
5937
6090
|
};
|
|
5938
6091
|
};
|
|
5939
|
-
const
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
6092
|
+
const parseBlockQuoteLine = line => {
|
|
6093
|
+
const trimmedStart = line.trimStart();
|
|
6094
|
+
if (!trimmedStart.startsWith('>')) {
|
|
6095
|
+
return undefined;
|
|
6096
|
+
}
|
|
6097
|
+
const content = trimmedStart.slice(1);
|
|
6098
|
+
if (!content) {
|
|
6099
|
+
return '';
|
|
6100
|
+
}
|
|
6101
|
+
if (content.startsWith(' ')) {
|
|
6102
|
+
return content.slice(1);
|
|
6103
|
+
}
|
|
6104
|
+
return content;
|
|
5947
6105
|
};
|
|
5948
|
-
const
|
|
5949
|
-
|
|
5950
|
-
|
|
6106
|
+
const isTableRow = line => {
|
|
6107
|
+
const trimmed = line.trim();
|
|
6108
|
+
if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) {
|
|
6109
|
+
return false;
|
|
5951
6110
|
}
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
6111
|
+
return trimmed.length > 2 && trimmed.slice(1, -1).includes('|');
|
|
6112
|
+
};
|
|
6113
|
+
const getTableCells = line => {
|
|
6114
|
+
const trimmed = line.trim();
|
|
6115
|
+
return trimmed.slice(1, -1).split('|').map(part => part.trim());
|
|
6116
|
+
};
|
|
6117
|
+
const scanBlockTokens = rawMessage => {
|
|
6118
|
+
const normalizedMessage = normalizeInlineTables(normalizeEscapedNewlines(rawMessage));
|
|
6119
|
+
const lines = normalizedMessage.split(/\r?\n/);
|
|
6120
|
+
const tokens = [];
|
|
6121
|
+
for (let i = 0; i < lines.length; i++) {
|
|
6122
|
+
const line = lines[i];
|
|
6123
|
+
const trimmed = line.trim();
|
|
6124
|
+
if (!trimmed) {
|
|
6125
|
+
tokens.push({
|
|
6126
|
+
type: 'blank-line'
|
|
6127
|
+
});
|
|
6128
|
+
continue;
|
|
5969
6129
|
}
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
};
|
|
5977
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
5978
|
-
const token = tokens[i];
|
|
5979
|
-
if (token.type === 'blank-line') {
|
|
5980
|
-
flushList();
|
|
5981
|
-
flushParagraph();
|
|
6130
|
+
const blockQuoteLine = parseBlockQuoteLine(line);
|
|
6131
|
+
if (blockQuoteLine !== undefined) {
|
|
6132
|
+
tokens.push({
|
|
6133
|
+
text: blockQuoteLine,
|
|
6134
|
+
type: 'blockquote-line'
|
|
6135
|
+
});
|
|
5982
6136
|
continue;
|
|
5983
6137
|
}
|
|
5984
|
-
if (
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
6138
|
+
if (trimmed.startsWith('```')) {
|
|
6139
|
+
const language = trimmed.slice(3).trim();
|
|
6140
|
+
const codeLines = [];
|
|
6141
|
+
i++;
|
|
6142
|
+
while (i < lines.length && !lines[i].trim().startsWith('```')) {
|
|
6143
|
+
codeLines.push(lines[i]);
|
|
6144
|
+
i++;
|
|
6145
|
+
}
|
|
6146
|
+
if (language) {
|
|
6147
|
+
tokens.push({
|
|
6148
|
+
language,
|
|
6149
|
+
text: codeLines.join('\n'),
|
|
5991
6150
|
type: 'code-block'
|
|
5992
6151
|
});
|
|
5993
6152
|
} else {
|
|
5994
|
-
|
|
5995
|
-
text:
|
|
6153
|
+
tokens.push({
|
|
6154
|
+
text: codeLines.join('\n'),
|
|
6155
|
+
type: 'code-block'
|
|
6156
|
+
});
|
|
6157
|
+
}
|
|
6158
|
+
continue;
|
|
6159
|
+
}
|
|
6160
|
+
if (trimmed === markdownMathBlockDelimiter) {
|
|
6161
|
+
const endIndex = lines.findIndex((candidate, index) => {
|
|
6162
|
+
if (index <= i) {
|
|
6163
|
+
return false;
|
|
6164
|
+
}
|
|
6165
|
+
return candidate.trim() === markdownMathBlockDelimiter;
|
|
6166
|
+
});
|
|
6167
|
+
if (endIndex !== -1) {
|
|
6168
|
+
tokens.push({
|
|
6169
|
+
text: lines.slice(i + 1, endIndex).join('\n').trim(),
|
|
6170
|
+
type: 'math-block'
|
|
6171
|
+
});
|
|
6172
|
+
i = endIndex;
|
|
6173
|
+
continue;
|
|
6174
|
+
}
|
|
6175
|
+
}
|
|
6176
|
+
const heading = parseHeadingLine(line);
|
|
6177
|
+
if (heading) {
|
|
6178
|
+
tokens.push({
|
|
6179
|
+
level: heading.level,
|
|
6180
|
+
text: heading.text,
|
|
6181
|
+
type: 'heading-line'
|
|
6182
|
+
});
|
|
6183
|
+
continue;
|
|
6184
|
+
}
|
|
6185
|
+
const ordered = parseOrderedListItemLine(line);
|
|
6186
|
+
if (ordered) {
|
|
6187
|
+
tokens.push({
|
|
6188
|
+
text: ordered.text,
|
|
6189
|
+
type: 'ordered-list-item-line'
|
|
6190
|
+
});
|
|
6191
|
+
continue;
|
|
6192
|
+
}
|
|
6193
|
+
const unordered = parseUnorderedListItemLine(line);
|
|
6194
|
+
if (unordered) {
|
|
6195
|
+
tokens.push({
|
|
6196
|
+
indentation: unordered.indentation,
|
|
6197
|
+
text: unordered.text,
|
|
6198
|
+
type: 'unordered-list-item-line'
|
|
6199
|
+
});
|
|
6200
|
+
continue;
|
|
6201
|
+
}
|
|
6202
|
+
if (isTableRow(line)) {
|
|
6203
|
+
tokens.push({
|
|
6204
|
+
cells: getTableCells(line),
|
|
6205
|
+
line,
|
|
6206
|
+
type: 'table-row-line'
|
|
6207
|
+
});
|
|
6208
|
+
continue;
|
|
6209
|
+
}
|
|
6210
|
+
tokens.push({
|
|
6211
|
+
text: line,
|
|
6212
|
+
type: 'paragraph-line'
|
|
6213
|
+
});
|
|
6214
|
+
}
|
|
6215
|
+
return tokens;
|
|
6216
|
+
};
|
|
6217
|
+
|
|
6218
|
+
const isTableSeparatorCell = value => {
|
|
6219
|
+
if (!value) {
|
|
6220
|
+
return false;
|
|
6221
|
+
}
|
|
6222
|
+
let index = 0;
|
|
6223
|
+
if (value[index] === ':') {
|
|
6224
|
+
index++;
|
|
6225
|
+
}
|
|
6226
|
+
let dashCount = 0;
|
|
6227
|
+
while (index < value.length && value[index] === '-') {
|
|
6228
|
+
dashCount++;
|
|
6229
|
+
index++;
|
|
6230
|
+
}
|
|
6231
|
+
if (dashCount < 3) {
|
|
6232
|
+
return false;
|
|
6233
|
+
}
|
|
6234
|
+
if (index < value.length && value[index] === ':') {
|
|
6235
|
+
index++;
|
|
6236
|
+
}
|
|
6237
|
+
return index === value.length;
|
|
6238
|
+
};
|
|
6239
|
+
const isTableSeparatorToken = (token, expectedColumns) => {
|
|
6240
|
+
if (!token || token.type !== 'table-row-line') {
|
|
6241
|
+
return false;
|
|
6242
|
+
}
|
|
6243
|
+
if (token.cells.length !== expectedColumns) {
|
|
6244
|
+
return false;
|
|
6245
|
+
}
|
|
6246
|
+
return token.cells.every(isTableSeparatorCell);
|
|
6247
|
+
};
|
|
6248
|
+
const toTableCell = value => {
|
|
6249
|
+
return {
|
|
6250
|
+
children: parseInlineNodes(value),
|
|
6251
|
+
type: 'table-cell'
|
|
6252
|
+
};
|
|
6253
|
+
};
|
|
6254
|
+
const toTableRow = token => {
|
|
6255
|
+
return {
|
|
6256
|
+
cells: token.cells.map(toTableCell),
|
|
6257
|
+
type: 'table-row'
|
|
6258
|
+
};
|
|
6259
|
+
};
|
|
6260
|
+
const getEmptyTextNode = () => {
|
|
6261
|
+
return [{
|
|
6262
|
+
children: [{
|
|
6263
|
+
text: '',
|
|
6264
|
+
type: 'text'
|
|
6265
|
+
}],
|
|
6266
|
+
type: 'text'
|
|
6267
|
+
}];
|
|
6268
|
+
};
|
|
6269
|
+
const parseBlockTokens = tokens => {
|
|
6270
|
+
if (tokens.length === 0) {
|
|
6271
|
+
return getEmptyTextNode();
|
|
6272
|
+
}
|
|
6273
|
+
const nodes = [];
|
|
6274
|
+
let paragraphLines = [];
|
|
6275
|
+
let listItems = [];
|
|
6276
|
+
let listType = '';
|
|
6277
|
+
const flushParagraph = () => {
|
|
6278
|
+
if (paragraphLines.length === 0) {
|
|
6279
|
+
return;
|
|
6280
|
+
}
|
|
6281
|
+
nodes.push({
|
|
6282
|
+
children: parseInlineNodes(paragraphLines.join('\n')),
|
|
6283
|
+
type: 'text'
|
|
6284
|
+
});
|
|
6285
|
+
paragraphLines = [];
|
|
6286
|
+
};
|
|
6287
|
+
const flushList = () => {
|
|
6288
|
+
if (listItems.length === 0) {
|
|
6289
|
+
return;
|
|
6290
|
+
}
|
|
6291
|
+
nodes.push({
|
|
6292
|
+
items: listItems,
|
|
6293
|
+
type: listType || 'ordered-list'
|
|
6294
|
+
});
|
|
6295
|
+
listItems = [];
|
|
6296
|
+
listType = '';
|
|
6297
|
+
};
|
|
6298
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
6299
|
+
const token = tokens[i];
|
|
6300
|
+
if (token.type === 'blank-line') {
|
|
6301
|
+
flushList();
|
|
6302
|
+
flushParagraph();
|
|
6303
|
+
continue;
|
|
6304
|
+
}
|
|
6305
|
+
if (token.type === 'code-block') {
|
|
6306
|
+
flushList();
|
|
6307
|
+
flushParagraph();
|
|
6308
|
+
if (token.language) {
|
|
6309
|
+
nodes.push({
|
|
6310
|
+
language: token.language,
|
|
6311
|
+
text: token.text,
|
|
6312
|
+
type: 'code-block'
|
|
6313
|
+
});
|
|
6314
|
+
} else {
|
|
6315
|
+
nodes.push({
|
|
6316
|
+
text: token.text,
|
|
5996
6317
|
type: 'code-block'
|
|
5997
6318
|
});
|
|
5998
6319
|
}
|
|
@@ -6007,6 +6328,24 @@ const parseBlockTokens = tokens => {
|
|
|
6007
6328
|
});
|
|
6008
6329
|
continue;
|
|
6009
6330
|
}
|
|
6331
|
+
if (token.type === 'blockquote-line') {
|
|
6332
|
+
flushList();
|
|
6333
|
+
flushParagraph();
|
|
6334
|
+
const lines = [];
|
|
6335
|
+
while (i < tokens.length && tokens[i].type === 'blockquote-line') {
|
|
6336
|
+
const quoteToken = tokens[i];
|
|
6337
|
+
if (quoteToken.type === 'blockquote-line') {
|
|
6338
|
+
lines.push(quoteToken.text);
|
|
6339
|
+
}
|
|
6340
|
+
i++;
|
|
6341
|
+
}
|
|
6342
|
+
i--;
|
|
6343
|
+
nodes.push({
|
|
6344
|
+
children: parseBlockTokens(scanBlockTokens(lines.join('\n'))),
|
|
6345
|
+
type: 'blockquote'
|
|
6346
|
+
});
|
|
6347
|
+
continue;
|
|
6348
|
+
}
|
|
6010
6349
|
if (token.type === 'table-row-line') {
|
|
6011
6350
|
const expectedColumns = token.cells.length;
|
|
6012
6351
|
if (isTableSeparatorToken(tokens[i + 1], expectedColumns)) {
|
|
@@ -6093,190 +6432,6 @@ const parseBlockTokens = tokens => {
|
|
|
6093
6432
|
return nodes.length === 0 ? getEmptyTextNode() : nodes;
|
|
6094
6433
|
};
|
|
6095
6434
|
|
|
6096
|
-
const markdownMathBlockDelimiter = '$$';
|
|
6097
|
-
const normalizeEscapedNewlines = value => {
|
|
6098
|
-
if (value.includes('\\n')) {
|
|
6099
|
-
return value.replaceAll(/\\r\\n|\\n/g, '\n');
|
|
6100
|
-
}
|
|
6101
|
-
return value;
|
|
6102
|
-
};
|
|
6103
|
-
const normalizeInlineTables = value => {
|
|
6104
|
-
return value.split(/\r?\n/).map(line => {
|
|
6105
|
-
if (!line.includes('|')) {
|
|
6106
|
-
return line;
|
|
6107
|
-
}
|
|
6108
|
-
if (!/\|\s*[-:]{3,}/.test(line)) {
|
|
6109
|
-
return line;
|
|
6110
|
-
}
|
|
6111
|
-
return line.replaceAll(/\|\s+\|/g, '|\n|');
|
|
6112
|
-
}).join('\n');
|
|
6113
|
-
};
|
|
6114
|
-
const parseHeadingLine = line => {
|
|
6115
|
-
const trimmedStart = line.trimStart();
|
|
6116
|
-
let index = 0;
|
|
6117
|
-
while (index < trimmedStart.length && trimmedStart[index] === '#') {
|
|
6118
|
-
index++;
|
|
6119
|
-
}
|
|
6120
|
-
if (index === 0 || index > 6) {
|
|
6121
|
-
return undefined;
|
|
6122
|
-
}
|
|
6123
|
-
if (trimmedStart[index] !== ' ') {
|
|
6124
|
-
return undefined;
|
|
6125
|
-
}
|
|
6126
|
-
const text = trimmedStart.slice(index).trimStart();
|
|
6127
|
-
return {
|
|
6128
|
-
level: index,
|
|
6129
|
-
text
|
|
6130
|
-
};
|
|
6131
|
-
};
|
|
6132
|
-
const parseOrderedListItemLine = line => {
|
|
6133
|
-
let index = 0;
|
|
6134
|
-
while (index < line.length && line[index] === ' ') {
|
|
6135
|
-
index++;
|
|
6136
|
-
}
|
|
6137
|
-
const firstDigit = index;
|
|
6138
|
-
while (index < line.length && line[index] >= '0' && line[index] <= '9') {
|
|
6139
|
-
index++;
|
|
6140
|
-
}
|
|
6141
|
-
if (index === firstDigit || line[index] !== '.') {
|
|
6142
|
-
return undefined;
|
|
6143
|
-
}
|
|
6144
|
-
index++;
|
|
6145
|
-
if (line[index] !== ' ') {
|
|
6146
|
-
return undefined;
|
|
6147
|
-
}
|
|
6148
|
-
while (index < line.length && line[index] === ' ') {
|
|
6149
|
-
index++;
|
|
6150
|
-
}
|
|
6151
|
-
return {
|
|
6152
|
-
text: line.slice(index)
|
|
6153
|
-
};
|
|
6154
|
-
};
|
|
6155
|
-
const parseUnorderedListItemLine = line => {
|
|
6156
|
-
let indentation = 0;
|
|
6157
|
-
while (indentation < line.length && line[indentation] === ' ') {
|
|
6158
|
-
indentation++;
|
|
6159
|
-
}
|
|
6160
|
-
const marker = line[indentation];
|
|
6161
|
-
if (marker !== '-' && marker !== '*') {
|
|
6162
|
-
return undefined;
|
|
6163
|
-
}
|
|
6164
|
-
let index = indentation + 1;
|
|
6165
|
-
if (line[index] !== ' ') {
|
|
6166
|
-
return undefined;
|
|
6167
|
-
}
|
|
6168
|
-
while (index < line.length && line[index] === ' ') {
|
|
6169
|
-
index++;
|
|
6170
|
-
}
|
|
6171
|
-
return {
|
|
6172
|
-
indentation,
|
|
6173
|
-
text: line.slice(index)
|
|
6174
|
-
};
|
|
6175
|
-
};
|
|
6176
|
-
const isTableRow = line => {
|
|
6177
|
-
const trimmed = line.trim();
|
|
6178
|
-
if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) {
|
|
6179
|
-
return false;
|
|
6180
|
-
}
|
|
6181
|
-
return trimmed.length > 2 && trimmed.slice(1, -1).includes('|');
|
|
6182
|
-
};
|
|
6183
|
-
const getTableCells = line => {
|
|
6184
|
-
const trimmed = line.trim();
|
|
6185
|
-
return trimmed.slice(1, -1).split('|').map(part => part.trim());
|
|
6186
|
-
};
|
|
6187
|
-
const scanBlockTokens = rawMessage => {
|
|
6188
|
-
const normalizedMessage = normalizeInlineTables(normalizeEscapedNewlines(rawMessage));
|
|
6189
|
-
const lines = normalizedMessage.split(/\r?\n/);
|
|
6190
|
-
const tokens = [];
|
|
6191
|
-
for (let i = 0; i < lines.length; i++) {
|
|
6192
|
-
const line = lines[i];
|
|
6193
|
-
const trimmed = line.trim();
|
|
6194
|
-
if (!trimmed) {
|
|
6195
|
-
tokens.push({
|
|
6196
|
-
type: 'blank-line'
|
|
6197
|
-
});
|
|
6198
|
-
continue;
|
|
6199
|
-
}
|
|
6200
|
-
if (trimmed.startsWith('```')) {
|
|
6201
|
-
const language = trimmed.slice(3).trim();
|
|
6202
|
-
const codeLines = [];
|
|
6203
|
-
i++;
|
|
6204
|
-
while (i < lines.length && !lines[i].trim().startsWith('```')) {
|
|
6205
|
-
codeLines.push(lines[i]);
|
|
6206
|
-
i++;
|
|
6207
|
-
}
|
|
6208
|
-
if (language) {
|
|
6209
|
-
tokens.push({
|
|
6210
|
-
language,
|
|
6211
|
-
text: codeLines.join('\n'),
|
|
6212
|
-
type: 'code-block'
|
|
6213
|
-
});
|
|
6214
|
-
} else {
|
|
6215
|
-
tokens.push({
|
|
6216
|
-
text: codeLines.join('\n'),
|
|
6217
|
-
type: 'code-block'
|
|
6218
|
-
});
|
|
6219
|
-
}
|
|
6220
|
-
continue;
|
|
6221
|
-
}
|
|
6222
|
-
if (trimmed === markdownMathBlockDelimiter) {
|
|
6223
|
-
const endIndex = lines.findIndex((candidate, index) => {
|
|
6224
|
-
if (index <= i) {
|
|
6225
|
-
return false;
|
|
6226
|
-
}
|
|
6227
|
-
return candidate.trim() === markdownMathBlockDelimiter;
|
|
6228
|
-
});
|
|
6229
|
-
if (endIndex !== -1) {
|
|
6230
|
-
tokens.push({
|
|
6231
|
-
text: lines.slice(i + 1, endIndex).join('\n').trim(),
|
|
6232
|
-
type: 'math-block'
|
|
6233
|
-
});
|
|
6234
|
-
i = endIndex;
|
|
6235
|
-
continue;
|
|
6236
|
-
}
|
|
6237
|
-
}
|
|
6238
|
-
const heading = parseHeadingLine(line);
|
|
6239
|
-
if (heading) {
|
|
6240
|
-
tokens.push({
|
|
6241
|
-
level: heading.level,
|
|
6242
|
-
text: heading.text,
|
|
6243
|
-
type: 'heading-line'
|
|
6244
|
-
});
|
|
6245
|
-
continue;
|
|
6246
|
-
}
|
|
6247
|
-
const ordered = parseOrderedListItemLine(line);
|
|
6248
|
-
if (ordered) {
|
|
6249
|
-
tokens.push({
|
|
6250
|
-
text: ordered.text,
|
|
6251
|
-
type: 'ordered-list-item-line'
|
|
6252
|
-
});
|
|
6253
|
-
continue;
|
|
6254
|
-
}
|
|
6255
|
-
const unordered = parseUnorderedListItemLine(line);
|
|
6256
|
-
if (unordered) {
|
|
6257
|
-
tokens.push({
|
|
6258
|
-
indentation: unordered.indentation,
|
|
6259
|
-
text: unordered.text,
|
|
6260
|
-
type: 'unordered-list-item-line'
|
|
6261
|
-
});
|
|
6262
|
-
continue;
|
|
6263
|
-
}
|
|
6264
|
-
if (isTableRow(line)) {
|
|
6265
|
-
tokens.push({
|
|
6266
|
-
cells: getTableCells(line),
|
|
6267
|
-
line,
|
|
6268
|
-
type: 'table-row-line'
|
|
6269
|
-
});
|
|
6270
|
-
continue;
|
|
6271
|
-
}
|
|
6272
|
-
tokens.push({
|
|
6273
|
-
text: line,
|
|
6274
|
-
type: 'paragraph-line'
|
|
6275
|
-
});
|
|
6276
|
-
}
|
|
6277
|
-
return tokens;
|
|
6278
|
-
};
|
|
6279
|
-
|
|
6280
6435
|
const parseMessageContent = rawMessage => {
|
|
6281
6436
|
return parseBlockTokens(scanBlockTokens(rawMessage));
|
|
6282
6437
|
};
|
|
@@ -6313,6 +6468,13 @@ const parseMathInline = async children => {
|
|
|
6313
6468
|
});
|
|
6314
6469
|
continue;
|
|
6315
6470
|
}
|
|
6471
|
+
if (child.type === 'strikethrough') {
|
|
6472
|
+
nextChildren.push({
|
|
6473
|
+
...child,
|
|
6474
|
+
children: await parseMathInline(child.children)
|
|
6475
|
+
});
|
|
6476
|
+
continue;
|
|
6477
|
+
}
|
|
6316
6478
|
nextChildren.push(child);
|
|
6317
6479
|
}
|
|
6318
6480
|
return nextChildren;
|
|
@@ -6341,60 +6503,69 @@ const parseMathTableCell = async cell => {
|
|
|
6341
6503
|
children: await parseMathInline(cell.children)
|
|
6342
6504
|
};
|
|
6343
6505
|
};
|
|
6344
|
-
const
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6506
|
+
const parseMathNode = async node => {
|
|
6507
|
+
if (node.type === 'math-block') {
|
|
6508
|
+
const dom = await getMathBlockDom(node);
|
|
6509
|
+
return {
|
|
6510
|
+
dom,
|
|
6511
|
+
type: 'math-block-dom'
|
|
6512
|
+
};
|
|
6513
|
+
}
|
|
6514
|
+
if (node.type === 'text' || node.type === 'heading') {
|
|
6515
|
+
return {
|
|
6516
|
+
...node,
|
|
6517
|
+
children: await parseMathInline(node.children)
|
|
6518
|
+
};
|
|
6519
|
+
}
|
|
6520
|
+
if (node.type === 'blockquote') {
|
|
6521
|
+
const children = [];
|
|
6522
|
+
for (const child of node.children) {
|
|
6523
|
+
children.push(await parseMathNode(child));
|
|
6362
6524
|
}
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
continue;
|
|
6525
|
+
return {
|
|
6526
|
+
...node,
|
|
6527
|
+
children
|
|
6528
|
+
};
|
|
6529
|
+
}
|
|
6530
|
+
if (node.type === 'ordered-list' || node.type === 'unordered-list') {
|
|
6531
|
+
const items = [];
|
|
6532
|
+
for (const item of node.items) {
|
|
6533
|
+
items.push(await parseMathListItem(item));
|
|
6373
6534
|
}
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6535
|
+
return {
|
|
6536
|
+
...node,
|
|
6537
|
+
items
|
|
6538
|
+
};
|
|
6539
|
+
}
|
|
6540
|
+
if (node.type === 'table') {
|
|
6541
|
+
const headers = [];
|
|
6542
|
+
for (const header of node.headers) {
|
|
6543
|
+
headers.push(await parseMathTableCell(header));
|
|
6544
|
+
}
|
|
6545
|
+
const rows = [];
|
|
6546
|
+
for (const row of node.rows) {
|
|
6547
|
+
const cells = [];
|
|
6548
|
+
for (const cell of row.cells) {
|
|
6549
|
+
cells.push(await parseMathTableCell(cell));
|
|
6389
6550
|
}
|
|
6390
|
-
|
|
6391
|
-
...
|
|
6392
|
-
|
|
6393
|
-
rows
|
|
6551
|
+
rows.push({
|
|
6552
|
+
...row,
|
|
6553
|
+
cells
|
|
6394
6554
|
});
|
|
6395
|
-
continue;
|
|
6396
6555
|
}
|
|
6397
|
-
|
|
6556
|
+
return {
|
|
6557
|
+
...node,
|
|
6558
|
+
headers,
|
|
6559
|
+
rows
|
|
6560
|
+
};
|
|
6561
|
+
}
|
|
6562
|
+
return node;
|
|
6563
|
+
};
|
|
6564
|
+
const parseMessage = async rawMessage => {
|
|
6565
|
+
const parsedContent = parseMessageContent(rawMessage);
|
|
6566
|
+
const nextParsedContent = [];
|
|
6567
|
+
for (const node of parsedContent) {
|
|
6568
|
+
nextParsedContent.push(await parseMathNode(node));
|
|
6398
6569
|
}
|
|
6399
6570
|
return nextParsedContent;
|
|
6400
6571
|
};
|
|
@@ -6591,6 +6762,7 @@ Assistant: ${assistantText}`;
|
|
|
6591
6762
|
streamingEnabled: false,
|
|
6592
6763
|
useChatCoordinatorWorker: state.useChatCoordinatorWorker,
|
|
6593
6764
|
useChatNetworkWorkerForRequests: state.useChatNetworkWorkerForRequests,
|
|
6765
|
+
useChatToolWorker: state.useChatToolWorker,
|
|
6594
6766
|
useMockApi,
|
|
6595
6767
|
userText: titlePrompt,
|
|
6596
6768
|
webSearchEnabled: false
|
|
@@ -6649,6 +6821,12 @@ const getMentionContextMessage = async value => {
|
|
|
6649
6821
|
};
|
|
6650
6822
|
};
|
|
6651
6823
|
|
|
6824
|
+
const AutoScrollTopA = Number.MAX_SAFE_INTEGER;
|
|
6825
|
+
const AutoScrollTopB = Number.MAX_SAFE_INTEGER - 1;
|
|
6826
|
+
const getNextAutoScrollTop = currentScrollTop => {
|
|
6827
|
+
return currentScrollTop === AutoScrollTopA ? AutoScrollTopB : AutoScrollTopA;
|
|
6828
|
+
};
|
|
6829
|
+
|
|
6652
6830
|
const slashCommandRegex = /^\/(clear|export|help|new)(?:\s+.*)?$/;
|
|
6653
6831
|
const getSlashCommand = value => {
|
|
6654
6832
|
const trimmed = value.trim();
|
|
@@ -6738,6 +6916,9 @@ const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTex
|
|
|
6738
6916
|
const updated = await updateMessageTextInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, updatedText, true);
|
|
6739
6917
|
const nextState = {
|
|
6740
6918
|
...handleTextChunkState.latestState,
|
|
6919
|
+
...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
|
|
6920
|
+
messagesScrollTop: getNextAutoScrollTop(handleTextChunkState.latestState.messagesScrollTop)
|
|
6921
|
+
} : {}),
|
|
6741
6922
|
parsedMessages: updated.parsedMessages,
|
|
6742
6923
|
sessions: updated.sessions
|
|
6743
6924
|
};
|
|
@@ -6767,6 +6948,9 @@ const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls,
|
|
|
6767
6948
|
const updated = updateMessageToolCallsInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, toolCalls);
|
|
6768
6949
|
const nextState = {
|
|
6769
6950
|
...handleTextChunkState.latestState,
|
|
6951
|
+
...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
|
|
6952
|
+
messagesScrollTop: getNextAutoScrollTop(handleTextChunkState.latestState.messagesScrollTop)
|
|
6953
|
+
} : {}),
|
|
6770
6954
|
parsedMessages: updated.parsedMessages,
|
|
6771
6955
|
sessions: updated.sessions
|
|
6772
6956
|
};
|
|
@@ -6832,6 +7016,15 @@ const updateSessionTitle = (sessions, selectedSessionId, title) => {
|
|
|
6832
7016
|
});
|
|
6833
7017
|
};
|
|
6834
7018
|
|
|
7019
|
+
const withUpdatedMessageScrollTop = state => {
|
|
7020
|
+
if (!state.messagesAutoScrollEnabled) {
|
|
7021
|
+
return state;
|
|
7022
|
+
}
|
|
7023
|
+
return {
|
|
7024
|
+
...state,
|
|
7025
|
+
messagesScrollTop: getNextAutoScrollTop(state.messagesScrollTop)
|
|
7026
|
+
};
|
|
7027
|
+
};
|
|
6835
7028
|
const handleSubmit = async state => {
|
|
6836
7029
|
const {
|
|
6837
7030
|
aiSessionTitleGenerationEnabled,
|
|
@@ -6854,6 +7047,7 @@ const handleSubmit = async state => {
|
|
|
6854
7047
|
streamingEnabled,
|
|
6855
7048
|
useChatCoordinatorWorker,
|
|
6856
7049
|
useChatNetworkWorkerForRequests,
|
|
7050
|
+
useChatToolWorker,
|
|
6857
7051
|
useMockApi,
|
|
6858
7052
|
viewMode,
|
|
6859
7053
|
webSearchEnabled
|
|
@@ -6922,7 +7116,7 @@ const handleSubmit = async state => {
|
|
|
6922
7116
|
title: `Chat ${workingSessions.length + 1}`
|
|
6923
7117
|
};
|
|
6924
7118
|
await saveChatSession(newSession);
|
|
6925
|
-
optimisticState = focusInput({
|
|
7119
|
+
optimisticState = withUpdatedMessageScrollTop(focusInput({
|
|
6926
7120
|
...state,
|
|
6927
7121
|
composerHeight: getMinComposerHeightForState(state),
|
|
6928
7122
|
composerValue: '',
|
|
@@ -6933,7 +7127,7 @@ const handleSubmit = async state => {
|
|
|
6933
7127
|
selectedSessionId: newSessionId,
|
|
6934
7128
|
sessions: [...workingSessions, newSession],
|
|
6935
7129
|
viewMode: 'detail'
|
|
6936
|
-
});
|
|
7130
|
+
}));
|
|
6937
7131
|
} else {
|
|
6938
7132
|
await appendChatViewEvent({
|
|
6939
7133
|
sessionId: selectedSessionId,
|
|
@@ -6947,7 +7141,7 @@ const handleSubmit = async state => {
|
|
|
6947
7141
|
if (selectedSession) {
|
|
6948
7142
|
await saveChatSession(selectedSession);
|
|
6949
7143
|
}
|
|
6950
|
-
optimisticState = focusInput({
|
|
7144
|
+
optimisticState = withUpdatedMessageScrollTop(focusInput({
|
|
6951
7145
|
...state,
|
|
6952
7146
|
composerHeight: getMinComposerHeightForState(state),
|
|
6953
7147
|
composerValue: '',
|
|
@@ -6956,7 +7150,7 @@ const handleSubmit = async state => {
|
|
|
6956
7150
|
nextMessageId: nextMessageId + 1,
|
|
6957
7151
|
parsedMessages,
|
|
6958
7152
|
sessions: updatedSessions
|
|
6959
|
-
});
|
|
7153
|
+
}));
|
|
6960
7154
|
}
|
|
6961
7155
|
set$1(state.uid, state, optimisticState);
|
|
6962
7156
|
// @ts-ignore
|
|
@@ -7016,6 +7210,7 @@ const handleSubmit = async state => {
|
|
|
7016
7210
|
streamingEnabled,
|
|
7017
7211
|
useChatCoordinatorWorker,
|
|
7018
7212
|
useChatNetworkWorkerForRequests,
|
|
7213
|
+
useChatToolWorker,
|
|
7019
7214
|
useMockApi,
|
|
7020
7215
|
userText,
|
|
7021
7216
|
webSearchEnabled
|
|
@@ -7046,12 +7241,12 @@ const handleSubmit = async state => {
|
|
|
7046
7241
|
if (selectedSession) {
|
|
7047
7242
|
await saveChatSession(selectedSession);
|
|
7048
7243
|
}
|
|
7049
|
-
return focusInput({
|
|
7244
|
+
return withUpdatedMessageScrollTop(focusInput({
|
|
7050
7245
|
...latestState,
|
|
7051
7246
|
nextMessageId: latestState.nextMessageId + 1,
|
|
7052
7247
|
parsedMessages: finalParsedMessages,
|
|
7053
7248
|
sessions: updatedSessions
|
|
7054
|
-
});
|
|
7249
|
+
}));
|
|
7055
7250
|
};
|
|
7056
7251
|
|
|
7057
7252
|
const handleClickSend = async state => {
|
|
@@ -7313,7 +7508,8 @@ const handleClickDictationButton = async state => {
|
|
|
7313
7508
|
};
|
|
7314
7509
|
|
|
7315
7510
|
const handleClickNew = async state => {
|
|
7316
|
-
|
|
7511
|
+
const newState = await createSession(state);
|
|
7512
|
+
return focusInput(newState);
|
|
7317
7513
|
};
|
|
7318
7514
|
|
|
7319
7515
|
const handleClickReadFile = async uri => {
|
|
@@ -7329,7 +7525,6 @@ const handleClickSessionDebug = async state => {
|
|
|
7329
7525
|
};
|
|
7330
7526
|
|
|
7331
7527
|
const handleClickSettings = async () => {
|
|
7332
|
-
// TODO
|
|
7333
7528
|
await invoke$1('Main.openUri', 'app://settings.json');
|
|
7334
7529
|
};
|
|
7335
7530
|
|
|
@@ -7574,12 +7769,14 @@ const handleChatListScroll = async (state, chatListScrollTop) => {
|
|
|
7574
7769
|
chatListScrollTop
|
|
7575
7770
|
};
|
|
7576
7771
|
};
|
|
7577
|
-
const handleMessagesScroll = async (state, messagesScrollTop) => {
|
|
7578
|
-
|
|
7772
|
+
const handleMessagesScroll = async (state, messagesScrollTop, scrollHeight, clientHeight) => {
|
|
7773
|
+
const messagesAutoScrollEnabled = messagesScrollTop + clientHeight >= scrollHeight - 8;
|
|
7774
|
+
if (state.messagesScrollTop === messagesScrollTop && state.messagesAutoScrollEnabled === messagesAutoScrollEnabled) {
|
|
7579
7775
|
return state;
|
|
7580
7776
|
}
|
|
7581
7777
|
return {
|
|
7582
7778
|
...state,
|
|
7779
|
+
messagesAutoScrollEnabled,
|
|
7583
7780
|
messagesScrollTop
|
|
7584
7781
|
};
|
|
7585
7782
|
};
|
|
@@ -7612,7 +7809,7 @@ const createExtensionHostRpc = async () => {
|
|
|
7612
7809
|
|
|
7613
7810
|
const initialize = async () => {
|
|
7614
7811
|
const rpc = await createExtensionHostRpc();
|
|
7615
|
-
set$
|
|
7812
|
+
set$4(rpc);
|
|
7616
7813
|
};
|
|
7617
7814
|
|
|
7618
7815
|
const isObject = value => {
|
|
@@ -7771,9 +7968,9 @@ const loadStreamingEnabled = async () => {
|
|
|
7771
7968
|
const loadUseChatCoordinatorWorker = async () => {
|
|
7772
7969
|
try {
|
|
7773
7970
|
const savedUseChatCoordinatorWorker = await get('chatView.useChatCoordinatorWorker');
|
|
7774
|
-
return typeof savedUseChatCoordinatorWorker === 'boolean' ? savedUseChatCoordinatorWorker :
|
|
7971
|
+
return typeof savedUseChatCoordinatorWorker === 'boolean' ? savedUseChatCoordinatorWorker : true;
|
|
7775
7972
|
} catch {
|
|
7776
|
-
return
|
|
7973
|
+
return true;
|
|
7777
7974
|
}
|
|
7778
7975
|
};
|
|
7779
7976
|
|
|
@@ -7795,6 +7992,15 @@ const loadUseChatNetworkWorkerForRequests = async () => {
|
|
|
7795
7992
|
}
|
|
7796
7993
|
};
|
|
7797
7994
|
|
|
7995
|
+
const loadUseChatToolWorker = async () => {
|
|
7996
|
+
try {
|
|
7997
|
+
const savedUseChatToolWorker = await get('chatView.useChatToolWorker');
|
|
7998
|
+
return typeof savedUseChatToolWorker === 'boolean' ? savedUseChatToolWorker : false;
|
|
7999
|
+
} catch {
|
|
8000
|
+
return false;
|
|
8001
|
+
}
|
|
8002
|
+
};
|
|
8003
|
+
|
|
7798
8004
|
const loadVoiceDictationEnabled = async () => {
|
|
7799
8005
|
try {
|
|
7800
8006
|
const savedVoiceDictationEnabled = await get('chatView.voiceDictationEnabled');
|
|
@@ -7805,7 +8011,7 @@ const loadVoiceDictationEnabled = async () => {
|
|
|
7805
8011
|
};
|
|
7806
8012
|
|
|
7807
8013
|
const loadPreferences = async () => {
|
|
7808
|
-
const [aiSessionTitleGenerationEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatNetworkWorkerForRequests, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatNetworkWorkerForRequests(), loadVoiceDictationEnabled()]);
|
|
8014
|
+
const [aiSessionTitleGenerationEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatNetworkWorkerForRequests, useChatToolWorker, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatNetworkWorkerForRequests(), loadUseChatToolWorker(), loadVoiceDictationEnabled()]);
|
|
7809
8015
|
return {
|
|
7810
8016
|
aiSessionTitleGenerationEnabled,
|
|
7811
8017
|
composerDropEnabled,
|
|
@@ -7817,6 +8023,7 @@ const loadPreferences = async () => {
|
|
|
7817
8023
|
useChatCoordinatorWorker,
|
|
7818
8024
|
useChatMathWorker,
|
|
7819
8025
|
useChatNetworkWorkerForRequests,
|
|
8026
|
+
useChatToolWorker,
|
|
7820
8027
|
voiceDictationEnabled
|
|
7821
8028
|
};
|
|
7822
8029
|
};
|
|
@@ -7957,6 +8164,7 @@ const loadContent = async (state, savedState) => {
|
|
|
7957
8164
|
useChatCoordinatorWorker,
|
|
7958
8165
|
useChatMathWorker,
|
|
7959
8166
|
useChatNetworkWorkerForRequests,
|
|
8167
|
+
useChatToolWorker,
|
|
7960
8168
|
voiceDictationEnabled
|
|
7961
8169
|
} = await loadPreferences();
|
|
7962
8170
|
const legacySavedSessions = getSavedSessions(savedState);
|
|
@@ -8033,6 +8241,7 @@ const loadContent = async (state, savedState) => {
|
|
|
8033
8241
|
useChatCoordinatorWorker,
|
|
8034
8242
|
useChatMathWorker,
|
|
8035
8243
|
useChatNetworkWorkerForRequests,
|
|
8244
|
+
useChatToolWorker,
|
|
8036
8245
|
viewMode,
|
|
8037
8246
|
voiceDictationEnabled
|
|
8038
8247
|
};
|
|
@@ -8343,11 +8552,21 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
|
|
|
8343
8552
|
vertical-align: middle;
|
|
8344
8553
|
}
|
|
8345
8554
|
|
|
8555
|
+
.MarkdownQuote {
|
|
8556
|
+
border-left: 3px solid var(--ColorBorder, #3a3d41);
|
|
8557
|
+
margin: 8px 0;
|
|
8558
|
+
padding-left: 12px;
|
|
8559
|
+
}
|
|
8560
|
+
|
|
8346
8561
|
.MarkdownMathBlock {
|
|
8347
8562
|
margin: 8px 0;
|
|
8348
8563
|
overflow-x: auto;
|
|
8349
8564
|
overflow-y: hidden;
|
|
8350
8565
|
}
|
|
8566
|
+
|
|
8567
|
+
.StrikeThrough {
|
|
8568
|
+
text-decoration: line-through;
|
|
8569
|
+
}
|
|
8351
8570
|
`;
|
|
8352
8571
|
if (!renderHtmlCss.trim()) {
|
|
8353
8572
|
return baseCss;
|
|
@@ -8418,6 +8637,7 @@ const ButtonSecondary = 'ButtonSecondary';
|
|
|
8418
8637
|
const Empty = '';
|
|
8419
8638
|
const FileIcon = 'FileIcon';
|
|
8420
8639
|
const IconButton = 'IconButton';
|
|
8640
|
+
const ImageElement = 'ImageElement';
|
|
8421
8641
|
const InputBox = 'InputBox';
|
|
8422
8642
|
const Label = 'Label';
|
|
8423
8643
|
const LabelDetail = 'LabelDetail';
|
|
@@ -8439,6 +8659,7 @@ const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
|
|
|
8439
8659
|
const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
|
|
8440
8660
|
const ProjectSidebar = 'ProjectSidebar';
|
|
8441
8661
|
const Markdown = 'Markdown';
|
|
8662
|
+
const MarkdownQuote = 'MarkdownQuote';
|
|
8442
8663
|
const MarkdownMathBlock = 'MarkdownMathBlock';
|
|
8443
8664
|
const MarkdownTable = 'MarkdownTable';
|
|
8444
8665
|
const Message = 'Message';
|
|
@@ -8470,6 +8691,7 @@ const TokenAttribute = 'TokenAttribute';
|
|
|
8470
8691
|
const TokenValue = 'TokenValue';
|
|
8471
8692
|
const TokenProperty = 'TokenProperty';
|
|
8472
8693
|
const Select = 'Select';
|
|
8694
|
+
const StrikeThrough = 'StrikeThrough';
|
|
8473
8695
|
const Viewlet = 'Viewlet';
|
|
8474
8696
|
const ChatWelcomeMessage = 'ChatWelcomeMessage';
|
|
8475
8697
|
|
|
@@ -8544,7 +8766,6 @@ const getSendButtonDom = (isSendDisabled, voiceDictationEnabled) => {
|
|
|
8544
8766
|
className: IconButton,
|
|
8545
8767
|
name: Dictate,
|
|
8546
8768
|
onClick: HandleClickDictationButton,
|
|
8547
|
-
role: Button$2,
|
|
8548
8769
|
title: startVoiceDictation(),
|
|
8549
8770
|
type: Button$1
|
|
8550
8771
|
}, {
|
|
@@ -8557,7 +8778,6 @@ const getSendButtonDom = (isSendDisabled, voiceDictationEnabled) => {
|
|
|
8557
8778
|
className: sendButtonClassName,
|
|
8558
8779
|
disabled: isSendDisabled,
|
|
8559
8780
|
name: Send,
|
|
8560
|
-
role: Button$2,
|
|
8561
8781
|
title: sendMessage(),
|
|
8562
8782
|
type: Button$1
|
|
8563
8783
|
}, {
|
|
@@ -8602,7 +8822,7 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
|
|
|
8602
8822
|
}, text(usageLabel)];
|
|
8603
8823
|
};
|
|
8604
8824
|
|
|
8605
|
-
const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax,
|
|
8825
|
+
const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled = false) => {
|
|
8606
8826
|
const isSendDisabled = composerValue.trim() === '';
|
|
8607
8827
|
const controlsCount = usageOverviewEnabled ? 3 : 2;
|
|
8608
8828
|
return [{
|
|
@@ -8630,10 +8850,25 @@ const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOvervie
|
|
|
8630
8850
|
}, ...getChatSelectVirtualDom(models, selectedModelId), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
|
|
8631
8851
|
};
|
|
8632
8852
|
|
|
8853
|
+
const getImageAltText = alt => {
|
|
8854
|
+
if (!alt.trim()) {
|
|
8855
|
+
return 'image could not be loaded';
|
|
8856
|
+
}
|
|
8857
|
+
return `${alt} (image could not be loaded)`;
|
|
8858
|
+
};
|
|
8633
8859
|
const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
|
|
8634
8860
|
if (inlineNode.type === 'text') {
|
|
8635
8861
|
return [text(inlineNode.text)];
|
|
8636
8862
|
}
|
|
8863
|
+
if (inlineNode.type === 'image') {
|
|
8864
|
+
return [{
|
|
8865
|
+
alt: getImageAltText(inlineNode.alt),
|
|
8866
|
+
childCount: 0,
|
|
8867
|
+
className: ImageElement,
|
|
8868
|
+
src: inlineNode.src,
|
|
8869
|
+
type: Img
|
|
8870
|
+
}];
|
|
8871
|
+
}
|
|
8637
8872
|
if (inlineNode.type === 'bold') {
|
|
8638
8873
|
return [{
|
|
8639
8874
|
childCount: inlineNode.children.length,
|
|
@@ -8646,6 +8881,13 @@ const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
|
|
|
8646
8881
|
type: Em
|
|
8647
8882
|
}, ...inlineNode.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
|
|
8648
8883
|
}
|
|
8884
|
+
if (inlineNode.type === 'strikethrough') {
|
|
8885
|
+
return [{
|
|
8886
|
+
childCount: inlineNode.children.length,
|
|
8887
|
+
className: StrikeThrough,
|
|
8888
|
+
type: Span
|
|
8889
|
+
}, ...inlineNode.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
|
|
8890
|
+
}
|
|
8649
8891
|
if (inlineNode.type === 'math-inline') {
|
|
8650
8892
|
const fallback = inlineNode.displayMode ? `$$${inlineNode.text}$$` : `$${inlineNode.text}$`;
|
|
8651
8893
|
return [text(fallback)];
|
|
@@ -8883,6 +9125,13 @@ const getHeadingDom = (node, useChatMathWorker) => {
|
|
|
8883
9125
|
type: getHeadingElementType(node.level)
|
|
8884
9126
|
}, ...node.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
|
|
8885
9127
|
};
|
|
9128
|
+
const getBlockQuoteDom = (node, useChatMathWorker) => {
|
|
9129
|
+
return [{
|
|
9130
|
+
childCount: node.children.length,
|
|
9131
|
+
className: MarkdownQuote,
|
|
9132
|
+
type: Div
|
|
9133
|
+
}, ...node.children.flatMap(child => getMessageNodeDom(child, useChatMathWorker))];
|
|
9134
|
+
};
|
|
8886
9135
|
const getMessageNodeDom = (node, useChatMathWorker = false) => {
|
|
8887
9136
|
if (node.type === 'text') {
|
|
8888
9137
|
return [{
|
|
@@ -8910,6 +9159,9 @@ const getMessageNodeDom = (node, useChatMathWorker = false) => {
|
|
|
8910
9159
|
if (node.type === 'heading') {
|
|
8911
9160
|
return getHeadingDom(node, useChatMathWorker);
|
|
8912
9161
|
}
|
|
9162
|
+
if (node.type === 'blockquote') {
|
|
9163
|
+
return getBlockQuoteDom(node, useChatMathWorker);
|
|
9164
|
+
}
|
|
8913
9165
|
if (node.type === 'ordered-list') {
|
|
8914
9166
|
return [{
|
|
8915
9167
|
childCount: node.items.length,
|
|
@@ -8984,7 +9236,7 @@ const getMissingOpenApiApiKeyDom = openApiApiKeyInput => {
|
|
|
8984
9236
|
inputPattern: '^sk-.+',
|
|
8985
9237
|
inputRequired: true,
|
|
8986
9238
|
inputValue: openApiApiKeyInput,
|
|
8987
|
-
openSettingsButtonName:
|
|
9239
|
+
openSettingsButtonName: OpenOpenApiApiKeyWebsite,
|
|
8988
9240
|
placeholder: openApiApiKeyPlaceholder(),
|
|
8989
9241
|
saveButtonName: SaveOpenApiApiKey,
|
|
8990
9242
|
saveButtonType: 'submit',
|
|
@@ -9715,14 +9967,14 @@ const getChatModeChatFocusVirtualDom = (sessions, selectedSessionId, composerVal
|
|
|
9715
9967
|
const messages = selectedSession ? selectedSession.messages : [];
|
|
9716
9968
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
9717
9969
|
return [{
|
|
9718
|
-
childCount: 4,
|
|
9970
|
+
childCount: isDropOverlayVisible ? 4 : 3,
|
|
9719
9971
|
className: mergeClassNames(Viewlet, Chat, 'ChatFocus'),
|
|
9720
9972
|
onDragEnter: HandleDragEnterChatView,
|
|
9721
9973
|
onDragOver: HandleDragOverChatView,
|
|
9722
9974
|
type: Div
|
|
9723
|
-
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax,
|
|
9975
|
+
}, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
9724
9976
|
childCount: 1,
|
|
9725
|
-
className: mergeClassNames(ChatViewDropOverlay,
|
|
9977
|
+
className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
|
|
9726
9978
|
name: ComposerDropTarget,
|
|
9727
9979
|
onDragLeave: HandleDragLeave,
|
|
9728
9980
|
onDragOver: HandleDragOver,
|
|
@@ -9731,7 +9983,7 @@ const getChatModeChatFocusVirtualDom = (sessions, selectedSessionId, composerVal
|
|
|
9731
9983
|
}, {
|
|
9732
9984
|
text: attachImageAsContext(),
|
|
9733
9985
|
type: Text
|
|
9734
|
-
}];
|
|
9986
|
+
}] : [])];
|
|
9735
9987
|
};
|
|
9736
9988
|
|
|
9737
9989
|
const getBackButtonVirtualDom = () => {
|
|
@@ -9822,14 +10074,14 @@ const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue,
|
|
|
9822
10074
|
const messages = selectedSession ? selectedSession.messages : [];
|
|
9823
10075
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
9824
10076
|
return [{
|
|
9825
|
-
childCount: 4,
|
|
10077
|
+
childCount: isDropOverlayVisible ? 4 : 3,
|
|
9826
10078
|
className: mergeClassNames(Viewlet, Chat),
|
|
9827
10079
|
onDragEnter: HandleDragEnterChatView,
|
|
9828
10080
|
onDragOver: HandleDragOverChatView,
|
|
9829
10081
|
type: Div
|
|
9830
|
-
}, ...getChatHeaderDomDetailMode(selectedSessionTitle), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax,
|
|
10082
|
+
}, ...getChatHeaderDomDetailMode(selectedSessionTitle), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
9831
10083
|
childCount: 1,
|
|
9832
|
-
className: mergeClassNames(ChatViewDropOverlay,
|
|
10084
|
+
className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
|
|
9833
10085
|
name: ComposerDropTarget,
|
|
9834
10086
|
onDragLeave: HandleDragLeave,
|
|
9835
10087
|
onDragOver: HandleDragOver,
|
|
@@ -9838,7 +10090,7 @@ const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue,
|
|
|
9838
10090
|
}, {
|
|
9839
10091
|
text: attachImageAsContext(),
|
|
9840
10092
|
type: Text
|
|
9841
|
-
}];
|
|
10093
|
+
}] : [])];
|
|
9842
10094
|
};
|
|
9843
10095
|
|
|
9844
10096
|
const getChatHeaderListModeDom = () => {
|
|
@@ -9911,14 +10163,14 @@ const getChatListDom = (sessions, selectedSessionId, chatListScrollTop = 0) => {
|
|
|
9911
10163
|
const getChatModeListVirtualDom = (sessions, selectedSessionId, composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, chatListScrollTop = 0, composerDropActive = false, composerDropEnabled = true, voiceDictationEnabled = false) => {
|
|
9912
10164
|
const isDropOverlayVisible = composerDropEnabled && composerDropActive;
|
|
9913
10165
|
return [{
|
|
9914
|
-
childCount: 4,
|
|
10166
|
+
childCount: isDropOverlayVisible ? 4 : 3,
|
|
9915
10167
|
className: mergeClassNames(Viewlet, Chat),
|
|
9916
10168
|
onDragEnter: HandleDragEnterChatView,
|
|
9917
10169
|
onDragOver: HandleDragOverChatView,
|
|
9918
10170
|
type: Div
|
|
9919
|
-
}, ...getChatHeaderListModeDom(), ...getChatListDom(sessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax,
|
|
10171
|
+
}, ...getChatHeaderListModeDom(), ...getChatListDom(sessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
|
|
9920
10172
|
childCount: 1,
|
|
9921
|
-
className: mergeClassNames(ChatViewDropOverlay,
|
|
10173
|
+
className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
|
|
9922
10174
|
name: ComposerDropTarget,
|
|
9923
10175
|
onDragLeave: HandleDragLeave,
|
|
9924
10176
|
onDragOver: HandleDragOver,
|
|
@@ -9927,7 +10179,7 @@ const getChatModeListVirtualDom = (sessions, selectedSessionId, composerValue, m
|
|
|
9927
10179
|
}, {
|
|
9928
10180
|
text: attachImageAsContext(),
|
|
9929
10181
|
type: Text
|
|
9930
|
-
}];
|
|
10182
|
+
}] : [])];
|
|
9931
10183
|
};
|
|
9932
10184
|
|
|
9933
10185
|
const getChatModeUnsupportedVirtualDom = () => {
|
|
@@ -10199,7 +10451,7 @@ const renderEventListeners = () => {
|
|
|
10199
10451
|
params: ['handleChatListScroll', 'event.target.scrollTop']
|
|
10200
10452
|
}, {
|
|
10201
10453
|
name: HandleMessagesScroll,
|
|
10202
|
-
params: ['handleMessagesScroll', 'event.target.scrollTop']
|
|
10454
|
+
params: ['handleMessagesScroll', 'event.target.scrollTop', 'event.target.scrollHeight', 'event.target.clientHeight']
|
|
10203
10455
|
}, {
|
|
10204
10456
|
name: HandleProjectListScroll,
|
|
10205
10457
|
params: ['handleProjectListScroll', 'event.target.scrollTop']
|
|
@@ -10458,18 +10710,40 @@ const initializeChatMathWorker = async () => {
|
|
|
10458
10710
|
commandMap: {},
|
|
10459
10711
|
send: sendMessagePortToChatMathWorker
|
|
10460
10712
|
});
|
|
10461
|
-
set$
|
|
10713
|
+
set$7(rpc);
|
|
10462
10714
|
};
|
|
10463
10715
|
|
|
10464
|
-
const send = port => {
|
|
10716
|
+
const send$1 = port => {
|
|
10465
10717
|
return sendMessagePortToChatNetworkWorker(port);
|
|
10466
10718
|
};
|
|
10467
10719
|
const initializeChatNetworkWorker = async () => {
|
|
10720
|
+
const rpc = await create$4({
|
|
10721
|
+
commandMap: {},
|
|
10722
|
+
send: send$1
|
|
10723
|
+
});
|
|
10724
|
+
set$6(rpc);
|
|
10725
|
+
};
|
|
10726
|
+
|
|
10727
|
+
const send = port => {
|
|
10728
|
+
return sendMessagePortToChatToolWorker(port);
|
|
10729
|
+
};
|
|
10730
|
+
const initializeChatToolWorker = async () => {
|
|
10468
10731
|
const rpc = await create$4({
|
|
10469
10732
|
commandMap: {},
|
|
10470
10733
|
send
|
|
10471
10734
|
});
|
|
10472
|
-
set$
|
|
10735
|
+
set$5(rpc);
|
|
10736
|
+
};
|
|
10737
|
+
|
|
10738
|
+
const sendMessagePortToOpenerWorker = async port => {
|
|
10739
|
+
await sendMessagePortToOpenerWorker$1(port, 0);
|
|
10740
|
+
};
|
|
10741
|
+
const initializeOpenerWorker = async () => {
|
|
10742
|
+
const rpc = await create$4({
|
|
10743
|
+
commandMap: {},
|
|
10744
|
+
send: sendMessagePortToOpenerWorker
|
|
10745
|
+
});
|
|
10746
|
+
set$3(rpc);
|
|
10473
10747
|
};
|
|
10474
10748
|
|
|
10475
10749
|
const listen = async () => {
|
|
@@ -10478,7 +10752,7 @@ const listen = async () => {
|
|
|
10478
10752
|
commandMap: commandMap
|
|
10479
10753
|
});
|
|
10480
10754
|
set$2(rpc);
|
|
10481
|
-
await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker(), initializeChatCoordinatorWorker()]);
|
|
10755
|
+
await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker(), initializeChatCoordinatorWorker(), initializeChatToolWorker(), initializeOpenerWorker()]);
|
|
10482
10756
|
};
|
|
10483
10757
|
|
|
10484
10758
|
const main = async () => {
|