@lvce-editor/chat-view 6.0.0 → 6.2.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.
@@ -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$6 = (id, rpc) => {
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$6(rpcId, mockRpc);
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$6(rpcId, rpc);
1072
+ set$8(rpcId, rpc);
1073
1073
  }
1074
1074
  };
1075
1075
  };
1076
1076
 
1077
1077
  const {
1078
- invoke: invoke$4,
1079
- set: set$5
1078
+ invoke: invoke$5,
1079
+ set: set$7
1080
1080
  } = create$2(6007);
1081
1081
  const getMathBlockDom = async node => {
1082
- return invoke$4('ChatMath.getMathBlockDom', node);
1082
+ return invoke$5('ChatMath.getMathBlockDom', node);
1083
1083
  };
1084
1084
  const getMathInlineDom = async node => {
1085
- return invoke$4('ChatMath.getMathInlineDom', node);
1085
+ return invoke$5('ChatMath.getMathInlineDom', node);
1086
1086
  };
1087
1087
 
1088
1088
  const Button$2 = 'button';
@@ -1157,7 +1157,9 @@ const None = 0;
1157
1157
  const RestoreFocus = 6;
1158
1158
 
1159
1159
  const ChatNetworkWorker = 6002;
1160
+ const ChatToolWorker = 6005;
1160
1161
  const ExtensionHostWorker = 44;
1162
+ const OpenerWorker = 4561;
1161
1163
  const RendererWorker = 1;
1162
1164
 
1163
1165
  const FocusSelector = 'Viewlet.focusSelector';
@@ -1171,20 +1173,33 @@ const SetPatches = 'Viewlet.setPatches';
1171
1173
  const FocusChatInput = 8000;
1172
1174
 
1173
1175
  const {
1174
- invoke: invoke$3,
1175
- set: set$4
1176
+ invoke: invoke$4,
1177
+ set: set$6
1176
1178
  } = create$2(ChatNetworkWorker);
1177
1179
 
1180
+ const {
1181
+ invoke: invoke$3,
1182
+ set: set$5
1183
+ } = create$2(ChatToolWorker);
1184
+
1178
1185
  const {
1179
1186
  invoke: invoke$2,
1180
- set: set$3
1187
+ set: set$4
1181
1188
  } = create$2(ExtensionHostWorker);
1182
1189
 
1190
+ const {
1191
+ set: set$3
1192
+ } = create$2(OpenerWorker);
1193
+
1183
1194
  const {
1184
1195
  invoke: invoke$1,
1185
1196
  invokeAndTransfer,
1186
1197
  set: set$2
1187
1198
  } = create$2(RendererWorker);
