@lvce-editor/chat-view 7.0.0 → 7.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.
@@ -1118,20 +1118,13 @@ const create$2 = rpcId => {
1118
1118
  };
1119
1119
 
1120
1120
  const {
1121
- invoke: invoke$9,
1121
+ invoke: invoke$8,
1122
1122
  set: set$c
1123
1123
  } = create$2(6008);
1124
1124
 
1125
1125
  const {
1126
- invoke: invoke$8,
1127
1126
  set: set$b
1128
1127
  } = create$2(6007);
1129
- const getMathBlockDom = async node => {
1130
- return invoke$8('ChatMath.getMathBlockDom', node);
1131
- };
1132
- const getMathInlineDom = async node => {
1133
- return invoke$8('ChatMath.getMathInlineDom', node);
1134
- };
1135
1128
 
1136
1129
  const {
1137
1130
  invoke: invoke$7,
@@ -1185,7 +1178,7 @@ const Br = 55;
1185
1178
  const Tfoot = 59;
1186
1179
  const Ul = 60;
1187
1180
  const TextArea = 62;
1188
- const Select$1 = 63;
1181
+ const Select = 63;
1189
1182
  const Option = 64;
1190
1183
  const Code = 65;
1191
1184
  const Label$1 = 66;
@@ -1214,7 +1207,6 @@ const Home = 12;
1214
1207
  const UpArrow = 14;
1215
1208
  const DownArrow = 16;
1216
1209
  const KeyN = 42;
1217
- const KeyV = 50;
1218
1210
 
1219
1211
  const CtrlCmd = 1 << 11 >>> 0;
1220
1212
  const Shift = 1 << 10 >>> 0;
@@ -2471,7 +2463,6 @@ const createDefaultState = () => {
2471
2463
  usageOverviewEnabled: false,
2472
2464
  useChatCoordinatorWorker: false,
2473
2465
  useChatMathWorker: true,
2474
- useChatMessageParsingWorker: false,
2475
2466
  useChatNetworkWorkerForRequests: false,
2476
2467
  useChatToolWorker: true,
2477
2468
  useMockApi: false,
@@ -3326,10 +3317,6 @@ const getKeyBindings = () => {
3326
3317
  command: 'Chat.chatInputHistoryDown',
3327
3318
  key: DownArrow,
3328
3319
  when: FocusChatInput
3329
- }, {
3330
- command: 'Chat.pasteInput',
3331
- key: CtrlCmd | KeyV,
3332
- when: FocusChatInput
3333
3320
  }, {
3334
3321
  command: 'Chat.chatInputHistoryUp',
3335
3322
  key: UpArrow,
@@ -3526,9 +3513,6 @@ const isRenameInputName = name => {
3526
3513
  const getRenameIdFromInputName = name => {
3527
3514
  return name.slice(RenamePrefix.length);
3528
3515
  };
3529
- const getModelPickerItemInputName = modelId => {
3530
- return `${ModelPickerItemPrefix}${modelId}`;
3531
- };
3532
3516
  const getGitBranchPickerItemInputName = branchName => {
3533
3517
  return `${GitBranchPickerItemPrefix}${branchName}`;
3534
3518
  };
@@ -4596,7 +4580,7 @@ const handleClickOpenRouterApiKeyWebsite = async state => {
4596
4580
  };
4597
4581
 
4598
4582
  const getAiResponse$1 = async options => {
4599
- return invoke$9('ChatCoordinator.getAiResponse', options);
4583
+ return invoke$8('ChatCoordinator.getAiResponse', options);
4600
4584
  };
4601
4585
 
4602
4586
  const execute = async (name, rawArguments, options) => {
@@ -7218,1476 +7202,46 @@ const getAiResponse = async ({
7218
7202
  text = getOpenRouterErrorMessage(result);
7219
7203
  }
7220
7204
  } else if (openRouterApiKey) {
7221
- const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests, useChatToolWorker, questionToolEnabled, systemPrompt, workspaceUri, agentMode, toolEnablement);
7222
- if (result.type === 'success') {
7223
- const {
7224
- text: assistantText
7225
- } = result;
7226
- text = assistantText;
7227
- } else {
7228
- text = getOpenRouterErrorMessage(result);
7229
- }
7230
- } else {
7231
- text = openRouterApiKeyRequiredMessage;
7232
- }
7233
- }
7234
- if (!text && !usesOpenApiModel && !usesOpenRouterModel) {
7235
- text = await getMockAiResponse(userText, mockAiResponseDelay);
7236
- }
7237
- const assistantTime = new Date().toLocaleTimeString([], {
7238
- hour: '2-digit',
7239
- minute: '2-digit'
7240
- });
7241
- const message = {
7242
- id: messageId || crypto.randomUUID(),
7243
- role: 'assistant',
7244
- text,
7245
- time: assistantTime
7246
- };
7247
- return message;
7248
- };
7249
-
7250
- const parseMessageContents = async rawMessages => {
7251
- return invoke$7('ChatMessageParsing.parseMessageContents', rawMessages);
7252
- };
7253
-
7254
- const Actions = 'Actions';
7255
- const Button = 'Button';
7256
- const ButtonPrimary = 'ButtonPrimary';
7257
- const ButtonSecondary = 'ButtonSecondary';
7258
- const Chat = 'Chat';
7259
- const ChatActions = 'ChatActions';
7260
- const ChatAuthError = 'ChatAuthError';
7261
- const ChatFocus = 'ChatFocus';
7262
- const ChatFocusActions = 'ChatFocusActions';
7263
- const ChatFocusHeader = 'ChatFocusHeader';
7264
- const ChatFocusMainArea = 'ChatFocusMainArea';
7265
- const ChatFocusProject = 'ChatFocusProject';
7266
- const ChatGitBranchPicker = 'ChatGitBranchPicker';
7267
- const ChatGitBranchPickerErrorMessage = 'ChatGitBranchPickerErrorMessage';
7268
- const ChatGitBranchPickerMessage = 'ChatGitBranchPickerMessage';
7269
- const ChatHeader = 'ChatHeader';
7270
- const ChatHeaderAuth = 'ChatHeaderAuth';
7271
- const ChatHeaderAuthName = 'ChatHeaderAuthName';
7272
- const ChatHeaderLabel = 'ChatHeaderLabel';
7273
- const ChatInputBox = 'ChatInputBox';
7274
- const ChatList = 'ChatList';
7275
- const ChatListEmpty = 'ChatListEmpty';
7276
- const ChatListItem = 'ChatListItem';
7277
- const ChatListItemFocused = 'ChatListItemFocused';
7278
- const ChatListItemLabel = 'ChatListItemLabel';
7279
- const ChatListItemStatusFinished = 'ChatListItemStatusFinished';
7280
- const ChatListItemStatusIcon = 'ChatListItemStatusIcon';
7281
- const ChatListItemStatusInProgress = 'ChatListItemStatusInProgress';
7282
- const ChatListItemStatusRow = 'ChatListItemStatusRow';
7283
- const ChatListItemStatusStopped = 'ChatListItemStatusStopped';
7284
- const ChatMessageContent = 'ChatMessageContent';
7285
- const ChatImageMessageContent = 'ChatImageMessageContent';
7286
- const ChatMessageLink = 'ChatMessageLink';
7287
- const ChatModelPicker = 'ChatModelPicker';
7288
- const ChatModelPickerContainer = 'ChatModelPickerContainer';
7289
- const ChatModelPickerHeader = 'ChatModelPickerHeader';
7290
- const ChatModelPickerItem = 'ChatModelPickerItem';
7291
- const ChatModelPickerItemLabel = 'ChatModelPickerItemLabel';
7292
- const ChatModelPickerItemSelected = 'ChatModelPickerItemSelected';
7293
- const ChatModelPickerItemUsageCost = 'ChatModelPickerItemUsageCost';
7294
- const ChatModelPickerList = 'ChatModelPickerList';
7295
- const ChatName = 'ChatName';
7296
- const ChatOverlays = 'ChatOverlays';
7297
- const ChatOrderedList = 'ChatOrderedList';
7298
- const ChatOrderedListItem = 'ChatOrderedListItem';
7299
- const ChatOrderedListItemContent = 'ChatOrderedListItemContent';
7300
- const ChatOrderedListItemPrefix = 'ChatOrderedListItemPrefix';
7301
- const ChatOrderedListMarker = 'ChatOrderedListMarker';
7302
- const ChatComposerAttachment = 'ChatComposerAttachment';
7303
- const ChatComposerAttachmentImage = 'ChatComposerAttachmentImage';
7304
- const ChatComposerAttachmentInvalidImage = 'ChatComposerAttachmentInvalidImage';
7305
- const ChatComposerAttachmentLabel = 'ChatComposerAttachmentLabel';
7306
- const ChatComposerAttachmentPreview = 'ChatComposerAttachmentPreview';
7307
- const ChatComposerAttachmentPreviewOverlay = 'ChatComposerAttachmentPreviewOverlay';
7308
- const ChatComposerAttachmentPreviewOverlayError = 'ChatComposerAttachmentPreviewOverlayError';
7309
- const ChatComposerAttachmentPreviewOverlayImage = 'ChatComposerAttachmentPreviewOverlayImage';
7310
- const ChatComposerAttachmentRemoveButton = 'ChatComposerAttachmentRemoveButton';
7311
- const ChatComposerAttachments = 'ChatComposerAttachments';
7312
- const ChatComposerAttachmentTextFile = 'ChatComposerAttachmentTextFile';
7313
- const ChatAttachment = 'ChatAttachment';
7314
- const ChatAttachmentImage = 'ChatAttachmentImage';
7315
- const ChatAttachmentInvalidImage = 'ChatAttachmentInvalidImage';
7316
- const ChatAttachmentLabel = 'ChatAttachmentLabel';
7317
- const ChatAttachmentPreview = 'ChatAttachmentPreview';
7318
- const ChatAttachments = 'ChatAttachments';
7319
- const ChatAttachmentTextFile = 'ChatAttachmentTextFile';
7320
- const ChatMessageImage = 'ChatMessageImage';
7321
- const ChatSendArea = 'ChatSendArea';
7322
- const ChatSendAreaBottom = 'ChatSendAreaBottom';
7323
- const ChatSendAreaContent = 'ChatSendAreaContent';
7324
- const ChatSendAreaPrimaryControls = 'ChatSendAreaPrimaryControls';
7325
- const ChatTableWrapper = 'ChatTableWrapper';
7326
- const ChatTodoList = 'ChatTodoList';
7327
- const ChatTodoListHeader = 'ChatTodoListHeader';
7328
- const ChatTodoListItem = 'ChatTodoListItem';
7329
- const ChatTodoListItemCompleted = 'ChatTodoListItemCompleted';
7330
- const ChatTodoListItemInProgress = 'ChatTodoListItemInProgress';
7331
- const ChatTodoListItems = 'ChatTodoListItems';
7332
- const ChatTodoListItemTodo = 'ChatTodoListItemTodo';
7333
- const ChatToolCallFileName = 'ChatToolCallFileName';
7334
- const ChatToolCallQuestionOption = 'ChatToolCallQuestionOption';
7335
- const ChatToolCallQuestionOptions = 'ChatToolCallQuestionOptions';
7336
- const ChatToolCallQuestionText = 'ChatToolCallQuestionText';
7337
- const ChatToolCallReadFileLink = 'ChatToolCallReadFileLink';
7338
- const ChatToolCallRenderHtmlBody = 'ChatToolCallRenderHtmlBody';
7339
- const ChatToolCallRenderHtmlContent = 'ChatToolCallRenderHtmlContent';
7340
- const ChatToolCallRenderHtmlLabel = 'ChatToolCallRenderHtmlLabel';
7341
- const ChatToolCalls = 'ChatToolCalls';
7342
- const ChatToolCallsLabel = 'ChatToolCallsLabel';
7343
- const ChatUnorderedList = 'ChatUnorderedList';
7344
- const ChatUnorderedListItem = 'ChatUnorderedListItem';
7345
- const ChatViewDropOverlay = 'ChatViewDropOverlay';
7346
- const ChatViewDropOverlayActive = 'ChatViewDropOverlayActive';
7347
- const ChatWelcomeMessage = 'ChatWelcomeMessage';
7348
- const CustomSelectContainer = 'CustomSelectContainer';
7349
- const CustomSelectPopOver = 'CustomSelectPopOver';
7350
- const Deletion = 'Deletion';
7351
- const Empty = '';
7352
- const FileIcon = 'FileIcon';
7353
- const IconButton = 'IconButton';
7354
- const IconButtonDisabled = 'IconButtonDisabled';
7355
- const ImageElement = 'ImageElement';
7356
- const ImageErrorMessage = 'ImageErrorMessage';
7357
- const InputBox = 'InputBox';
7358
- const InputInvalid = 'InputInvalid';
7359
- const Insertion = 'Insertion';
7360
- const Label = 'Label';
7361
- const LabelDetail = 'LabelDetail';
7362
- const Markdown = 'Markdown';
7363
- const MarkdownMathBlock = 'MarkdownMathBlock';
7364
- const MarkdownQuote = 'MarkdownQuote';
7365
- const MarkdownTable = 'MarkdownTable';
7366
- const MaskIcon = 'MaskIcon';
7367
- const MaskIconAdd = 'MaskIconAdd';
7368
- const MaskIconArrowLeft = 'MaskIconArrowLeft';
7369
- const MaskIconChevronDown = 'MaskIconChevronDown';
7370
- const MaskIconChevronRight = 'MaskIconChevronRight';
7371
- const MaskIconChevronUp = 'MaskIconChevronUp';
7372
- const MaskIconClose = 'MaskIconClose';
7373
- const MaskIconDebugPause = 'MaskIconDebugPause';
7374
- const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
7375
- const MaskIconSearch = 'MaskIconSearch';
7376
- const MaskIconSettingsGear = 'MaskIconSettingsGear';
7377
- const Message = 'Message';
7378
- const MessageAssistant = 'MessageAssistant';
7379
- const MessageUser = 'MessageUser';
7380
- const MissingApiKeyForm = 'MissingApiKeyForm';
7381
- const MultiLineInputBox = 'MultilineInputBox';
7382
- const ProjectAddButton = 'ProjectAddButton';
7383
- const ProjectList = 'ProjectList';
7384
- const ProjectListChevron = 'ProjectListChevron';
7385
- const ProjectListGroup = 'ProjectListGroup';
7386
- const ProjectListItem = 'ProjectListItem';
7387
- const ProjectListItemActions = 'ProjectListItemActions';
7388
- const ProjectListItemAddChatButton = 'ProjectListItemAddChatButton';
7389
- const ProjectListItemLabel = 'ProjectListItemLabel';
7390
- const ProjectListItemSelected = 'ProjectListItemSelected';
7391
- const ProjectSessionItem = 'ProjectSessionItem';
7392
- const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
7393
- const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
7394
- const ProjectSidebar = 'ProjectSidebar';
7395
- const SearchFieldContainer = 'SearchFieldContainer';
7396
- const RunModePickerContainer = 'RunModePickerContainer';
7397
- const RunModePickerPopOver = 'RunModePickerPopOver';
7398
- const Select = 'Select';
7399
- const SelectLabel = 'SelectLabel';
7400
- const SendButtonDisabled = 'SendButtonDisabled';
7401
- const SessionArchiveButton = 'SessionArchiveButton';
7402
- const StrikeThrough = 'StrikeThrough';
7403
- const TokenAttribute = 'TokenAttribute';
7404
- const TokenComment = 'TokenComment';
7405
- const TokenKeyword = 'TokenKeyword';
7406
- const TokenNumber = 'TokenNumber';
7407
- const TokenProperty = 'TokenProperty';
7408
- const TokenString = 'TokenString';
7409
- const TokenTag = 'TokenTag';
7410
- const TokenUsageOverview = 'TokenUsageOverview';
7411
- const TokenUsageRing = 'TokenUsageRing';
7412
- const TokenUsageRingInner = 'TokenUsageRingInner';
7413
- const TokenValue = 'TokenValue';
7414
- const ToolCallName = 'ToolCallName';
7415
- const Viewlet = 'Viewlet';
7416
-
7417
- const jsRules = [{
7418
- className: TokenComment,
7419
- regex: /\/\/[^\n]*/
7420
- }, {
7421
- className: TokenComment,
7422
- regex: /\/\*[\s\S]*?\*\//
7423
- }, {
7424
- className: TokenString,
7425
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
7426
- }, {
7427
- className: TokenString,
7428
- regex: /'[^'\\]*(?:\\.[^'\\]*)*'/
7429
- }, {
7430
- className: TokenString,
7431
- regex: /`[^`\\]*(?:\\.[^`\\]*)*`/
7432
- }, {
7433
- className: TokenNumber,
7434
- regex: /\b\d+\.?\d*\b/
7435
- }, {
7436
- className: TokenKeyword,
7437
- regex: /\b(?:const|let|var|function|return|if|else|for|while|class|new|typeof|instanceof|import|export|from|default|async|await|try|catch|finally|throw|this|true|false|null|undefined)\b/
7438
- }];
7439
- const tsRules = [{
7440
- className: TokenComment,
7441
- regex: /\/\/[^\n]*/
7442
- }, {
7443
- className: TokenComment,
7444
- regex: /\/\*[\s\S]*?\*\//
7445
- }, {
7446
- className: TokenString,
7447
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
7448
- }, {
7449
- className: TokenString,
7450
- regex: /'[^'\\]*(?:\\.[^'\\]*)*'/
7451
- }, {
7452
- className: TokenString,
7453
- regex: /`[^`\\]*(?:\\.[^`\\]*)*`/
7454
- }, {
7455
- className: TokenNumber,
7456
- regex: /\b\d+\.?\d*\b/
7457
- }, {
7458
- className: TokenKeyword,
7459
- regex: /\b(?:abstract|any|as|asserts|async|await|boolean|class|const|constructor|declare|default|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|infer|instanceof|interface|is|keyof|let|module|namespace|never|new|null|number|object|override|private|protected|public|readonly|return|satisfies|set|static|string|super|switch|symbol|this|throw|true|try|type|typeof|undefined|unknown|var|void|while)\b/
7460
- }];
7461
- const htmlRules = [{
7462
- className: TokenComment,
7463
- regex: /<!--[\s\S]*?-->/
7464
- }, {
7465
- className: TokenTag,
7466
- regex: /<\/[a-zA-Z][a-zA-Z0-9-]*\s*>/
7467
- }, {
7468
- className: TokenTag,
7469
- regex: /<[a-zA-Z][a-zA-Z0-9-]*/
7470
- }, {
7471
- className: TokenTag,
7472
- regex: /\/?>/
7473
- }, {
7474
- className: TokenString,
7475
- regex: /"[^"]*"/
7476
- }, {
7477
- className: TokenString,
7478
- regex: /'[^']*'/
7479
- }, {
7480
- className: TokenAttribute,
7481
- regex: /[a-zA-Z-]+(?=\s*=)/
7482
- }];
7483
- const cssRules = [{
7484
- className: TokenComment,
7485
- regex: /\/\*[\s\S]*?\*\//
7486
- }, {
7487
- className: TokenString,
7488
- regex: /"[^"]*"/
7489
- }, {
7490
- className: TokenString,
7491
- regex: /'[^']*'/
7492
- }, {
7493
- className: TokenValue,
7494
- regex: /#[0-9a-fA-F]{3,8}/
7495
- }, {
7496
- className: TokenValue,
7497
- regex: /\b\d+(?:\.\d+)?(?:px|em|rem|%|vh|vw|pt|s|ms|fr)?\b/
7498
- }, {
7499
- className: TokenProperty,
7500
- regex: /[a-zA-Z-]+(?=\s*:)/
7501
- }];
7502
- const pythonRules = [{
7503
- className: TokenComment,
7504
- regex: /#[^\n]*/
7505
- }, {
7506
- className: TokenString,
7507
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
7508
- }, {
7509
- className: TokenString,
7510
- regex: /'[^'\\]*(?:\\.[^'\\]*)*'/
7511
- }, {
7512
- className: TokenNumber,
7513
- regex: /\b\d+\.?\d*\b/
7514
- }, {
7515
- className: TokenKeyword,
7516
- regex: /\b(?:def|class|return|if|elif|else|for|while|in|import|from|as|with|try|except|finally|raise|lambda|yield|pass|break|continue|True|False|None|and|or|not|is)\b/
7517
- }];
7518
- const jsonRules = [{
7519
- className: TokenProperty,
7520
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"(?=\s*:)/
7521
- }, {
7522
- className: TokenString,
7523
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
7524
- }, {
7525
- className: TokenNumber,
7526
- regex: /-?\b\d+\.?\d*(?:[eE][+-]?\d+)?\b/
7527
- }, {
7528
- className: TokenKeyword,
7529
- regex: /\b(?:true|false|null)\b/
7530
- }];
7531
- const tokenize = (code, rules) => {
7532
- const tokens = [];
7533
- let pos = 0;
7534
- while (pos < code.length) {
7535
- let matched = false;
7536
- for (const rule of rules) {
7537
- const match = rule.regex.exec(code.slice(pos));
7538
- if (match && match.index === 0) {
7539
- tokens.push({
7540
- className: rule.className,
7541
- text: match[0]
7542
- });
7543
- pos += match[0].length;
7544
- matched = true;
7545
- break;
7546
- }
7547
- }
7548
- if (!matched) {
7549
- const last = tokens.at(-1);
7550
- if (last && last.className === '') {
7551
- tokens.pop();
7552
- tokens.push({
7553
- className: '',
7554
- text: last.text + code[pos]
7555
- });
7556
- } else {
7557
- tokens.push({
7558
- className: '',
7559
- text: code[pos]
7560
- });
7561
- }
7562
- pos++;
7563
- }
7564
- }
7565
- return tokens;
7566
- };
7567
- const highlightCode = (code, language) => {
7568
- if (!language) {
7569
- return [{
7570
- className: '',
7571
- text: code
7572
- }];
7573
- }
7574
- const normalized = language.toLowerCase();
7575
- if (normalized === 'html') {
7576
- return tokenize(code, htmlRules);
7577
- }
7578
- if (normalized === 'css') {
7579
- return tokenize(code, cssRules);
7580
- }
7581
- if (normalized === 'js' || normalized === 'javascript') {
7582
- return tokenize(code, jsRules);
7583
- }
7584
- if (normalized === 'ts' || normalized === 'typescript') {
7585
- return tokenize(code, tsRules);
7586
- }
7587
- if (normalized === 'py' || normalized === 'python') {
7588
- return tokenize(code, pythonRules);
7589
- }
7590
- if (normalized === 'json') {
7591
- return tokenize(code, jsonRules);
7592
- }
7593
- return [{
7594
- className: '',
7595
- text: code
7596
- }];
7597
- };
7598
-
7599
- const isAlphaNumeric = value => {
7600
- if (!value) {
7601
- return false;
7602
- }
7603
- const code = value.codePointAt(0) ?? 0;
7604
- if (code >= 48 && code <= 57) {
7605
- return true;
7606
- }
7607
- if (code >= 65 && code <= 90) {
7608
- return true;
7609
- }
7610
- return code >= 97 && code <= 122;
7611
- };
7612
- const sanitizeLinkUrl = url => {
7613
- const trimmedUrl = url.trim();
7614
- const normalized = url.trim().toLowerCase();
7615
- if (normalized.startsWith('http://') || normalized.startsWith('https://') || normalized.startsWith('file://') || normalized.startsWith('vscode-references://')) {
7616
- return trimmedUrl;
7617
- }
7618
- if (!trimmedUrl || trimmedUrl.startsWith('#') || trimmedUrl.startsWith('?') || trimmedUrl.startsWith('/') || trimmedUrl.startsWith('\\')) {
7619
- return '#';
7620
- }
7621
- if (trimmedUrl.includes('://') || trimmedUrl.includes(':')) {
7622
- return '#';
7623
- }
7624
- if (isPathTraversalAttempt(trimmedUrl)) {
7625
- return '#';
7626
- }
7627
- const normalizedPath = normalizeRelativePath(trimmedUrl);
7628
- if (normalizedPath === '.') {
7629
- return '#';
7630
- }
7631
- return `file:///workspace/${normalizedPath}`;
7632
- };
7633
- const sanitizeImageUrl = url => {
7634
- const normalized = url.trim().toLowerCase();
7635
- if (normalized.startsWith('http://') || normalized.startsWith('https://')) {
7636
- return url;
7637
- }
7638
- return '#';
7639
- };
7640
- const isOpenBracket = value => {
7641
- return value === '(' || value === '[' || value === '{';
7642
- };
7643
- const isCloseBracket = value => {
7644
- return value === ')' || value === ']' || value === '}';
7645
- };
7646
- const findRawUrlEnd = (value, start) => {
7647
- let index = start;
7648
- while (index < value.length) {
7649
- const current = value[index];
7650
- if (current === ' ' || current === '\n' || current === '\r' || current === '\t' || current === '"' || current === "'" || current === '`' || current === '<' || current === '>') {
7651
- break;
7652
- }
7653
- index++;
7654
- }
7655
- return index;
7656
- };
7657
- const trimRawUrlEnd = url => {
7658
- let end = url.length;
7659
- while (end > 0) {
7660
- const current = url[end - 1];
7661
- if (current === '.' || current === ',' || current === ':' || current === ';' || current === '!' || current === '?') {
7662
- end--;
7663
- continue;
7664
- }
7665
- if (isCloseBracket(current)) {
7666
- const inner = url.slice(0, end - 1);
7667
- let openCount = 0;
7668
- let closeCount = 0;
7669
- for (let i = 0; i < inner.length; i++) {
7670
- if (isOpenBracket(inner[i])) {
7671
- openCount++;
7672
- } else if (isCloseBracket(inner[i])) {
7673
- closeCount++;
7674
- }
7675
- }
7676
- if (closeCount >= openCount) {
7677
- end--;
7678
- continue;
7679
- }
7680
- }
7681
- break;
7682
- }
7683
- return url.slice(0, end);
7684
- };
7685
- const parseRawLinkToken = (value, start) => {
7686
- if (!value.startsWith('https://', start) && !value.startsWith('http://', start)) {
7687
- return undefined;
7688
- }
7689
- if (start >= 2 && value[start - 1] === '(' && value[start - 2] === ']') {
7690
- return undefined;
7691
- }
7692
- const end = findRawUrlEnd(value, start);
7693
- const rawUrl = value.slice(start, end);
7694
- const href = trimRawUrlEnd(rawUrl);
7695
- if (!href) {
7696
- return undefined;
7697
- }
7698
- return {
7699
- length: href.length,
7700
- node: {
7701
- href: sanitizeLinkUrl(href),
7702
- text: href,
7703
- type: 'link'
7704
- }
7705
- };
7706
- };
7707
- const parseLinkToken = (value, start) => {
7708
- if (value[start] !== '[') {
7709
- return undefined;
7710
- }
7711
- const textEnd = value.indexOf(']', start + 1);
7712
- if (textEnd === -1) {
7713
- return undefined;
7714
- }
7715
- if (value[textEnd + 1] !== '(') {
7716
- return undefined;
7717
- }
7718
- let depth = 1;
7719
- let index = textEnd + 2;
7720
- while (index < value.length) {
7721
- const current = value[index];
7722
- if (current === '\n') {
7723
- return undefined;
7724
- }
7725
- if (current === '(') {
7726
- depth++;
7727
- } else if (current === ')') {
7728
- depth--;
7729
- if (depth === 0) {
7730
- const text = value.slice(start + 1, textEnd);
7731
- const href = value.slice(textEnd + 2, index);
7732
- if (!text || !href) {
7733
- return undefined;
7734
- }
7735
- return {
7736
- length: index - start + 1,
7737
- node: {
7738
- href: sanitizeLinkUrl(href),
7739
- text,
7740
- type: 'link'
7741
- }
7742
- };
7743
- }
7744
- }
7745
- index++;
7746
- }
7747
- return undefined;
7748
- };
7749
- const parseImageToken = (value, start) => {
7750
- if (value[start] !== '!' || value[start + 1] !== '[') {
7751
- return undefined;
7752
- }
7753
- const textEnd = value.indexOf(']', start + 2);
7754
- if (textEnd === -1) {
7755
- return undefined;
7756
- }
7757
- if (value[textEnd + 1] !== '(') {
7758
- return undefined;
7759
- }
7760
- let depth = 1;
7761
- let index = textEnd + 2;
7762
- while (index < value.length) {
7763
- const current = value[index];
7764
- if (current === '\n') {
7765
- return undefined;
7766
- }
7767
- if (current === '(') {
7768
- depth++;
7769
- } else if (current === ')') {
7770
- depth--;
7771
- if (depth === 0) {
7772
- const alt = value.slice(start + 2, textEnd);
7773
- const src = value.slice(textEnd + 2, index);
7774
- if (!src) {
7775
- return undefined;
7776
- }
7777
- return {
7778
- length: index - start + 1,
7779
- node: {
7780
- alt,
7781
- src: sanitizeImageUrl(src),
7782
- type: 'image'
7783
- }
7784
- };
7785
- }
7786
- }
7787
- index++;
7788
- }
7789
- return undefined;
7790
- };
7791
- const parseBoldToken = (value, start) => {
7792
- if (value[start] !== '*' || value[start + 1] !== '*') {
7793
- return undefined;
7794
- }
7795
- const end = value.indexOf('**', start + 2);
7796
- if (end === -1) {
7797
- return undefined;
7798
- }
7799
- const text = value.slice(start + 2, end);
7800
- if (!text || text.includes('\n')) {
7801
- return undefined;
7802
- }
7803
- return {
7804
- length: end - start + 2,
7805
- node: {
7806
- children: parseInlineNodes(text),
7807
- type: 'bold'
7808
- }
7809
- };
7810
- };
7811
- const parseBoldItalicToken = (value, start) => {
7812
- if (value[start] !== '*' || value[start + 1] !== '*' || value[start + 2] !== '*') {
7813
- return undefined;
7814
- }
7815
- const end = value.indexOf('***', start + 3);
7816
- if (end === -1) {
7817
- return undefined;
7818
- }
7819
- const text = value.slice(start + 3, end);
7820
- if (!text || text.includes('\n')) {
7821
- return undefined;
7822
- }
7823
- return {
7824
- length: end - start + 3,
7825
- node: {
7826
- children: [{
7827
- children: parseInlineNodes(text),
7828
- type: 'italic'
7829
- }],
7830
- type: 'bold'
7831
- }
7832
- };
7833
- };
7834
- const findItalicEnd = (value, start) => {
7835
- let index = start + 1;
7836
- while (index < value.length) {
7837
- if (value[index] !== '*') {
7838
- index++;
7839
- continue;
7840
- }
7841
- if (value[index + 1] !== '*') {
7842
- return index;
7843
- }
7844
- const boldEnd = value.indexOf('**', index + 2);
7845
- if (boldEnd === -1) {
7846
- return -1;
7847
- }
7848
- index = boldEnd + 2;
7849
- }
7850
- return -1;
7851
- };
7852
- const parseItalicToken = (value, start) => {
7853
- if (value[start] !== '*' || value[start + 1] === '*') {
7854
- return undefined;
7855
- }
7856
- const end = findItalicEnd(value, start);
7857
- if (end === -1) {
7858
- return undefined;
7859
- }
7860
- const text = value.slice(start + 1, end);
7861
- if (!text) {
7862
- return undefined;
7863
- }
7864
- return {
7865
- length: end - start + 1,
7866
- node: {
7867
- children: parseInlineNodes(text),
7868
- type: 'italic'
7869
- }
7870
- };
7871
- };
7872
- const parseStrikethroughToken = (value, start) => {
7873
- if (value[start] !== '~' || value[start + 1] !== '~') {
7874
- return undefined;
7875
- }
7876
- const end = value.indexOf('~~', start + 2);
7877
- if (end === -1) {
7878
- return undefined;
7879
- }
7880
- const text = value.slice(start + 2, end);
7881
- if (!text || text.includes('\n')) {
7882
- return undefined;
7883
- }
7884
- return {
7885
- length: end - start + 2,
7886
- node: {
7887
- children: parseInlineNodes(text),
7888
- type: 'strikethrough'
7889
- }
7890
- };
7891
- };
7892
- const parseInlineCodeToken = (value, start) => {
7893
- if (value[start] !== '`') {
7894
- return undefined;
7895
- }
7896
- const end = value.indexOf('`', start + 1);
7897
- if (end === -1) {
7898
- return undefined;
7899
- }
7900
- const codeText = value.slice(start + 1, end);
7901
- if (!codeText || codeText.includes('\n')) {
7902
- return undefined;
7903
- }
7904
- return {
7905
- length: end - start + 1,
7906
- node: {
7907
- text: codeText,
7908
- type: 'inline-code'
7909
- }
7910
- };
7911
- };
7912
- const parseMathToken = (value, start) => {
7913
- if (value[start] !== '$') {
7914
- return undefined;
7915
- }
7916
- const delimiterLength = value[start + 1] === '$' ? 2 : 1;
7917
- const previous = value[start - 1];
7918
- if (isAlphaNumeric(previous)) {
7919
- return undefined;
7920
- }
7921
- const next = value[start + delimiterLength];
7922
- if (!next || next === '.') {
7923
- return undefined;
7924
- }
7925
- if (next === '(' && (value[start + delimiterLength + 1] === '"' || value[start + delimiterLength + 1] === "'")) {
7926
- return undefined;
7927
- }
7928
- let index = start + delimiterLength;
7929
- while (index < value.length) {
7930
- if (value[index] === '\n') {
7931
- return undefined;
7932
- }
7933
- const isClosed = delimiterLength === 2 ? value.startsWith('$$', index) : value[index] === '$';
7934
- if (isClosed) {
7935
- const body = value.slice(start + delimiterLength, index);
7936
- const following = value[index + delimiterLength];
7937
- if (!body || isAlphaNumeric(following)) {
7938
- return undefined;
7939
- }
7940
- return {
7941
- length: index - start + delimiterLength,
7942
- node: {
7943
- displayMode: delimiterLength === 2,
7944
- text: body.trim(),
7945
- type: 'math-inline'
7946
- }
7947
- };
7948
- }
7949
- if (value[index] === '\\') {
7950
- index += 2;
7951
- continue;
7952
- }
7953
- index++;
7954
- }
7955
- return undefined;
7956
- };
7957
- const parseInlineToken = (value, start) => {
7958
- return parseImageToken(value, start) || parseLinkToken(value, start) || parseRawLinkToken(value, start) || parseBoldItalicToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseLinkToken(value, start) || parseBoldItalicToken(value, start) || parseBoldToken(value, start) || parseItalicToken(value, start) || parseStrikethroughToken(value, start) || parseInlineCodeToken(value, start) || parseMathToken(value, start);
7959
- };
7960
- const parseInlineNodes = value => {
7961
- const nodes = [];
7962
- let textStart = 0;
7963
- let index = 0;
7964
- const pushText = end => {
7965
- if (end <= textStart) {
7966
- return;
7967
- }
7968
- nodes.push({
7969
- text: value.slice(textStart, end),
7970
- type: 'text'
7971
- });
7972
- };
7973
- while (index < value.length) {
7974
- const parsed = parseInlineToken(value, index);
7975
- if (!parsed) {
7976
- index++;
7977
- continue;
7978
- }
7979
- pushText(index);
7980
- nodes.push(parsed.node);
7981
- index += parsed.length;
7982
- textStart = index;
7983
- }
7984
- pushText(value.length);
7985
- if (nodes.length === 0) {
7986
- return [{
7987
- text: value,
7988
- type: 'text'
7989
- }];
7990
- }
7991
- return nodes;
7992
- };
7993
-
7994
- const markdownMathBlockDelimiter = '$$';
7995
- const escapedNewlineRegex = /\\r\\n|\\n/g;
7996
- const lineBreakRegex = /\r?\n/;
7997
- const tableDelimiterRegex = /\|\s*[-:]{3,}/;
7998
- const inlineTableCellRegex = /\|\s+\|/g;
7999
- const normalizeEscapedNewlines = value => {
8000
- if (value.includes('\\n')) {
8001
- return value.replaceAll(escapedNewlineRegex, '\n');
8002
- }
8003
- return value;
8004
- };
8005
- const normalizeInlineTables = value => {
8006
- return value.split(lineBreakRegex).map(line => {
8007
- if (!line.includes('|')) {
8008
- return line;
8009
- }
8010
- if (!tableDelimiterRegex.test(line)) {
8011
- return line;
8012
- }
8013
- return line.replaceAll(inlineTableCellRegex, '|\n|');
8014
- }).join('\n');
8015
- };
8016
- const parseHeadingLine = line => {
8017
- const trimmedStart = line.trimStart();
8018
- let index = 0;
8019
- while (index < trimmedStart.length && trimmedStart[index] === '#') {
8020
- index++;
8021
- }
8022
- if (index === 0 || index > 6) {
8023
- return undefined;
8024
- }
8025
- if (trimmedStart[index] !== ' ') {
8026
- return undefined;
8027
- }
8028
- const text = trimmedStart.slice(index).trimStart();
8029
- return {
8030
- level: index,
8031
- text
8032
- };
8033
- };
8034
- const parseOrderedListItemLine = line => {
8035
- let indentation = 0;
8036
- while (indentation < line.length && line[indentation] === ' ') {
8037
- indentation++;
8038
- }
8039
- let index = indentation;
8040
- const firstDigit = index;
8041
- while (index < line.length && line[index] >= '0' && line[index] <= '9') {
8042
- index++;
8043
- }
8044
- if (index === firstDigit || line[index] !== '.') {
8045
- return undefined;
8046
- }
8047
- index++;
8048
- if (line[index] !== ' ') {
8049
- return undefined;
8050
- }
8051
- while (index < line.length && line[index] === ' ') {
8052
- index++;
8053
- }
8054
- return {
8055
- indentation,
8056
- text: line.slice(index)
8057
- };
8058
- };
8059
- const parseUnorderedListItemLine = line => {
8060
- let indentation = 0;
8061
- while (indentation < line.length && line[indentation] === ' ') {
8062
- indentation++;
8063
- }
8064
- const marker = line[indentation];
8065
- if (marker !== '-' && marker !== '*') {
8066
- return undefined;
8067
- }
8068
- let index = indentation + 1;
8069
- if (line[index] !== ' ') {
8070
- return undefined;
8071
- }
8072
- while (index < line.length && line[index] === ' ') {
8073
- index++;
8074
- }
8075
- return {
8076
- indentation,
8077
- text: line.slice(index)
8078
- };
8079
- };
8080
- const parseBlockQuoteLine = line => {
8081
- const trimmedStart = line.trimStart();
8082
- if (!trimmedStart.startsWith('>')) {
8083
- return undefined;
8084
- }
8085
- const content = trimmedStart.slice(1);
8086
- if (!content) {
8087
- return '';
8088
- }
8089
- if (content.startsWith(' ')) {
8090
- return content.slice(1);
8091
- }
8092
- return content;
8093
- };
8094
- const isThematicBreakLine = line => {
8095
- const trimmedStart = line.trimStart();
8096
- const leadingSpaces = line.length - trimmedStart.length;
8097
- if (leadingSpaces > 3) {
8098
- return false;
8099
- }
8100
- const trimmed = trimmedStart.trimEnd();
8101
- if (!trimmed) {
8102
- return false;
8103
- }
8104
- const marker = trimmed[0];
8105
- if (marker !== '-' && marker !== '_' && marker !== '*') {
8106
- return false;
8107
- }
8108
- let markerCount = 0;
8109
- for (let i = 0; i < trimmed.length; i++) {
8110
- const char = trimmed[i];
8111
- if (char === marker) {
8112
- markerCount++;
8113
- continue;
8114
- }
8115
- if (char !== ' ') {
8116
- return false;
8117
- }
8118
- }
8119
- return markerCount >= 3;
8120
- };
8121
- const isTableRow = line => {
8122
- const trimmed = line.trim();
8123
- if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) {
8124
- return false;
8125
- }
8126
- return trimmed.length > 2;
8127
- };
8128
- const getTableCells = line => {
8129
- const trimmed = line.trim();
8130
- return trimmed.slice(1, -1).split('|').map(part => part.trim());
8131
- };
8132
- const scanBlockTokens = rawMessage => {
8133
- const normalizedMessage = normalizeInlineTables(normalizeEscapedNewlines(rawMessage));
8134
- const lines = normalizedMessage.split(lineBreakRegex);
8135
- const tokens = [];
8136
- for (let i = 0; i < lines.length; i++) {
8137
- const line = lines[i];
8138
- const trimmed = line.trim();
8139
- if (!trimmed) {
8140
- tokens.push({
8141
- type: 'blank-line'
8142
- });
8143
- continue;
8144
- }
8145
- const blockQuoteLine = parseBlockQuoteLine(line);
8146
- if (blockQuoteLine !== undefined) {
8147
- tokens.push({
8148
- text: blockQuoteLine,
8149
- type: 'blockquote-line'
8150
- });
8151
- continue;
8152
- }
8153
- if (trimmed.startsWith('```')) {
8154
- const language = trimmed.slice(3).trim();
8155
- const codeLines = [];
8156
- i++;
8157
- while (i < lines.length && !lines[i].trim().startsWith('```')) {
8158
- codeLines.push(lines[i]);
8159
- i++;
8160
- }
8161
- if (language) {
8162
- tokens.push({
8163
- language,
8164
- text: codeLines.join('\n'),
8165
- type: 'code-block'
8166
- });
8167
- } else {
8168
- tokens.push({
8169
- text: codeLines.join('\n'),
8170
- type: 'code-block'
8171
- });
8172
- }
8173
- continue;
8174
- }
8175
- if (trimmed === markdownMathBlockDelimiter) {
8176
- const endIndex = lines.findIndex((candidate, index) => {
8177
- if (index <= i) {
8178
- return false;
8179
- }
8180
- return candidate.trim() === markdownMathBlockDelimiter;
8181
- });
8182
- if (endIndex !== -1) {
8183
- tokens.push({
8184
- text: lines.slice(i + 1, endIndex).join('\n').trim(),
8185
- type: 'math-block'
8186
- });
8187
- i = endIndex;
8188
- continue;
8189
- }
8190
- }
8191
- const heading = parseHeadingLine(line);
8192
- if (heading) {
8193
- tokens.push({
8194
- level: heading.level,
8195
- text: heading.text,
8196
- type: 'heading-line'
8197
- });
8198
- continue;
8199
- }
8200
- if (isThematicBreakLine(line)) {
8201
- tokens.push({
8202
- type: 'thematic-break'
8203
- });
8204
- continue;
8205
- }
8206
- const ordered = parseOrderedListItemLine(line);
8207
- if (ordered) {
8208
- tokens.push({
8209
- indentation: ordered.indentation,
8210
- text: ordered.text,
8211
- type: 'ordered-list-item-line'
8212
- });
8213
- continue;
8214
- }
8215
- const unordered = parseUnorderedListItemLine(line);
8216
- if (unordered) {
8217
- tokens.push({
8218
- indentation: unordered.indentation,
8219
- text: unordered.text,
8220
- type: 'unordered-list-item-line'
8221
- });
8222
- continue;
8223
- }
8224
- if (isTableRow(line)) {
8225
- tokens.push({
8226
- cells: getTableCells(line),
8227
- line,
8228
- type: 'table-row-line'
8229
- });
8230
- continue;
8231
- }
8232
- tokens.push({
8233
- text: line,
8234
- type: 'paragraph-line'
8235
- });
8236
- }
8237
- return tokens;
8238
- };
8239
-
8240
- const isTableSeparatorCell = value => {
8241
- if (!value) {
8242
- return false;
8243
- }
8244
- let index = 0;
8245
- if (value[index] === ':') {
8246
- index++;
8247
- }
8248
- let dashCount = 0;
8249
- while (index < value.length && value[index] === '-') {
8250
- dashCount++;
8251
- index++;
8252
- }
8253
- if (dashCount < 3) {
8254
- return false;
8255
- }
8256
- if (index < value.length && value[index] === ':') {
8257
- index++;
8258
- }
8259
- return index === value.length;
8260
- };
8261
- const isTableSeparatorToken = (token, expectedColumns) => {
8262
- if (!token || token.type !== 'table-row-line') {
8263
- return false;
8264
- }
8265
- if (token.cells.length !== expectedColumns) {
8266
- return false;
8267
- }
8268
- return token.cells.every(isTableSeparatorCell);
8269
- };
8270
- const toTableCell = value => {
8271
- return {
8272
- children: parseInlineNodes(value),
8273
- type: 'table-cell'
8274
- };
8275
- };
8276
- const toTableRow = token => {
8277
- return {
8278
- cells: token.cells.map(toTableCell),
8279
- type: 'table-row'
8280
- };
8281
- };
8282
- const getEmptyTextNode = () => {
8283
- return [{
8284
- children: [{
8285
- text: '',
8286
- type: 'text'
8287
- }],
8288
- type: 'text'
8289
- }];
8290
- };
8291
- const parseBlockTokens = tokens => {
8292
- if (tokens.length === 0) {
8293
- return getEmptyTextNode();
8294
- }
8295
- const nodes = [];
8296
- let paragraphLines = [];
8297
- let listItems = [];
8298
- let listType = '';
8299
- let orderedListPathStack = [];
8300
- let canContinueOrderedListItemParagraph = false;
8301
- const createListItem = (text, index) => {
8302
- return {
8303
- children: parseInlineNodes(text),
8304
- ...(index === undefined ? {} : {
8305
- index
8306
- }),
8307
- type: 'list-item'
8308
- };
8309
- };
8310
- const getListItemAtPath = (items, path) => {
8311
- let currentItems = items;
8312
- let currentItem;
8313
- for (const index of path) {
8314
- currentItem = currentItems[index];
8315
- if (!currentItem) {
8316
- return undefined;
8317
- }
8318
- currentItems = currentItem.nestedItems || [];
8319
- }
8320
- return currentItem;
8321
- };
8322
- const appendNestedItemAtPath = (items, path, item, nestedListType) => {
8323
- if (path.length === 0) {
8324
- return [...items, item];
8325
- }
8326
- const [index, ...rest] = path;
8327
- const current = items[index];
8328
- if (!current) {
8329
- return [...items];
8330
- }
8331
- const nextNestedItems = rest.length > 0 ? appendNestedItemAtPath(current.nestedItems || [], rest, item, nestedListType) : [...(current.nestedItems || []), item];
8332
- const nextItem = {
8333
- ...current,
8334
- nestedItems: nextNestedItems,
8335
- nestedListType
8336
- };
8337
- return [...items.slice(0, index), nextItem, ...items.slice(index + 1)];
8338
- };
8339
- const appendInlineChildrenAtPath = (items, path, children) => {
8340
- if (path.length === 0) {
8341
- return [...items];
8342
- }
8343
- const [index, ...rest] = path;
8344
- const current = items[index];
8345
- if (!current) {
8346
- return [...items];
8347
- }
8348
- const lineBreakNode = {
8349
- text: '\n',
8350
- type: 'text'
8351
- };
8352
- const nextChildren = [...current.children, lineBreakNode, ...children];
8353
- const nextItem = rest.length > 0 ? {
8354
- ...current,
8355
- nestedItems: appendInlineChildrenAtPath(current.nestedItems || [], rest, children)
8356
- } : {
8357
- ...current,
8358
- children: nextChildren
8359
- };
8360
- return [...items.slice(0, index), nextItem, ...items.slice(index + 1)];
8361
- };
8362
- const flushParagraph = () => {
8363
- if (paragraphLines.length === 0) {
8364
- return;
8365
- }
8366
- nodes.push({
8367
- children: parseInlineNodes(paragraphLines.join('\n')),
8368
- type: 'text'
8369
- });
8370
- paragraphLines = [];
8371
- };
8372
- const flushList = () => {
8373
- if (listItems.length === 0) {
8374
- return;
8375
- }
8376
- nodes.push({
8377
- items: listItems,
8378
- type: listType || 'ordered-list'
8379
- });
8380
- listItems = [];
8381
- listType = '';
8382
- orderedListPathStack = [];
8383
- canContinueOrderedListItemParagraph = false;
8384
- };
8385
- for (let i = 0; i < tokens.length; i++) {
8386
- const token = tokens[i];
8387
- if (token.type === 'blank-line') {
8388
- flushParagraph();
8389
- canContinueOrderedListItemParagraph = false;
8390
- continue;
8391
- }
8392
- if (token.type === 'code-block') {
8393
- flushList();
8394
- flushParagraph();
8395
- if (token.language) {
8396
- nodes.push({
8397
- codeTokens: highlightCode(token.text, token.language),
8398
- language: token.language,
8399
- text: token.text,
8400
- type: 'code-block'
8401
- });
8402
- } else {
8403
- nodes.push({
8404
- codeTokens: highlightCode(token.text, undefined),
8405
- text: token.text,
8406
- type: 'code-block'
8407
- });
8408
- }
8409
- continue;
8410
- }
8411
- if (token.type === 'math-block') {
8412
- flushList();
8413
- flushParagraph();
8414
- nodes.push({
8415
- text: token.text,
8416
- type: 'math-block'
8417
- });
8418
- continue;
8419
- }
8420
- if (token.type === 'thematic-break') {
8421
- flushList();
8422
- flushParagraph();
8423
- nodes.push({
8424
- type: 'thematic-break'
8425
- });
8426
- continue;
8427
- }
8428
- if (token.type === 'blockquote-line') {
8429
- flushList();
8430
- flushParagraph();
8431
- const lines = [];
8432
- while (i < tokens.length && tokens[i].type === 'blockquote-line') {
8433
- const quoteToken = tokens[i];
8434
- if (quoteToken.type === 'blockquote-line') {
8435
- lines.push(quoteToken.text);
8436
- }
8437
- i++;
8438
- }
8439
- i--;
8440
- nodes.push({
8441
- children: parseBlockTokens(scanBlockTokens(lines.join('\n'))),
8442
- type: 'blockquote'
8443
- });
8444
- continue;
8445
- }
8446
- if (token.type === 'table-row-line') {
8447
- const expectedColumns = token.cells.length;
8448
- if (isTableSeparatorToken(tokens[i + 1], expectedColumns)) {
8449
- flushList();
8450
- flushParagraph();
8451
- const rows = [];
8452
- i += 2;
8453
- while (i < tokens.length && tokens[i].type === 'table-row-line') {
8454
- const rowToken = tokens[i];
8455
- if (rowToken.type !== 'table-row-line') {
8456
- break;
8457
- }
8458
- if (rowToken.cells.length === expectedColumns) {
8459
- rows.push(toTableRow(rowToken));
8460
- }
8461
- i++;
8462
- }
8463
- i--;
8464
- nodes.push({
8465
- headers: token.cells.map(toTableCell),
8466
- rows,
8467
- type: 'table'
8468
- });
8469
- continue;
8470
- }
8471
- flushList();
8472
- paragraphLines.push(token.line);
8473
- continue;
8474
- }
8475
- if (token.type === 'ordered-list-item-line') {
8476
- if (listType === 'ordered-list' && listItems.length > 0 && token.indentation > 0 && orderedListPathStack.length > 0) {
8477
- const parentEntry = orderedListPathStack.toReversed().find(entry => entry.indentation < token.indentation);
8478
- if (parentEntry) {
8479
- const parentItem = getListItemAtPath(listItems, parentEntry.path);
8480
- if (parentItem) {
8481
- const nextIndex = parentItem.nestedItems?.length || 0;
8482
- const nextItem = createListItem(token.text, nextIndex + 1);
8483
- listItems = appendNestedItemAtPath(listItems, parentEntry.path, nextItem, 'ordered-list');
8484
- const nextPath = [...parentEntry.path, nextIndex];
8485
- orderedListPathStack = [...orderedListPathStack.filter(entry => entry.indentation < token.indentation), {
8486
- indentation: token.indentation,
8487
- path: nextPath
8488
- }];
8489
- canContinueOrderedListItemParagraph = true;
8490
- continue;
8491
- }
8492
- }
8493
- }
8494
- if (listType && listType !== 'ordered-list') {
8495
- flushList();
8496
- }
8497
- flushParagraph();
8498
- listType = 'ordered-list';
8499
- const nextIndex = listItems.length;
8500
- const nextItem = createListItem(token.text, nextIndex + 1);
8501
- listItems.push(nextItem);
8502
- orderedListPathStack = [...orderedListPathStack.filter(entry => entry.indentation < token.indentation), {
8503
- indentation: token.indentation,
8504
- path: [nextIndex]
8505
- }];
8506
- canContinueOrderedListItemParagraph = true;
8507
- continue;
8508
- }
8509
- if (token.type === 'unordered-list-item-line') {
8510
- if (listType === 'ordered-list' && listItems.length > 0 && token.indentation > 0 && orderedListPathStack.length > 0) {
8511
- const parentEntry = orderedListPathStack.toReversed().find(entry => entry.indentation < token.indentation);
8512
- if (parentEntry) {
8513
- const nextItem = createListItem(token.text);
8514
- listItems = appendNestedItemAtPath(listItems, parentEntry.path, nextItem, 'unordered-list');
8515
- canContinueOrderedListItemParagraph = false;
8516
- continue;
8517
- }
8518
- }
8519
- if (listType && listType !== 'unordered-list') {
8520
- flushList();
8521
- }
8522
- flushParagraph();
8523
- listType = 'unordered-list';
8524
- listItems.push(createListItem(token.text));
8525
- canContinueOrderedListItemParagraph = false;
8526
- continue;
8527
- }
8528
- if (token.type === 'heading-line') {
8529
- flushList();
8530
- flushParagraph();
8531
- nodes.push({
8532
- children: parseInlineNodes(token.text),
8533
- level: token.level,
8534
- type: 'heading'
8535
- });
8536
- continue;
8537
- }
8538
- if (token.type === 'paragraph-line' && listType === 'ordered-list' && listItems.length > 0 && canContinueOrderedListItemParagraph) {
8539
- const currentPath = orderedListPathStack.at(-1)?.path;
8540
- if (currentPath) {
8541
- listItems = appendInlineChildrenAtPath(listItems, currentPath, parseInlineNodes(token.text));
8542
- continue;
8543
- }
8544
- }
8545
- flushList();
8546
- paragraphLines.push(token.text);
8547
- canContinueOrderedListItemParagraph = false;
8548
- }
8549
- flushList();
8550
- flushParagraph();
8551
- return nodes.length === 0 ? getEmptyTextNode() : nodes;
8552
- };
8553
-
8554
- const parseMessageContent = async rawMessage => {
8555
- return parseBlockTokens(scanBlockTokens(rawMessage));
8556
- };
8557
-
8558
- const emptyMessageContent = [{
8559
- children: [{
8560
- text: '',
8561
- type: 'text'
8562
- }],
8563
- type: 'text'
8564
- }];
8565
- const parseMathInline = async children => {
8566
- const nextChildren = [];
8567
- for (const child of children) {
8568
- if (child.type === 'math-inline') {
8569
- const dom = await getMathInlineDom(child);
8570
- nextChildren.push({
8571
- dom,
8572
- type: 'math-inline-dom'
8573
- });
8574
- continue;
8575
- }
8576
- if (child.type === 'bold') {
8577
- nextChildren.push({
8578
- ...child,
8579
- children: await parseMathInline(child.children)
8580
- });
8581
- continue;
8582
- }
8583
- if (child.type === 'italic') {
8584
- nextChildren.push({
8585
- ...child,
8586
- children: await parseMathInline(child.children)
8587
- });
8588
- continue;
8589
- }
8590
- if (child.type === 'strikethrough') {
8591
- nextChildren.push({
8592
- ...child,
8593
- children: await parseMathInline(child.children)
8594
- });
8595
- continue;
8596
- }
8597
- nextChildren.push(child);
8598
- }
8599
- return nextChildren;
8600
- };
8601
- const parseMathListItem = async item => {
8602
- const children = await parseMathInline(item.children);
8603
- if (!item.nestedItems) {
8604
- return {
8605
- ...item,
8606
- children
8607
- };
8608
- }
8609
- const nestedItems = [];
8610
- for (const nestedItem of item.nestedItems) {
8611
- nestedItems.push(await parseMathListItem(nestedItem));
8612
- }
8613
- return {
8614
- ...item,
8615
- children,
8616
- nestedItems
8617
- };
8618
- };
8619
- const parseMathTableCell = async cell => {
8620
- return {
8621
- ...cell,
8622
- children: await parseMathInline(cell.children)
8623
- };
8624
- };
8625
- const parseMathNode = async node => {
8626
- if (node.type === 'math-block') {
8627
- const dom = await getMathBlockDom(node);
8628
- return {
8629
- dom,
8630
- type: 'math-block-dom'
8631
- };
8632
- }
8633
- if (node.type === 'text' || node.type === 'heading') {
8634
- return {
8635
- ...node,
8636
- children: await parseMathInline(node.children)
8637
- };
8638
- }
8639
- if (node.type === 'blockquote') {
8640
- const children = [];
8641
- for (const child of node.children) {
8642
- children.push(await parseMathNode(child));
8643
- }
8644
- return {
8645
- ...node,
8646
- children
8647
- };
8648
- }
8649
- if (node.type === 'ordered-list' || node.type === 'unordered-list') {
8650
- const items = [];
8651
- for (const item of node.items) {
8652
- items.push(await parseMathListItem(item));
8653
- }
8654
- return {
8655
- ...node,
8656
- items
8657
- };
8658
- }
8659
- if (node.type === 'table') {
8660
- const headers = [];
8661
- for (const header of node.headers) {
8662
- headers.push(await parseMathTableCell(header));
8663
- }
8664
- const rows = [];
8665
- for (const row of node.rows) {
8666
- const cells = [];
8667
- for (const cell of row.cells) {
8668
- cells.push(await parseMathTableCell(cell));
7205
+ const result = await getOpenRouterAssistantText(messages, modelId, openRouterApiKey, openRouterApiBaseUrl, assetDir, platform, useChatNetworkWorkerForRequests, useChatToolWorker, questionToolEnabled, systemPrompt, workspaceUri, agentMode, toolEnablement);
7206
+ if (result.type === 'success') {
7207
+ const {
7208
+ text: assistantText
7209
+ } = result;
7210
+ text = assistantText;
7211
+ } else {
7212
+ text = getOpenRouterErrorMessage(result);
8669
7213
  }
8670
- rows.push({
8671
- ...row,
8672
- cells
8673
- });
7214
+ } else {
7215
+ text = openRouterApiKeyRequiredMessage;
8674
7216
  }
8675
- return {
8676
- ...node,
8677
- headers,
8678
- rows
8679
- };
8680
7217
  }
8681
- return node;
8682
- };
8683
- const parseMessage = async rawMessage => {
8684
- const parsedContent = await parseMessageContent(rawMessage);
8685
- const nextParsedContent = [];
8686
- for (const node of parsedContent) {
8687
- nextParsedContent.push(await parseMathNode(node));
7218
+ if (!text && !usesOpenApiModel && !usesOpenRouterModel) {
7219
+ text = await getMockAiResponse(userText, mockAiResponseDelay);
8688
7220
  }
8689
- return nextParsedContent;
7221
+ const assistantTime = new Date().toLocaleTimeString([], {
7222
+ hour: '2-digit',
7223
+ minute: '2-digit'
7224
+ });
7225
+ const message = {
7226
+ id: messageId || crypto.randomUUID(),
7227
+ role: 'assistant',
7228
+ text,
7229
+ time: assistantTime
7230
+ };
7231
+ return message;
7232
+ };
7233
+
7234
+ const parseMessageContents = async rawMessages => {
7235
+ return invoke$7('ChatMessageParsing.parseMessageContents', rawMessages);
8690
7236
  };
7237
+
7238
+ const emptyMessageContent = [{
7239
+ children: [{
7240
+ text: '',
7241
+ type: 'text'
7242
+ }],
7243
+ type: 'text'
7244
+ }];
8691
7245
  const getParsedMessageContent = (parsedMessages, messageId) => {
8692
7246
  const parsedMessage = parsedMessages.find(item => item.id === messageId);
8693
7247
  return parsedMessage?.parsedContent;
@@ -8719,26 +7273,10 @@ const copyParsedMessageContent = (parsedMessages, sourceMessageId, targetMessage
8719
7273
  return setParsedMessageContent(parsedMessages, targetMessageId, parsedMessage.text, parsedMessage.parsedContent);
8720
7274
  };
8721
7275
  const parseAndStoreMessageContent = async (parsedMessages, message) => {
8722
- const existingParsedMessage = parsedMessages.find(item => item.id === message.id);
8723
- if (existingParsedMessage && existingParsedMessage.text === message.text) {
8724
- return parsedMessages;
8725
- }
8726
- await Promise.resolve();
8727
- const parsedContent = message.text === '' ? emptyMessageContent : await parseMessage(message.text);
8728
- return setParsedMessageContent(parsedMessages, message.id, message.text, parsedContent);
8729
- };
8730
- const parseAndStoreMessageContentWithWorkerPreference = async (parsedMessages, message, useChatMessageParsingWorker) => {
8731
- if (useChatMessageParsingWorker) {
8732
- return parseAndStoreMessagesContentInWorker(parsedMessages, [message]);
8733
- }
8734
- return parseAndStoreMessageContent(parsedMessages, message);
7276
+ return parseAndStoreMessagesContentInWorker(parsedMessages, [message]);
8735
7277
  };
8736
7278
  const parseAndStoreMessagesContent = async (parsedMessages, messages) => {
8737
- let nextParsedMessages = parsedMessages;
8738
- for (const message of messages) {
8739
- nextParsedMessages = await parseAndStoreMessageContent(nextParsedMessages, message);
8740
- }
8741
- return nextParsedMessages;
7279
+ return parseAndStoreMessagesContentInWorker(parsedMessages, messages);
8742
7280
  };
8743
7281
  const getMessagesNeedingParsing = (parsedMessages, messages) => {
8744
7282
  return messages.filter(message => {
@@ -8759,12 +7297,6 @@ const parseAndStoreMessagesContentInWorker = async (parsedMessages, messages) =>
8759
7297
  }
8760
7298
  return nextParsedMessages;
8761
7299
  };
8762
- const parseAndStoreMessagesContentWithWorkerPreference = async (parsedMessages, messages, useChatMessageParsingWorker) => {
8763
- if (useChatMessageParsingWorker) {
8764
- return parseAndStoreMessagesContentInWorker(parsedMessages, messages);
8765
- }
8766
- return parseAndStoreMessagesContent(parsedMessages, messages);
8767
- };
8768
7300
  const getEmptyMessageContent = () => {
8769
7301
  return emptyMessageContent;
8770
7302
  };
@@ -9276,7 +7808,7 @@ const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls,
9276
7808
  };
9277
7809
  };
9278
7810
 
9279
- const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress, useChatMessageParsingWorker) => {
7811
+ const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress) => {
9280
7812
  let updatedMessage;
9281
7813
  const updatedSessions = sessions.map(session => {
9282
7814
  if (session.id !== selectedSessionId) {
@@ -9299,7 +7831,7 @@ const updateMessageTextInSelectedSession = async (sessions, parsedMessages, sele
9299
7831
  });
9300
7832
  let nextParsedMessages = parsedMessages;
9301
7833
  if (updatedMessage) {
9302
- nextParsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, updatedMessage, useChatMessageParsingWorker);
7834
+ nextParsedMessages = await parseAndStoreMessageContent(parsedMessages, updatedMessage);
9303
7835
  }
9304
7836
  return {
9305
7837
  parsedMessages: nextParsedMessages,
@@ -9322,7 +7854,7 @@ const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTex
9322
7854
  };
9323
7855
  }
9324
7856
  const updatedText = assistantMessage.text + chunk;
9325
- const updated = await updateMessageTextInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, updatedText, true, handleTextChunkState.latestState.useChatMessageParsingWorker);
7857
+ const updated = await updateMessageTextInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, updatedText, true);
9326
7858
  const nextState = {
9327
7859
  ...handleTextChunkState.latestState,
9328
7860
  ...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
@@ -9521,7 +8053,6 @@ const handleSubmit = async state => {
9521
8053
  streamingEnabled,
9522
8054
  toolEnablement,
9523
8055
  useChatCoordinatorWorker,
9524
- useChatMessageParsingWorker,
9525
8056
  useChatNetworkWorkerForRequests,
9526
8057
  useChatToolWorker,
9527
8058
  useMockApi,
@@ -9567,8 +8098,8 @@ const handleSubmit = async state => {
9567
8098
  let {
9568
8099
  parsedMessages
9569
8100
  } = effectiveState;
9570
- parsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, userMessage, useChatMessageParsingWorker);
9571
- parsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, inProgressAssistantMessage, useChatMessageParsingWorker);
8101
+ parsedMessages = await parseAndStoreMessageContent(parsedMessages, userMessage);
8102
+ parsedMessages = await parseAndStoreMessageContent(parsedMessages, inProgressAssistantMessage);
9572
8103
  let workingSessions = sessions;
9573
8104
  if (viewMode === 'detail') {
9574
8105
  const loadedSession = await getChatSession(selectedSessionId);
@@ -9743,11 +8274,11 @@ const handleSubmit = async state => {
9743
8274
  let finalParsedMessages = latestState.parsedMessages;
9744
8275
  let updatedSessions;
9745
8276
  if (streamingEnabled) {
9746
- const updated = await updateMessageTextInSelectedSession(latestState.sessions, finalParsedMessages, latestState.selectedSessionId, assistantMessageId, assistantMessage.text, false, latestState.useChatMessageParsingWorker);
8277
+ const updated = await updateMessageTextInSelectedSession(latestState.sessions, finalParsedMessages, latestState.selectedSessionId, assistantMessageId, assistantMessage.text, false);
9747
8278
  updatedSessions = updated.sessions;
9748
8279
  finalParsedMessages = updated.parsedMessages;
9749
8280
  } else {
9750
- finalParsedMessages = await parseAndStoreMessageContentWithWorkerPreference(finalParsedMessages, assistantMessage, latestState.useChatMessageParsingWorker);
8281
+ finalParsedMessages = await parseAndStoreMessageContent(finalParsedMessages, assistantMessage);
9751
8282
  updatedSessions = appendMessageToSelectedSession(latestState.sessions, latestState.selectedSessionId, assistantMessage);
9752
8283
  }
9753
8284
  if (aiSessionTitleGenerationEnabled && createsNewSession) {
@@ -11393,15 +9924,6 @@ const loadUseChatMathWorker = async () => {
11393
9924
  }
11394
9925
  };
11395
9926
 
11396
- const loadUseChatMessageParsingWorker = async () => {
11397
- try {
11398
- const savedUseChatMessageParsingWorker = await get('chatView.useChatMessageParsingWorker');
11399
- return typeof savedUseChatMessageParsingWorker === 'boolean' ? savedUseChatMessageParsingWorker : false;
11400
- } catch {
11401
- return false;
11402
- }
11403
- };
11404
-
11405
9927
  const loadUseChatNetworkWorkerForRequests = async () => {
11406
9928
  try {
11407
9929
  const savedUseChatNetworkWorkerForRequests = await get('chatView.useChatNetworkWorkerForRequests');
@@ -11430,7 +9952,7 @@ const loadVoiceDictationEnabled = async () => {
11430
9952
  };
11431
9953
 
11432
9954
  const loadPreferences = async () => {
11433
- const [aiSessionTitleGenerationEnabled, authEnabled, backendUrl, chatHistoryEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, reasoningPickerEnabled, scrollDownButtonEnabled, searchEnabled, streamingEnabled, todoListToolEnabled, toolEnablement, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatMessageParsingWorker, useChatNetworkWorkerForRequests, useChatToolWorker, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadAuthEnabled(), loadBackendUrl(), loadChatHistoryEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadReasoningPickerEnabled(), loadScrollDownButtonEnabled(), loadSearchEnabled(), loadStreamingEnabled(), loadTodoListToolEnabled(), loadToolEnablement(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatMessageParsingWorker(), loadUseChatNetworkWorkerForRequests(), loadUseChatToolWorker(), loadVoiceDictationEnabled()]);
9955
+ const [aiSessionTitleGenerationEnabled, authEnabled, backendUrl, chatHistoryEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, reasoningPickerEnabled, scrollDownButtonEnabled, searchEnabled, streamingEnabled, todoListToolEnabled, toolEnablement, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatNetworkWorkerForRequests, useChatToolWorker, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadAuthEnabled(), loadBackendUrl(), loadChatHistoryEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadReasoningPickerEnabled(), loadScrollDownButtonEnabled(), loadSearchEnabled(), loadStreamingEnabled(), loadTodoListToolEnabled(), loadToolEnablement(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatNetworkWorkerForRequests(), loadUseChatToolWorker(), loadVoiceDictationEnabled()]);
11434
9956
  return {
11435
9957
  aiSessionTitleGenerationEnabled,
11436
9958
  authEnabled,
@@ -11449,7 +9971,6 @@ const loadPreferences = async () => {
11449
9971
  toolEnablement,
11450
9972
  useChatCoordinatorWorker,
11451
9973
  useChatMathWorker,
11452
- useChatMessageParsingWorker,
11453
9974
  useChatNetworkWorkerForRequests,
11454
9975
  useChatToolWorker,
11455
9976
  voiceDictationEnabled
@@ -11521,12 +10042,10 @@ const loadContent = async (state, savedState) => {
11521
10042
  toolEnablement,
11522
10043
  useChatCoordinatorWorker,
11523
10044
  useChatMathWorker,
11524
- // useChatMessageParsingWorker,
11525
10045
  useChatNetworkWorkerForRequests,
11526
10046
  useChatToolWorker,
11527
10047
  voiceDictationEnabled
11528
10048
  } = await loadPreferences();
11529
- const useChatMessageParsingWorker = true;
11530
10049
  const authState = authEnabled && backendUrl ? await syncBackendAuth(backendUrl) : getLoggedOutBackendAuthState();
11531
10050
  const legacySavedSessions = getSavedSessions(savedState);
11532
10051
  const storedSessions = await listChatSessions();
@@ -11572,7 +10091,7 @@ const loadContent = async (state, savedState) => {
11572
10091
  parsedMessages
11573
10092
  } = state;
11574
10093
  for (const session of sessions) {
11575
- parsedMessages = await parseAndStoreMessagesContentWithWorkerPreference(parsedMessages, session.messages, useChatMessageParsingWorker);
10094
+ parsedMessages = await parseAndStoreMessagesContent(parsedMessages, session.messages);
11576
10095
  }
11577
10096
  const preferredViewMode = savedViewMode || state.viewMode;
11578
10097
  const savedLastNormalViewMode = getSavedLastNormalViewMode(savedState);
@@ -11630,7 +10149,6 @@ const loadContent = async (state, savedState) => {
11630
10149
  toolEnablement,
11631
10150
  useChatCoordinatorWorker,
11632
10151
  useChatMathWorker,
11633
- useChatMessageParsingWorker,
11634
10152
  useChatNetworkWorkerForRequests,
11635
10153
  useChatToolWorker,
11636
10154
  userName: authState.userName,
@@ -11755,7 +10273,7 @@ const openMockSession = async (state, mockSessionId, mockChatMessages, options)
11755
10273
  if (!mockSessionId) {
11756
10274
  return state;
11757
10275
  }
11758
- const parsedMessages = await parseAndStoreMessagesContentWithWorkerPreference(state.parsedMessages, mockChatMessages, state.useChatMessageParsingWorker);
10276
+ const parsedMessages = await parseAndStoreMessagesContent(state.parsedMessages, mockChatMessages);
11759
10277
  const existingSession = currentSessions.find(session => session.id === mockSessionId);
11760
10278
  const sessions = existingSession ? currentSessions.map(session => {
11761
10279
  if (session.id !== mockSessionId) {
@@ -11897,7 +10415,7 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
11897
10415
  }
11898
10416
 
11899
10417
  .InputInvalid{
11900
- border-color: var(--vscode-inputValidation-errorBorder, var(--vscode-errorForeground));
10418
+ border-color: var(--InputValidationErrorBorder, red);
11901
10419
  }
11902
10420
 
11903
10421
  .ChatComposerAttachmentTextFile{
@@ -12008,12 +10526,16 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
12008
10526
  color: var(--vscode-errorForeground, var(--vscode-foreground));
12009
10527
  }
12010
10528
 
12011
- .CustomSelectContainer{
10529
+ .ChatSelect{
12012
10530
  position: relative;
12013
10531
  min-width: 0;
12014
10532
 
12015
10533
  }
12016
10534
 
10535
+ .ChatModelPickerItem{
10536
+ display: flex;
10537
+ }
10538
+
12017
10539
  .ChatGitBranchPickerMessage{
12018
10540
  padding: 6px 8px;
12019
10541
  }
@@ -12141,6 +10663,11 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
12141
10663
  flex: 1;
12142
10664
  min-height: 0;
12143
10665
  }
10666
+
10667
+ .ChatModelPickerList {
10668
+ display: flex;
10669
+ contain: content;
10670
+ }
12144
10671
  `;
12145
10672
  return `${baseCss}
12146
10673
 
@@ -12233,6 +10760,160 @@ const renderFocusContext = (oldState, newState) => {
12233
10760
  return [SetFocusContext, newState.uid, FocusChatInput];
12234
10761
  };
12235
10762
 
10763
+ const Actions = 'Actions';
10764
+ const Button = 'Button';
10765
+ const ButtonPrimary = 'ButtonPrimary';
10766
+ const ButtonSecondary = 'ButtonSecondary';
10767
+ const Chat = 'Chat';
10768
+ const ChatActions = 'ChatActions';
10769
+ const ChatAuthError = 'ChatAuthError';
10770
+ const ChatFocus = 'ChatFocus';
10771
+ const ChatFocusActions = 'ChatFocusActions';
10772
+ const ChatFocusHeader = 'ChatFocusHeader';
10773
+ const ChatFocusMainArea = 'ChatFocusMainArea';
10774
+ const ChatFocusProject = 'ChatFocusProject';
10775
+ const ChatGitBranchPicker = 'ChatGitBranchPicker';
10776
+ const ChatGitBranchPickerErrorMessage = 'ChatGitBranchPickerErrorMessage';
10777
+ const ChatGitBranchPickerMessage = 'ChatGitBranchPickerMessage';
10778
+ const ChatHeader = 'ChatHeader';
10779
+ const ChatHeaderAuth = 'ChatHeaderAuth';
10780
+ const ChatHeaderAuthName = 'ChatHeaderAuthName';
10781
+ const ChatHeaderLabel = 'ChatHeaderLabel';
10782
+ const ChatInputBox = 'ChatInputBox';
10783
+ const ChatList = 'ChatList';
10784
+ const ChatListEmpty = 'ChatListEmpty';
10785
+ const ChatListItem = 'ChatListItem';
10786
+ const ChatListItemFocused = 'ChatListItemFocused';
10787
+ const ChatListItemLabel = 'ChatListItemLabel';
10788
+ const ChatListItemStatusFinished = 'ChatListItemStatusFinished';
10789
+ const ChatListItemStatusIcon = 'ChatListItemStatusIcon';
10790
+ const ChatListItemStatusInProgress = 'ChatListItemStatusInProgress';
10791
+ const ChatListItemStatusRow = 'ChatListItemStatusRow';
10792
+ const ChatListItemStatusStopped = 'ChatListItemStatusStopped';
10793
+ const ChatMessageContent = 'ChatMessageContent';
10794
+ const ChatImageMessageContent = 'ChatImageMessageContent';
10795
+ const ChatMessageLink = 'ChatMessageLink';
10796
+ const ChatModelPicker = 'ChatModelPicker';
10797
+ const ChatModelPickerContainer = 'ChatModelPickerContainer';
10798
+ const ChatModelPickerHeader = 'ChatModelPickerHeader';
10799
+ const ChatModelPickerItem = 'ChatModelPickerItem';
10800
+ const ChatModelPickerItemLabel = 'ChatModelPickerItemLabel';
10801
+ const ChatModelPickerItemSelected = 'ChatModelPickerItemSelected';
10802
+ const ChatModelPickerItemUsageCost = 'ChatModelPickerItemUsageCost';
10803
+ const ChatModelPickerList = 'ChatModelPickerList';
10804
+ const ChatName = 'ChatName';
10805
+ const ChatOverlays = 'ChatOverlays';
10806
+ const ChatOrderedList = 'ChatOrderedList';
10807
+ const ChatOrderedListItem = 'ChatOrderedListItem';
10808
+ const ChatOrderedListItemContent = 'ChatOrderedListItemContent';
10809
+ const ChatOrderedListItemPrefix = 'ChatOrderedListItemPrefix';
10810
+ const ChatOrderedListMarker = 'ChatOrderedListMarker';
10811
+ const ChatComposerAttachment = 'ChatComposerAttachment';
10812
+ const ChatComposerAttachmentImage = 'ChatComposerAttachmentImage';
10813
+ const ChatComposerAttachmentInvalidImage = 'ChatComposerAttachmentInvalidImage';
10814
+ const ChatComposerAttachmentLabel = 'ChatComposerAttachmentLabel';
10815
+ const ChatComposerAttachmentPreview = 'ChatComposerAttachmentPreview';
10816
+ const ChatComposerAttachmentPreviewOverlay = 'ChatComposerAttachmentPreviewOverlay';
10817
+ const ChatComposerAttachmentPreviewOverlayError = 'ChatComposerAttachmentPreviewOverlayError';
10818
+ const ChatComposerAttachmentPreviewOverlayImage = 'ChatComposerAttachmentPreviewOverlayImage';
10819
+ const ChatComposerAttachmentRemoveButton = 'ChatComposerAttachmentRemoveButton';
10820
+ const ChatComposerAttachments = 'ChatComposerAttachments';
10821
+ const ChatComposerAttachmentTextFile = 'ChatComposerAttachmentTextFile';
10822
+ const ChatAttachment = 'ChatAttachment';
10823
+ const ChatAttachmentImage = 'ChatAttachmentImage';
10824
+ const ChatAttachmentInvalidImage = 'ChatAttachmentInvalidImage';
10825
+ const ChatAttachmentLabel = 'ChatAttachmentLabel';
10826
+ const ChatAttachmentPreview = 'ChatAttachmentPreview';
10827
+ const ChatAttachments = 'ChatAttachments';
10828
+ const ChatAttachmentTextFile = 'ChatAttachmentTextFile';
10829
+ const ChatMessageImage = 'ChatMessageImage';
10830
+ const ChatSendArea = 'ChatSendArea';
10831
+ const ChatSendAreaBottom = 'ChatSendAreaBottom';
10832
+ const ChatSendAreaContent = 'ChatSendAreaContent';
10833
+ const ChatSendAreaPrimaryControls = 'ChatSendAreaPrimaryControls';
10834
+ const ChatSelect = 'ChatSelect';
10835
+ const ChatTableWrapper = 'ChatTableWrapper';
10836
+ const ChatTodoList = 'ChatTodoList';
10837
+ const ChatTodoListHeader = 'ChatTodoListHeader';
10838
+ const ChatTodoListItem = 'ChatTodoListItem';
10839
+ const ChatTodoListItemCompleted = 'ChatTodoListItemCompleted';
10840
+ const ChatTodoListItemInProgress = 'ChatTodoListItemInProgress';
10841
+ const ChatTodoListItems = 'ChatTodoListItems';
10842
+ const ChatTodoListItemTodo = 'ChatTodoListItemTodo';
10843
+ const ChatToolCallFileName = 'ChatToolCallFileName';
10844
+ const ChatToolCallQuestionOption = 'ChatToolCallQuestionOption';
10845
+ const ChatToolCallQuestionOptions = 'ChatToolCallQuestionOptions';
10846
+ const ChatToolCallQuestionText = 'ChatToolCallQuestionText';
10847
+ const ChatToolCallReadFileLink = 'ChatToolCallReadFileLink';
10848
+ const ChatToolCallRenderHtmlBody = 'ChatToolCallRenderHtmlBody';
10849
+ const ChatToolCallRenderHtmlContent = 'ChatToolCallRenderHtmlContent';
10850
+ const ChatToolCallRenderHtmlLabel = 'ChatToolCallRenderHtmlLabel';
10851
+ const ChatToolCalls = 'ChatToolCalls';
10852
+ const ChatToolCallsLabel = 'ChatToolCallsLabel';
10853
+ const ChatUnorderedList = 'ChatUnorderedList';
10854
+ const ChatUnorderedListItem = 'ChatUnorderedListItem';
10855
+ const ChatViewDropOverlay = 'ChatViewDropOverlay';
10856
+ const ChatViewDropOverlayActive = 'ChatViewDropOverlayActive';
10857
+ const ChatWelcomeMessage = 'ChatWelcomeMessage';
10858
+ const CustomSelectPopOver = 'CustomSelectPopOver';
10859
+ const Deletion = 'Deletion';
10860
+ const Empty = '';
10861
+ const FileIcon = 'FileIcon';
10862
+ const IconButton = 'IconButton';
10863
+ const IconButtonDisabled = 'IconButtonDisabled';
10864
+ const ImageElement = 'ImageElement';
10865
+ const ImageErrorMessage = 'ImageErrorMessage';
10866
+ const InputBox = 'InputBox';
10867
+ const InputInvalid = 'InputInvalid';
10868
+ const Insertion = 'Insertion';
10869
+ const Label = 'Label';
10870
+ const LabelDetail = 'LabelDetail';
10871
+ const Markdown = 'Markdown';
10872
+ const MarkdownMathBlock = 'MarkdownMathBlock';
10873
+ const MarkdownQuote = 'MarkdownQuote';
10874
+ const MarkdownTable = 'MarkdownTable';
10875
+ const MaskIcon = 'MaskIcon';
10876
+ const MaskIconAdd = 'MaskIconAdd';
10877
+ const MaskIconArrowLeft = 'MaskIconArrowLeft';
10878
+ const MaskIconChevronDown = 'MaskIconChevronDown';
10879
+ const MaskIconChevronRight = 'MaskIconChevronRight';
10880
+ const MaskIconChevronUp = 'MaskIconChevronUp';
10881
+ const MaskIconClose = 'MaskIconClose';
10882
+ const MaskIconDebugPause = 'MaskIconDebugPause';
10883
+ const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
10884
+ const MaskIconSearch = 'MaskIconSearch';
10885
+ const MaskIconSettingsGear = 'MaskIconSettingsGear';
10886
+ const Message = 'Message';
10887
+ const MessageAssistant = 'MessageAssistant';
10888
+ const MessageUser = 'MessageUser';
10889
+ const MissingApiKeyForm = 'MissingApiKeyForm';
10890
+ const MultiLineInputBox = 'MultilineInputBox';
10891
+ const ProjectAddButton = 'ProjectAddButton';
10892
+ const ProjectList = 'ProjectList';
10893
+ const ProjectListChevron = 'ProjectListChevron';
10894
+ const ProjectListGroup = 'ProjectListGroup';
10895
+ const ProjectListItem = 'ProjectListItem';
10896
+ const ProjectListItemActions = 'ProjectListItemActions';
10897
+ const ProjectListItemAddChatButton = 'ProjectListItemAddChatButton';
10898
+ const ProjectListItemLabel = 'ProjectListItemLabel';
10899
+ const ProjectListItemSelected = 'ProjectListItemSelected';
10900
+ const ProjectSessionItem = 'ProjectSessionItem';
10901
+ const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
10902
+ const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
10903
+ const ProjectSidebar = 'ProjectSidebar';
10904
+ const SearchFieldContainer = 'SearchFieldContainer';
10905
+ const RunModePickerContainer = 'RunModePickerContainer';
10906
+ const RunModePickerPopOver = 'RunModePickerPopOver';
10907
+ const SelectLabel = 'SelectLabel';
10908
+ const SendButtonDisabled = 'SendButtonDisabled';
10909
+ const SessionArchiveButton = 'SessionArchiveButton';
10910
+ const StrikeThrough = 'StrikeThrough';
10911
+ const TokenUsageOverview = 'TokenUsageOverview';
10912
+ const TokenUsageRing = 'TokenUsageRing';
10913
+ const TokenUsageRingInner = 'TokenUsageRingInner';
10914
+ const ToolCallName = 'ToolCallName';
10915
+ const Viewlet = 'Viewlet';
10916
+
12236
10917
  const HandleListContextMenu = 2;
12237
10918
  const HandleFocus = 3;
12238
10919
  const HandleInput = 4;
@@ -12302,13 +10983,22 @@ const getAddContextButtonDom = () => {
12302
10983
  };
12303
10984
 
12304
10985
  const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title) => {
10986
+ const getChevronDom = expanded => {
10987
+ return {
10988
+ childCount: 0,
10989
+ className: mergeClassNames(MaskIcon, expanded ? MaskIconChevronUp : MaskIconChevronDown),
10990
+ name,
10991
+ role: None$1,
10992
+ type: Div
10993
+ };
10994
+ };
12305
10995
  return [{
12306
10996
  'aria-expanded': open ? 'true' : 'false',
12307
10997
  'aria-haspopup': 'true',
12308
10998
  'aria-label': ariaLabel,
12309
10999
  ariaLabel,
12310
11000
  childCount: 2,
12311
- className: Select,
11001
+ className: ChatSelect,
12312
11002
  inputType: 'button',
12313
11003
  name,
12314
11004
  onClick,
@@ -12320,21 +11010,11 @@ const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = lab
12320
11010
  name,
12321
11011
  role: None$1,
12322
11012
  type: Span
12323
- }, text(label), {
12324
- childCount: 0,
12325
- className: mergeClassNames(MaskIcon, open ? MaskIconChevronUp : MaskIconChevronDown),
12326
- name,
12327
- role: None$1,
12328
- type: Div
12329
- }];
11013
+ }, text(label), getChevronDom(open)];
12330
11014
  };
12331
11015
 
12332
- const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title, containerChildCount = 1) => {
12333
- return [{
12334
- childCount: containerChildCount,
12335
- className: CustomSelectContainer,
12336
- type: Div
12337
- }, ...getCustomSelectToggleVirtualDom(label, name, open, onClick, title, ariaLabel)];
11016
+ const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title) => {
11017
+ return getCustomSelectToggleVirtualDom(label, name, open, onClick, title, ariaLabel);
12338
11018
  };
12339
11019
 
12340
11020
  const getAgentModePickerVirtualDom = (selectedAgentMode, agentModePickerOpen) => {
@@ -12426,7 +11106,7 @@ const getGitBranchPickerVirtualDom = (gitBranches, gitBranchPickerOpen, gitBranc
12426
11106
  const messageDom = getBranchPickerMessageDom(gitBranches, gitBranchPickerErrorMessage);
12427
11107
  const showMessage = messageDom.length > 0;
12428
11108
  const popOverHeight = gitBranches.length * itemHeight + (showMessage ? messageHeight : 0);
12429
- return [...getCustomSelectPickerToggleVirtualDom(label, GitBranchPickerToggle, gitBranchPickerOpen, HandleClickGitBranchPickerToggle, 'Switch branch', 'Switch branch', gitBranchPickerOpen ? 2 : 1), ...(gitBranchPickerOpen ? [{
11109
+ return [...getCustomSelectPickerToggleVirtualDom(label, GitBranchPickerToggle, gitBranchPickerOpen, HandleClickGitBranchPickerToggle, 'Switch branch', 'Switch branch'), ...(gitBranchPickerOpen ? [{
12430
11110
  childCount: (showMessage ? 1 : 0) + 1,
12431
11111
  className: mergeClassNames(ChatModelPicker, CustomSelectPopOver, ChatGitBranchPicker),
12432
11112
  style: `height: ${popOverHeight}px;`,
@@ -12447,7 +11127,7 @@ const getReasoningEffortOptionsVirtualDom = selectedReasoningEffort => {
12447
11127
  });
12448
11128
  };
12449
11129
  const getReasoningEffortPickerVirtualDom = (selectedReasoningEffort, reasoningEffortPickerOpen) => {
12450
- return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', 'Reasoning', reasoningEffortPickerOpen ? 2 : 1), ...(reasoningEffortPickerOpen ? [{
11130
+ return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', 'Reasoning'), ...(reasoningEffortPickerOpen ? [{
12451
11131
  childCount: 1,
12452
11132
  className: mergeClassNames(ChatModelPicker, CustomSelectPopOver),
12453
11133
  style: `height: ${reasoningEffortPickerHeight}px;`,
@@ -12858,7 +11538,23 @@ const getUsageCostLabel = model => {
12858
11538
  };
12859
11539
 
12860
11540
  const getChatModelListItemVirtualDom = (model, selectedModelId) => {
12861
- return getCustomSelectOptionVirtualDom(getModelPickerItemInputName(model.id), getModelLabel(model), model.id === selectedModelId, getUsageCostLabel(model));
11541
+ const detail = getUsageCostLabel(model);
11542
+ const hasDetail = detail !== '';
11543
+ const className = mergeClassNames(ChatModelPickerItem, model.id === selectedModelId ? ChatModelPickerItemSelected : '');
11544
+ return [{
11545
+ childCount: hasDetail ? 2 : 1,
11546
+ className,
11547
+ 'data-id': model.id,
11548
+ type: Li
11549
+ }, {
11550
+ childCount: 1,
11551
+ className: ChatModelPickerItemLabel,
11552
+ type: Span
11553
+ }, text(getModelLabel(model)), ...(hasDetail ? [{
11554
+ childCount: 1,
11555
+ className: ChatModelPickerItemUsageCost,
11556
+ type: Span
11557
+ }, text(detail)] : [])];
12862
11558
  };
12863
11559
 
12864
11560
  const parentNode$2 = {
@@ -13121,19 +11817,7 @@ const getBlockQuoteDom = (node, useChatMathWorker, getMessageNodeDom) => {
13121
11817
  }, ...node.children.flatMap(child => getMessageNodeDom(child, useChatMathWorker))];
13122
11818
  };
13123
11819
 
13124
- const getTokenDom = token => {
13125
- if (!token.className) {
13126
- return [text(token.text)];
13127
- }
13128
- return [{
13129
- childCount: 1,
13130
- className: token.className,
13131
- type: Span
13132
- }, text(token.text)];
13133
- };
13134
-
13135
11820
  const getCodeBlockDom = node => {
13136
- const tokenDom = node.codeTokens.flatMap(getTokenDom);
13137
11821
  const languageAttribute = node.language ? {
13138
11822
  'data-lang': node.language
13139
11823
  } : {};
@@ -13142,10 +11826,10 @@ const getCodeBlockDom = node => {
13142
11826
  type: Pre,
13143
11827
  ...languageAttribute
13144
11828
  }, {
13145
- childCount: node.codeTokens.length,
11829
+ childCount: 1,
13146
11830
  type: Code,
13147
11831
  ...languageAttribute
13148
- }, ...tokenDom];
11832
+ }, text(node.text)];
13149
11833
  };
13150
11834
 
13151
11835
  const getHeadingElementType = level => {
@@ -14055,7 +12739,7 @@ const getElementType = tagName => {
14055
12739
  case 'section':
14056
12740
  return Section;
14057
12741
  case 'select':
14058
- return Select$1;
12742
+ return Select;
14059
12743
  case 'span':
14060
12744
  return Span;
14061
12745
  case 'strong':
@@ -15053,7 +13737,7 @@ const getSessionDom = (session, focused = false) => {
15053
13737
  type: Div
15054
13738
  }, {
15055
13739
  childCount: 0,
15056
- className: `${ChatListItemStatusIcon} codicon codicon-circle-filled ${sessionStatusClassName}`,
13740
+ className: `${ChatListItemStatusIcon} ${sessionStatusClassName}`,
15057
13741
  type: Div
15058
13742
  }, {
15059
13743
  childCount: 1,
@@ -16200,18 +14884,6 @@ const setUseChatMathWorker = async (state, useChatMathWorker, persist = true) =>
16200
14884
  };
16201
14885
  };
16202
14886
 
16203
- const setUseChatMessageParsingWorker = async (state, useChatMessageParsingWorker, persist = true) => {
16204
- if (persist) {
16205
- await update({
16206
- 'chatView.useChatMessageParsingWorker': useChatMessageParsingWorker
16207
- });
16208
- }
16209
- return {
16210
- ...state,
16211
- useChatMessageParsingWorker
16212
- };
16213
- };
16214
-
16215
14887
  const setUseChatNetworkWorkerForRequests = async (state, useChatNetworkWorkerForRequests, persist = true) => {
16216
14888
  if (persist) {
16217
14889
  await update({
@@ -16363,7 +15035,6 @@ const commandMap = {
16363
15035
  'Chat.setToolEnablement': wrapCommand(setToolEnablement),
16364
15036
  'Chat.setUseChatCoordinatorWorker': wrapCommand(setUseChatCoordinatorWorker),
16365
15037
  'Chat.setUseChatMathWorker': wrapCommand(setUseChatMathWorker),
16366
- 'Chat.setUseChatMessageParsingWorker': wrapCommand(setUseChatMessageParsingWorker),
16367
15038
  'Chat.setUseChatNetworkWorkerForRequests': wrapCommand(setUseChatNetworkWorkerForRequests),
16368
15039
  'Chat.showComposerAttachmentPreviewOverlay': wrapCommand(showComposerAttachmentPreviewOverlay),
16369
15040
  'Chat.terminate': terminate,