@lvce-editor/chat-view 6.0.0 → 6.1.0

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