1199
+ const sendMessagePortToOpenerWorker$1 = async (port, rpcId) => {
1200
+ const command = 'HandleMessagePort.handleMessagePort';
1201
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToOpenerWorker', port, command, rpcId);
1202
+ };
1188
1203
  const sendMessagePortToChatMathWorker$1 = async (port, rpcId) => {
1189
1204
  const command = 'HandleMessagePort.handleMessagePort';
1190
1205
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatMathWorker', port, command, rpcId);
@@ -1199,6 +1214,9 @@ const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
1199
1214
  const sendMessagePortToChatNetworkWorker = async port => {
1200
1215
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatNetworkWorker', port, 'HandleMessagePort.handleMessagePort');
1201
1216
  };
1217
+ const sendMessagePortToChatToolWorker = async port => {
1218
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatToolWorker', port, 'HandleMessagePort.handleMessagePort');
1219
+ };
1202
1220
  const writeFile = async (uri, text) => {
1203
1221
  await invoke$1('FileSystem.writeFile', uri, text);
1204
1222
  };
@@ -1647,6 +1665,7 @@ const createDefaultState = () => {
1647
1665
  useChatCoordinatorWorker: true,
1648
1666
  useChatMathWorker: true,
1649
1667
  useChatNetworkWorkerForRequests: false,
1668
+ useChatToolWorker: false,
1650
1669
  useMockApi: false,
1651
1670
  viewMode: 'list',
1652
1671
  voiceDictationEnabled: false,
@@ -3105,6 +3124,10 @@ const getAiResponse$1 = async options => {
3105
3124
  return invoke('ChatCoordinator.getAiResponse', options);
3106
3125
  };
3107
3126
 
3127
+ const execute = async (name, rawArguments, options) => {
3128
+ return invoke$3('ChatTool.execute', name, rawArguments, options);
3129
+ };
3130
+
3108
3131
  const getToolErrorPayload = error => {
3109
3132
  const rawStack = error && typeof error === 'object' ? Reflect.get(error, 'stack') : undefined;
3110
3133
  return {
@@ -3283,6 +3306,12 @@ const parseToolArguments = rawArguments => {
3283
3306
  };
3284
3307
 
3285
3308
  const executeChatTool = async (name, rawArguments, options) => {
3309
+ if (options.useChatToolWorker) {
3310
+ return execute(name, rawArguments, {
3311
+ assetDir: options.assetDir,
3312
+ platform: options.platform
3313
+ });
3314
+ }
3286
3315
  const args = parseToolArguments(rawArguments);
3287
3316
  if (name === 'read_file') {
3288
3317
  return executeReadFileTool(args);
@@ -3871,10 +3900,10 @@ const getOpenApiApiEndpoint = openApiApiBaseUrl => {
3871
3900
  };
3872
3901
 
3873
3902
  const makeApiRequest = async options => {
3874
- return invoke$3('ChatNetwork.makeApiRequest', options);
3903
+ return invoke$4('ChatNetwork.makeApiRequest', options);
3875
3904
  };
3876
3905
  const makeStreamingApiRequest = async options => {
3877
- return invoke$3('ChatNetwork.makeStreamingApiRequest', options);
3906
+ return invoke$4('ChatNetwork.makeStreamingApiRequest', options);
3878
3907
  };
3879
3908
 
3880
3909
  const getTextContent = content => {
@@ -4504,6 +4533,7 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
4504
4533
  onToolCallsChunk,
4505
4534
  stream,
4506
4535
  useChatNetworkWorkerForRequests = false,
4536
+ useChatToolWorker = false,
4507
4537
  webSearchEnabled = false
4508
4538
  } = options ?? {
4509
4539
  stream: false
@@ -4609,7 +4639,11 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
4609
4639
  openAiInput.length = 0;
4610
4640
  const executedToolCalls = [];
4611
4641
  for (const toolCall of streamResult.responseFunctionCalls) {
4612
- const content = await executeChatTool(toolCall.name, toolCall.arguments);
4642
+ const content = await executeChatTool(toolCall.name, toolCall.arguments, {
4643
+ assetDir,
4644
+ platform,
4645
+ useChatToolWorker
4646
+ });
4613
4647
  const executionStatus = getToolCallExecutionStatus(content);
4614
4648
  executedToolCalls.push({
4615
4649
  arguments: toolCall.arguments,
@@ -4750,7 +4784,11 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
4750
4784
  openAiInput.length = 0;
4751
4785
  const executedToolCalls = [];
4752
4786
  for (const toolCall of responseFunctionCalls) {
4753
- const content = await executeChatTool(toolCall.name, toolCall.arguments);
4787
+ const content = await executeChatTool(toolCall.name, toolCall.arguments, {
4788
+ assetDir,
4789
+ platform,
4790
+ useChatToolWorker
4791
+ });
4754
4792
  const executionStatus = getToolCallExecutionStatus(content);
4755
4793
  executedToolCalls.push({
4756
4794
  arguments: toolCall.arguments,
@@ -4818,7 +4856,11 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
4818
4856
  }
4819
4857
  const name = Reflect.get(toolFunction, 'name');
4820
4858
  const rawArguments = Reflect.get(toolFunction, 'arguments');
4821
- const content = typeof name === 'string' ? await executeChatTool(name, rawArguments) : '{}';
4859
+ const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
4860
+ assetDir,
4861
+ platform,
4862
+ useChatToolWorker
4863
+ }) : '{}';
4822
4864
  if (typeof name === 'string') {
4823
4865
  const executionStatus = getToolCallExecutionStatus(content);
4824
4866
  executedToolCalls.push({
@@ -5066,7 +5108,7 @@ const getOpenRouterLimitInfo = async (openRouterApiKey, openRouterApiBaseUrl, us
5066
5108
  }
5067
5109
  return normalizedLimitInfo;
5068
5110
  };
5069
- const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false) => {
5111
+ const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests = false, useChatToolWorker = false) => {
5070
5112
  const completionMessages = messages.map(message => ({
5071
5113
  content: message.text,
5072
5114
  role: message.role
@@ -5221,7 +5263,11 @@ const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, o
5221
5263
  }
5222
5264
  const name = Reflect.get(toolFunction, 'name');
5223
5265
  const rawArguments = Reflect.get(toolFunction, 'arguments');
5224
- const content = typeof name === 'string' ? await executeChatTool(name, rawArguments) : '{}';
5266
+ const content = typeof name === 'string' ? await executeChatTool(name, rawArguments, {
5267
+ assetDir,
5268
+ platform,
5269
+ useChatToolWorker
5270
+ }) : '{}';
5225
5271
  completionMessages.push({
5226
5272
  content,
5227
5273
  role: 'tool',
@@ -5350,6 +5396,7 @@ const getAiResponse = async ({
5350
5396
  streamingEnabled = true,
5351
5397
  useChatCoordinatorWorker = false,
5352
5398
  useChatNetworkWorkerForRequests = false,
5399
+ useChatToolWorker = false,
5353
5400
  useMockApi,
5354
5401
  userText,
5355
5402
  webSearchEnabled = false
@@ -5375,6 +5422,7 @@ const getAiResponse = async ({
5375
5422
  selectedModelId,
5376
5423
  streamingEnabled,
5377
5424
  useChatNetworkWorkerForRequests,
5425
+ useChatToolWorker,
5378
5426
  useMockApi,
5379
5427
  userText,
5380
5428
  webSearchEnabled
@@ -5430,7 +5478,11 @@ const getAiResponse = async ({
5430
5478
  }
5431
5479
  openAiInput.length = 0;
5432
5480
  for (const toolCall of result.responseFunctionCalls) {
5433
- const content = await executeChatTool(toolCall.name, toolCall.arguments);
5481
+ const content = await executeChatTool(toolCall.name, toolCall.arguments, {
5482
+ assetDir,
5483
+ platform,
5484
+ useChatToolWorker
5485
+ });
5434
5486
  openAiInput.push({
5435
5487
  call_id: toolCall.callId,
5436
5488
  output: content,
@@ -5455,6 +5507,7 @@ const getAiResponse = async ({
5455
5507
  } : {}),
5456
5508
  stream: streamingEnabled,
5457
5509
  useChatNetworkWorkerForRequests,
5510
+ useChatToolWorker,
5458
5511
  webSearchEnabled
5459
5512
  });
5460
5513
  if (result.type === 'success') {
@@ -5481,7 +5534,7 @@ const getAiResponse = async ({
5481
5534
  text = getOpenRouterErrorMessage(result);
5482
5535
  }
5483
5536
  } else if (openRouterApiKey) {
5484
- const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests);
5537
+ const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests, useChatToolWorker);
5485
5538
  if (result.type === 'success') {
5486
5539
  const {
5487
5540
  text: assistantText
@@ -5752,6 +5805,48 @@ const parseLinkToken = (value, start) => {
5752
5805
  }
5753
5806
  return undefined;
5754
5807
  };
5808
+ const parseImageToken = (value, start) => {
5809
+ if (value[start] !== '!' || value[start + 1] !== '[') {
5810
+ return undefined;
5811
+ }
5812
+ const textEnd = value.indexOf(']', start + 2);
5813
+ if (textEnd === -1) {
5814
+ return undefined;
5815
+ }
5816
+ if (value[textEnd + 1] !== '(') {
5817
+ return undefined;
5818
+ }
5819
+ let depth = 1;
5820
+ let index = textEnd + 2;
5821
+ while (index < value.length) {
5822
+ const current = value[index];
5823
+ if (current === '\n') {
5824
+ return undefined;
5825
+ }
5826
+ if (current === '(') {
5827
+ depth++;
5828
+ } else if (current === ')') {
5829
+ depth--;
5830
+ if (depth === 0) {
5831
+ const alt = value.slice(start + 2, textEnd);
5832
+ const src = value.slice(textEnd + 2, index);
5833
+ if (!src) {
5834
+ return undefined;
5835
+ }
5836
+ return {
5837
+ length: index - start + 1,
5838
+ node: {
5839
+ alt,
5840
+ src: sanitizeUrl(src),
5841
+ type: 'image'
5842
+ }
5843
+ };
5844
+ }
5845
+ }
5846
+ index++;
5847
+ }
5848
+ return undefined;
5849
+ };
5755
5850
  const parseBoldToken = (value, start) => {
5756
5851
  if (value[start] !== '*' || value[start + 1] !== '*') {
5757
5852
  return undefined;
@@ -5813,6 +5908,26 @@ const parseItalicToken = (value, start) => {
5813
5908
  }
5814
5909
  };
5815
5910
  };
5911
+ const parseStrikethroughToken = (value, start) => {
5912
+ if (value[start] !== '~' || value[start + 1] !== '~') {
5913
+ return undefined;
5914
+ }
5915
+ const end = value.indexOf('~~', start + 2);
5916
+ if (end === -1) {
5917
+ return undefined;
5918
+ }
5919
+ const text = value.slice(start + 2, end);
5920
+ if (!text || text.includes('\n')) {
5921
+ return undefined;
5922
+ }
5923
+ return {
5924
+ length: end - start + 2,
5925
+ node: {
5926
+ children: parseInlineNodes(text),
5927
+ type: 'strikethrough'
5928
+ }
5929
+ };
5930
+ };
5816
5931
  const parseMathToken = (value, start) => {
5817
5932
  if (value[start] !== '$') {
5818
5933
  return undefined;
@@ -5859,7 +5974,7 @@ const parseMathToken = (value, start) => {
5859
5974
  return undefined;
5860
5975
  };
5861
5976
  const parseInlineToken = (value, start) => {
5862
- return parseLinkToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseMathToken(value, start);
5977
+ 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);
5863
5978
  };
5864
5979
  const parseInlineNodes = value => {
5865
5980
  const nodes = [];
@@ -5895,105 +6010,311 @@ const parseInlineNodes = value => {
5895
6010
  return nodes;
5896
6011
  };
5897
6012
 
5898
- const isTableSeparatorCell = value => {
5899
- if (!value) {
5900
- return false;
6013
+ const markdownMathBlockDelimiter = '$$';
6014
+ const normalizeEscapedNewlines = value => {
6015
+ if (value.includes('\\n')) {
6016
+ return value.replaceAll(/\\r\\n|\\n/g, '\n');
5901
6017
  }
6018
+ return value;
6019
+ };
6020
+ const normalizeInlineTables = value => {
6021
+ return value.split(/\r?\n/).map(line => {
6022
+ if (!line.includes('|')) {
6023
+ return line;
6024
+ }
6025
+ if (!/\|\s*[-:]{3,}/.test(line)) {
6026
+ return line;
6027
+ }
6028
+ return line.replaceAll(/\|\s+\|/g, '|\n|');
6029
+ }).join('\n');
6030
+ };
6031
+ const parseHeadingLine = line => {
6032
+ const trimmedStart = line.trimStart();
5902
6033
  let index = 0;
5903
- if (value[index] === ':') {
6034
+ while (index < trimmedStart.length && trimmedStart[index] === '#') {
5904
6035
  index++;
5905
6036
  }
5906
- let dashCount = 0;
5907
- while (index < value.length && value[index] === '-') {
5908
- dashCount++;
5909
- index++;
6037
+ if (index === 0 || index > 6) {
6038
+ return undefined;
5910
6039
  }
5911
- if (dashCount < 3) {
5912
- return false;
6040
+ if (trimmedStart[index] !== ' ') {
6041
+ return undefined;
5913
6042
  }
5914
- if (index < value.length && value[index] === ':') {
6043
+ const text = trimmedStart.slice(index).trimStart();
6044
+ return {
6045
+ level: index,
6046
+ text
6047
+ };
6048
+ };
6049
+ const parseOrderedListItemLine = line => {
6050
+ let index = 0;
6051
+ while (index < line.length && line[index] === ' ') {
5915
6052
  index++;
5916
6053
  }
5917
- return index === value.length;
5918
- };
5919
- const isTableSeparatorToken = (token, expectedColumns) => {
5920
- if (!token || token.type !== 'table-row-line') {
5921
- return false;
6054
+ const firstDigit = index;
6055
+ while (index < line.length && line[index] >= '0' && line[index] <= '9') {
6056
+ index++;
5922
6057
  }
5923
- if (token.cells.length !== expectedColumns) {
5924
- return false;
6058
+ if (index === firstDigit || line[index] !== '.') {
6059
+ return undefined;
6060
+ }
6061
+ index++;
6062
+ if (line[index] !== ' ') {
6063
+ return undefined;
6064
+ }
6065
+ while (index < line.length && line[index] === ' ') {
6066
+ index++;
5925
6067
  }
5926
- return token.cells.every(isTableSeparatorCell);
5927
- };
5928
- const toTableCell = value => {
5929
6068
  return {
5930
- children: parseInlineNodes(value),
5931
- type: 'table-cell'
6069
+ text: line.slice(index)
5932
6070
  };
5933
6071
  };
5934
- const toTableRow = token => {
6072
+ const parseUnorderedListItemLine = line => {
6073
+ let indentation = 0;
6074
+ while (indentation < line.length && line[indentation] === ' ') {
6075
+ indentation++;
6076
+ }
6077
+ const marker = line[indentation];
6078
+ if (marker !== '-' && marker !== '*') {
6079
+ return undefined;
6080
+ }
6081
+ let index = indentation + 1;
6082
+ if (line[index] !== ' ') {
6083
+ return undefined;
6084
+ }
6085
+ while (index < line.length && line[index] === ' ') {
6086
+ index++;
6087
+ }
5935
6088
  return {
5936
- cells: token.cells.map(toTableCell),
5937
- type: 'table-row'
6089
+ indentation,
6090
+ text: line.slice(index)
5938
6091
  };
5939
6092
  };
5940
- const getEmptyTextNode = () => {
5941
- return [{
5942
- children: [{
5943
- text: '',
5944
- type: 'text'
5945
- }],
5946
- type: 'text'
5947
- }];
6093
+ const parseBlockQuoteLine = line => {
6094
+ const trimmedStart = line.trimStart();
6095
+ if (!trimmedStart.startsWith('>')) {
6096
+ return undefined;
6097
+ }
6098
+ const content = trimmedStart.slice(1);
6099
+ if (!content) {
6100
+ return '';
6101
+ }
6102
+ if (content.startsWith(' ')) {
6103
+ return content.slice(1);
6104
+ }
6105
+ return content;
5948
6106
  };
5949
- const parseBlockTokens = tokens => {
5950
- if (tokens.length === 0) {
5951
- return getEmptyTextNode();
6107
+ const isTableRow = line => {
6108
+ const trimmed = line.trim();
6109
+ if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) {
6110
+ return false;
5952
6111
  }
5953
- const nodes = [];
5954
- let paragraphLines = [];
5955
- let listItems = [];
5956
- let listType = '';
5957
- const flushParagraph = () => {
5958
- if (paragraphLines.length === 0) {
5959
- return;
5960
- }
5961
- nodes.push({
5962
- children: parseInlineNodes(paragraphLines.join('\n')),
5963
- type: 'text'
5964
- });
5965
- paragraphLines = [];
5966
- };
5967
- const flushList = () => {
5968
- if (listItems.length === 0) {
5969
- return;
6112
+ return trimmed.length > 2 && trimmed.slice(1, -1).includes('|');
6113
+ };
6114
+ const getTableCells = line => {
6115
+ const trimmed = line.trim();
6116
+ return trimmed.slice(1, -1).split('|').map(part => part.trim());
6117
+ };
6118
+ const scanBlockTokens = rawMessage => {
6119
+ const normalizedMessage = normalizeInlineTables(normalizeEscapedNewlines(rawMessage));
6120
+ const lines = normalizedMessage.split(/\r?\n/);
6121
+ const tokens = [];
6122
+ for (let i = 0; i < lines.length; i++) {
6123
+ const line = lines[i];
6124
+ const trimmed = line.trim();
6125
+ if (!trimmed) {
6126
+ tokens.push({
6127
+ type: 'blank-line'
6128
+ });
6129
+ continue;
5970
6130
  }
5971
- nodes.push({
5972
- items: listItems,
5973
- type: listType || 'ordered-list'
5974
- });
5975
- listItems = [];
5976
- listType = '';
5977
- };
5978
- for (let i = 0; i < tokens.length; i++) {
5979
- const token = tokens[i];
5980
- if (token.type === 'blank-line') {
5981
- flushList();
5982
- flushParagraph();
6131
+ const blockQuoteLine = parseBlockQuoteLine(line);
6132
+ if (blockQuoteLine !== undefined) {
6133
+ tokens.push({
6134
+ text: blockQuoteLine,
6135
+ type: 'blockquote-line'
6136
+ });
5983
6137
  continue;
5984
6138
  }
5985
- if (token.type === 'code-block') {
5986
- flushList();
5987
- flushParagraph();
5988
- if (token.language) {
5989
- nodes.push({
5990
- language: token.language,
5991
- text: token.text,
6139
+ if (trimmed.startsWith('```')) {
6140
+ const language = trimmed.slice(3).trim();
6141
+ const codeLines = [];
6142
+ i++;
6143
+ while (i < lines.length && !lines[i].trim().startsWith('```')) {
6144
+ codeLines.push(lines[i]);
6145
+ i++;
6146
+ }
6147
+ if (language) {
6148
+ tokens.push({
6149
+ language,
6150
+ text: codeLines.join('\n'),
5992
6151
  type: 'code-block'
5993
6152
  });
5994
6153
  } else {
5995
- nodes.push({
5996
- text: token.text,
6154
+ tokens.push({
6155
+ text: codeLines.join('\n'),
6156
+ type: 'code-block'
6157
+ });
6158
+ }
6159
+ continue;
6160
+ }
6161
+ if (trimmed === markdownMathBlockDelimiter) {
6162
+ const endIndex = lines.findIndex((candidate, index) => {
6163
+ if (index <= i) {
6164
+ return false;
6165
+ }
6166
+ return candidate.trim() === markdownMathBlockDelimiter;
6167
+ });
6168
+ if (endIndex !== -1) {
6169
+ tokens.push({
6170
+ text: lines.slice(i + 1, endIndex).join('\n').trim(),
6171
+ type: 'math-block'
6172
+ });
6173
+ i = endIndex;
6174
+ continue;
6175
+ }
6176
+ }
6177
+ const heading = parseHeadingLine(line);
6178
+ if (heading) {
6179
+ tokens.push({
6180
+ level: heading.level,
6181
+ text: heading.text,
6182
+ type: 'heading-line'
6183
+ });
6184
+ continue;
6185
+ }
6186
+ const ordered = parseOrderedListItemLine(line);
6187
+ if (ordered) {
6188
+ tokens.push({
6189
+ text: ordered.text,
6190
+ type: 'ordered-list-item-line'
6191
+ });
6192
+ continue;
6193
+ }
6194
+ const unordered = parseUnorderedListItemLine(line);
6195
+ if (unordered) {
6196
+ tokens.push({
6197
+ indentation: unordered.indentation,
6198
+ text: unordered.text,
6199
+ type: 'unordered-list-item-line'
6200
+ });
6201
+ continue;
6202
+ }
6203
+ if (isTableRow(line)) {
6204
+ tokens.push({
6205
+ cells: getTableCells(line),
6206
+ line,
6207
+ type: 'table-row-line'
6208
+ });
6209
+ continue;
6210
+ }
6211
+ tokens.push({
6212
+ text: line,
6213
+ type: 'paragraph-line'
6214
+ });
6215
+ }
6216
+ return tokens;
6217
+ };
6218
+
6219
+ const isTableSeparatorCell = value => {
6220
+ if (!value) {
6221
+ return false;
6222
+ }
6223
+ let index = 0;
6224
+ if (value[index] === ':') {
6225
+ index++;
6226
+ }
6227
+ let dashCount = 0;
6228
+ while (index < value.length && value[index] === '-') {
6229
+ dashCount++;
6230
+ index++;
6231
+ }
6232
+ if (dashCount < 3) {
6233
+ return false;
6234
+ }
6235
+ if (index < value.length && value[index] === ':') {
6236
+ index++;
6237
+ }
6238
+ return index === value.length;
6239
+ };
6240
+ const isTableSeparatorToken = (token, expectedColumns) => {
6241
+ if (!token || token.type !== 'table-row-line') {
6242
+ return false;
6243
+ }
6244
+ if (token.cells.length !== expectedColumns) {
6245
+ return false;
6246
+ }
6247
+ return token.cells.every(isTableSeparatorCell);
6248
+ };
6249
+ const toTableCell = value => {
6250
+ return {
6251
+ children: parseInlineNodes(value),
6252
+ type: 'table-cell'
6253
+ };
6254
+ };
6255
+ const toTableRow = token => {
6256
+ return {
6257
+ cells: token.cells.map(toTableCell),
6258
+ type: 'table-row'
6259
+ };
6260
+ };
6261
+ const getEmptyTextNode = () => {
6262
+ return [{
6263
+ children: [{
6264
+ text: '',
6265
+ type: 'text'
6266
+ }],
6267
+ type: 'text'
6268
+ }];
6269
+ };
6270
+ const parseBlockTokens = tokens => {
6271
+ if (tokens.length === 0) {
6272
+ return getEmptyTextNode();
6273
+ }
6274
+ const nodes = [];
6275
+ let paragraphLines = [];
6276
+ let listItems = [];
6277
+ let listType = '';
6278
+ const flushParagraph = () => {
6279
+ if (paragraphLines.length === 0) {
6280
+ return;
6281
+ }
6282
+ nodes.push({
6283
+ children: parseInlineNodes(paragraphLines.join('\n')),
6284
+ type: 'text'
6285
+ });
6286
+ paragraphLines = [];
6287
+ };
6288
+ const flushList = () => {
6289
+ if (listItems.length === 0) {
6290
+ return;
6291
+ }
6292
+ nodes.push({
6293
+ items: listItems,
6294
+ type: listType || 'ordered-list'
6295
+ });
6296
+ listItems = [];
6297
+ listType = '';
6298
+ };
6299
+ for (let i = 0; i < tokens.length; i++) {
6300
+ const token = tokens[i];
6301
+ if (token.type === 'blank-line') {
6302
+ flushList();
6303
+ flushParagraph();
6304
+ continue;
6305
+ }
6306
+ if (token.type === 'code-block') {
6307
+ flushList();
6308
+ flushParagraph();
6309
+ if (token.language) {
6310
+ nodes.push({
6311
+ language: token.language,
6312
+ text: token.text,
6313
+ type: 'code-block'
6314
+ });
6315
+ } else {
6316
+ nodes.push({
6317
+ text: token.text,
5997
6318
  type: 'code-block'
5998
6319
  });
5999
6320
  }
@@ -6008,6 +6329,24 @@ const parseBlockTokens = tokens => {
6008
6329
  });
6009
6330
  continue;
6010
6331
  }
6332
+ if (token.type === 'blockquote-line') {
6333
+ flushList();
6334
+ flushParagraph();
6335
+ const lines = [];
6336
+ while (i < tokens.length && tokens[i].type === 'blockquote-line') {
6337
+ const quoteToken = tokens[i];
6338
+ if (quoteToken.type === 'blockquote-line') {
6339
+ lines.push(quoteToken.text);
6340
+ }
6341
+ i++;
6342
+ }
6343
+ i--;
6344
+ nodes.push({
6345
+ children: parseBlockTokens(scanBlockTokens(lines.join('\n'))),
6346
+ type: 'blockquote'
6347
+ });
6348
+ continue;
6349
+ }
6011
6350
  if (token.type === 'table-row-line') {
6012
6351
  const expectedColumns = token.cells.length;
6013
6352
  if (isTableSeparatorToken(tokens[i + 1], expectedColumns)) {
@@ -6094,190 +6433,6 @@ const parseBlockTokens = tokens => {
6094
6433
  return nodes.length === 0 ? getEmptyTextNode() : nodes;
6095
6434
  };
6096
6435
 
6097
- const markdownMathBlockDelimiter = '$$';
6098
- const normalizeEscapedNewlines = value => {
6099
- if (value.includes('\\n')) {
6100
- return value.replaceAll(/\\r\\n|\\n/g, '\n');
6101
- }
6102
- return value;
6103
- };
6104
- const normalizeInlineTables = value => {
6105
- return value.split(/\r?\n/).map(line => {
6106
- if (!line.includes('|')) {
6107
- return line;
6108
- }
6109
- if (!/\|\s*[-:]{3,}/.test(line)) {
6110
- return line;
6111
- }
6112
- return line.replaceAll(/\|\s+\|/g, '|\n|');
6113
- }).join('\n');
6114
- };
6115
- const parseHeadingLine = line => {
6116
- const trimmedStart = line.trimStart();
6117
- let index = 0;
6118
- while (index < trimmedStart.length && trimmedStart[index] === '#') {
6119
- index++;
6120
- }
6121
- if (index === 0 || index > 6) {
6122
- return undefined;
6123
- }
6124
- if (trimmedStart[index] !== ' ') {
6125
- return undefined;
6126
- }
6127
- const text = trimmedStart.slice(index).trimStart();
6128
- return {
6129
- level: index,
6130
- text
6131
- };
6132
- };
6133
- const parseOrderedListItemLine = line => {
6134
- let index = 0;
6135
- while (index < line.length && line[index] === ' ') {
6136
- index++;
6137
- }
6138
- const firstDigit = index;
6139
- while (index < line.length && line[index] >= '0' && line[index] <= '9') {
6140
- index++;
6141
- }
6142
- if (index === firstDigit || line[index] !== '.') {
6143
- return undefined;
6144
- }
6145
- index++;
6146
- if (line[index] !== ' ') {
6147
- return undefined;
6148
- }
6149
- while (index < line.length && line[index] === ' ') {
6150
- index++;
6151
- }
6152
- return {
6153
- text: line.slice(index)
6154
- };
6155
- };
6156
- const parseUnorderedListItemLine = line => {
6157
- let indentation = 0;
6158
- while (indentation < line.length && line[indentation] === ' ') {
6159
- indentation++;
6160
- }
6161
- const marker = line[indentation];
6162
- if (marker !== '-' && marker !== '*') {
6163
- return undefined;
6164
- }
6165
- let index = indentation + 1;
6166
- if (line[index] !== ' ') {
6167
- return undefined;
6168
- }
6169
- while (index < line.length && line[index] === ' ') {
6170
- index++;
6171
- }
6172
- return {
6173
- indentation,
6174
- text: line.slice(index)
6175
- };
6176
- };
6177
- const isTableRow = line => {
6178
- const trimmed = line.trim();
6179
- if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) {
6180
- return false;
6181
- }
6182
- return trimmed.length > 2 && trimmed.slice(1, -1).includes('|');
6183
- };
6184
- const getTableCells = line => {
6185
- const trimmed = line.trim();
6186
- return trimmed.slice(1, -1).split('|').map(part => part.trim());
6187
- };
6188
- const scanBlockTokens = rawMessage => {
6189
- const normalizedMessage = normalizeInlineTables(normalizeEscapedNewlines(rawMessage));
6190
- const lines = normalizedMessage.split(/\r?\n/);
6191
- const tokens = [];
6192
- for (let i = 0; i < lines.length; i++) {
6193
- const line = lines[i];
6194
- const trimmed = line.trim();
6195
- if (!trimmed) {
6196
- tokens.push({
6197
- type: 'blank-line'
6198
- });
6199
- continue;
6200
- }
6201
- if (trimmed.startsWith('```')) {
6202
- const language = trimmed.slice(3).trim();
6203
- const codeLines = [];
6204
- i++;
6205
- while (i < lines.length && !lines[i].trim().startsWith('```')) {
6206
- codeLines.push(lines[i]);
6207
- i++;
6208
- }
6209
- if (language) {
6210
- tokens.push({
6211
- language,
6212
- text: codeLines.join('\n'),
6213
- type: 'code-block'
6214
- });
6215
- } else {
6216
- tokens.push({
6217
- text: codeLines.join('\n'),
6218
- type: 'code-block'
6219
- });
6220
- }
6221
- continue;
6222
- }
6223
- if (trimmed === markdownMathBlockDelimiter) {
6224
- const endIndex = lines.findIndex((candidate, index) => {
6225
- if (index <= i) {
6226
- return false;
6227
- }
6228
- return candidate.trim() === markdownMathBlockDelimiter;
6229
- });
6230
- if (endIndex !== -1) {
6231
- tokens.push({
6232
- text: lines.slice(i + 1, endIndex).join('\n').trim(),
6233
- type: 'math-block'
6234
- });
6235
- i = endIndex;
6236
- continue;
6237
- }
6238
- }
6239
- const heading = parseHeadingLine(line);
6240
- if (heading) {
6241
- tokens.push({
6242
- level: heading.level,
6243
- text: heading.text,
6244
- type: 'heading-line'
6245
- });
6246
- continue;
6247
- }
6248
- const ordered = parseOrderedListItemLine(line);
6249
- if (ordered) {
6250
- tokens.push({
6251
- text: ordered.text,
6252
- type: 'ordered-list-item-line'
6253
- });
6254
- continue;
6255
- }
6256
- const unordered = parseUnorderedListItemLine(line);
6257
- if (unordered) {
6258
- tokens.push({
6259
- indentation: unordered.indentation,
6260
- text: unordered.text,
6261
- type: 'unordered-list-item-line'
6262
- });
6263
- continue;
6264
- }
6265
- if (isTableRow(line)) {
6266
- tokens.push({
6267
- cells: getTableCells(line),
6268
- line,
6269
- type: 'table-row-line'
6270
- });
6271
- continue;
6272
- }
6273
- tokens.push({
6274
- text: line,
6275
- type: 'paragraph-line'
6276
- });
6277
- }
6278
- return tokens;
6279
- };
6280
-
6281
6436
  const parseMessageContent = rawMessage => {
6282
6437
  return parseBlockTokens(scanBlockTokens(rawMessage));
6283
6438
  };
@@ -6314,6 +6469,13 @@ const parseMathInline = async children => {
6314
6469
  });
6315
6470
  continue;
6316
6471
  }
6472
+ if (child.type === 'strikethrough') {
6473
+ nextChildren.push({
6474
+ ...child,
6475
+ children: await parseMathInline(child.children)
6476
+ });
6477
+ continue;
6478
+ }
6317
6479
  nextChildren.push(child);
6318
6480
  }
6319
6481
  return nextChildren;
@@ -6342,60 +6504,69 @@ const parseMathTableCell = async cell => {
6342
6504
  children: await parseMathInline(cell.children)
6343
6505
  };
6344
6506
  };
6345
- const parseMessage = async rawMessage => {
6346
- const parsedContent = parseMessageContent(rawMessage);
6347
- const nextParsedContent = [];
6348
- for (const node of parsedContent) {
6349
- if (node.type === 'math-block') {
6350
- const dom = await getMathBlockDom(node);
6351
- nextParsedContent.push({
6352
- dom,
6353
- type: 'math-block-dom'
6354
- });
6355
- continue;
6356
- }
6357
- if (node.type === 'text' || node.type === 'heading') {
6358
- nextParsedContent.push({
6359
- ...node,
6360
- children: await parseMathInline(node.children)
6361
- });
6362
- continue;
6507
+ const parseMathNode = async node => {
6508
+ if (node.type === 'math-block') {
6509
+ const dom = await getMathBlockDom(node);
6510
+ return {
6511
+ dom,
6512
+ type: 'math-block-dom'
6513
+ };
6514
+ }
6515
+ if (node.type === 'text' || node.type === 'heading') {
6516
+ return {
6517
+ ...node,
6518
+ children: await parseMathInline(node.children)
6519
+ };
6520
+ }
6521
+ if (node.type === 'blockquote') {
6522
+ const children = [];
6523
+ for (const child of node.children) {
6524
+ children.push(await parseMathNode(child));
6363
6525
  }
6364
- if (node.type === 'ordered-list' || node.type === 'unordered-list') {
6365
- const items = [];
6366
- for (const item of node.items) {
6367
- items.push(await parseMathListItem(item));
6368
- }
6369
- nextParsedContent.push({
6370
- ...node,
6371
- items
6372
- });
6373
- continue;
6526
+ return {
6527
+ ...node,
6528
+ children
6529
+ };
6530
+ }
6531
+ if (node.type === 'ordered-list' || node.type === 'unordered-list') {
6532
+ const items = [];
6533
+ for (const item of node.items) {
6534
+ items.push(await parseMathListItem(item));
6374
6535
  }
6375
- if (node.type === 'table') {
6376
- const headers = [];
6377
- for (const header of node.headers) {
6378
- headers.push(await parseMathTableCell(header));
6379
- }
6380
- const rows = [];
6381
- for (const row of node.rows) {
6382
- const cells = [];
6383
- for (const cell of row.cells) {
6384
- cells.push(await parseMathTableCell(cell));
6385
- }
6386
- rows.push({
6387
- ...row,
6388
- cells
6389
- });
6536
+ return {
6537
+ ...node,
6538
+ items
6539
+ };
6540
+ }
6541
+ if (node.type === 'table') {
6542
+ const headers = [];
6543
+ for (const header of node.headers) {
6544
+ headers.push(await parseMathTableCell(header));
6545
+ }
6546
+ const rows = [];
6547
+ for (const row of node.rows) {
6548
+ const cells = [];
6549
+ for (const cell of row.cells) {
6550
+ cells.push(await parseMathTableCell(cell));
6390
6551
  }
6391
- nextParsedContent.push({
6392
- ...node,
6393
- headers,
6394
- rows
6552
+ rows.push({
6553
+ ...row,
6554
+ cells
6395
6555
  });
6396
- continue;
6397
6556
  }
6398
- nextParsedContent.push(node);
6557
+ return {
6558
+ ...node,
6559
+ headers,
6560
+ rows
6561
+ };
6562
+ }
6563
+ return node;
6564
+ };
6565
+ const parseMessage = async rawMessage => {
6566
+ const parsedContent = parseMessageContent(rawMessage);
6567
+ const nextParsedContent = [];
6568
+ for (const node of parsedContent) {
6569
+ nextParsedContent.push(await parseMathNode(node));
6399
6570
  }
6400
6571
  return nextParsedContent;
6401
6572
  };
@@ -6592,6 +6763,7 @@ Assistant: ${assistantText}`;
6592
6763
  streamingEnabled: false,
6593
6764
  useChatCoordinatorWorker: state.useChatCoordinatorWorker,
6594
6765
  useChatNetworkWorkerForRequests: state.useChatNetworkWorkerForRequests,
6766
+ useChatToolWorker: state.useChatToolWorker,
6595
6767
  useMockApi,
6596
6768
  userText: titlePrompt,
6597
6769
  webSearchEnabled: false
@@ -6876,6 +7048,7 @@ const handleSubmit = async state => {
6876
7048
  streamingEnabled,
6877
7049
  useChatCoordinatorWorker,
6878
7050
  useChatNetworkWorkerForRequests,
7051
+ useChatToolWorker,
6879
7052
  useMockApi,
6880
7053
  viewMode,
6881
7054
  webSearchEnabled
@@ -7038,6 +7211,7 @@ const handleSubmit = async state => {
7038
7211
  streamingEnabled,
7039
7212
  useChatCoordinatorWorker,
7040
7213
  useChatNetworkWorkerForRequests,
7214
+ useChatToolWorker,
7041
7215
  useMockApi,
7042
7216
  userText,
7043
7217
  webSearchEnabled
@@ -7335,7 +7509,8 @@ const handleClickDictationButton = async state => {
7335
7509
  };
7336
7510
 
7337
7511
  const handleClickNew = async state => {
7338
- return createSession(state);
7512
+ const newState = await createSession(state);
7513
+ return focusInput(newState);
7339
7514
  };
7340
7515
 
7341
7516
  const handleClickReadFile = async uri => {
@@ -7351,7 +7526,6 @@ const handleClickSessionDebug = async state => {
7351
7526
  };
7352
7527
 
7353
7528
  const handleClickSettings = async () => {
7354
- // TODO
7355
7529
  await invoke$1('Main.openUri', 'app://settings.json');
7356
7530
  };
7357
7531
 
@@ -7636,7 +7810,7 @@ const createExtensionHostRpc = async () => {
7636
7810
 
7637
7811
  const initialize = async () => {
7638
7812
  const rpc = await createExtensionHostRpc();
7639
- set$3(rpc);
7813
+ set$4(rpc);
7640
7814
  };
7641
7815
 
7642
7816
  const isObject = value => {
@@ -7819,6 +7993,15 @@ const loadUseChatNetworkWorkerForRequests = async () => {
7819
7993
  }
7820
7994
  };
7821
7995
 
7996
+ const loadUseChatToolWorker = async () => {
7997
+ try {
7998
+ const savedUseChatToolWorker = await get('chatView.useChatToolWorker');
7999
+ return typeof savedUseChatToolWorker === 'boolean' ? savedUseChatToolWorker : false;
8000
+ } catch {
8001
+ return false;
8002
+ }
8003
+ };
8004
+
7822
8005
  const loadVoiceDictationEnabled = async () => {
7823
8006
  try {
7824
8007
  const savedVoiceDictationEnabled = await get('chatView.voiceDictationEnabled');
@@ -7829,7 +8012,7 @@ const loadVoiceDictationEnabled = async () => {
7829
8012
  };
7830
8013
 
7831
8014
  const loadPreferences = async () => {
7832
- 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()]);
8015
+ 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()]);
7833
8016
  return {
7834
8017
  aiSessionTitleGenerationEnabled,
7835
8018
  composerDropEnabled,
@@ -7841,6 +8024,7 @@ const loadPreferences = async () => {
7841
8024
  useChatCoordinatorWorker,
7842
8025
  useChatMathWorker,
7843
8026
  useChatNetworkWorkerForRequests,
8027
+ useChatToolWorker,
7844
8028
  voiceDictationEnabled
7845
8029
  };
7846
8030
  };
@@ -7981,6 +8165,7 @@ const loadContent = async (state, savedState) => {
7981
8165
  useChatCoordinatorWorker,
7982
8166
  useChatMathWorker,
7983
8167
  useChatNetworkWorkerForRequests,
8168
+ useChatToolWorker,
7984
8169
  voiceDictationEnabled
7985
8170
  } = await loadPreferences();
7986
8171
  const legacySavedSessions = getSavedSessions(savedState);
@@ -8057,6 +8242,7 @@ const loadContent = async (state, savedState) => {
8057
8242
  useChatCoordinatorWorker,
8058
8243
  useChatMathWorker,
8059
8244
  useChatNetworkWorkerForRequests,
8245
+ useChatToolWorker,
8060
8246
  viewMode,
8061
8247
  voiceDictationEnabled
8062
8248
  };
@@ -8367,11 +8553,21 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
8367
8553
  vertical-align: middle;
8368
8554
  }
8369
8555
 
8556
+ .MarkdownQuote {
8557
+ border-left: 3px solid var(--ColorBorder, #3a3d41);
8558
+ margin: 8px 0;
8559
+ padding-left: 12px;
8560
+ }
8561
+
8370
8562
  .MarkdownMathBlock {
8371
8563
  margin: 8px 0;
8372
8564
  overflow-x: auto;
8373
8565
  overflow-y: hidden;
8374
8566
  }
8567
+
8568
+ .StrikeThrough {
8569
+ text-decoration: line-through;
8570
+ }
8375
8571
  `;
8376
8572
  if (!renderHtmlCss.trim()) {
8377
8573
  return baseCss;
@@ -8442,6 +8638,7 @@ const ButtonSecondary = 'ButtonSecondary';
8442
8638
  const Empty = '';
8443
8639
  const FileIcon = 'FileIcon';
8444
8640
  const IconButton = 'IconButton';
8641
+ const ImageElement = 'ImageElement';
8445
8642
  const InputBox = 'InputBox';
8446
8643
  const Label = 'Label';
8447
8644
  const LabelDetail = 'LabelDetail';
@@ -8463,6 +8660,7 @@ const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
8463
8660
  const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
8464
8661
  const ProjectSidebar = 'ProjectSidebar';
8465
8662
  const Markdown = 'Markdown';
8663
+ const MarkdownQuote = 'MarkdownQuote';
8466
8664
  const MarkdownMathBlock = 'MarkdownMathBlock';
8467
8665
  const MarkdownTable = 'MarkdownTable';
8468
8666
  const Message = 'Message';
@@ -8494,6 +8692,7 @@ const TokenAttribute = 'TokenAttribute';
8494
8692
  const TokenValue = 'TokenValue';
8495
8693
  const TokenProperty = 'TokenProperty';
8496
8694
  const Select = 'Select';
8695
+ const StrikeThrough = 'StrikeThrough';
8497
8696
  const Viewlet = 'Viewlet';
8498
8697
  const ChatWelcomeMessage = 'ChatWelcomeMessage';
8499
8698
 
@@ -8568,7 +8767,6 @@ const getSendButtonDom = (isSendDisabled, voiceDictationEnabled) => {
8568
8767
  className: IconButton,
8569
8768
  name: Dictate,
8570
8769
  onClick: HandleClickDictationButton,
8571
- role: Button$2,
8572
8770
  title: startVoiceDictation(),
8573
8771
  type: Button$1
8574
8772
  }, {
@@ -8581,7 +8779,6 @@ const getSendButtonDom = (isSendDisabled, voiceDictationEnabled) => {
8581
8779
  className: sendButtonClassName,
8582
8780
  disabled: isSendDisabled,
8583
8781
  name: Send,
8584
- role: Button$2,
8585
8782
  title: sendMessage(),
8586
8783
  type: Button$1
8587
8784
  }, {
@@ -8626,7 +8823,7 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
8626
8823
  }, text(usageLabel)];
8627
8824
  };
8628
8825
 
8629
- const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, voiceDictationEnabled = false) => {
8826
+ const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled = false) => {
8630
8827
  const isSendDisabled = composerValue.trim() === '';
8631
8828
  const controlsCount = usageOverviewEnabled ? 3 : 2;
8632
8829
  return [{
@@ -8654,10 +8851,25 @@ const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOvervie
8654
8851
  }, ...getChatSelectVirtualDom(models, selectedModelId), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
8655
8852
  };
8656
8853
 
8854
+ const getImageAltText = alt => {
8855
+ if (!alt.trim()) {
8856
+ return 'image could not be loaded';
8857
+ }
8858
+ return `${alt} (image could not be loaded)`;
8859
+ };
8657
8860
  const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
8658
8861
  if (inlineNode.type === 'text') {
8659
8862
  return [text(inlineNode.text)];
8660
8863
  }
8864
+ if (inlineNode.type === 'image') {
8865
+ return [{
8866
+ alt: getImageAltText(inlineNode.alt),
8867
+ childCount: 0,
8868
+ className: ImageElement,
8869
+ src: inlineNode.src,
8870
+ type: Img
8871
+ }];
8872
+ }
8661
8873
  if (inlineNode.type === 'bold') {
8662
8874
  return [{
8663
8875
  childCount: inlineNode.children.length,
@@ -8670,6 +8882,13 @@ const getInlineNodeDom = (inlineNode, useChatMathWorker = false) => {
8670
8882
  type: Em
8671
8883
  }, ...inlineNode.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
8672
8884
  }
8885
+ if (inlineNode.type === 'strikethrough') {
8886
+ return [{
8887
+ childCount: inlineNode.children.length,
8888
+ className: StrikeThrough,
8889
+ type: Span
8890
+ }, ...inlineNode.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
8891
+ }
8673
8892
  if (inlineNode.type === 'math-inline') {
8674
8893
  const fallback = inlineNode.displayMode ? `$$${inlineNode.text}$$` : `$${inlineNode.text}$`;
8675
8894
  return [text(fallback)];
@@ -8907,6 +9126,13 @@ const getHeadingDom = (node, useChatMathWorker) => {
8907
9126
  type: getHeadingElementType(node.level)
8908
9127
  }, ...node.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
8909
9128
  };
9129
+ const getBlockQuoteDom = (node, useChatMathWorker) => {
9130
+ return [{
9131
+ childCount: node.children.length,
9132
+ className: MarkdownQuote,
9133
+ type: Div
9134
+ }, ...node.children.flatMap(child => getMessageNodeDom(child, useChatMathWorker))];
9135
+ };
8910
9136
  const getMessageNodeDom = (node, useChatMathWorker = false) => {
8911
9137
  if (node.type === 'text') {
8912
9138
  return [{
@@ -8934,6 +9160,9 @@ const getMessageNodeDom = (node, useChatMathWorker = false) => {
8934
9160
  if (node.type === 'heading') {
8935
9161
  return getHeadingDom(node, useChatMathWorker);
8936
9162
  }
9163
+ if (node.type === 'blockquote') {
9164
+ return getBlockQuoteDom(node, useChatMathWorker);
9165
+ }
8937
9166
  if (node.type === 'ordered-list') {
8938
9167
  return [{
8939
9168
  childCount: node.items.length,
@@ -9008,7 +9237,7 @@ const getMissingOpenApiApiKeyDom = openApiApiKeyInput => {
9008
9237
  inputPattern: '^sk-.+',
9009
9238
  inputRequired: true,
9010
9239
  inputValue: openApiApiKeyInput,
9011
- openSettingsButtonName: OpenOpenApiApiKeySettings,
9240
+ openSettingsButtonName: OpenOpenApiApiKeyWebsite,
9012
9241
  placeholder: openApiApiKeyPlaceholder(),
9013
9242
  saveButtonName: SaveOpenApiApiKey,
9014
9243
  saveButtonType: 'submit',
@@ -9739,14 +9968,14 @@ const getChatModeChatFocusVirtualDom = (sessions, selectedSessionId, composerVal
9739
9968
  const messages = selectedSession ? selectedSession.messages : [];
9740
9969
  const isDropOverlayVisible = composerDropEnabled && composerDropActive;
9741
9970
  return [{
9742
- childCount: 4,
9971
+ childCount: isDropOverlayVisible ? 4 : 3,
9743
9972
  className: mergeClassNames(Viewlet, Chat, 'ChatFocus'),
9744
9973
  onDragEnter: HandleDragEnterChatView,
9745
9974
  onDragOver: HandleDragOverChatView,
9746
9975
  type: Div
9747
- }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, voiceDictationEnabled), {
9976
+ }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
9748
9977
  childCount: 1,
9749
- className: mergeClassNames(ChatViewDropOverlay, isDropOverlayVisible ? ChatViewDropOverlayActive : Empty),
9978
+ className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
9750
9979
  name: ComposerDropTarget,
9751
9980
  onDragLeave: HandleDragLeave,
9752
9981
  onDragOver: HandleDragOver,
@@ -9755,7 +9984,7 @@ const getChatModeChatFocusVirtualDom = (sessions, selectedSessionId, composerVal
9755
9984
  }, {
9756
9985
  text: attachImageAsContext(),
9757
9986
  type: Text
9758
- }];
9987
+ }] : [])];
9759
9988
  };
9760
9989
 
9761
9990
  const getBackButtonVirtualDom = () => {
@@ -9846,14 +10075,14 @@ const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue,
9846
10075
  const messages = selectedSession ? selectedSession.messages : [];
9847
10076
  const isDropOverlayVisible = composerDropEnabled && composerDropActive;
9848
10077
  return [{
9849
- childCount: 4,
10078
+ childCount: isDropOverlayVisible ? 4 : 3,
9850
10079
  className: mergeClassNames(Viewlet, Chat),
9851
10080
  onDragEnter: HandleDragEnterChatView,
9852
10081
  onDragOver: HandleDragOverChatView,
9853
10082
  type: Div
9854
- }, ...getChatHeaderDomDetailMode(selectedSessionTitle), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, voiceDictationEnabled), {
10083
+ }, ...getChatHeaderDomDetailMode(selectedSessionTitle), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
9855
10084
  childCount: 1,
9856
- className: mergeClassNames(ChatViewDropOverlay, isDropOverlayVisible ? ChatViewDropOverlayActive : Empty),
10085
+ className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
9857
10086
  name: ComposerDropTarget,
9858
10087
  onDragLeave: HandleDragLeave,
9859
10088
  onDragOver: HandleDragOver,
@@ -9862,7 +10091,7 @@ const getChatModeDetailVirtualDom = (sessions, selectedSessionId, composerValue,
9862
10091
  }, {
9863
10092
  text: attachImageAsContext(),
9864
10093
  type: Text
9865
- }];
10094
+ }] : [])];
9866
10095
  };
9867
10096
 
9868
10097
  const getChatHeaderListModeDom = () => {
@@ -9935,14 +10164,14 @@ const getChatListDom = (sessions, selectedSessionId, chatListScrollTop = 0) => {
9935
10164
  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) => {
9936
10165
  const isDropOverlayVisible = composerDropEnabled && composerDropActive;
9937
10166
  return [{
9938
- childCount: 4,
10167
+ childCount: isDropOverlayVisible ? 4 : 3,
9939
10168
  className: mergeClassNames(Viewlet, Chat),
9940
10169
  onDragEnter: HandleDragEnterChatView,
9941
10170
  onDragOver: HandleDragOverChatView,
9942
10171
  type: Div
9943
- }, ...getChatHeaderListModeDom(), ...getChatListDom(sessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, voiceDictationEnabled), {
10172
+ }, ...getChatHeaderListModeDom(), ...getChatListDom(sessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
9944
10173
  childCount: 1,
9945
- className: mergeClassNames(ChatViewDropOverlay, isDropOverlayVisible ? ChatViewDropOverlayActive : Empty),
10174
+ className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
9946
10175
  name: ComposerDropTarget,
9947
10176
  onDragLeave: HandleDragLeave,
9948
10177
  onDragOver: HandleDragOver,
@@ -9951,7 +10180,7 @@ const getChatModeListVirtualDom = (sessions, selectedSessionId, composerValue, m
9951
10180
  }, {
9952
10181
  text: attachImageAsContext(),
9953
10182
  type: Text
9954
- }];
10183
+ }] : [])];
9955
10184
  };
9956
10185
 
9957
10186
  const getChatModeUnsupportedVirtualDom = () => {
@@ -10482,18 +10711,40 @@ const initializeChatMathWorker = async () => {
10482
10711
  commandMap: {},
10483
10712
  send: sendMessagePortToChatMathWorker
10484
10713
  });
10485
- set$5(rpc);
10714
+ set$7(rpc);
10486
10715
  };
10487
10716
 
10488
- const send = port => {
10717
+ const send$1 = port => {
10489
10718
  return sendMessagePortToChatNetworkWorker(port);
10490
10719
  };
10491
10720
  const initializeChatNetworkWorker = async () => {
10721
+ const rpc = await create$4({
10722
+ commandMap: {},
10723
+ send: send$1
10724
+ });
10725
+ set$6(rpc);
10726
+ };
10727
+
10728
+ const send = port => {
10729
+ return sendMessagePortToChatToolWorker(port);
10730
+ };
10731
+ const initializeChatToolWorker = async () => {
10492
10732
  const rpc = await create$4({
10493
10733
  commandMap: {},
10494
10734
  send
10495
10735
  });
10496
- set$4(rpc);
10736
+ set$5(rpc);
10737
+ };
10738
+
10739
+ const sendMessagePortToOpenerWorker = async port => {
10740
+ await sendMessagePortToOpenerWorker$1(port, 0);
10741
+ };
10742
+ const initializeOpenerWorker = async () => {
10743
+ const rpc = await create$4({
10744
+ commandMap: {},
10745
+ send: sendMessagePortToOpenerWorker
10746
+ });
10747
+ set$3(rpc);
10497
10748
  };
10498
10749
 
10499
10750
  const listen = async () => {
@@ -10502,7 +10753,7 @@ const listen = async () => {
10502
10753
  commandMap: commandMap
10503
10754
  });
10504
10755
  set$2(rpc);
10505
- await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker(), initializeChatCoordinatorWorker()]);
10756
+ await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker(), initializeChatCoordinatorWorker(), initializeChatToolWorker(), initializeOpenerWorker()]);
10506
10757
  };
10507
10758
 
10508
10759
  const main = async () => {