@lvce-editor/chat-view 4.3.0 → 4.5.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.
@@ -851,7 +851,7 @@ const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer)
851
851
  const responseMessage = await promise;
852
852
  return unwrapJsonRpcResult(responseMessage);
853
853
  };
854
- const createRpc = ipc => {
854
+ const createRpc$1 = ipc => {
855
855
  const callbacks = Object.create(null);
856
856
  ipc._resolve = (id, response) => {
857
857
  const fn = callbacks[id];
@@ -931,7 +931,7 @@ const create$6 = async ({
931
931
  });
932
932
  const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
933
933
  handleIpc(ipc);
934
- const rpc = createRpc(ipc);
934
+ const rpc = createRpc$1(ipc);
935
935
  messagePort.start();
936
936
  return rpc;
937
937
  };
@@ -1002,7 +1002,7 @@ const create$3 = async ({
1002
1002
  register(commandMap);
1003
1003
  const ipc = await listen$1(IpcChildWithModuleWorkerAndMessagePort$1);
1004
1004
  handleIpc(ipc);
1005
- const rpc = createRpc(ipc);
1005
+ const rpc = createRpc$1(ipc);
1006
1006
  return rpc;
1007
1007
  };
1008
1008
 
@@ -1027,7 +1027,7 @@ const createMockRpc = ({
1027
1027
  };
1028
1028
 
1029
1029
  const rpcs = Object.create(null);
1030
- const set$4 = (id, rpc) => {
1030
+ const set$5 = (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$4(rpcId, mockRpc);
1063
+ set$5(rpcId, mockRpc);
1064
1064
  // @ts-ignore
1065
1065
  mockRpc[Symbol.dispose] = () => {
1066
1066
  remove(rpcId);
@@ -1069,15 +1069,15 @@ const create$2 = rpcId => {
1069
1069
  return mockRpc;
1070
1070
  },
1071
1071
  set(rpc) {
1072
- set$4(rpcId, rpc);
1072
+ set$5(rpcId, rpc);
1073
1073
  }
1074
1074
  };
1075
1075
  };
1076
1076
 
1077
1077
  const {
1078
- invoke: invoke$2,
1079
- set: set$3
1080
- } = create$2(6002);
1078
+ invoke: invoke$4,
1079
+ set: set$4
1080
+ } = create$2(6007);
1081
1081
 
1082
1082
  const Button$2 = 'button';
1083
1083
 
@@ -1146,6 +1146,7 @@ const Enter = 3;
1146
1146
 
1147
1147
  const Shift = 1 << 10 >>> 0;
1148
1148
 
1149
+ const ChatNetworkWorker = 6002;
1149
1150
  const ExtensionHostWorker = 44;
1150
1151
  const RendererWorker = 1;
1151
1152
 
@@ -1160,17 +1161,22 @@ const SetPatches = 'Viewlet.setPatches';
1160
1161
  const FocusChatInput = 8000;
1161
1162
 
1162
1163
  const {
1163
- invoke: invoke$1,
1164
+ invoke: invoke$3,
1165
+ set: set$3
1166
+ } = create$2(ChatNetworkWorker);
1167
+
1168
+ const {
1169
+ invoke: invoke$2,
1164
1170
  set: set$2
1165
1171
  } = create$2(ExtensionHostWorker);
1166
1172
 
1167
1173
  const {
1168
- invoke,
1174
+ invoke: invoke$1,
1169
1175
  invokeAndTransfer,
1170
1176
  set: set$1
1171
1177
  } = create$2(RendererWorker);
1172
1178
  const readFile = async uri => {
1173
- return invoke('FileSystem.readFile', uri);
1179
+ return invoke$1('FileSystem.readFile', uri);
1174
1180
  };
1175
1181
  const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
1176
1182
  const command = 'HandleMessagePort.handleMessagePort2';
@@ -1179,27 +1185,23 @@ const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
1179
1185
  const sendMessagePortToChatNetworkWorker = async port => {
1180
1186
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatNetworkWorker', port, 'HandleMessagePort.handleMessagePort');
1181
1187
  };
1182
- const confirm = async (message, options) => {
1183
- const result = await invoke('ConfirmPrompt.prompt', message, options);
1184
- return result;
1185
- };
1186
1188
  const writeFile = async (uri, text) => {
1187
- await invoke('FileSystem.writeFile', uri, text);
1189
+ await invoke$1('FileSystem.writeFile', uri, text);
1188
1190
  };
1189
1191
  const activateByEvent$1 = (event, assetDir, platform) => {
1190
- return invoke('ExtensionHostManagement.activateByEvent', event, assetDir, platform);
1192
+ return invoke$1('ExtensionHostManagement.activateByEvent', event, assetDir, platform);
1191
1193
  };
1192
1194
  const getWorkspacePath = () => {
1193
- return invoke('Workspace.getPath');
1195
+ return invoke$1('Workspace.getPath');
1194
1196
  };
1195
1197
  const getPreference = async key => {
1196
- return await invoke('Preferences.get', key);
1198
+ return await invoke$1('Preferences.get', key);
1197
1199
  };
1198
1200
  const openExternal = async uri => {
1199
- await invoke('Open.openExternal', uri);
1201
+ await invoke$1('Open.openExternal', uri);
1200
1202
  };
1201
1203
  const measureTextBlockHeight$1 = async (actualInput, fontFamily, fontSize, lineHeightPx, width) => {
1202
- return invoke(`MeasureTextHeight.measureTextBlockHeight`, actualInput, fontFamily, fontSize, lineHeightPx, width);
1204
+ return invoke$1(`MeasureTextHeight.measureTextBlockHeight`, actualInput, fontFamily, fontSize, lineHeightPx, width);
1203
1205
  };
1204
1206
 
1205
1207
  const toCommandId = key => {
@@ -1323,6 +1325,9 @@ const terminate = () => {
1323
1325
  };
1324
1326
 
1325
1327
  const measureTextBlockHeight = async (text, fontFamily, fontSize, lineHeight, width) => {
1328
+ // Upstream renderer types currently require number, but runtime accepts px strings.
1329
+ // Keep forwarding the string to preserve chat-view behavior until upstream is updated.
1330
+ // @ts-ignore
1326
1331
  return measureTextBlockHeight$1(text, fontFamily, fontSize, lineHeight, width);
1327
1332
  };
1328
1333
 
@@ -1354,7 +1359,7 @@ const getComposerHeight = async (state, value, width = state.width) => {
1354
1359
  const content = value || ' ';
1355
1360
  const composerWidth = getComposerWidth(width);
1356
1361
  try {
1357
- const measuredHeight = await measureTextBlockHeight(content, composerFontFamily, composerFontSize, composerLineHeight, composerWidth);
1362
+ const measuredHeight = await measureTextBlockHeight(content, composerFontFamily, composerFontSize, `${composerLineHeight}px`, composerWidth);
1358
1363
  const height = Math.ceil(measuredHeight) + 8;
1359
1364
  return Math.max(minimumHeight, Math.min(maximumHeight, height));
1360
1365
  } catch {
@@ -1623,6 +1628,7 @@ const createDefaultState = () => {
1623
1628
  tokensUsed: 0,
1624
1629
  uid: 0,
1625
1630
  usageOverviewEnabled: false,
1631
+ useChatMathWorker: true,
1626
1632
  useChatNetworkWorkerForRequests: false,
1627
1633
  useMockApi: false,
1628
1634
  viewMode: 'list',
@@ -2430,7 +2436,7 @@ const isEqualProjectExpandedIds = (a, b) => {
2430
2436
  return true;
2431
2437
  };
2432
2438
  const isEqual = (oldState, newState) => {
2433
- return 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.viewMode === newState.viewMode && oldState.voiceDictationEnabled === newState.voiceDictationEnabled;
2439
+ return 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;
2434
2440
  };
2435
2441
 
2436
2442
  const diffScrollTop = (oldState, newState) => {
@@ -2819,7 +2825,7 @@ const handleChatListContextMenu = async (state, eventX, eventY) => {
2819
2825
  if (!item) {
2820
2826
  return state;
2821
2827
  }
2822
- await invoke('ContextMenu.show', eventX, eventY, CHAT_LIST_ITEM_CONTEXT_MENU, item.id);
2828
+ await invoke$1('ContextMenu.show', eventX, eventY, CHAT_LIST_ITEM_CONTEXT_MENU, item.id);
2823
2829
  return state;
2824
2830
  };
2825
2831
 
@@ -2848,6 +2854,14 @@ const createSession = async (state, projectIdOverride = '') => {
2848
2854
  };
2849
2855
  };
2850
2856
 
2857
+ const openFolder = async () => {
2858
+ try {
2859
+ return await invoke$1('FilePicker.showDirectoryPicker');
2860
+ } catch {
2861
+ return '';
2862
+ }
2863
+ };
2864
+
2851
2865
  const selectProject = async (state, projectId) => {
2852
2866
  if (!projectId || state.selectedProjectId === projectId) {
2853
2867
  return state;
@@ -2894,17 +2908,8 @@ const getProjectName = (uri, fallbackIndex) => {
2894
2908
  const getNextProjectId = projects => {
2895
2909
  return `project-${projects.length + 1}`;
2896
2910
  };
2897
- const pickProjectUri = async () => {
2898
- try {
2899
- const workspaceUri = await getWorkspacePath();
2900
- return workspaceUri;
2901
- } catch {
2902
- return '';
2903
- }
2904
- };
2905
2911
  const handleClickCreateProject = async state => {
2906
- await confirm('project added');
2907
- const uri = await pickProjectUri();
2912
+ const uri = await openFolder();
2908
2913
  if (!uri) {
2909
2914
  return state;
2910
2915
  }
@@ -2928,7 +2933,7 @@ const handleClickCreateProject = async state => {
2928
2933
  };
2929
2934
 
2930
2935
  const handleClickOpenApiApiKeySettings = async state => {
2931
- await invoke('Main.openUri', 'app://settings.json');
2936
+ await invoke$1('Main.openUri', 'app://settings.json');
2932
2937
  return state;
2933
2938
  };
2934
2939
 
@@ -2938,7 +2943,7 @@ const handleClickOpenApiApiKeyWebsite = async state => {
2938
2943
  };
2939
2944
 
2940
2945
  const handleClickOpenRouterApiKeySettings = async state => {
2941
- await invoke('Main.openUri', 'app://settings.json');
2946
+ await invoke$1('Main.openUri', 'app://settings.json');
2942
2947
  return state;
2943
2948
  };
2944
2949
 
@@ -2956,6 +2961,17 @@ const openRouterTooManyRequestsMessage = 'OpenRouter rate limit reached (429). P
2956
2961
  const openRouterRequestFailureReasons = ['ContentSecurityPolicyViolation: Check DevTools for details.', 'OpenRouter server offline: Check DevTools for details.', 'Check your internet connection.'];
2957
2962
  const openRouterTooManyRequestsReasons = ['Wait a short time and retry your request.', 'Reduce request frequency to avoid rate limits.', 'Use a different model if this one is saturated.'];
2958
2963
 
2964
+ const getToolErrorPayload = error => {
2965
+ const rawStack = error && typeof error === 'object' ? Reflect.get(error, 'stack') : undefined;
2966
+ return {
2967
+ error: String(error),
2968
+ ...(typeof rawStack === 'string' && rawStack.trim() ? {
2969
+ errorStack: rawStack,
2970
+ stack: rawStack
2971
+ } : {})
2972
+ };
2973
+ };
2974
+
2959
2975
  const executeGetWorkspaceUriTool = async (_args, _options) => {
2960
2976
  try {
2961
2977
  const workspaceUri = await getWorkspacePath();
@@ -2963,9 +2979,7 @@ const executeGetWorkspaceUriTool = async (_args, _options) => {
2963
2979
  workspaceUri
2964
2980
  });
2965
2981
  } catch (error) {
2966
- return JSON.stringify({
2967
- error: String(error)
2968
- });
2982
+ return JSON.stringify(getToolErrorPayload(error));
2969
2983
  }
2970
2984
  };
2971
2985
 
@@ -2980,14 +2994,14 @@ const executeListFilesTool = async (args, _options) => {
2980
2994
  });
2981
2995
  }
2982
2996
  try {
2983
- const entries = await invoke('FileSystem.readDirWithFileTypes', uri);
2997
+ const entries = await invoke$1('FileSystem.readDirWithFileTypes', uri);
2984
2998
  return JSON.stringify({
2985
2999
  entries,
2986
3000
  uri
2987
3001
  });
2988
3002
  } catch (error) {
2989
3003
  return JSON.stringify({
2990
- error: String(error),
3004
+ ...getToolErrorPayload(error),
2991
3005
  uri
2992
3006
  });
2993
3007
  }
@@ -3037,10 +3051,7 @@ const executeReadFileTool = async (args, _options) => {
3037
3051
  });
3038
3052
  } catch (error) {
3039
3053
  return JSON.stringify({
3040
- error: String(error),
3041
- ...(error instanceof Error && typeof error.stack === 'string' ? {
3042
- stack: error.stack
3043
- } : {}),
3054
+ ...getToolErrorPayload(error),
3044
3055
  uri
3045
3056
  });
3046
3057
  }
@@ -3060,10 +3071,7 @@ const executeReadFileTool = async (args, _options) => {
3060
3071
  });
3061
3072
  } catch (error) {
3062
3073
  return JSON.stringify({
3063
- error: String(error),
3064
- ...(error instanceof Error && typeof error.stack === 'string' ? {
3065
- stack: error.stack
3066
- } : {}),
3074
+ ...getToolErrorPayload(error),
3067
3075
  path: normalizedPath
3068
3076
  });
3069
3077
  }
@@ -3109,7 +3117,7 @@ const executeWriteFileTool = async (args, _options) => {
3109
3117
  });
3110
3118
  } catch (error) {
3111
3119
  return JSON.stringify({
3112
- error: String(error),
3120
+ ...getToolErrorPayload(error),
3113
3121
  path: normalizedPath
3114
3122
  });
3115
3123
  }
@@ -3346,6 +3354,36 @@ const readNextChunk = async () => {
3346
3354
  return promise;
3347
3355
  };
3348
3356
 
3357
+ const getResponseFunctionCalls$1 = value => {
3358
+ if (!value || typeof value !== 'object') {
3359
+ return [];
3360
+ }
3361
+ const output = Reflect.get(value, 'output');
3362
+ if (!Array.isArray(output)) {
3363
+ return [];
3364
+ }
3365
+ const responseFunctionCalls = [];
3366
+ for (const item of output) {
3367
+ if (!item || typeof item !== 'object') {
3368
+ continue;
3369
+ }
3370
+ if (Reflect.get(item, 'type') !== 'function_call') {
3371
+ continue;
3372
+ }
3373
+ const callId = Reflect.get(item, 'call_id');
3374
+ const name = Reflect.get(item, 'name');
3375
+ const rawArguments = Reflect.get(item, 'arguments');
3376
+ if (typeof callId !== 'string' || typeof name !== 'string') {
3377
+ continue;
3378
+ }
3379
+ responseFunctionCalls.push({
3380
+ arguments: typeof rawArguments === 'string' ? rawArguments : '',
3381
+ callId,
3382
+ name
3383
+ });
3384
+ }
3385
+ return responseFunctionCalls;
3386
+ };
3349
3387
  const parseSseDataLines = eventChunk => {
3350
3388
  const lines = eventChunk.split('\n');
3351
3389
  const dataLines = [];
@@ -3375,6 +3413,9 @@ const getMockOpenApiAssistantText = async (stream, onTextChunk, onToolCallsChunk
3375
3413
  let text = '';
3376
3414
  let remainder = '';
3377
3415
  let toolCallAccumulator = {};
3416
+ let responseFunctionCalls = [];
3417
+ let responseId;
3418
+ let requestDone = false;
3378
3419
  let finishedNotified = false;
3379
3420
  const notifyFinished = async () => {
3380
3421
  if (finishedNotified) {
@@ -3394,6 +3435,13 @@ const getMockOpenApiAssistantText = async (stream, onTextChunk, onToolCallsChunk
3394
3435
  }
3395
3436
  const eventType = Reflect.get(parsed, 'type');
3396
3437
  if (eventType === 'response.completed') {
3438
+ const response = Reflect.get(parsed, 'response');
3439
+ responseFunctionCalls = getResponseFunctionCalls$1(response);
3440
+ const parsedResponseId = response && typeof response === 'object' ? Reflect.get(response, 'id') : undefined;
3441
+ if (typeof parsedResponseId === 'string' && parsedResponseId) {
3442
+ responseId = parsedResponseId;
3443
+ }
3444
+ requestDone = true;
3397
3445
  await notifyFinished();
3398
3446
  return;
3399
3447
  }
@@ -3465,8 +3513,9 @@ const getMockOpenApiAssistantText = async (stream, onTextChunk, onToolCallsChunk
3465
3513
  const consumeSseDataLines = async dataLines => {
3466
3514
  for (const line of dataLines) {
3467
3515
  if (line === '[DONE]') {
3516
+ requestDone = true;
3468
3517
  await notifyFinished();
3469
- continue;
3518
+ break;
3470
3519
  }
3471
3520
  let parsed;
3472
3521
  try {
@@ -3475,9 +3524,12 @@ const getMockOpenApiAssistantText = async (stream, onTextChunk, onToolCallsChunk
3475
3524
  continue;
3476
3525
  }
3477
3526
  await handleParsedSseEvent(parsed);
3527
+ if (requestDone) {
3528
+ break;
3529
+ }
3478
3530
  }
3479
3531
  };
3480
- while (true) {
3532
+ while (!requestDone) {
3481
3533
  const chunk = await readNextChunk();
3482
3534
  if (typeof chunk !== 'string') {
3483
3535
  break;
@@ -3493,6 +3545,9 @@ const getMockOpenApiAssistantText = async (stream, onTextChunk, onToolCallsChunk
3493
3545
  remainder = remainder.slice(separatorIndex + 2);
3494
3546
  const dataLines = parseSseDataLines(rawEvent);
3495
3547
  await consumeSseDataLines(dataLines);
3548
+ if (requestDone) {
3549
+ break;
3550
+ }
3496
3551
  }
3497
3552
  continue;
3498
3553
  }
@@ -3501,12 +3556,16 @@ const getMockOpenApiAssistantText = async (stream, onTextChunk, onToolCallsChunk
3501
3556
  await onTextChunk(chunk);
3502
3557
  }
3503
3558
  }
3504
- if (remainder) {
3559
+ if (!requestDone && remainder) {
3505
3560
  const dataLines = parseSseDataLines(remainder);
3506
3561
  await consumeSseDataLines(dataLines);
3507
3562
  }
3508
3563
  await notifyFinished();
3509
3564
  return {
3565
+ ...(responseId ? {
3566
+ responseId
3567
+ } : {}),
3568
+ responseFunctionCalls,
3510
3569
  text,
3511
3570
  type: 'success'
3512
3571
  };
@@ -3527,7 +3586,7 @@ const executeProvider = async ({
3527
3586
  }) => {
3528
3587
  await activateByEvent(event, assetDir, platform);
3529
3588
  // @ts-ignore
3530
- const result = invoke$1(method, ...params);
3589
+ const result = invoke$2(method, ...params);
3531
3590
  return result;
3532
3591
  };
3533
3592
 
@@ -3659,10 +3718,10 @@ const getOpenApiApiEndpoint = openApiApiBaseUrl => {
3659
3718
  };
3660
3719
 
3661
3720
  const makeApiRequest = async options => {
3662
- return invoke$2('ChatNetwork.makeApiRequest', options);
3721
+ return invoke$3('ChatNetwork.makeApiRequest', options);
3663
3722
  };
3664
3723
  const makeStreamingApiRequest = async options => {
3665
- return invoke$2('ChatNetwork.makeStreamingApiRequest', options);
3724
+ return invoke$3('ChatNetwork.makeStreamingApiRequest', options);
3666
3725
  };
3667
3726
 
3668
3727
  const getTextContent = content => {
@@ -3782,18 +3841,22 @@ const getToolCallExecutionStatus = content => {
3782
3841
  status: 'success'
3783
3842
  };
3784
3843
  }
3785
- const rawErrorStack = Reflect.get(parsed, 'stack');
3844
+ const rawStack = Reflect.get(parsed, 'errorStack') ?? Reflect.get(parsed, 'stack');
3845
+ const errorStack = typeof rawStack === 'string' && rawStack.trim() ? rawStack : undefined;
3786
3846
  const errorMessage = getShortToolErrorMessage(rawError);
3787
3847
  if (/not[\s_-]?found|enoent/i.test(errorMessage)) {
3788
3848
  return {
3849
+ ...(errorStack ? {
3850
+ errorStack
3851
+ } : {}),
3789
3852
  status: 'not-found'
3790
3853
  };
3791
3854
  }
3792
3855
  return {
3793
- errorMessage,
3794
- ...(typeof rawErrorStack === 'string' && rawErrorStack.trim() ? {
3795
- errorStack: rawErrorStack
3856
+ ...(errorStack ? {
3857
+ errorStack
3796
3858
  } : {}),
3859
+ errorMessage,
3797
3860
  status: 'error'
3798
3861
  };
3799
3862
  };
@@ -4397,6 +4460,9 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
4397
4460
  const executionStatus = getToolCallExecutionStatus(content);
4398
4461
  executedToolCalls.push({
4399
4462
  arguments: toolCall.arguments,
4463
+ ...(executionStatus.errorStack ? {
4464
+ errorStack: executionStatus.errorStack
4465
+ } : {}),
4400
4466
  ...(executionStatus.errorMessage ? {
4401
4467
  errorMessage: executionStatus.errorMessage
4402
4468
  } : {}),
@@ -4535,6 +4601,9 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
4535
4601
  const executionStatus = getToolCallExecutionStatus(content);
4536
4602
  executedToolCalls.push({
4537
4603
  arguments: toolCall.arguments,
4604
+ ...(executionStatus.errorStack ? {
4605
+ errorStack: executionStatus.errorStack
4606
+ } : {}),
4538
4607
  ...(executionStatus.errorMessage ? {
4539
4608
  errorMessage: executionStatus.errorMessage
4540
4609
  } : {}),
@@ -4601,6 +4670,9 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
4601
4670
  const executionStatus = getToolCallExecutionStatus(content);
4602
4671
  executedToolCalls.push({
4603
4672
  arguments: typeof rawArguments === 'string' ? rawArguments : '',
4673
+ ...(executionStatus.errorStack ? {
4674
+ errorStack: executionStatus.errorStack
4675
+ } : {}),
4604
4676
  ...(executionStatus.errorMessage ? {
4605
4677
  errorMessage: executionStatus.errorMessage
4606
4678
  } : {}),
@@ -5101,6 +5173,8 @@ const getAll = () => {
5101
5173
  return requests;
5102
5174
  };
5103
5175
 
5176
+ /* eslint-disable prefer-destructuring */
5177
+
5104
5178
  const getAiResponse = async ({
5105
5179
  assetDir,
5106
5180
  messageId,
@@ -5140,20 +5214,36 @@ const getAiResponse = async ({
5140
5214
  'Content-Type': 'application/json',
5141
5215
  ...getClientRequestIdHeader()
5142
5216
  };
5143
- capture({
5144
- headers,
5145
- method: 'POST',
5146
- payload: getOpenAiParams(openAiInput, modelId, streamingEnabled, passIncludeObfuscation, getBasicChatTools(), webSearchEnabled),
5147
- url: getOpenApiApiEndpoint(openApiApiBaseUrl)
5148
- });
5149
- const result = await getMockOpenApiAssistantText(streamingEnabled, onTextChunk, onToolCallsChunk, onDataEvent, onEventStreamFinished);
5150
- if (result.type === 'success') {
5151
- const {
5152
- text: assistantText
5153
- } = result;
5154
- text = assistantText;
5155
- } else {
5156
- text = getOpenApiErrorMessage(result);
5217
+ const maxToolIterations = 4;
5218
+ let previousResponseId;
5219
+ for (let i = 0; i <= maxToolIterations; i++) {
5220
+ capture({
5221
+ headers,
5222
+ method: 'POST',
5223
+ payload: getOpenAiParams(openAiInput, modelId, streamingEnabled, passIncludeObfuscation, getBasicChatTools(), webSearchEnabled, previousResponseId),
5224
+ url: getOpenApiApiEndpoint(openApiApiBaseUrl)
5225
+ });
5226
+ const result = await getMockOpenApiAssistantText(streamingEnabled, onTextChunk, onToolCallsChunk, onDataEvent, onEventStreamFinished);
5227
+ if (result.type !== 'success') {
5228
+ text = getOpenApiErrorMessage(result);
5229
+ break;
5230
+ }
5231
+ text = result.text;
5232
+ if (result.responseId) {
5233
+ previousResponseId = result.responseId;
5234
+ }
5235
+ if (result.responseFunctionCalls.length === 0) {
5236
+ break;
5237
+ }
5238
+ openAiInput.length = 0;
5239
+ for (const toolCall of result.responseFunctionCalls) {
5240
+ const content = await executeChatTool(toolCall.name, toolCall.arguments);
5241
+ openAiInput.push({
5242
+ call_id: toolCall.callId,
5243
+ output: content,
5244
+ type: 'function_call_output'
5245
+ });
5246
+ }
5157
5247
  }
5158
5248
  } else if (openApiApiKey) {
5159
5249
  const result = await getOpenApiAssistantText(messages, getOpenApiModelId(selectedModelId), openApiApiKey, openApiApiBaseUrl, assetDir, platform, {
@@ -5230,7 +5320,7 @@ const get = async key => {
5230
5320
  return getPreference(key);
5231
5321
  };
5232
5322
  const update = async settings => {
5233
- await invoke('Preferences.update', settings);
5323
+ await invoke$1('Preferences.update', settings);
5234
5324
  };
5235
5325
 
5236
5326
  const setOpenApiApiKey = async (state, openApiApiKey, persist = true) => {
@@ -5331,7 +5421,7 @@ const handleClickSaveOpenRouterApiKey = async state => {
5331
5421
  };
5332
5422
  set(state.uid, state, optimisticState);
5333
5423
  // @ts-ignore
5334
- await invoke('Chat.rerender');
5424
+ await invoke$1('Chat.rerender');
5335
5425
  const persistedState = await setOpenRouterApiKey(optimisticState, openRouterApiKey);
5336
5426
  const updatedState = {
5337
5427
  ...persistedState,
@@ -5675,7 +5765,7 @@ const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTex
5675
5765
  };
5676
5766
  set(uid, handleTextChunkState.previousState, nextState);
5677
5767
  // @ts-ignore
5678
- await invoke('Chat.rerender');
5768
+ await invoke$1('Chat.rerender');
5679
5769
  return {
5680
5770
  latestState: nextState,
5681
5771
  previousState: nextState
@@ -5703,7 +5793,7 @@ const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls,
5703
5793
  };
5704
5794
  set(uid, handleTextChunkState.previousState, nextState);
5705
5795
  // @ts-ignore
5706
- await invoke('Chat.rerender');
5796
+ await invoke$1('Chat.rerender');
5707
5797
  return {
5708
5798
  latestState: nextState,
5709
5799
  previousState: nextState
@@ -5883,7 +5973,7 @@ const handleSubmit = async state => {
5883
5973
  }
5884
5974
  set(state.uid, state, optimisticState);
5885
5975
  // @ts-ignore
5886
- await invoke('Chat.rerender');
5976
+ await invoke$1('Chat.rerender');
5887
5977
  let handleTextChunkState = {
5888
5978
  latestState: optimisticState,
5889
5979
  previousState: optimisticState
@@ -6216,7 +6306,7 @@ const handleClickBack = async state => {
6216
6306
 
6217
6307
  const handleClickClose = async () => {
6218
6308
  // @ts-ignore
6219
- await invoke('Layout.hideSecondarySideBar');
6309
+ await invoke$1('Layout.hideSecondarySideBar');
6220
6310
  };
6221
6311
 
6222
6312
  const handleClickDelete = async (state, sessionId = '') => {
@@ -6235,17 +6325,17 @@ const handleClickReadFile = async uri => {
6235
6325
  if (!uri) {
6236
6326
  return;
6237
6327
  }
6238
- await invoke('Main.openUri', uri);
6328
+ await invoke$1('Main.openUri', uri);
6239
6329
  };
6240
6330
 
6241
6331
  const handleClickSessionDebug = async state => {
6242
- await invoke('Main.openUri', `chat-debug://${state.selectedSessionId}`);
6332
+ await invoke$1('Main.openUri', `chat-debug://${state.selectedSessionId}`);
6243
6333
  return state;
6244
6334
  };
6245
6335
 
6246
6336
  const handleClickSettings = async () => {
6247
6337
  // TODO
6248
- await invoke('Main.openUri', 'app://settings.json');
6338
+ await invoke$1('Main.openUri', 'app://settings.json');
6249
6339
  };
6250
6340
 
6251
6341
  const handleDragEnter = async (state, name, hasFiles = true) => {
@@ -6458,7 +6548,7 @@ const handleKeyDown = async (state, key, shiftKey) => {
6458
6548
  };
6459
6549
 
6460
6550
  const handleMessagesContextMenu = async state => {
6461
- await invoke('ContextMenu.show', 1234);
6551
+ await invoke$1('ContextMenu.show', 1234);
6462
6552
  return state;
6463
6553
  };
6464
6554
 
@@ -6525,7 +6615,7 @@ const createExtensionHostRpc = async () => {
6525
6615
  }
6526
6616
  };
6527
6617
 
6528
- const initialize = async () => {
6618
+ const initialize$1 = async () => {
6529
6619
  const rpc = await createExtensionHostRpc();
6530
6620
  set$2(rpc);
6531
6621
  };
@@ -6683,6 +6773,15 @@ const loadStreamingEnabled = async () => {
6683
6773
  }
6684
6774
  };
6685
6775
 
6776
+ const loadUseChatMathWorker = async () => {
6777
+ try {
6778
+ const savedUseChatMathWorker = await get('chatView.useChatMathWorker');
6779
+ return typeof savedUseChatMathWorker === 'boolean' ? savedUseChatMathWorker : true;
6780
+ } catch {
6781
+ return true;
6782
+ }
6783
+ };
6784
+
6686
6785
  const loadUseChatNetworkWorkerForRequests = async () => {
6687
6786
  try {
6688
6787
  const savedUseChatNetworkWorkerForRequests = await get('chatView.useChatNetworkWorkerForRequests');
@@ -6702,7 +6801,7 @@ const loadVoiceDictationEnabled = async () => {
6702
6801
  };
6703
6802
 
6704
6803
  const loadPreferences = async () => {
6705
- const [aiSessionTitleGenerationEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation, useChatNetworkWorkerForRequests, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation(), loadUseChatNetworkWorkerForRequests(), loadVoiceDictationEnabled()]);
6804
+ const [aiSessionTitleGenerationEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation, useChatMathWorker, useChatNetworkWorkerForRequests, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation(), loadUseChatMathWorker(), loadUseChatNetworkWorkerForRequests(), loadVoiceDictationEnabled()]);
6706
6805
  return {
6707
6806
  aiSessionTitleGenerationEnabled,
6708
6807
  composerDropEnabled,
@@ -6711,6 +6810,7 @@ const loadPreferences = async () => {
6711
6810
  openRouterApiKey,
6712
6811
  passIncludeObfuscation,
6713
6812
  streamingEnabled,
6813
+ useChatMathWorker,
6714
6814
  useChatNetworkWorkerForRequests,
6715
6815
  voiceDictationEnabled
6716
6816
  };
@@ -6825,9 +6925,22 @@ const getSavedLastNormalViewMode = savedState => {
6825
6925
  }
6826
6926
  return lastNormalViewMode;
6827
6927
  };
6928
+ const getSavedComposerValue = savedState => {
6929
+ if (!isObject(savedState)) {
6930
+ return undefined;
6931
+ }
6932
+ const {
6933
+ composerValue
6934
+ } = savedState;
6935
+ if (typeof composerValue !== 'string') {
6936
+ return undefined;
6937
+ }
6938
+ return composerValue;
6939
+ };
6828
6940
  const loadContent = async (state, savedState) => {
6829
6941
  const savedSelectedModelId = getSavedSelectedModelId(savedState);
6830
6942
  const savedViewMode = getSavedViewMode(savedState);
6943
+ const savedComposerValue = getSavedComposerValue(savedState);
6831
6944
  const {
6832
6945
  aiSessionTitleGenerationEnabled,
6833
6946
  composerDropEnabled,
@@ -6836,6 +6949,7 @@ const loadContent = async (state, savedState) => {
6836
6949
  openRouterApiKey,
6837
6950
  passIncludeObfuscation,
6838
6951
  streamingEnabled,
6952
+ useChatMathWorker,
6839
6953
  useChatNetworkWorkerForRequests,
6840
6954
  voiceDictationEnabled
6841
6955
  } = await loadPreferences();
@@ -6885,6 +6999,7 @@ const loadContent = async (state, savedState) => {
6885
6999
  chatListScrollTop,
6886
7000
  composerDropActive: false,
6887
7001
  composerDropEnabled,
7002
+ composerValue: savedComposerValue ?? state.composerValue,
6888
7003
  emitStreamingFunctionCallEvents,
6889
7004
  initial: false,
6890
7005
  lastNormalViewMode,
@@ -6902,6 +7017,7 @@ const loadContent = async (state, savedState) => {
6902
7017
  selectedSessionId,
6903
7018
  sessions,
6904
7019
  streamingEnabled,
7020
+ useChatMathWorker,
6905
7021
  useChatNetworkWorkerForRequests,
6906
7022
  viewMode,
6907
7023
  voiceDictationEnabled
@@ -23948,6 +24064,88 @@ var katex = {
23948
24064
  __domTree
23949
24065
  };
23950
24066
 
24067
+ let initialized = false;
24068
+ const renderCache = new Map();
24069
+ const pendingRenders = new Set();
24070
+ const getCacheKey = (value, displayMode) => {
24071
+ return `${displayMode ? '1' : '0'}:${value}`;
24072
+ };
24073
+ const sendMessagePortToChatMathWorker = async port => {
24074
+ try {
24075
+ await invoke$1('sendMessagePortToChatMathWorker', port);
24076
+ } catch {
24077
+ await invoke$1('SendMessagePortToChatMathWorker.sendMessagePortToChatMathWorker', port);
24078
+ }
24079
+ };
24080
+ const createRpc = () => {
24081
+ return create$4({
24082
+ commandMap: {},
24083
+ send: sendMessagePortToChatMathWorker
24084
+ });
24085
+ };
24086
+ const initialize = async () => {
24087
+ if (initialized) {
24088
+ return;
24089
+ }
24090
+ const rpc = await createRpc();
24091
+ set$4(rpc);
24092
+ initialized = true;
24093
+ };
24094
+ const invoke = async (method, ...params) => {
24095
+ await initialize();
24096
+ return invoke$4(method, ...params);
24097
+ };
24098
+ const renderViaRpc = async (value, displayMode) => {
24099
+ const methods = ['renderToString', 'RenderToString.renderToString', 'RenderMath.renderMath', 'Math.renderToString'];
24100
+ for (const method of methods) {
24101
+ try {
24102
+ const result = await invoke(method, value, {
24103
+ displayMode,
24104
+ throwOnError: true
24105
+ });
24106
+ if (typeof result === 'string') {
24107
+ return result;
24108
+ }
24109
+ } catch {
24110
+ // Try next known method signature.
24111
+ }
24112
+ try {
24113
+ const result = await invoke(method, value, displayMode);
24114
+ if (typeof result === 'string') {
24115
+ return result;
24116
+ }
24117
+ } catch {
24118
+ // Try next known method signature.
24119
+ }
24120
+ }
24121
+ throw new Error('ChatMathWorker did not provide renderToString');
24122
+ };
24123
+ const startRender = (cacheKey, value, displayMode) => {
24124
+ if (pendingRenders.has(cacheKey)) {
24125
+ return;
24126
+ }
24127
+ pendingRenders.add(cacheKey);
24128
+ void (async () => {
24129
+ try {
24130
+ const html = await renderViaRpc(value, displayMode);
24131
+ renderCache.set(cacheKey, html);
24132
+ } catch {
24133
+ // Keep cache empty so caller can continue to show fallback text.
24134
+ } finally {
24135
+ pendingRenders.delete(cacheKey);
24136
+ }
24137
+ })();
24138
+ };
24139
+ const tryRenderToString = (value, displayMode) => {
24140
+ const cacheKey = getCacheKey(value, displayMode);
24141
+ const cached = renderCache.get(cacheKey);
24142
+ if (cached) {
24143
+ return cached;
24144
+ }
24145
+ startRender(cacheKey, value, displayMode);
24146
+ return undefined;
24147
+ };
24148
+
23951
24149
  const maxHtmlLength = 40_000;
23952
24150
  const tokenRegex = /<!--[\s\S]*?-->|<\/?[a-zA-Z][\w:-]*(?:\s[^<>]*?)?>|[^<]+/g;
23953
24151
  const attributeRegex = /([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
@@ -24223,19 +24421,28 @@ const parseHtmlToVirtualDomWithRootCount = value => {
24223
24421
 
24224
24422
  // cspell:ignore katex
24225
24423
 
24226
- const renderMath = (value, displayMode) => {
24424
+ const renderMath = (value, displayMode, useChatMathWorker = false) => {
24227
24425
  try {
24228
- const html = katex.renderToString(value, {
24229
- displayMode,
24230
- throwOnError: true
24231
- });
24426
+ let html;
24427
+ if (useChatMathWorker) {
24428
+ html = tryRenderToString(value, displayMode);
24429
+ }
24430
+ if (typeof html !== 'string') {
24431
+ html = katex.renderToString(value, {
24432
+ displayMode,
24433
+ throwOnError: true
24434
+ });
24435
+ }
24436
+ if (typeof html !== 'string') {
24437
+ return undefined;
24438
+ }
24232
24439
  return parseHtmlToVirtualDomWithRootCount(html);
24233
24440
  } catch {
24234
24441
  return undefined;
24235
24442
  }
24236
24443
  };
24237
- const getMathInlineDom = node => {
24238
- const rendered = renderMath(node.text, node.displayMode);
24444
+ const getMathInlineDom = (node, useChatMathWorker = false) => {
24445
+ const rendered = renderMath(node.text, node.displayMode, useChatMathWorker);
24239
24446
  if (!rendered) {
24240
24447
  const fallback = node.displayMode ? `$$${node.text}$$` : `$${node.text}$`;
24241
24448
  return [text$2(fallback)];
@@ -24246,8 +24453,8 @@ const getMathInlineDom = node => {
24246
24453
  type: Span$1
24247
24454
  }, ...rendered.virtualDom];
24248
24455
  };
24249
- const getMathBlockDom = node => {
24250
- const rendered = renderMath(node.text, true);
24456
+ const getMathBlockDom = (node, useChatMathWorker = false) => {
24457
+ const rendered = renderMath(node.text, true, useChatMathWorker);
24251
24458
  if (!rendered) {
24252
24459
  return [{
24253
24460
  childCount: 1,
@@ -24262,7 +24469,7 @@ const getMathBlockDom = node => {
24262
24469
  }, ...rendered.virtualDom];
24263
24470
  };
24264
24471
 
24265
- const getInlineNodeDom = inlineNode => {
24472
+ const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
24266
24473
  if (inlineNode.type === 'text') {
24267
24474
  return [text$2(inlineNode.text)];
24268
24475
  }
@@ -24279,7 +24486,7 @@ const getInlineNodeDom = inlineNode => {
24279
24486
  }, text$2(inlineNode.text)];
24280
24487
  }
24281
24488
  if (inlineNode.type === 'math-inline') {
24282
- return getMathInlineDom(inlineNode);
24489
+ return getMathInlineDom(inlineNode, useChatMathWorker);
24283
24490
  }
24284
24491
  return [{
24285
24492
  childCount: 1,
@@ -24435,45 +24642,45 @@ const getCodeBlockDom = node => {
24435
24642
  type: Code
24436
24643
  }, ...tokenDom];
24437
24644
  };
24438
- const getOrderedListItemDom = item => {
24645
+ const getOrderedListItemDom = (item, useChatMathWorker) => {
24439
24646
  const hasNestedUnorderedList = (item.nestedItems?.length || 0) > 0;
24440
24647
  const nestedUnorderedListDom = hasNestedUnorderedList ? [{
24441
24648
  childCount: item.nestedItems?.length || 0,
24442
24649
  className: ChatUnorderedList,
24443
24650
  type: Ul
24444
- }, ...(item.nestedItems || []).flatMap(getUnorderedListItemDom)] : [];
24651
+ }, ...(item.nestedItems || []).flatMap(nestedItem => getUnorderedListItemDom(nestedItem, useChatMathWorker))] : [];
24445
24652
  return [{
24446
24653
  childCount: item.children.length + (hasNestedUnorderedList ? 1 : 0),
24447
24654
  className: ChatOrderedListItem,
24448
24655
  type: Li
24449
- }, ...item.children.flatMap(getInlineNodeDom), ...nestedUnorderedListDom];
24656
+ }, ...item.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker)), ...nestedUnorderedListDom];
24450
24657
  };
24451
- const getUnorderedListItemDom = item => {
24658
+ const getUnorderedListItemDom = (item, useChatMathWorker) => {
24452
24659
  return [{
24453
24660
  childCount: item.children.length,
24454
24661
  className: ChatUnorderedListItem,
24455
24662
  type: Li
24456
- }, ...item.children.flatMap(getInlineNodeDom)];
24663
+ }, ...item.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
24457
24664
  };
24458
- const getTableHeadCellDom = cell => {
24665
+ const getTableHeadCellDom = (cell, useChatMathWorker) => {
24459
24666
  return [{
24460
24667
  childCount: cell.children.length,
24461
24668
  type: Th
24462
- }, ...cell.children.flatMap(getInlineNodeDom)];
24669
+ }, ...cell.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
24463
24670
  };
24464
- const getTableBodyCellDom = cell => {
24671
+ const getTableBodyCellDom = (cell, useChatMathWorker) => {
24465
24672
  return [{
24466
24673
  childCount: cell.children.length,
24467
24674
  type: Td
24468
- }, ...cell.children.flatMap(getInlineNodeDom)];
24675
+ }, ...cell.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
24469
24676
  };
24470
- const getTableRowDom = row => {
24677
+ const getTableRowDom = (row, useChatMathWorker) => {
24471
24678
  return [{
24472
24679
  childCount: row.cells.length,
24473
24680
  type: Tr
24474
- }, ...row.cells.flatMap(getTableBodyCellDom)];
24681
+ }, ...row.cells.flatMap(cell => getTableBodyCellDom(cell, useChatMathWorker))];
24475
24682
  };
24476
- const getTableDom = node => {
24683
+ const getTableDom = (node, useChatMathWorker) => {
24477
24684
  return [{
24478
24685
  childCount: 2,
24479
24686
  className: MarkdownTable,
@@ -24484,10 +24691,10 @@ const getTableDom = node => {
24484
24691
  }, {
24485
24692
  childCount: node.headers.length,
24486
24693
  type: Tr
24487
- }, ...node.headers.flatMap(getTableHeadCellDom), {
24694
+ }, ...node.headers.flatMap(cell => getTableHeadCellDom(cell, useChatMathWorker)), {
24488
24695
  childCount: node.rows.length,
24489
24696
  type: TBody
24490
- }, ...node.rows.flatMap(getTableRowDom)];
24697
+ }, ...node.rows.flatMap(row => getTableRowDom(row, useChatMathWorker))];
24491
24698
  };
24492
24699
  const getHeadingElementType = level => {
24493
24700
  switch (level) {
@@ -24505,48 +24712,48 @@ const getHeadingElementType = level => {
24505
24712
  return H6;
24506
24713
  }
24507
24714
  };
24508
- const getHeadingDom = node => {
24715
+ const getHeadingDom = (node, useChatMathWorker) => {
24509
24716
  return [{
24510
24717
  childCount: node.children.length,
24511
24718
  type: getHeadingElementType(node.level)
24512
- }, ...node.children.flatMap(getInlineNodeDom)];
24719
+ }, ...node.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
24513
24720
  };
24514
- const getMessageNodeDom = node => {
24721
+ const getMessageNodeDom = (node, useChatMathWorker = false) => {
24515
24722
  if (node.type === 'text') {
24516
24723
  return [{
24517
24724
  childCount: node.children.length,
24518
24725
  className: Markdown,
24519
24726
  type: P
24520
- }, ...node.children.flatMap(getInlineNodeDom)];
24727
+ }, ...node.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
24521
24728
  }
24522
24729
  if (node.type === 'table') {
24523
- return getTableDom(node);
24730
+ return getTableDom(node, useChatMathWorker);
24524
24731
  }
24525
24732
  if (node.type === 'code-block') {
24526
24733
  return getCodeBlockDom(node);
24527
24734
  }
24528
24735
  if (node.type === 'math-block') {
24529
- return getMathBlockDom(node);
24736
+ return getMathBlockDom(node, useChatMathWorker);
24530
24737
  }
24531
24738
  if (node.type === 'heading') {
24532
- return getHeadingDom(node);
24739
+ return getHeadingDom(node, useChatMathWorker);
24533
24740
  }
24534
24741
  if (node.type === 'ordered-list') {
24535
24742
  return [{
24536
24743
  childCount: node.items.length,
24537
24744
  className: ChatOrderedList,
24538
24745
  type: Ol
24539
- }, ...node.items.flatMap(getOrderedListItemDom)];
24746
+ }, ...node.items.flatMap(item => getOrderedListItemDom(item, useChatMathWorker))];
24540
24747
  }
24541
24748
  return [{
24542
24749
  childCount: node.items.length,
24543
24750
  className: ChatUnorderedList,
24544
24751
  type: Ul
24545
- }, ...node.items.flatMap(getUnorderedListItemDom)];
24752
+ }, ...node.items.flatMap(item => getUnorderedListItemDom(item, useChatMathWorker))];
24546
24753
  };
24547
24754
 
24548
- const getMessageContentDom = nodes => {
24549
- return nodes.flatMap(getMessageNodeDom);
24755
+ const getMessageContentDom = (nodes, useChatMathWorker = false) => {
24756
+ return nodes.flatMap(node => getMessageNodeDom(node, useChatMathWorker));
24550
24757
  };
24551
24758
 
24552
24759
  const getMissingApiKeyDom = ({
@@ -24879,6 +25086,7 @@ const getToolCallsDom = message => {
24879
25086
  const orderedListItemRegex = /^\s*\d+\.\s+(.*)$/;
24880
25087
  const unorderedListItemRegex = /^(\s*)[-*]\s+(.*)$/;
24881
25088
  const markdownInlineRegex = /\[([^\]]+)\]\(([^)]+)\)|\*\*([^*]+)\*\*|\*([^*]+)\*|(?<![a-zA-Z0-9])(?<mathDollars>\${1,2})(?!\.|\(["'])(?<mathText>(?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\k<mathDollars>(?![a-zA-Z0-9])/g;
25089
+ const markdownItalicWithBoldRegex = /\*([^*\n]*?)\*\*([^*\n]+)\*\*([^*\n]*?)\*/g;
24882
25090
  const markdownTableSeparatorCellRegex = /^:?-{3,}:?$/;
24883
25091
  const fencedCodeBlockRegex = /^```/;
24884
25092
  const markdownHeadingRegex = /^\s*(#{1,6})\s+(.*)$/;
@@ -24940,7 +25148,7 @@ const toTableRow = line => {
24940
25148
  type: 'table-row'
24941
25149
  };
24942
25150
  };
24943
- const parseInlineNodes = value => {
25151
+ const parseInlineNodesSimple = value => {
24944
25152
  const matches = value.matchAll(markdownInlineRegex);
24945
25153
  const nodes = [];
24946
25154
  let lastIndex = 0;
@@ -24998,6 +25206,53 @@ const parseInlineNodes = value => {
24998
25206
  }
24999
25207
  return nodes;
25000
25208
  };
25209
+ const parseInlineNodes = value => {
25210
+ const nestedMatches = value.matchAll(markdownItalicWithBoldRegex);
25211
+ const nodes = [];
25212
+ let lastIndex = 0;
25213
+ let foundNestedItalicBold = false;
25214
+ for (const match of nestedMatches) {
25215
+ const fullMatch = match[0];
25216
+ const italicBefore = match[1];
25217
+ const boldText = match[2];
25218
+ const italicAfter = match[3];
25219
+ const index = match.index ?? 0;
25220
+ foundNestedItalicBold = true;
25221
+ if (index > lastIndex) {
25222
+ nodes.push(...parseInlineNodesSimple(value.slice(lastIndex, index)));
25223
+ }
25224
+ if (italicBefore) {
25225
+ nodes.push({
25226
+ text: italicBefore,
25227
+ type: 'italic'
25228
+ });
25229
+ }
25230
+ nodes.push({
25231
+ text: boldText,
25232
+ type: 'bold'
25233
+ });
25234
+ if (italicAfter) {
25235
+ nodes.push({
25236
+ text: italicAfter,
25237
+ type: 'italic'
25238
+ });
25239
+ }
25240
+ lastIndex = index + fullMatch.length;
25241
+ }
25242
+ if (!foundNestedItalicBold) {
25243
+ return parseInlineNodesSimple(value);
25244
+ }
25245
+ if (lastIndex < value.length) {
25246
+ nodes.push(...parseInlineNodesSimple(value.slice(lastIndex)));
25247
+ }
25248
+ if (nodes.length === 0) {
25249
+ return [{
25250
+ text: value,
25251
+ type: 'text'
25252
+ }];
25253
+ }
25254
+ return nodes;
25255
+ };
25001
25256
  const parseMessageContent = rawMessage => {
25002
25257
  if (rawMessage === '') {
25003
25258
  return [{
@@ -25175,14 +25430,14 @@ const parseMessageContent = rawMessage => {
25175
25430
  }] : nodes;
25176
25431
  };
25177
25432
 
25178
- const getChatMessageDom = (message, openRouterApiKeyInput, openApiApiKeyInput = '', openRouterApiKeyState = 'idle') => {
25433
+ const getChatMessageDom = (message, openRouterApiKeyInput, openApiApiKeyInput = '', openRouterApiKeyState = 'idle', useChatMathWorker = false) => {
25179
25434
  const roleClassName = message.role === 'user' ? MessageUser : MessageAssistant;
25180
25435
  const isOpenApiApiKeyMissingMessage = message.role === 'assistant' && message.text === openApiApiKeyRequiredMessage;
25181
25436
  const isOpenRouterApiKeyMissingMessage = message.role === 'assistant' && message.text === openRouterApiKeyRequiredMessage;
25182
25437
  const isOpenRouterRequestFailedMessage = message.role === 'assistant' && message.text === openRouterRequestFailedMessage;
25183
25438
  const isOpenRouterTooManyRequestsMessage = message.role === 'assistant' && message.text.startsWith(openRouterTooManyRequestsMessage);
25184
25439
  const messageIntermediate = parseMessageContent(message.text);
25185
- const messageDom = getMessageContentDom(messageIntermediate);
25440
+ const messageDom = getMessageContentDom(messageIntermediate, useChatMathWorker);
25186
25441
  const toolCallsDom = getToolCallsDom(message);
25187
25442
  const toolCallsChildCount = toolCallsDom.length > 0 ? 1 : 0;
25188
25443
  const extraChildCount = isOpenApiApiKeyMissingMessage || isOpenRouterApiKeyMissingMessage || isOpenRouterRequestFailedMessage || isOpenRouterTooManyRequestsMessage ? messageIntermediate.length + 1 + toolCallsChildCount : messageIntermediate.length + toolCallsChildCount;
@@ -25231,7 +25486,7 @@ const getDisplayMessages = messages => {
25231
25486
  }
25232
25487
  return displayMessages;
25233
25488
  };
25234
- const getMessagesDom = (messages, openRouterApiKeyInput, openApiApiKeyInput = '', openRouterApiKeyState = 'idle', messagesScrollTop = 0) => {
25489
+ const getMessagesDom = (messages, openRouterApiKeyInput, openApiApiKeyInput = '', openRouterApiKeyState = 'idle', messagesScrollTop = 0, useChatMathWorker = false) => {
25235
25490
  if (messages.length === 0) {
25236
25491
  return getEmptyMessagesDom();
25237
25492
  }
@@ -25243,7 +25498,7 @@ const getMessagesDom = (messages, openRouterApiKeyInput, openApiApiKeyInput = ''
25243
25498
  onScroll: HandleMessagesScroll,
25244
25499
  scrollTop: messagesScrollTop,
25245
25500
  type: Div
25246
- }, ...displayMessages.flatMap(message => getChatMessageDom(message, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState))];
25501
+ }, ...displayMessages.flatMap(message => getChatMessageDom(message, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, useChatMathWorker))];
25247
25502
  };
25248
25503
 
25249
25504
  const getProjectSessionDom = (session, selectedSessionId) => {
@@ -25331,29 +25586,17 @@ const getProjectListDom = (projects, sessions, projectExpandedIds, selectedProje
25331
25586
  }, text$2('+ Add Project')];
25332
25587
  };
25333
25588
 
25334
- const getChatModeChatFocusVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState = 'idle', composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, messagesScrollTop = 0, composerDropActive = false, composerDropEnabled = true, projects = [], projectExpandedIds = [], selectedProjectId = '', projectListScrollTop = 0, voiceDictationEnabled = false) => {
25589
+ const getChatModeChatFocusVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState = 'idle', composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, messagesScrollTop = 0, composerDropActive = false, composerDropEnabled = true, projects = [], projectExpandedIds = [], selectedProjectId = '', projectListScrollTop = 0, voiceDictationEnabled = false, useChatMathWorker = false) => {
25335
25590
  const selectedSession = sessions.find(session => session.id === selectedSessionId);
25336
- const selectedSessionTitle = selectedSession?.title || chatTitle();
25337
25591
  const messages = selectedSession ? selectedSession.messages : [];
25338
25592
  const isDropOverlayVisible = composerDropEnabled && composerDropActive;
25339
25593
  return [{
25340
- childCount: 5,
25594
+ childCount: 4,
25341
25595
  className: mergeClassNames(Viewlet, Chat, 'ChatFocus'),
25342
25596
  onDragEnter: HandleDragEnterChatView,
25343
25597
  onDragOver: HandleDragOverChatView,
25344
25598
  type: Div
25345
- }, {
25346
- childCount: 1,
25347
- className: ChatHeader,
25348
- type: Div
25349
- }, {
25350
- childCount: 1,
25351
- className: Label,
25352
- type: Span$1
25353
- }, {
25354
- text: selectedSessionTitle,
25355
- type: Text
25356
- }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, voiceDictationEnabled), {
25599
+ }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, voiceDictationEnabled), {
25357
25600
  childCount: 1,
25358
25601
  className: mergeClassNames(ChatViewDropOverlay, isDropOverlayVisible ? ChatViewDropOverlayActive : Empty),
25359
25602
  name: ComposerDropTarget,
@@ -25449,7 +25692,7 @@ const getChatHeaderDomDetailMode = selectedSessionTitle => {
25449
25692
  }, text$2(selectedSessionTitle), ...getChatHeaderActionsDom('detail')];
25450
25693
  };
25451
25694
 
25452
- const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState = 'idle', composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, messagesScrollTop = 0, composerDropActive = false, composerDropEnabled = true, voiceDictationEnabled = false) => {
25695
+ const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState = 'idle', composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, messagesScrollTop = 0, composerDropActive = false, composerDropEnabled = true, voiceDictationEnabled = false, useChatMathWorker = false) => {
25453
25696
  const selectedSession = sessions.find(session => session.id === selectedSessionId);
25454
25697
  const selectedSessionTitle = selectedSession?.title || chatTitle();
25455
25698
  const messages = selectedSession ? selectedSession.messages : [];
@@ -25460,7 +25703,7 @@ const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue,
25460
25703
  onDragEnter: HandleDragEnterChatView,
25461
25704
  onDragOver: HandleDragOverChatView,
25462
25705
  type: Div
25463
- }, ...getChatHeaderDomDetailMode(selectedSessionTitle), ...getMessagesDom(messages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, voiceDictationEnabled), {
25706
+ }, ...getChatHeaderDomDetailMode(selectedSessionTitle), ...getMessagesDom(messages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, voiceDictationEnabled), {
25464
25707
  childCount: 1,
25465
25708
  className: mergeClassNames(ChatViewDropOverlay, isDropOverlayVisible ? ChatViewDropOverlayActive : Empty),
25466
25709
  name: ComposerDropTarget,
@@ -25570,12 +25813,12 @@ const getChatModeUnsupportedVirtualDom = () => {
25570
25813
  }, text$2(unknownViewMode())];
25571
25814
  };
25572
25815
 
25573
- const getChatVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop, composerDropActive = false, composerDropEnabled = true, projects = [], projectExpandedIds = [], selectedProjectId = '', projectListScrollTop = 0, voiceDictationEnabled = false) => {
25816
+ const getChatVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop, composerDropActive = false, composerDropEnabled = true, projects = [], projectExpandedIds = [], selectedProjectId = '', projectListScrollTop = 0, voiceDictationEnabled = false, useChatMathWorker = false) => {
25574
25817
  switch (viewMode) {
25575
25818
  case 'chat-focus':
25576
- return getChatModeChatFocusVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, messagesScrollTop, composerDropActive, composerDropEnabled, projects, projectExpandedIds, selectedProjectId, projectListScrollTop, voiceDictationEnabled);
25819
+ return getChatModeChatFocusVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, messagesScrollTop, composerDropActive, composerDropEnabled, projects, projectExpandedIds, selectedProjectId, projectListScrollTop, voiceDictationEnabled, useChatMathWorker);
25577
25820
  case 'detail':
25578
- return getChatModeDetailVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, messagesScrollTop, composerDropActive, composerDropEnabled, voiceDictationEnabled);
25821
+ return getChatModeDetailVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, messagesScrollTop, composerDropActive, composerDropEnabled, voiceDictationEnabled, useChatMathWorker);
25579
25822
  case 'list':
25580
25823
  return getChatModeListVirtualDom(sessions, selectedSessionId, composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, composerDropActive, composerDropEnabled, voiceDictationEnabled);
25581
25824
  default:
@@ -25610,13 +25853,14 @@ const renderItems = (oldState, newState) => {
25610
25853
  tokensUsed,
25611
25854
  uid,
25612
25855
  usageOverviewEnabled,
25856
+ useChatMathWorker,
25613
25857
  viewMode,
25614
25858
  voiceDictationEnabled
25615
25859
  } = newState;
25616
25860
  if (initial) {
25617
25861
  return [SetDom2, uid, []];
25618
25862
  }
25619
- const dom = getChatVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop, composerDropActive, composerDropEnabled, projects, projectExpandedIds, selectedProjectId, projectListScrollTop, voiceDictationEnabled);
25863
+ const dom = getChatVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop, composerDropActive, composerDropEnabled, projects, projectExpandedIds, selectedProjectId, projectListScrollTop, voiceDictationEnabled, useChatMathWorker);
25620
25864
  return [SetDom2, uid, dom];
25621
25865
  };
25622
25866
 
@@ -25637,9 +25881,10 @@ const renderScrollTop = (oldState, newState) => {
25637
25881
 
25638
25882
  const renderValue = (oldState, newState) => {
25639
25883
  const {
25640
- composerValue
25884
+ composerValue,
25885
+ uid
25641
25886
  } = newState;
25642
- return [SetValueByName, newState.uid, Composer, composerValue];
25887
+ return [SetValueByName, uid, Composer, composerValue];
25643
25888
  };
25644
25889
 
25645
25890
  const getRenderer = diffType => {
@@ -25932,6 +26177,18 @@ const setStreamingEnabled = (state, streamingEnabled) => {
25932
26177
  };
25933
26178
  };
25934
26179
 
26180
+ const setUseChatMathWorker = async (state, useChatMathWorker, persist = true) => {
26181
+ if (persist) {
26182
+ await update({
26183
+ 'chatView.useChatMathWorker': useChatMathWorker
26184
+ });
26185
+ }
26186
+ return {
26187
+ ...state,
26188
+ useChatMathWorker
26189
+ };
26190
+ };
26191
+
25935
26192
  const setUseChatNetworkWorkerForRequests = async (state, useChatNetworkWorkerForRequests, persist = true) => {
25936
26193
  if (persist) {
25937
26194
  await update({
@@ -25993,7 +26250,7 @@ const commandMap = {
25993
26250
  'Chat.handleProjectListContextMenu': wrapCommand(handleProjectListContextMenu),
25994
26251
  'Chat.handleProjectListScroll': wrapCommand(handleProjectListScroll),
25995
26252
  'Chat.handleSubmit': wrapCommand(handleSubmit),
25996
- 'Chat.initialize': initialize,
26253
+ 'Chat.initialize': initialize$1,
25997
26254
  'Chat.loadContent': wrapCommand(loadContent),
25998
26255
  'Chat.loadContent2': wrapCommand(loadContent),
25999
26256
  'Chat.mockOpenApiRequestGetAll': wrapGetter(mockOpenApiRequestGetAll),
@@ -26014,11 +26271,16 @@ const commandMap = {
26014
26271
  'Chat.setEmitStreamingFunctionCallEvents': wrapCommand(setEmitStreamingFunctionCallEvents),
26015
26272
  'Chat.setOpenRouterApiKey': wrapCommand(setOpenRouterApiKey),
26016
26273
  'Chat.setStreamingEnabled': wrapCommand(setStreamingEnabled),
26274
+ 'Chat.setUseChatMathWorker': wrapCommand(setUseChatMathWorker),
26017
26275
  'Chat.setUseChatNetworkWorkerForRequests': wrapCommand(setUseChatNetworkWorkerForRequests),
26018
26276
  'Chat.terminate': terminate,
26019
26277
  'Chat.useMockApi': wrapCommand(useMockApi)
26020
26278
  };
26021
26279
 
26280
+ const initializeChatMathWorker = async () => {
26281
+ await initialize();
26282
+ };
26283
+
26022
26284
  const send = port => {
26023
26285
  return sendMessagePortToChatNetworkWorker(port);
26024
26286
  };
@@ -26036,7 +26298,7 @@ const listen = async () => {
26036
26298
  commandMap: commandMap
26037
26299
  });
26038
26300
  set$1(rpc);
26039
- await initializeChatNetworkWorker();
26301
+ await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker()]);
26040
26302
  };
26041
26303
 
26042
26304
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-view",
3
- "version": "4.3.0",
3
+ "version": "4.5.0",
4
4
  "description": "Chat View Worker",
5
5
  "repository": {
6
6
  "type": "git",