@lvce-editor/chat-view 7.1.0 → 7.3.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;
@@ -2470,7 +2463,6 @@ const createDefaultState = () => {
2470
2463
  usageOverviewEnabled: false,
2471
2464
  useChatCoordinatorWorker: false,
2472
2465
  useChatMathWorker: true,
2473
- useChatMessageParsingWorker: false,
2474
2466
  useChatNetworkWorkerForRequests: false,
2475
2467
  useChatToolWorker: true,
2476
2468
  useMockApi: false,
@@ -3521,9 +3513,6 @@ const isRenameInputName = name => {
3521
3513
  const getRenameIdFromInputName = name => {
3522
3514
  return name.slice(RenamePrefix.length);
3523
3515
  };
3524
- const getModelPickerItemInputName = modelId => {
3525
- return `${ModelPickerItemPrefix}${modelId}`;
3526
- };
3527
3516
  const getGitBranchPickerItemInputName = branchName => {
3528
3517
  return `${GitBranchPickerItemPrefix}${branchName}`;
3529
3518
  };
@@ -4591,7 +4580,7 @@ const handleClickOpenRouterApiKeyWebsite = async state => {
4591
4580
  };
4592
4581
 
4593
4582
  const getAiResponse$1 = async options => {
4594
- return invoke$9('ChatCoordinator.getAiResponse', options);
4583
+ return invoke$8('ChatCoordinator.getAiResponse', options);
4595
4584
  };
4596
4585
 
4597
4586
  const execute = async (name, rawArguments, options) => {
@@ -7246,1494 +7235,48 @@ const parseMessageContents = async rawMessages => {
7246
7235
  return invoke$7('ChatMessageParsing.parseMessageContents', rawMessages);
7247
7236
  };
7248
7237
 
7249
- const Actions = 'Actions';
7250
- const Button = 'Button';
7251
- const ButtonPrimary = 'ButtonPrimary';
7252
- const ButtonSecondary = 'ButtonSecondary';
7253
- const Chat = 'Chat';
7254
- const ChatActions = 'ChatActions';
7255
- const ChatAuthError = 'ChatAuthError';
7256
- const ChatFocus = 'ChatFocus';
7257
- const ChatFocusActions = 'ChatFocusActions';
7258
- const ChatFocusHeader = 'ChatFocusHeader';
7259
- const ChatFocusMainArea = 'ChatFocusMainArea';
7260
- const ChatFocusProject = 'ChatFocusProject';
7261
- const ChatGitBranchPicker = 'ChatGitBranchPicker';
7262
- const ChatGitBranchPickerErrorMessage = 'ChatGitBranchPickerErrorMessage';
7263
- const ChatGitBranchPickerMessage = 'ChatGitBranchPickerMessage';
7264
- const ChatHeader = 'ChatHeader';
7265
- const ChatHeaderAuth = 'ChatHeaderAuth';
7266
- const ChatHeaderAuthName = 'ChatHeaderAuthName';
7267
- const ChatHeaderLabel = 'ChatHeaderLabel';
7268
- const ChatInputBox = 'ChatInputBox';
7269
- const ChatList = 'ChatList';
7270
- const ChatListEmpty = 'ChatListEmpty';
7271
- const ChatListItem = 'ChatListItem';
7272
- const ChatListItemFocused = 'ChatListItemFocused';
7273
- const ChatListItemLabel = 'ChatListItemLabel';
7274
- const ChatListItemStatusFinished = 'ChatListItemStatusFinished';
7275
- const ChatListItemStatusIcon = 'ChatListItemStatusIcon';
7276
- const ChatListItemStatusInProgress = 'ChatListItemStatusInProgress';
7277
- const ChatListItemStatusRow = 'ChatListItemStatusRow';
7278
- const ChatListItemStatusStopped = 'ChatListItemStatusStopped';
7279
- const ChatMessageContent = 'ChatMessageContent';
7280
- const ChatImageMessageContent = 'ChatImageMessageContent';
7281
- const ChatMessageLink = 'ChatMessageLink';
7282
- const ChatModelPicker = 'ChatModelPicker';
7283
- const ChatModelPickerContainer = 'ChatModelPickerContainer';
7284
- const ChatModelPickerHeader = 'ChatModelPickerHeader';
7285
- const ChatModelPickerItem = 'ChatModelPickerItem';
7286
- const ChatModelPickerItemLabel = 'ChatModelPickerItemLabel';
7287
- const ChatModelPickerItemSelected = 'ChatModelPickerItemSelected';
7288
- const ChatModelPickerItemUsageCost = 'ChatModelPickerItemUsageCost';
7289
- const ChatModelPickerList = 'ChatModelPickerList';
7290
- const ChatName = 'ChatName';
7291
- const ChatOverlays = 'ChatOverlays';
7292
- const ChatOrderedList = 'ChatOrderedList';
7293
- const ChatOrderedListItem = 'ChatOrderedListItem';
7294
- const ChatOrderedListItemContent = 'ChatOrderedListItemContent';
7295
- const ChatOrderedListItemPrefix = 'ChatOrderedListItemPrefix';
7296
- const ChatOrderedListMarker = 'ChatOrderedListMarker';
7297
- const ChatComposerAttachment = 'ChatComposerAttachment';
7298
- const ChatComposerAttachmentImage = 'ChatComposerAttachmentImage';
7299
- const ChatComposerAttachmentInvalidImage = 'ChatComposerAttachmentInvalidImage';
7300
- const ChatComposerAttachmentLabel = 'ChatComposerAttachmentLabel';
7301
- const ChatComposerAttachmentPreview = 'ChatComposerAttachmentPreview';
7302
- const ChatComposerAttachmentPreviewOverlay = 'ChatComposerAttachmentPreviewOverlay';
7303
- const ChatComposerAttachmentPreviewOverlayError = 'ChatComposerAttachmentPreviewOverlayError';
7304
- const ChatComposerAttachmentPreviewOverlayImage = 'ChatComposerAttachmentPreviewOverlayImage';
7305
- const ChatComposerAttachmentRemoveButton = 'ChatComposerAttachmentRemoveButton';
7306
- const ChatComposerAttachments = 'ChatComposerAttachments';
7307
- const ChatComposerAttachmentTextFile = 'ChatComposerAttachmentTextFile';
7308
- const ChatAttachment = 'ChatAttachment';
7309
- const ChatAttachmentImage = 'ChatAttachmentImage';
7310
- const ChatAttachmentInvalidImage = 'ChatAttachmentInvalidImage';
7311
- const ChatAttachmentLabel = 'ChatAttachmentLabel';
7312
- const ChatAttachmentPreview = 'ChatAttachmentPreview';
7313
- const ChatAttachments = 'ChatAttachments';
7314
- const ChatAttachmentTextFile = 'ChatAttachmentTextFile';
7315
- const ChatMessageImage = 'ChatMessageImage';
7316
- const ChatSendArea = 'ChatSendArea';
7317
- const ChatSendAreaBottom = 'ChatSendAreaBottom';
7318
- const ChatSendAreaContent = 'ChatSendAreaContent';
7319
- const ChatSendAreaPrimaryControls = 'ChatSendAreaPrimaryControls';
7320
- const ChatTableWrapper = 'ChatTableWrapper';
7321
- const ChatTodoList = 'ChatTodoList';
7322
- const ChatTodoListHeader = 'ChatTodoListHeader';
7323
- const ChatTodoListItem = 'ChatTodoListItem';
7324
- const ChatTodoListItemCompleted = 'ChatTodoListItemCompleted';
7325
- const ChatTodoListItemInProgress = 'ChatTodoListItemInProgress';
7326
- const ChatTodoListItems = 'ChatTodoListItems';
7327
- const ChatTodoListItemTodo = 'ChatTodoListItemTodo';
7328
- const ChatToolCallFileName = 'ChatToolCallFileName';
7329
- const ChatToolCallQuestionOption = 'ChatToolCallQuestionOption';
7330
- const ChatToolCallQuestionOptions = 'ChatToolCallQuestionOptions';
7331
- const ChatToolCallQuestionText = 'ChatToolCallQuestionText';
7332
- const ChatToolCallReadFileLink = 'ChatToolCallReadFileLink';
7333
- const ChatToolCallRenderHtmlBody = 'ChatToolCallRenderHtmlBody';
7334
- const ChatToolCallRenderHtmlContent = 'ChatToolCallRenderHtmlContent';
7335
- const ChatToolCallRenderHtmlLabel = 'ChatToolCallRenderHtmlLabel';
7336
- const ChatToolCalls = 'ChatToolCalls';
7337
- const ChatToolCallsLabel = 'ChatToolCallsLabel';
7338
- const ChatUnorderedList = 'ChatUnorderedList';
7339
- const ChatUnorderedListItem = 'ChatUnorderedListItem';
7340
- const ChatViewDropOverlay = 'ChatViewDropOverlay';
7341
- const ChatViewDropOverlayActive = 'ChatViewDropOverlayActive';
7342
- const ChatWelcomeMessage = 'ChatWelcomeMessage';
7343
- const CustomSelectContainer = 'CustomSelectContainer';
7344
- const CustomSelectPopOver = 'CustomSelectPopOver';
7345
- const Deletion = 'Deletion';
7346
- const Empty = '';
7347
- const FileIcon = 'FileIcon';
7348
- const IconButton = 'IconButton';
7349
- const IconButtonDisabled = 'IconButtonDisabled';
7350
- const ImageElement = 'ImageElement';
7351
- const ImageErrorMessage = 'ImageErrorMessage';
7352
- const InputBox = 'InputBox';
7353
- const InputInvalid = 'InputInvalid';
7354
- const Insertion = 'Insertion';
7355
- const Label = 'Label';
7356
- const LabelDetail = 'LabelDetail';
7357
- const Markdown = 'Markdown';
7358
- const MarkdownMathBlock = 'MarkdownMathBlock';
7359
- const MarkdownQuote = 'MarkdownQuote';
7360
- const MarkdownTable = 'MarkdownTable';
7361
- const MaskIcon = 'MaskIcon';
7362
- const MaskIconAdd = 'MaskIconAdd';
7363
- const MaskIconArrowLeft = 'MaskIconArrowLeft';
7364
- const MaskIconChevronDown = 'MaskIconChevronDown';
7365
- const MaskIconChevronRight = 'MaskIconChevronRight';
7366
- const MaskIconChevronUp = 'MaskIconChevronUp';
7367
- const MaskIconClose = 'MaskIconClose';
7368
- const MaskIconDebugPause = 'MaskIconDebugPause';
7369
- const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
7370
- const MaskIconSearch = 'MaskIconSearch';
7371
- const MaskIconSettingsGear = 'MaskIconSettingsGear';
7372
- const Message = 'Message';
7373
- const MessageAssistant = 'MessageAssistant';
7374
- const MessageUser = 'MessageUser';
7375
- const MissingApiKeyForm = 'MissingApiKeyForm';
7376
- const MultiLineInputBox = 'MultilineInputBox';
7377
- const ProjectAddButton = 'ProjectAddButton';
7378
- const ProjectList = 'ProjectList';
7379
- const ProjectListChevron = 'ProjectListChevron';
7380
- const ProjectListGroup = 'ProjectListGroup';
7381
- const ProjectListItem = 'ProjectListItem';
7382
- const ProjectListItemActions = 'ProjectListItemActions';
7383
- const ProjectListItemAddChatButton = 'ProjectListItemAddChatButton';
7384
- const ProjectListItemLabel = 'ProjectListItemLabel';
7385
- const ProjectListItemSelected = 'ProjectListItemSelected';
7386
- const ProjectSessionItem = 'ProjectSessionItem';
7387
- const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
7388
- const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
7389
- const ProjectSidebar = 'ProjectSidebar';
7390
- const SearchFieldContainer = 'SearchFieldContainer';
7391
- const RunModePickerContainer = 'RunModePickerContainer';
7392
- const RunModePickerPopOver = 'RunModePickerPopOver';
7393
- const Select = 'Select';
7394
- const SelectLabel = 'SelectLabel';
7395
- const SendButtonDisabled = 'SendButtonDisabled';
7396
- const SessionArchiveButton = 'SessionArchiveButton';
7397
- const StrikeThrough = 'StrikeThrough';
7398
- const TokenAttribute = 'TokenAttribute';
7399
- const TokenComment = 'TokenComment';
7400
- const TokenKeyword = 'TokenKeyword';
7401
- const TokenNumber = 'TokenNumber';
7402
- const TokenProperty = 'TokenProperty';
7403
- const TokenString = 'TokenString';
7404
- const TokenTag = 'TokenTag';
7405
- const TokenUsageOverview = 'TokenUsageOverview';
7406
- const TokenUsageRing = 'TokenUsageRing';
7407
- const TokenUsageRingInner = 'TokenUsageRingInner';
7408
- const TokenValue = 'TokenValue';
7409
- const ToolCallName = 'ToolCallName';
7410
- const Viewlet = 'Viewlet';
7411
-
7412
- const jsRules = [{
7413
- className: TokenComment,
7414
- regex: /\/\/[^\n]*/
7415
- }, {
7416
- className: TokenComment,
7417
- regex: /\/\*[\s\S]*?\*\//
7418
- }, {
7419
- className: TokenString,
7420
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
7421
- }, {
7422
- className: TokenString,
7423
- regex: /'[^'\\]*(?:\\.[^'\\]*)*'/
7424
- }, {
7425
- className: TokenString,
7426
- regex: /`[^`\\]*(?:\\.[^`\\]*)*`/
7427
- }, {
7428
- className: TokenNumber,
7429
- regex: /\b\d+\.?\d*\b/
7430
- }, {
7431
- className: TokenKeyword,
7432
- 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/
7433
- }];
7434
- const tsRules = [{
7435
- className: TokenComment,
7436
- regex: /\/\/[^\n]*/
7437
- }, {
7438
- className: TokenComment,
7439
- regex: /\/\*[\s\S]*?\*\//
7440
- }, {
7441
- className: TokenString,
7442
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
7443
- }, {
7444
- className: TokenString,
7445
- regex: /'[^'\\]*(?:\\.[^'\\]*)*'/
7446
- }, {
7447
- className: TokenString,
7448
- regex: /`[^`\\]*(?:\\.[^`\\]*)*`/
7449
- }, {
7450
- className: TokenNumber,
7451
- regex: /\b\d+\.?\d*\b/
7452
- }, {
7453
- className: TokenKeyword,
7454
- 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/
7455
- }];
7456
- const htmlRules = [{
7457
- className: TokenComment,
7458
- regex: /<!--[\s\S]*?-->/
7459
- }, {
7460
- className: TokenTag,
7461
- regex: /<\/[a-zA-Z][a-zA-Z0-9-]*\s*>/
7462
- }, {
7463
- className: TokenTag,
7464
- regex: /<[a-zA-Z][a-zA-Z0-9-]*/
7465
- }, {
7466
- className: TokenTag,
7467
- regex: /\/?>/
7468
- }, {
7469
- className: TokenString,
7470
- regex: /"[^"]*"/
7471
- }, {
7472
- className: TokenString,
7473
- regex: /'[^']*'/
7474
- }, {
7475
- className: TokenAttribute,
7476
- regex: /[a-zA-Z-]+(?=\s*=)/
7477
- }];
7478
- const cssRules = [{
7479
- className: TokenComment,
7480
- regex: /\/\*[\s\S]*?\*\//
7481
- }, {
7482
- className: TokenString,
7483
- regex: /"[^"]*"/
7484
- }, {
7485
- className: TokenString,
7486
- regex: /'[^']*'/
7487
- }, {
7488
- className: TokenValue,
7489
- regex: /#[0-9a-fA-F]{3,8}/
7490
- }, {
7491
- className: TokenValue,
7492
- regex: /\b\d+(?:\.\d+)?(?:px|em|rem|%|vh|vw|pt|s|ms|fr)?\b/
7493
- }, {
7494
- className: TokenProperty,
7495
- regex: /[a-zA-Z-]+(?=\s*:)/
7496
- }];
7497
- const pythonRules = [{
7498
- className: TokenComment,
7499
- regex: /#[^\n]*/
7500
- }, {
7501
- className: TokenString,
7502
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
7503
- }, {
7504
- className: TokenString,
7505
- regex: /'[^'\\]*(?:\\.[^'\\]*)*'/
7506
- }, {
7507
- className: TokenNumber,
7508
- regex: /\b\d+\.?\d*\b/
7509
- }, {
7510
- className: TokenKeyword,
7511
- 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/
7512
- }];
7513
- const jsonRules = [{
7514
- className: TokenProperty,
7515
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"(?=\s*:)/
7516
- }, {
7517
- className: TokenString,
7518
- regex: /"[^"\\]*(?:\\.[^"\\]*)*"/
7519
- }, {
7520
- className: TokenNumber,
7521
- regex: /-?\b\d+\.?\d*(?:[eE][+-]?\d+)?\b/
7522
- }, {
7523
- className: TokenKeyword,
7524
- regex: /\b(?:true|false|null)\b/
7238
+ const emptyMessageContent = [{
7239
+ children: [{
7240
+ text: '',
7241
+ type: 'text'
7242
+ }],
7243
+ type: 'text'
7525
7244
  }];
7526
- const tokenize = (code, rules) => {
7527
- const tokens = [];
7528
- let pos = 0;
7529
- while (pos < code.length) {
7530
- let matched = false;
7531
- for (const rule of rules) {
7532
- const match = rule.regex.exec(code.slice(pos));
7533
- if (match && match.index === 0) {
7534
- tokens.push({
7535
- className: rule.className,
7536
- text: match[0]
7537
- });
7538
- pos += match[0].length;
7539
- matched = true;
7540
- break;
7541
- }
7542
- }
7543
- if (!matched) {
7544
- const last = tokens.at(-1);
7545
- if (last && last.className === '') {
7546
- tokens.pop();
7547
- tokens.push({
7548
- className: '',
7549
- text: last.text + code[pos]
7550
- });
7551
- } else {
7552
- tokens.push({
7553
- className: '',
7554
- text: code[pos]
7555
- });
7556
- }
7557
- pos++;
7558
- }
7559
- }
7560
- return tokens;
7245
+ const getParsedMessageContent = (parsedMessages, messageId) => {
7246
+ const parsedMessage = parsedMessages.find(item => item.id === messageId);
7247
+ return parsedMessage?.parsedContent;
7561
7248
  };
7562
- const highlightCode = (code, language) => {
7563
- if (!language) {
7564
- return [{
7565
- className: '',
7566
- text: code
7249
+ const setParsedMessageContent = (parsedMessages, messageId, text, parsedContent) => {
7250
+ const index = parsedMessages.findIndex(item => item.id === messageId);
7251
+ if (index === -1) {
7252
+ return [...parsedMessages, {
7253
+ id: messageId,
7254
+ parsedContent,
7255
+ text
7567
7256
  }];
7568
7257
  }
7569
- const normalized = language.toLowerCase();
7570
- if (normalized === 'html') {
7571
- return tokenize(code, htmlRules);
7572
- }
7573
- if (normalized === 'css') {
7574
- return tokenize(code, cssRules);
7575
- }
7576
- if (normalized === 'js' || normalized === 'javascript') {
7577
- return tokenize(code, jsRules);
7578
- }
7579
- if (normalized === 'ts' || normalized === 'typescript') {
7580
- return tokenize(code, tsRules);
7581
- }
7582
- if (normalized === 'py' || normalized === 'python') {
7583
- return tokenize(code, pythonRules);
7584
- }
7585
- if (normalized === 'json') {
7586
- return tokenize(code, jsonRules);
7587
- }
7588
- return [{
7589
- className: '',
7590
- text: code
7591
- }];
7592
- };
7593
-
7594
- const isAlphaNumeric = value => {
7595
- if (!value) {
7596
- return false;
7597
- }
7598
- const code = value.codePointAt(0) ?? 0;
7599
- if (code >= 48 && code <= 57) {
7600
- return true;
7601
- }
7602
- if (code >= 65 && code <= 90) {
7603
- return true;
7604
- }
7605
- return code >= 97 && code <= 122;
7606
- };
7607
- const sanitizeLinkUrl = url => {
7608
- const trimmedUrl = url.trim();
7609
- const normalized = url.trim().toLowerCase();
7610
- if (normalized.startsWith('http://') || normalized.startsWith('https://') || normalized.startsWith('file://') || normalized.startsWith('vscode-references://')) {
7611
- return trimmedUrl;
7612
- }
7613
- if (!trimmedUrl || trimmedUrl.startsWith('#') || trimmedUrl.startsWith('?') || trimmedUrl.startsWith('/') || trimmedUrl.startsWith('\\')) {
7614
- return '#';
7615
- }
7616
- if (trimmedUrl.includes('://') || trimmedUrl.includes(':')) {
7617
- return '#';
7618
- }
7619
- if (isPathTraversalAttempt(trimmedUrl)) {
7620
- return '#';
7621
- }
7622
- const normalizedPath = normalizeRelativePath(trimmedUrl);
7623
- if (normalizedPath === '.') {
7624
- return '#';
7625
- }
7626
- return `file:///workspace/${normalizedPath}`;
7627
- };
7628
- const sanitizeImageUrl = url => {
7629
- const normalized = url.trim().toLowerCase();
7630
- if (normalized.startsWith('http://') || normalized.startsWith('https://')) {
7631
- return url;
7632
- }
7633
- return '#';
7634
- };
7635
- const isOpenBracket = value => {
7636
- return value === '(' || value === '[' || value === '{';
7637
- };
7638
- const isCloseBracket = value => {
7639
- return value === ')' || value === ']' || value === '}';
7640
- };
7641
- const findRawUrlEnd = (value, start) => {
7642
- let index = start;
7643
- while (index < value.length) {
7644
- const current = value[index];
7645
- if (current === ' ' || current === '\n' || current === '\r' || current === '\t' || current === '"' || current === "'" || current === '`' || current === '<' || current === '>') {
7646
- break;
7647
- }
7648
- index++;
7649
- }
7650
- return index;
7651
- };
7652
- const trimRawUrlEnd = url => {
7653
- let end = url.length;
7654
- while (end > 0) {
7655
- const current = url[end - 1];
7656
- if (current === '.' || current === ',' || current === ':' || current === ';' || current === '!' || current === '?') {
7657
- end--;
7658
- continue;
7659
- }
7660
- if (isCloseBracket(current)) {
7661
- const inner = url.slice(0, end - 1);
7662
- let openCount = 0;
7663
- let closeCount = 0;
7664
- for (let i = 0; i < inner.length; i++) {
7665
- if (isOpenBracket(inner[i])) {
7666
- openCount++;
7667
- } else if (isCloseBracket(inner[i])) {
7668
- closeCount++;
7669
- }
7670
- }
7671
- if (closeCount >= openCount) {
7672
- end--;
7673
- continue;
7674
- }
7675
- }
7676
- break;
7258
+ const existingItem = parsedMessages[index];
7259
+ if (existingItem.text === text && existingItem.parsedContent === parsedContent) {
7260
+ return parsedMessages;
7677
7261
  }
7678
- return url.slice(0, end);
7262
+ return [...parsedMessages.slice(0, index), {
7263
+ ...existingItem,
7264
+ parsedContent,
7265
+ text
7266
+ }, ...parsedMessages.slice(index + 1)];
7679
7267
  };
7680
- const parseRawLinkToken = (value, start) => {
7681
- if (!value.startsWith('https://', start) && !value.startsWith('http://', start)) {
7682
- return undefined;
7683
- }
7684
- if (start >= 2 && value[start - 1] === '(' && value[start - 2] === ']') {
7685
- return undefined;
7686
- }
7687
- const end = findRawUrlEnd(value, start);
7688
- const rawUrl = value.slice(start, end);
7689
- const href = trimRawUrlEnd(rawUrl);
7690
- if (!href) {
7691
- return undefined;
7268
+ const copyParsedMessageContent = (parsedMessages, sourceMessageId, targetMessageId) => {
7269
+ const parsedMessage = parsedMessages.find(item => item.id === sourceMessageId);
7270
+ if (!parsedMessage) {
7271
+ return parsedMessages;
7692
7272
  }
7693
- return {
7694
- length: href.length,
7695
- node: {
7696
- href: sanitizeLinkUrl(href),
7697
- text: href,
7698
- type: 'link'
7699
- }
7700
- };
7273
+ return setParsedMessageContent(parsedMessages, targetMessageId, parsedMessage.text, parsedMessage.parsedContent);
7701
7274
  };
7702
- const parseLinkToken = (value, start) => {
7703
- if (value[start] !== '[') {
7704
- return undefined;
7705
- }
7706
- const textEnd = value.indexOf(']', start + 1);
7707
- if (textEnd === -1) {
7708
- return undefined;
7709
- }
7710
- if (value[textEnd + 1] !== '(') {
7711
- return undefined;
7712
- }
7713
- let depth = 1;
7714
- let index = textEnd + 2;
7715
- while (index < value.length) {
7716
- const current = value[index];
7717
- if (current === '\n') {
7718
- return undefined;
7719
- }
7720
- if (current === '(') {
7721
- depth++;
7722
- } else if (current === ')') {
7723
- depth--;
7724
- if (depth === 0) {
7725
- const text = value.slice(start + 1, textEnd);
7726
- const href = value.slice(textEnd + 2, index);
7727
- if (!text || !href) {
7728
- return undefined;
7729
- }
7730
- return {
7731
- length: index - start + 1,
7732
- node: {
7733
- href: sanitizeLinkUrl(href),
7734
- text,
7735
- type: 'link'
7736
- }
7737
- };
7738
- }
7739
- }
7740
- index++;
7741
- }
7742
- return undefined;
7743
- };
7744
- const parseImageToken = (value, start) => {
7745
- if (value[start] !== '!' || value[start + 1] !== '[') {
7746
- return undefined;
7747
- }
7748
- const textEnd = value.indexOf(']', start + 2);
7749
- if (textEnd === -1) {
7750
- return undefined;
7751
- }
7752
- if (value[textEnd + 1] !== '(') {
7753
- return undefined;
7754
- }
7755
- let depth = 1;
7756
- let index = textEnd + 2;
7757
- while (index < value.length) {
7758
- const current = value[index];
7759
- if (current === '\n') {
7760
- return undefined;
7761
- }
7762
- if (current === '(') {
7763
- depth++;
7764
- } else if (current === ')') {
7765
- depth--;
7766
- if (depth === 0) {
7767
- const alt = value.slice(start + 2, textEnd);
7768
- const src = value.slice(textEnd + 2, index);
7769
- if (!src) {
7770
- return undefined;
7771
- }
7772
- return {
7773
- length: index - start + 1,
7774
- node: {
7775
- alt,
7776
- src: sanitizeImageUrl(src),
7777
- type: 'image'
7778
- }
7779
- };
7780
- }
7781
- }
7782
- index++;
7783
- }
7784
- return undefined;
7785
- };
7786
- const parseBoldToken = (value, start) => {
7787
- if (value[start] !== '*' || value[start + 1] !== '*') {
7788
- return undefined;
7789
- }
7790
- const end = value.indexOf('**', start + 2);
7791
- if (end === -1) {
7792
- return undefined;
7793
- }
7794
- const text = value.slice(start + 2, end);
7795
- if (!text || text.includes('\n')) {
7796
- return undefined;
7797
- }
7798
- return {
7799
- length: end - start + 2,
7800
- node: {
7801
- children: parseInlineNodes(text),
7802
- type: 'bold'
7803
- }
7804
- };
7805
- };
7806
- const parseBoldItalicToken = (value, start) => {
7807
- if (value[start] !== '*' || value[start + 1] !== '*' || value[start + 2] !== '*') {
7808
- return undefined;
7809
- }
7810
- const end = value.indexOf('***', start + 3);
7811
- if (end === -1) {
7812
- return undefined;
7813
- }
7814
- const text = value.slice(start + 3, end);
7815
- if (!text || text.includes('\n')) {
7816
- return undefined;
7817
- }
7818
- return {
7819
- length: end - start + 3,
7820
- node: {
7821
- children: [{
7822
- children: parseInlineNodes(text),
7823
- type: 'italic'
7824
- }],
7825
- type: 'bold'
7826
- }
7827
- };
7828
- };
7829
- const findItalicEnd = (value, start) => {
7830
- let index = start + 1;
7831
- while (index < value.length) {
7832
- if (value[index] !== '*') {
7833
- index++;
7834
- continue;
7835
- }
7836
- if (value[index + 1] !== '*') {
7837
- return index;
7838
- }
7839
- const boldEnd = value.indexOf('**', index + 2);
7840
- if (boldEnd === -1) {
7841
- return -1;
7842
- }
7843
- index = boldEnd + 2;
7844
- }
7845
- return -1;
7846
- };
7847
- const parseItalicToken = (value, start) => {
7848
- if (value[start] !== '*' || value[start + 1] === '*') {
7849
- return undefined;
7850
- }
7851
- const end = findItalicEnd(value, start);
7852
- if (end === -1) {
7853
- return undefined;
7854
- }
7855
- const text = value.slice(start + 1, end);
7856
- if (!text) {
7857
- return undefined;
7858
- }
7859
- return {
7860
- length: end - start + 1,
7861
- node: {
7862
- children: parseInlineNodes(text),
7863
- type: 'italic'
7864
- }
7865
- };
7866
- };
7867
- const parseStrikethroughToken = (value, start) => {
7868
- if (value[start] !== '~' || value[start + 1] !== '~') {
7869
- return undefined;
7870
- }
7871
- const end = value.indexOf('~~', start + 2);
7872
- if (end === -1) {
7873
- return undefined;
7874
- }
7875
- const text = value.slice(start + 2, end);
7876
- if (!text || text.includes('\n')) {
7877
- return undefined;
7878
- }
7879
- return {
7880
- length: end - start + 2,
7881
- node: {
7882
- children: parseInlineNodes(text),
7883
- type: 'strikethrough'
7884
- }
7885
- };
7886
- };
7887
- const parseInlineCodeToken = (value, start) => {
7888
- if (value[start] !== '`') {
7889
- return undefined;
7890
- }
7891
- const end = value.indexOf('`', start + 1);
7892
- if (end === -1) {
7893
- return undefined;
7894
- }
7895
- const codeText = value.slice(start + 1, end);
7896
- if (!codeText || codeText.includes('\n')) {
7897
- return undefined;
7898
- }
7899
- return {
7900
- length: end - start + 1,
7901
- node: {
7902
- text: codeText,
7903
- type: 'inline-code'
7904
- }
7905
- };
7906
- };
7907
- const parseMathToken = (value, start) => {
7908
- if (value[start] !== '$') {
7909
- return undefined;
7910
- }
7911
- const delimiterLength = value[start + 1] === '$' ? 2 : 1;
7912
- const previous = value[start - 1];
7913
- if (isAlphaNumeric(previous)) {
7914
- return undefined;
7915
- }
7916
- const next = value[start + delimiterLength];
7917
- if (!next || next === '.') {
7918
- return undefined;
7919
- }
7920
- if (next === '(' && (value[start + delimiterLength + 1] === '"' || value[start + delimiterLength + 1] === "'")) {
7921
- return undefined;
7922
- }
7923
- let index = start + delimiterLength;
7924
- while (index < value.length) {
7925
- if (value[index] === '\n') {
7926
- return undefined;
7927
- }
7928
- const isClosed = delimiterLength === 2 ? value.startsWith('$$', index) : value[index] === '$';
7929
- if (isClosed) {
7930
- const body = value.slice(start + delimiterLength, index);
7931
- const following = value[index + delimiterLength];
7932
- if (!body || isAlphaNumeric(following)) {
7933
- return undefined;
7934
- }
7935
- return {
7936
- length: index - start + delimiterLength,
7937
- node: {
7938
- displayMode: delimiterLength === 2,
7939
- text: body.trim(),
7940
- type: 'math-inline'
7941
- }
7942
- };
7943
- }
7944
- if (value[index] === '\\') {
7945
- index += 2;
7946
- continue;
7947
- }
7948
- index++;
7949
- }
7950
- return undefined;
7951
- };
7952
- const parseInlineToken = (value, start) => {
7953
- 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);
7954
- };
7955
- const parseInlineNodes = value => {
7956
- const nodes = [];
7957
- let textStart = 0;
7958
- let index = 0;
7959
- const pushText = end => {
7960
- if (end <= textStart) {
7961
- return;
7962
- }
7963
- nodes.push({
7964
- text: value.slice(textStart, end),
7965
- type: 'text'
7966
- });
7967
- };
7968
- while (index < value.length) {
7969
- const parsed = parseInlineToken(value, index);
7970
- if (!parsed) {
7971
- index++;
7972
- continue;
7973
- }
7974
- pushText(index);
7975
- nodes.push(parsed.node);
7976
- index += parsed.length;
7977
- textStart = index;
7978
- }
7979
- pushText(value.length);
7980
- if (nodes.length === 0) {
7981
- return [{
7982
- text: value,
7983
- type: 'text'
7984
- }];
7985
- }
7986
- return nodes;
7987
- };
7988
-
7989
- const markdownMathBlockDelimiter = '$$';
7990
- const escapedNewlineRegex = /\\r\\n|\\n/g;
7991
- const lineBreakRegex = /\r?\n/;
7992
- const tableDelimiterRegex = /\|\s*[-:]{3,}/;
7993
- const inlineTableCellRegex = /\|\s+\|/g;
7994
- const normalizeEscapedNewlines = value => {
7995
- if (value.includes('\\n')) {
7996
- return value.replaceAll(escapedNewlineRegex, '\n');
7997
- }
7998
- return value;
7999
- };
8000
- const normalizeInlineTables = value => {
8001
- return value.split(lineBreakRegex).map(line => {
8002
- if (!line.includes('|')) {
8003
- return line;
8004
- }
8005
- if (!tableDelimiterRegex.test(line)) {
8006
- return line;
8007
- }
8008
- return line.replaceAll(inlineTableCellRegex, '|\n|');
8009
- }).join('\n');
8010
- };
8011
- const parseHeadingLine = line => {
8012
- const trimmedStart = line.trimStart();
8013
- let index = 0;
8014
- while (index < trimmedStart.length && trimmedStart[index] === '#') {
8015
- index++;
8016
- }
8017
- if (index === 0 || index > 6) {
8018
- return undefined;
8019
- }
8020
- if (trimmedStart[index] !== ' ') {
8021
- return undefined;
8022
- }
8023
- const text = trimmedStart.slice(index).trimStart();
8024
- return {
8025
- level: index,
8026
- text
8027
- };
8028
- };
8029
- const parseOrderedListItemLine = line => {
8030
- let indentation = 0;
8031
- while (indentation < line.length && line[indentation] === ' ') {
8032
- indentation++;
8033
- }
8034
- let index = indentation;
8035
- const firstDigit = index;
8036
- while (index < line.length && line[index] >= '0' && line[index] <= '9') {
8037
- index++;
8038
- }
8039
- if (index === firstDigit || line[index] !== '.') {
8040
- return undefined;
8041
- }
8042
- index++;
8043
- if (line[index] !== ' ') {
8044
- return undefined;
8045
- }
8046
- while (index < line.length && line[index] === ' ') {
8047
- index++;
8048
- }
8049
- return {
8050
- indentation,
8051
- text: line.slice(index)
8052
- };
8053
- };
8054
- const parseUnorderedListItemLine = line => {
8055
- let indentation = 0;
8056
- while (indentation < line.length && line[indentation] === ' ') {
8057
- indentation++;
8058
- }
8059
- const marker = line[indentation];
8060
- if (marker !== '-' && marker !== '*') {
8061
- return undefined;
8062
- }
8063
- let index = indentation + 1;
8064
- if (line[index] !== ' ') {
8065
- return undefined;
8066
- }
8067
- while (index < line.length && line[index] === ' ') {
8068
- index++;
8069
- }
8070
- return {
8071
- indentation,
8072
- text: line.slice(index)
8073
- };
8074
- };
8075
- const parseBlockQuoteLine = line => {
8076
- const trimmedStart = line.trimStart();
8077
- if (!trimmedStart.startsWith('>')) {
8078
- return undefined;
8079
- }
8080
- const content = trimmedStart.slice(1);
8081
- if (!content) {
8082
- return '';
8083
- }
8084
- if (content.startsWith(' ')) {
8085
- return content.slice(1);
8086
- }
8087
- return content;
8088
- };
8089
- const isThematicBreakLine = line => {
8090
- const trimmedStart = line.trimStart();
8091
- const leadingSpaces = line.length - trimmedStart.length;
8092
- if (leadingSpaces > 3) {
8093
- return false;
8094
- }
8095
- const trimmed = trimmedStart.trimEnd();
8096
- if (!trimmed) {
8097
- return false;
8098
- }
8099
- const marker = trimmed[0];
8100
- if (marker !== '-' && marker !== '_' && marker !== '*') {
8101
- return false;
8102
- }
8103
- let markerCount = 0;
8104
- for (let i = 0; i < trimmed.length; i++) {
8105
- const char = trimmed[i];
8106
- if (char === marker) {
8107
- markerCount++;
8108
- continue;
8109
- }
8110
- if (char !== ' ') {
8111
- return false;
8112
- }
8113
- }
8114
- return markerCount >= 3;
8115
- };
8116
- const isTableRow = line => {
8117
- const trimmed = line.trim();
8118
- if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) {
8119
- return false;
8120
- }
8121
- return trimmed.length > 2;
8122
- };
8123
- const getTableCells = line => {
8124
- const trimmed = line.trim();
8125
- return trimmed.slice(1, -1).split('|').map(part => part.trim());
8126
- };
8127
- const scanBlockTokens = rawMessage => {
8128
- const normalizedMessage = normalizeInlineTables(normalizeEscapedNewlines(rawMessage));
8129
- const lines = normalizedMessage.split(lineBreakRegex);
8130
- const tokens = [];
8131
- for (let i = 0; i < lines.length; i++) {
8132
- const line = lines[i];
8133
- const trimmed = line.trim();
8134
- if (!trimmed) {
8135
- tokens.push({
8136
- type: 'blank-line'
8137
- });
8138
- continue;
8139
- }
8140
- const blockQuoteLine = parseBlockQuoteLine(line);
8141
- if (blockQuoteLine !== undefined) {
8142
- tokens.push({
8143
- text: blockQuoteLine,
8144
- type: 'blockquote-line'
8145
- });
8146
- continue;
8147
- }
8148
- if (trimmed.startsWith('```')) {
8149
- const language = trimmed.slice(3).trim();
8150
- const codeLines = [];
8151
- i++;
8152
- while (i < lines.length && !lines[i].trim().startsWith('```')) {
8153
- codeLines.push(lines[i]);
8154
- i++;
8155
- }
8156
- if (language) {
8157
- tokens.push({
8158
- language,
8159
- text: codeLines.join('\n'),
8160
- type: 'code-block'
8161
- });
8162
- } else {
8163
- tokens.push({
8164
- text: codeLines.join('\n'),
8165
- type: 'code-block'
8166
- });
8167
- }
8168
- continue;
8169
- }
8170
- if (trimmed === markdownMathBlockDelimiter) {
8171
- const endIndex = lines.findIndex((candidate, index) => {
8172
- if (index <= i) {
8173
- return false;
8174
- }
8175
- return candidate.trim() === markdownMathBlockDelimiter;
8176
- });
8177
- if (endIndex !== -1) {
8178
- tokens.push({
8179
- text: lines.slice(i + 1, endIndex).join('\n').trim(),
8180
- type: 'math-block'
8181
- });
8182
- i = endIndex;
8183
- continue;
8184
- }
8185
- }
8186
- const heading = parseHeadingLine(line);
8187
- if (heading) {
8188
- tokens.push({
8189
- level: heading.level,
8190
- text: heading.text,
8191
- type: 'heading-line'
8192
- });
8193
- continue;
8194
- }
8195
- if (isThematicBreakLine(line)) {
8196
- tokens.push({
8197
- type: 'thematic-break'
8198
- });
8199
- continue;
8200
- }
8201
- const ordered = parseOrderedListItemLine(line);
8202
- if (ordered) {
8203
- tokens.push({
8204
- indentation: ordered.indentation,
8205
- text: ordered.text,
8206
- type: 'ordered-list-item-line'
8207
- });
8208
- continue;
8209
- }
8210
- const unordered = parseUnorderedListItemLine(line);
8211
- if (unordered) {
8212
- tokens.push({
8213
- indentation: unordered.indentation,
8214
- text: unordered.text,
8215
- type: 'unordered-list-item-line'
8216
- });
8217
- continue;
8218
- }
8219
- if (isTableRow(line)) {
8220
- tokens.push({
8221
- cells: getTableCells(line),
8222
- line,
8223
- type: 'table-row-line'
8224
- });
8225
- continue;
8226
- }
8227
- tokens.push({
8228
- text: line,
8229
- type: 'paragraph-line'
8230
- });
8231
- }
8232
- return tokens;
8233
- };
8234
-
8235
- const isTableSeparatorCell = value => {
8236
- if (!value) {
8237
- return false;
8238
- }
8239
- let index = 0;
8240
- if (value[index] === ':') {
8241
- index++;
8242
- }
8243
- let dashCount = 0;
8244
- while (index < value.length && value[index] === '-') {
8245
- dashCount++;
8246
- index++;
8247
- }
8248
- if (dashCount < 3) {
8249
- return false;
8250
- }
8251
- if (index < value.length && value[index] === ':') {
8252
- index++;
8253
- }
8254
- return index === value.length;
8255
- };
8256
- const isTableSeparatorToken = (token, expectedColumns) => {
8257
- if (!token || token.type !== 'table-row-line') {
8258
- return false;
8259
- }
8260
- if (token.cells.length !== expectedColumns) {
8261
- return false;
8262
- }
8263
- return token.cells.every(isTableSeparatorCell);
8264
- };
8265
- const toTableCell = value => {
8266
- return {
8267
- children: parseInlineNodes(value),
8268
- type: 'table-cell'
8269
- };
8270
- };
8271
- const toTableRow = token => {
8272
- return {
8273
- cells: token.cells.map(toTableCell),
8274
- type: 'table-row'
8275
- };
8276
- };
8277
- const getEmptyTextNode = () => {
8278
- return [{
8279
- children: [{
8280
- text: '',
8281
- type: 'text'
8282
- }],
8283
- type: 'text'
8284
- }];
8285
- };
8286
- const parseBlockTokens = tokens => {
8287
- if (tokens.length === 0) {
8288
- return getEmptyTextNode();
8289
- }
8290
- const nodes = [];
8291
- let paragraphLines = [];
8292
- let listItems = [];
8293
- let listType = '';
8294
- let orderedListPathStack = [];
8295
- let canContinueOrderedListItemParagraph = false;
8296
- const createListItem = (text, index) => {
8297
- return {
8298
- children: parseInlineNodes(text),
8299
- ...(index === undefined ? {} : {
8300
- index
8301
- }),
8302
- type: 'list-item'
8303
- };
8304
- };
8305
- const getListItemAtPath = (items, path) => {
8306
- let currentItems = items;
8307
- let currentItem;
8308
- for (const index of path) {
8309
- currentItem = currentItems[index];
8310
- if (!currentItem) {
8311
- return undefined;
8312
- }
8313
- currentItems = currentItem.nestedItems || [];
8314
- }
8315
- return currentItem;
8316
- };
8317
- const appendNestedItemAtPath = (items, path, item, nestedListType) => {
8318
- if (path.length === 0) {
8319
- return [...items, item];
8320
- }
8321
- const [index, ...rest] = path;
8322
- const current = items[index];
8323
- if (!current) {
8324
- return [...items];
8325
- }
8326
- const nextNestedItems = rest.length > 0 ? appendNestedItemAtPath(current.nestedItems || [], rest, item, nestedListType) : [...(current.nestedItems || []), item];
8327
- const nextItem = {
8328
- ...current,
8329
- nestedItems: nextNestedItems,
8330
- nestedListType
8331
- };
8332
- return [...items.slice(0, index), nextItem, ...items.slice(index + 1)];
8333
- };
8334
- const appendInlineChildrenAtPath = (items, path, children) => {
8335
- if (path.length === 0) {
8336
- return [...items];
8337
- }
8338
- const [index, ...rest] = path;
8339
- const current = items[index];
8340
- if (!current) {
8341
- return [...items];
8342
- }
8343
- const lineBreakNode = {
8344
- text: '\n',
8345
- type: 'text'
8346
- };
8347
- const nextChildren = [...current.children, lineBreakNode, ...children];
8348
- const nextItem = rest.length > 0 ? {
8349
- ...current,
8350
- nestedItems: appendInlineChildrenAtPath(current.nestedItems || [], rest, children)
8351
- } : {
8352
- ...current,
8353
- children: nextChildren
8354
- };
8355
- return [...items.slice(0, index), nextItem, ...items.slice(index + 1)];
8356
- };
8357
- const flushParagraph = () => {
8358
- if (paragraphLines.length === 0) {
8359
- return;
8360
- }
8361
- nodes.push({
8362
- children: parseInlineNodes(paragraphLines.join('\n')),
8363
- type: 'text'
8364
- });
8365
- paragraphLines = [];
8366
- };
8367
- const flushList = () => {
8368
- if (listItems.length === 0) {
8369
- return;
8370
- }
8371
- nodes.push({
8372
- items: listItems,
8373
- type: listType || 'ordered-list'
8374
- });
8375
- listItems = [];
8376
- listType = '';
8377
- orderedListPathStack = [];
8378
- canContinueOrderedListItemParagraph = false;
8379
- };
8380
- for (let i = 0; i < tokens.length; i++) {
8381
- const token = tokens[i];
8382
- if (token.type === 'blank-line') {
8383
- flushParagraph();
8384
- canContinueOrderedListItemParagraph = false;
8385
- continue;
8386
- }
8387
- if (token.type === 'code-block') {
8388
- flushList();
8389
- flushParagraph();
8390
- if (token.language) {
8391
- nodes.push({
8392
- codeTokens: highlightCode(token.text, token.language),
8393
- language: token.language,
8394
- text: token.text,
8395
- type: 'code-block'
8396
- });
8397
- } else {
8398
- nodes.push({
8399
- codeTokens: highlightCode(token.text, undefined),
8400
- text: token.text,
8401
- type: 'code-block'
8402
- });
8403
- }
8404
- continue;
8405
- }
8406
- if (token.type === 'math-block') {
8407
- flushList();
8408
- flushParagraph();
8409
- nodes.push({
8410
- text: token.text,
8411
- type: 'math-block'
8412
- });
8413
- continue;
8414
- }
8415
- if (token.type === 'thematic-break') {
8416
- flushList();
8417
- flushParagraph();
8418
- nodes.push({
8419
- type: 'thematic-break'
8420
- });
8421
- continue;
8422
- }
8423
- if (token.type === 'blockquote-line') {
8424
- flushList();
8425
- flushParagraph();
8426
- const lines = [];
8427
- while (i < tokens.length && tokens[i].type === 'blockquote-line') {
8428
- const quoteToken = tokens[i];
8429
- if (quoteToken.type === 'blockquote-line') {
8430
- lines.push(quoteToken.text);
8431
- }
8432
- i++;
8433
- }
8434
- i--;
8435
- nodes.push({
8436
- children: parseBlockTokens(scanBlockTokens(lines.join('\n'))),
8437
- type: 'blockquote'
8438
- });
8439
- continue;
8440
- }
8441
- if (token.type === 'table-row-line') {
8442
- const expectedColumns = token.cells.length;
8443
- if (isTableSeparatorToken(tokens[i + 1], expectedColumns)) {
8444
- flushList();
8445
- flushParagraph();
8446
- const rows = [];
8447
- i += 2;
8448
- while (i < tokens.length && tokens[i].type === 'table-row-line') {
8449
- const rowToken = tokens[i];
8450
- if (rowToken.type !== 'table-row-line') {
8451
- break;
8452
- }
8453
- if (rowToken.cells.length === expectedColumns) {
8454
- rows.push(toTableRow(rowToken));
8455
- }
8456
- i++;
8457
- }
8458
- i--;
8459
- nodes.push({
8460
- headers: token.cells.map(toTableCell),
8461
- rows,
8462
- type: 'table'
8463
- });
8464
- continue;
8465
- }
8466
- flushList();
8467
- paragraphLines.push(token.line);
8468
- continue;
8469
- }
8470
- if (token.type === 'ordered-list-item-line') {
8471
- if (listType === 'ordered-list' && listItems.length > 0 && token.indentation > 0 && orderedListPathStack.length > 0) {
8472
- const parentEntry = orderedListPathStack.toReversed().find(entry => entry.indentation < token.indentation);
8473
- if (parentEntry) {
8474
- const parentItem = getListItemAtPath(listItems, parentEntry.path);
8475
- if (parentItem) {
8476
- const nextIndex = parentItem.nestedItems?.length || 0;
8477
- const nextItem = createListItem(token.text, nextIndex + 1);
8478
- listItems = appendNestedItemAtPath(listItems, parentEntry.path, nextItem, 'ordered-list');
8479
- const nextPath = [...parentEntry.path, nextIndex];
8480
- orderedListPathStack = [...orderedListPathStack.filter(entry => entry.indentation < token.indentation), {
8481
- indentation: token.indentation,
8482
- path: nextPath
8483
- }];
8484
- canContinueOrderedListItemParagraph = true;
8485
- continue;
8486
- }
8487
- }
8488
- }
8489
- if (listType && listType !== 'ordered-list') {
8490
- flushList();
8491
- }
8492
- flushParagraph();
8493
- listType = 'ordered-list';
8494
- const nextIndex = listItems.length;
8495
- const nextItem = createListItem(token.text, nextIndex + 1);
8496
- listItems.push(nextItem);
8497
- orderedListPathStack = [...orderedListPathStack.filter(entry => entry.indentation < token.indentation), {
8498
- indentation: token.indentation,
8499
- path: [nextIndex]
8500
- }];
8501
- canContinueOrderedListItemParagraph = true;
8502
- continue;
8503
- }
8504
- if (token.type === 'unordered-list-item-line') {
8505
- if (listType === 'ordered-list' && listItems.length > 0 && token.indentation > 0 && orderedListPathStack.length > 0) {
8506
- const parentEntry = orderedListPathStack.toReversed().find(entry => entry.indentation < token.indentation);
8507
- if (parentEntry) {
8508
- const nextItem = createListItem(token.text);
8509
- listItems = appendNestedItemAtPath(listItems, parentEntry.path, nextItem, 'unordered-list');
8510
- canContinueOrderedListItemParagraph = false;
8511
- continue;
8512
- }
8513
- }
8514
- if (listType && listType !== 'unordered-list') {
8515
- flushList();
8516
- }
8517
- flushParagraph();
8518
- listType = 'unordered-list';
8519
- listItems.push(createListItem(token.text));
8520
- canContinueOrderedListItemParagraph = false;
8521
- continue;
8522
- }
8523
- if (token.type === 'heading-line') {
8524
- flushList();
8525
- flushParagraph();
8526
- nodes.push({
8527
- children: parseInlineNodes(token.text),
8528
- level: token.level,
8529
- type: 'heading'
8530
- });
8531
- continue;
8532
- }
8533
- if (token.type === 'paragraph-line' && listType === 'ordered-list' && listItems.length > 0 && canContinueOrderedListItemParagraph) {
8534
- const currentPath = orderedListPathStack.at(-1)?.path;
8535
- if (currentPath) {
8536
- listItems = appendInlineChildrenAtPath(listItems, currentPath, parseInlineNodes(token.text));
8537
- continue;
8538
- }
8539
- }
8540
- flushList();
8541
- paragraphLines.push(token.text);
8542
- canContinueOrderedListItemParagraph = false;
8543
- }
8544
- flushList();
8545
- flushParagraph();
8546
- return nodes.length === 0 ? getEmptyTextNode() : nodes;
8547
- };
8548
-
8549
- const parseMessageContent = async rawMessage => {
8550
- return parseBlockTokens(scanBlockTokens(rawMessage));
8551
- };
8552
-
8553
- const emptyMessageContent = [{
8554
- children: [{
8555
- text: '',
8556
- type: 'text'
8557
- }],
8558
- type: 'text'
8559
- }];
8560
- const parseMathInline = async children => {
8561
- const nextChildren = [];
8562
- for (const child of children) {
8563
- if (child.type === 'math-inline') {
8564
- const dom = await getMathInlineDom(child);
8565
- nextChildren.push({
8566
- dom,
8567
- type: 'math-inline-dom'
8568
- });
8569
- continue;
8570
- }
8571
- if (child.type === 'bold') {
8572
- nextChildren.push({
8573
- ...child,
8574
- children: await parseMathInline(child.children)
8575
- });
8576
- continue;
8577
- }
8578
- if (child.type === 'italic') {
8579
- nextChildren.push({
8580
- ...child,
8581
- children: await parseMathInline(child.children)
8582
- });
8583
- continue;
8584
- }
8585
- if (child.type === 'strikethrough') {
8586
- nextChildren.push({
8587
- ...child,
8588
- children: await parseMathInline(child.children)
8589
- });
8590
- continue;
8591
- }
8592
- nextChildren.push(child);
8593
- }
8594
- return nextChildren;
8595
- };
8596
- const parseMathListItem = async item => {
8597
- const children = await parseMathInline(item.children);
8598
- if (!item.nestedItems) {
8599
- return {
8600
- ...item,
8601
- children
8602
- };
8603
- }
8604
- const nestedItems = [];
8605
- for (const nestedItem of item.nestedItems) {
8606
- nestedItems.push(await parseMathListItem(nestedItem));
8607
- }
8608
- return {
8609
- ...item,
8610
- children,
8611
- nestedItems
8612
- };
8613
- };
8614
- const parseMathTableCell = async cell => {
8615
- return {
8616
- ...cell,
8617
- children: await parseMathInline(cell.children)
8618
- };
8619
- };
8620
- const parseMathNode = async node => {
8621
- if (node.type === 'math-block') {
8622
- const dom = await getMathBlockDom(node);
8623
- return {
8624
- dom,
8625
- type: 'math-block-dom'
8626
- };
8627
- }
8628
- if (node.type === 'text' || node.type === 'heading') {
8629
- return {
8630
- ...node,
8631
- children: await parseMathInline(node.children)
8632
- };
8633
- }
8634
- if (node.type === 'blockquote') {
8635
- const children = [];
8636
- for (const child of node.children) {
8637
- children.push(await parseMathNode(child));
8638
- }
8639
- return {
8640
- ...node,
8641
- children
8642
- };
8643
- }
8644
- if (node.type === 'ordered-list' || node.type === 'unordered-list') {
8645
- const items = [];
8646
- for (const item of node.items) {
8647
- items.push(await parseMathListItem(item));
8648
- }
8649
- return {
8650
- ...node,
8651
- items
8652
- };
8653
- }
8654
- if (node.type === 'table') {
8655
- const headers = [];
8656
- for (const header of node.headers) {
8657
- headers.push(await parseMathTableCell(header));
8658
- }
8659
- const rows = [];
8660
- for (const row of node.rows) {
8661
- const cells = [];
8662
- for (const cell of row.cells) {
8663
- cells.push(await parseMathTableCell(cell));
8664
- }
8665
- rows.push({
8666
- ...row,
8667
- cells
8668
- });
8669
- }
8670
- return {
8671
- ...node,
8672
- headers,
8673
- rows
8674
- };
8675
- }
8676
- return node;
8677
- };
8678
- const parseMessage = async rawMessage => {
8679
- const parsedContent = await parseMessageContent(rawMessage);
8680
- const nextParsedContent = [];
8681
- for (const node of parsedContent) {
8682
- nextParsedContent.push(await parseMathNode(node));
8683
- }
8684
- return nextParsedContent;
8685
- };
8686
- const getParsedMessageContent = (parsedMessages, messageId) => {
8687
- const parsedMessage = parsedMessages.find(item => item.id === messageId);
8688
- return parsedMessage?.parsedContent;
8689
- };
8690
- const setParsedMessageContent = (parsedMessages, messageId, text, parsedContent) => {
8691
- const index = parsedMessages.findIndex(item => item.id === messageId);
8692
- if (index === -1) {
8693
- return [...parsedMessages, {
8694
- id: messageId,
8695
- parsedContent,
8696
- text
8697
- }];
8698
- }
8699
- const existingItem = parsedMessages[index];
8700
- if (existingItem.text === text && existingItem.parsedContent === parsedContent) {
8701
- return parsedMessages;
8702
- }
8703
- return [...parsedMessages.slice(0, index), {
8704
- ...existingItem,
8705
- parsedContent,
8706
- text
8707
- }, ...parsedMessages.slice(index + 1)];
8708
- };
8709
- const copyParsedMessageContent = (parsedMessages, sourceMessageId, targetMessageId) => {
8710
- const parsedMessage = parsedMessages.find(item => item.id === sourceMessageId);
8711
- if (!parsedMessage) {
8712
- return parsedMessages;
8713
- }
8714
- return setParsedMessageContent(parsedMessages, targetMessageId, parsedMessage.text, parsedMessage.parsedContent);
8715
- };
8716
- const parseAndStoreMessageContent = async (parsedMessages, message) => {
8717
- const existingParsedMessage = parsedMessages.find(item => item.id === message.id);
8718
- if (existingParsedMessage && existingParsedMessage.text === message.text) {
8719
- return parsedMessages;
8720
- }
8721
- await Promise.resolve();
8722
- const parsedContent = message.text === '' ? emptyMessageContent : await parseMessage(message.text);
8723
- return setParsedMessageContent(parsedMessages, message.id, message.text, parsedContent);
8724
- };
8725
- const parseAndStoreMessageContentWithWorkerPreference = async (parsedMessages, message, useChatMessageParsingWorker) => {
8726
- if (useChatMessageParsingWorker) {
8727
- return parseAndStoreMessagesContentInWorker(parsedMessages, [message]);
8728
- }
8729
- return parseAndStoreMessageContent(parsedMessages, message);
8730
- };
8731
- const parseAndStoreMessagesContent = async (parsedMessages, messages) => {
8732
- let nextParsedMessages = parsedMessages;
8733
- for (const message of messages) {
8734
- nextParsedMessages = await parseAndStoreMessageContent(nextParsedMessages, message);
8735
- }
8736
- return nextParsedMessages;
7275
+ const parseAndStoreMessageContent = async (parsedMessages, message) => {
7276
+ return parseAndStoreMessagesContentInWorker(parsedMessages, [message]);
7277
+ };
7278
+ const parseAndStoreMessagesContent = async (parsedMessages, messages) => {
7279
+ return parseAndStoreMessagesContentInWorker(parsedMessages, messages);
8737
7280
  };
8738
7281
  const getMessagesNeedingParsing = (parsedMessages, messages) => {
8739
7282
  return messages.filter(message => {
@@ -8754,12 +7297,6 @@ const parseAndStoreMessagesContentInWorker = async (parsedMessages, messages) =>
8754
7297
  }
8755
7298
  return nextParsedMessages;
8756
7299
  };
8757
- const parseAndStoreMessagesContentWithWorkerPreference = async (parsedMessages, messages, useChatMessageParsingWorker) => {
8758
- if (useChatMessageParsingWorker) {
8759
- return parseAndStoreMessagesContentInWorker(parsedMessages, messages);
8760
- }
8761
- return parseAndStoreMessagesContent(parsedMessages, messages);
8762
- };
8763
7300
  const getEmptyMessageContent = () => {
8764
7301
  return emptyMessageContent;
8765
7302
  };
@@ -9271,7 +7808,7 @@ const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls,
9271
7808
  };
9272
7809
  };
9273
7810
 
9274
- const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress, useChatMessageParsingWorker) => {
7811
+ const updateMessageTextInSelectedSession = async (sessions, parsedMessages, selectedSessionId, messageId, text, inProgress) => {
9275
7812
  let updatedMessage;
9276
7813
  const updatedSessions = sessions.map(session => {
9277
7814
  if (session.id !== selectedSessionId) {
@@ -9294,7 +7831,7 @@ const updateMessageTextInSelectedSession = async (sessions, parsedMessages, sele
9294
7831
  });
9295
7832
  let nextParsedMessages = parsedMessages;
9296
7833
  if (updatedMessage) {
9297
- nextParsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, updatedMessage, useChatMessageParsingWorker);
7834
+ nextParsedMessages = await parseAndStoreMessageContent(parsedMessages, updatedMessage);
9298
7835
  }
9299
7836
  return {
9300
7837
  parsedMessages: nextParsedMessages,
@@ -9317,7 +7854,7 @@ const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTex
9317
7854
  };
9318
7855
  }
9319
7856
  const updatedText = assistantMessage.text + chunk;
9320
- 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);
9321
7858
  const nextState = {
9322
7859
  ...handleTextChunkState.latestState,
9323
7860
  ...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
@@ -9516,7 +8053,6 @@ const handleSubmit = async state => {
9516
8053
  streamingEnabled,
9517
8054
  toolEnablement,
9518
8055
  useChatCoordinatorWorker,
9519
- useChatMessageParsingWorker,
9520
8056
  useChatNetworkWorkerForRequests,
9521
8057
  useChatToolWorker,
9522
8058
  useMockApi,
@@ -9562,8 +8098,8 @@ const handleSubmit = async state => {
9562
8098
  let {
9563
8099
  parsedMessages
9564
8100
  } = effectiveState;
9565
- parsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, userMessage, useChatMessageParsingWorker);
9566
- parsedMessages = await parseAndStoreMessageContentWithWorkerPreference(parsedMessages, inProgressAssistantMessage, useChatMessageParsingWorker);
8101
+ parsedMessages = await parseAndStoreMessageContent(parsedMessages, userMessage);
8102
+ parsedMessages = await parseAndStoreMessageContent(parsedMessages, inProgressAssistantMessage);
9567
8103
  let workingSessions = sessions;
9568
8104
  if (viewMode === 'detail') {
9569
8105
  const loadedSession = await getChatSession(selectedSessionId);
@@ -9738,11 +8274,11 @@ const handleSubmit = async state => {
9738
8274
  let finalParsedMessages = latestState.parsedMessages;
9739
8275
  let updatedSessions;
9740
8276
  if (streamingEnabled) {
9741
- 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);
9742
8278
  updatedSessions = updated.sessions;
9743
8279
  finalParsedMessages = updated.parsedMessages;
9744
8280
  } else {
9745
- finalParsedMessages = await parseAndStoreMessageContentWithWorkerPreference(finalParsedMessages, assistantMessage, latestState.useChatMessageParsingWorker);
8281
+ finalParsedMessages = await parseAndStoreMessageContent(finalParsedMessages, assistantMessage);
9746
8282
  updatedSessions = appendMessageToSelectedSession(latestState.sessions, latestState.selectedSessionId, assistantMessage);
9747
8283
  }
9748
8284
  if (aiSessionTitleGenerationEnabled && createsNewSession) {
@@ -11388,15 +9924,6 @@ const loadUseChatMathWorker = async () => {
11388
9924
  }
11389
9925
  };
11390
9926
 
11391
- const loadUseChatMessageParsingWorker = async () => {
11392
- try {
11393
- const savedUseChatMessageParsingWorker = await get('chatView.useChatMessageParsingWorker');
11394
- return typeof savedUseChatMessageParsingWorker === 'boolean' ? savedUseChatMessageParsingWorker : false;
11395
- } catch {
11396
- return false;
11397
- }
11398
- };
11399
-
11400
9927
  const loadUseChatNetworkWorkerForRequests = async () => {
11401
9928
  try {
11402
9929
  const savedUseChatNetworkWorkerForRequests = await get('chatView.useChatNetworkWorkerForRequests');
@@ -11425,7 +9952,7 @@ const loadVoiceDictationEnabled = async () => {
11425
9952
  };
11426
9953
 
11427
9954
  const loadPreferences = async () => {
11428
- 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()]);
11429
9956
  return {
11430
9957
  aiSessionTitleGenerationEnabled,
11431
9958
  authEnabled,
@@ -11444,7 +9971,6 @@ const loadPreferences = async () => {
11444
9971
  toolEnablement,
11445
9972
  useChatCoordinatorWorker,
11446
9973
  useChatMathWorker,
11447
- useChatMessageParsingWorker,
11448
9974
  useChatNetworkWorkerForRequests,
11449
9975
  useChatToolWorker,
11450
9976
  voiceDictationEnabled
@@ -11516,12 +10042,10 @@ const loadContent = async (state, savedState) => {
11516
10042
  toolEnablement,
11517
10043
  useChatCoordinatorWorker,
11518
10044
  useChatMathWorker,
11519
- // useChatMessageParsingWorker,
11520
10045
  useChatNetworkWorkerForRequests,
11521
10046
  useChatToolWorker,
11522
10047
  voiceDictationEnabled
11523
10048
  } = await loadPreferences();
11524
- const useChatMessageParsingWorker = true;
11525
10049
  const authState = authEnabled && backendUrl ? await syncBackendAuth(backendUrl) : getLoggedOutBackendAuthState();
11526
10050
  const legacySavedSessions = getSavedSessions(savedState);
11527
10051
  const storedSessions = await listChatSessions();
@@ -11567,7 +10091,7 @@ const loadContent = async (state, savedState) => {
11567
10091
  parsedMessages
11568
10092
  } = state;
11569
10093
  for (const session of sessions) {
11570
- parsedMessages = await parseAndStoreMessagesContentWithWorkerPreference(parsedMessages, session.messages, useChatMessageParsingWorker);
10094
+ parsedMessages = await parseAndStoreMessagesContent(parsedMessages, session.messages);
11571
10095
  }
11572
10096
  const preferredViewMode = savedViewMode || state.viewMode;
11573
10097
  const savedLastNormalViewMode = getSavedLastNormalViewMode(savedState);
@@ -11625,7 +10149,6 @@ const loadContent = async (state, savedState) => {
11625
10149
  toolEnablement,
11626
10150
  useChatCoordinatorWorker,
11627
10151
  useChatMathWorker,
11628
- useChatMessageParsingWorker,
11629
10152
  useChatNetworkWorkerForRequests,
11630
10153
  useChatToolWorker,
11631
10154
  userName: authState.userName,
@@ -11750,7 +10273,7 @@ const openMockSession = async (state, mockSessionId, mockChatMessages, options)
11750
10273
  if (!mockSessionId) {
11751
10274
  return state;
11752
10275
  }
11753
- const parsedMessages = await parseAndStoreMessagesContentWithWorkerPreference(state.parsedMessages, mockChatMessages, state.useChatMessageParsingWorker);
10276
+ const parsedMessages = await parseAndStoreMessagesContent(state.parsedMessages, mockChatMessages);
11754
10277
  const existingSession = currentSessions.find(session => session.id === mockSessionId);
11755
10278
  const sessions = existingSession ? currentSessions.map(session => {
11756
10279
  if (session.id !== mockSessionId) {
@@ -12003,12 +10526,16 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
12003
10526
  color: var(--vscode-errorForeground, var(--vscode-foreground));
12004
10527
  }
12005
10528
 
12006
- .CustomSelectContainer{
10529
+ .ChatSelect{
12007
10530
  position: relative;
12008
10531
  min-width: 0;
12009
10532
 
12010
10533
  }
12011
10534
 
10535
+ .ChatModelPickerItem{
10536
+ display: flex;
10537
+ }
10538
+
12012
10539
  .ChatGitBranchPickerMessage{
12013
10540
  padding: 6px 8px;
12014
10541
  }
@@ -12136,6 +10663,85 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
12136
10663
  flex: 1;
12137
10664
  min-height: 0;
12138
10665
  }
10666
+
10667
+ .ChatModelPickerList {
10668
+ display: flex;
10669
+ contain: content;
10670
+ }
10671
+
10672
+
10673
+ .ChatSelect:hover{
10674
+ background: var(--vscode-toolbar-hoverBackground, color-mix(in srgb, var(--vscode-editor-background) 80%, white));
10675
+ color: var(--vscode-foreground);
10676
+ }
10677
+
10678
+ .SelectLabel {
10679
+ width: auto;
10680
+ max-width: 100%;
10681
+ min-width: 0;
10682
+ overflow: hidden;
10683
+ white-space: nowrap;
10684
+ text-overflow: ellipsis;
10685
+ }
10686
+
10687
+
10688
+ .ChatSelect {
10689
+ display: flex;
10690
+ gap: 4px;
10691
+ border: none;
10692
+ border-radius: 4px;
10693
+ background: transparent;
10694
+ color: var(--vscode-descriptionForeground, var(--vscode-disabledForeground));
10695
+ padding: 0 !important;
10696
+ }
10697
+
10698
+
10699
+
10700
+
10701
+
10702
+
10703
+
10704
+
10705
+
10706
+ .SelectLabel {
10707
+ width: auto;
10708
+ overflow: hidden;
10709
+ white-space: nowrap;
10710
+ text-overflow: ellipsis;
10711
+
10712
+ }
10713
+
10714
+
10715
+ .ChatSelect .MaskIcon {
10716
+
10717
+ width: 10px;
10718
+ height: 10px;
10719
+ pointer-events: none;
10720
+ }
10721
+
10722
+
10723
+ .ChatModelPickerList {
10724
+ flex-direction: column;
10725
+ flex: 1;
10726
+ display: flex;
10727
+ contain: strict;
10728
+
10729
+ }
10730
+
10731
+
10732
+ .ChatModelPickerItem {
10733
+ contain: strict;
10734
+ flex-shrink:0; /* TODO why?? */
10735
+ }
10736
+
10737
+
10738
+ .ChatModelPickerHeader {
10739
+ height: 40px;
10740
+ contain: strict;
10741
+
10742
+ }
10743
+
10744
+
12139
10745
  `;
12140
10746
  return `${baseCss}
12141
10747
 
@@ -12228,6 +10834,160 @@ const renderFocusContext = (oldState, newState) => {
12228
10834
  return [SetFocusContext, newState.uid, FocusChatInput];
12229
10835
  };
12230
10836
 
10837
+ const Actions = 'Actions';
10838
+ const Button = 'Button';
10839
+ const ButtonPrimary = 'ButtonPrimary';
10840
+ const ButtonSecondary = 'ButtonSecondary';
10841
+ const Chat = 'Chat';
10842
+ const ChatActions = 'ChatActions';
10843
+ const ChatAuthError = 'ChatAuthError';
10844
+ const ChatFocus = 'ChatFocus';
10845
+ const ChatFocusActions = 'ChatFocusActions';
10846
+ const ChatFocusHeader = 'ChatFocusHeader';
10847
+ const ChatFocusMainArea = 'ChatFocusMainArea';
10848
+ const ChatFocusProject = 'ChatFocusProject';
10849
+ const ChatGitBranchPicker = 'ChatGitBranchPicker';
10850
+ const ChatGitBranchPickerErrorMessage = 'ChatGitBranchPickerErrorMessage';
10851
+ const ChatGitBranchPickerMessage = 'ChatGitBranchPickerMessage';
10852
+ const ChatHeader = 'ChatHeader';
10853
+ const ChatHeaderAuth = 'ChatHeaderAuth';
10854
+ const ChatHeaderAuthName = 'ChatHeaderAuthName';
10855
+ const ChatHeaderLabel = 'ChatHeaderLabel';
10856
+ const ChatInputBox = 'ChatInputBox';
10857
+ const ChatList = 'ChatList';
10858
+ const ChatListEmpty = 'ChatListEmpty';
10859
+ const ChatListItem = 'ChatListItem';
10860
+ const ChatListItemFocused = 'ChatListItemFocused';
10861
+ const ChatListItemLabel = 'ChatListItemLabel';
10862
+ const ChatListItemStatusFinished = 'ChatListItemStatusFinished';
10863
+ const ChatListItemStatusIcon = 'ChatListItemStatusIcon';
10864
+ const ChatListItemStatusInProgress = 'ChatListItemStatusInProgress';
10865
+ const ChatListItemStatusRow = 'ChatListItemStatusRow';
10866
+ const ChatListItemStatusStopped = 'ChatListItemStatusStopped';
10867
+ const ChatMessageContent = 'ChatMessageContent';
10868
+ const ChatImageMessageContent = 'ChatImageMessageContent';
10869
+ const ChatMessageLink = 'ChatMessageLink';
10870
+ const ChatModelPicker = 'ChatModelPicker';
10871
+ const ChatModelPickerContainer = 'ChatModelPickerContainer';
10872
+ const ChatModelPickerHeader = 'ChatModelPickerHeader';
10873
+ const ChatModelPickerItem = 'ChatModelPickerItem';
10874
+ const ChatModelPickerItemLabel = 'ChatModelPickerItemLabel';
10875
+ const ChatModelPickerItemSelected = 'ChatModelPickerItemSelected';
10876
+ const ChatModelPickerItemUsageCost = 'ChatModelPickerItemUsageCost';
10877
+ const ChatModelPickerList = 'ChatModelPickerList';
10878
+ const ChatName = 'ChatName';
10879
+ const ChatOverlays = 'ChatOverlays';
10880
+ const ChatOrderedList = 'ChatOrderedList';
10881
+ const ChatOrderedListItem = 'ChatOrderedListItem';
10882
+ const ChatOrderedListItemContent = 'ChatOrderedListItemContent';
10883
+ const ChatOrderedListItemPrefix = 'ChatOrderedListItemPrefix';
10884
+ const ChatOrderedListMarker = 'ChatOrderedListMarker';
10885
+ const ChatComposerAttachment = 'ChatComposerAttachment';
10886
+ const ChatComposerAttachmentImage = 'ChatComposerAttachmentImage';
10887
+ const ChatComposerAttachmentInvalidImage = 'ChatComposerAttachmentInvalidImage';
10888
+ const ChatComposerAttachmentLabel = 'ChatComposerAttachmentLabel';
10889
+ const ChatComposerAttachmentPreview = 'ChatComposerAttachmentPreview';
10890
+ const ChatComposerAttachmentPreviewOverlay = 'ChatComposerAttachmentPreviewOverlay';
10891
+ const ChatComposerAttachmentPreviewOverlayError = 'ChatComposerAttachmentPreviewOverlayError';
10892
+ const ChatComposerAttachmentPreviewOverlayImage = 'ChatComposerAttachmentPreviewOverlayImage';
10893
+ const ChatComposerAttachmentRemoveButton = 'ChatComposerAttachmentRemoveButton';
10894
+ const ChatComposerAttachments = 'ChatComposerAttachments';
10895
+ const ChatComposerAttachmentTextFile = 'ChatComposerAttachmentTextFile';
10896
+ const ChatAttachment = 'ChatAttachment';
10897
+ const ChatAttachmentImage = 'ChatAttachmentImage';
10898
+ const ChatAttachmentInvalidImage = 'ChatAttachmentInvalidImage';
10899
+ const ChatAttachmentLabel = 'ChatAttachmentLabel';
10900
+ const ChatAttachmentPreview = 'ChatAttachmentPreview';
10901
+ const ChatAttachments = 'ChatAttachments';
10902
+ const ChatAttachmentTextFile = 'ChatAttachmentTextFile';
10903
+ const ChatMessageImage = 'ChatMessageImage';
10904
+ const ChatSendArea = 'ChatSendArea';
10905
+ const ChatSendAreaBottom = 'ChatSendAreaBottom';
10906
+ const ChatSendAreaContent = 'ChatSendAreaContent';
10907
+ const ChatSendAreaPrimaryControls = 'ChatSendAreaPrimaryControls';
10908
+ const ChatSelect = 'ChatSelect';
10909
+ const ChatTableWrapper = 'ChatTableWrapper';
10910
+ const ChatTodoList = 'ChatTodoList';
10911
+ const ChatTodoListHeader = 'ChatTodoListHeader';
10912
+ const ChatTodoListItem = 'ChatTodoListItem';
10913
+ const ChatTodoListItemCompleted = 'ChatTodoListItemCompleted';
10914
+ const ChatTodoListItemInProgress = 'ChatTodoListItemInProgress';
10915
+ const ChatTodoListItems = 'ChatTodoListItems';
10916
+ const ChatTodoListItemTodo = 'ChatTodoListItemTodo';
10917
+ const ChatToolCallFileName = 'ChatToolCallFileName';
10918
+ const ChatToolCallQuestionOption = 'ChatToolCallQuestionOption';
10919
+ const ChatToolCallQuestionOptions = 'ChatToolCallQuestionOptions';
10920
+ const ChatToolCallQuestionText = 'ChatToolCallQuestionText';
10921
+ const ChatToolCallReadFileLink = 'ChatToolCallReadFileLink';
10922
+ const ChatToolCallRenderHtmlBody = 'ChatToolCallRenderHtmlBody';
10923
+ const ChatToolCallRenderHtmlContent = 'ChatToolCallRenderHtmlContent';
10924
+ const ChatToolCallRenderHtmlLabel = 'ChatToolCallRenderHtmlLabel';
10925
+ const ChatToolCalls = 'ChatToolCalls';
10926
+ const ChatToolCallsLabel = 'ChatToolCallsLabel';
10927
+ const ChatUnorderedList = 'ChatUnorderedList';
10928
+ const ChatUnorderedListItem = 'ChatUnorderedListItem';
10929
+ const ChatViewDropOverlay = 'ChatViewDropOverlay';
10930
+ const ChatViewDropOverlayActive = 'ChatViewDropOverlayActive';
10931
+ const ChatWelcomeMessage = 'ChatWelcomeMessage';
10932
+ const CustomSelectPopOver = 'CustomSelectPopOver';
10933
+ const Deletion = 'Deletion';
10934
+ const Empty = '';
10935
+ const FileIcon = 'FileIcon';
10936
+ const IconButton = 'IconButton';
10937
+ const IconButtonDisabled = 'IconButtonDisabled';
10938
+ const ImageElement = 'ImageElement';
10939
+ const ImageErrorMessage = 'ImageErrorMessage';
10940
+ const InputBox = 'InputBox';
10941
+ const InputInvalid = 'InputInvalid';
10942
+ const Insertion = 'Insertion';
10943
+ const Label = 'Label';
10944
+ const LabelDetail = 'LabelDetail';
10945
+ const Markdown = 'Markdown';
10946
+ const MarkdownMathBlock = 'MarkdownMathBlock';
10947
+ const MarkdownQuote = 'MarkdownQuote';
10948
+ const MarkdownTable = 'MarkdownTable';
10949
+ const MaskIcon = 'MaskIcon';
10950
+ const MaskIconAdd = 'MaskIconAdd';
10951
+ const MaskIconArrowLeft = 'MaskIconArrowLeft';
10952
+ const MaskIconChevronDown = 'MaskIconChevronDown';
10953
+ const MaskIconChevronRight = 'MaskIconChevronRight';
10954
+ const MaskIconChevronUp = 'MaskIconChevronUp';
10955
+ const MaskIconClose = 'MaskIconClose';
10956
+ const MaskIconDebugPause = 'MaskIconDebugPause';
10957
+ const MaskIconLayoutPanelLeft = 'MaskIconLayoutPanelLeft';
10958
+ const MaskIconSearch = 'MaskIconSearch';
10959
+ const MaskIconSettingsGear = 'MaskIconSettingsGear';
10960
+ const Message = 'Message';
10961
+ const MessageAssistant = 'MessageAssistant';
10962
+ const MessageUser = 'MessageUser';
10963
+ const MissingApiKeyForm = 'MissingApiKeyForm';
10964
+ const MultiLineInputBox = 'MultilineInputBox';
10965
+ const ProjectAddButton = 'ProjectAddButton';
10966
+ const ProjectList = 'ProjectList';
10967
+ const ProjectListChevron = 'ProjectListChevron';
10968
+ const ProjectListGroup = 'ProjectListGroup';
10969
+ const ProjectListItem = 'ProjectListItem';
10970
+ const ProjectListItemActions = 'ProjectListItemActions';
10971
+ const ProjectListItemAddChatButton = 'ProjectListItemAddChatButton';
10972
+ const ProjectListItemLabel = 'ProjectListItemLabel';
10973
+ const ProjectListItemSelected = 'ProjectListItemSelected';
10974
+ const ProjectSessionItem = 'ProjectSessionItem';
10975
+ const ProjectSessionItemLabel = 'ProjectSessionItemLabel';
10976
+ const ProjectSessionItemSelected = 'ProjectSessionItemSelected';
10977
+ const ProjectSidebar = 'ProjectSidebar';
10978
+ const SearchFieldContainer = 'SearchFieldContainer';
10979
+ const RunModePickerContainer = 'RunModePickerContainer';
10980
+ const RunModePickerPopOver = 'RunModePickerPopOver';
10981
+ const SelectLabel = 'SelectLabel';
10982
+ const SendButtonDisabled = 'SendButtonDisabled';
10983
+ const SessionArchiveButton = 'SessionArchiveButton';
10984
+ const StrikeThrough = 'StrikeThrough';
10985
+ const TokenUsageOverview = 'TokenUsageOverview';
10986
+ const TokenUsageRing = 'TokenUsageRing';
10987
+ const TokenUsageRingInner = 'TokenUsageRingInner';
10988
+ const ToolCallName = 'ToolCallName';
10989
+ const Viewlet = 'Viewlet';
10990
+
12231
10991
  const HandleListContextMenu = 2;
12232
10992
  const HandleFocus = 3;
12233
10993
  const HandleInput = 4;
@@ -12297,13 +11057,22 @@ const getAddContextButtonDom = () => {
12297
11057
  };
12298
11058
 
12299
11059
  const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title) => {
11060
+ const getChevronDom = expanded => {
11061
+ return {
11062
+ childCount: 0,
11063
+ className: mergeClassNames(MaskIcon, expanded ? MaskIconChevronUp : MaskIconChevronDown),
11064
+ name,
11065
+ role: None$1,
11066
+ type: Div
11067
+ };
11068
+ };
12300
11069
  return [{
12301
11070
  'aria-expanded': open ? 'true' : 'false',
12302
11071
  'aria-haspopup': 'true',
12303
11072
  'aria-label': ariaLabel,
12304
11073
  ariaLabel,
12305
11074
  childCount: 2,
12306
- className: Select,
11075
+ className: ChatSelect,
12307
11076
  inputType: 'button',
12308
11077
  name,
12309
11078
  onClick,
@@ -12315,21 +11084,11 @@ const getCustomSelectToggleVirtualDom = (label, name, open, onClick, title = lab
12315
11084
  name,
12316
11085
  role: None$1,
12317
11086
  type: Span
12318
- }, text(label), {
12319
- childCount: 0,
12320
- className: mergeClassNames(MaskIcon, open ? MaskIconChevronUp : MaskIconChevronDown),
12321
- name,
12322
- role: None$1,
12323
- type: Div
12324
- }];
11087
+ }, text(label), getChevronDom(open)];
12325
11088
  };
12326
11089
 
12327
- const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title, containerChildCount = 1) => {
12328
- return [{
12329
- childCount: containerChildCount,
12330
- className: CustomSelectContainer,
12331
- type: Div
12332
- }, ...getCustomSelectToggleVirtualDom(label, name, open, onClick, title, ariaLabel)];
11090
+ const getCustomSelectPickerToggleVirtualDom = (label, name, open, onClick, title = label, ariaLabel = title) => {
11091
+ return getCustomSelectToggleVirtualDom(label, name, open, onClick, title, ariaLabel);
12333
11092
  };
12334
11093
 
12335
11094
  const getAgentModePickerVirtualDom = (selectedAgentMode, agentModePickerOpen) => {
@@ -12421,7 +11180,7 @@ const getGitBranchPickerVirtualDom = (gitBranches, gitBranchPickerOpen, gitBranc
12421
11180
  const messageDom = getBranchPickerMessageDom(gitBranches, gitBranchPickerErrorMessage);
12422
11181
  const showMessage = messageDom.length > 0;
12423
11182
  const popOverHeight = gitBranches.length * itemHeight + (showMessage ? messageHeight : 0);
12424
- return [...getCustomSelectPickerToggleVirtualDom(label, GitBranchPickerToggle, gitBranchPickerOpen, HandleClickGitBranchPickerToggle, 'Switch branch', 'Switch branch', gitBranchPickerOpen ? 2 : 1), ...(gitBranchPickerOpen ? [{
11183
+ return [...getCustomSelectPickerToggleVirtualDom(label, GitBranchPickerToggle, gitBranchPickerOpen, HandleClickGitBranchPickerToggle, 'Switch branch', 'Switch branch'), ...(gitBranchPickerOpen ? [{
12425
11184
  childCount: (showMessage ? 1 : 0) + 1,
12426
11185
  className: mergeClassNames(ChatModelPicker, CustomSelectPopOver, ChatGitBranchPicker),
12427
11186
  style: `height: ${popOverHeight}px;`,
@@ -12442,7 +11201,7 @@ const getReasoningEffortOptionsVirtualDom = selectedReasoningEffort => {
12442
11201
  });
12443
11202
  };
12444
11203
  const getReasoningEffortPickerVirtualDom = (selectedReasoningEffort, reasoningEffortPickerOpen) => {
12445
- return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', 'Reasoning', reasoningEffortPickerOpen ? 2 : 1), ...(reasoningEffortPickerOpen ? [{
11204
+ return [...getCustomSelectPickerToggleVirtualDom(getReasoningEffortLabel(selectedReasoningEffort), ReasoningEffortPickerToggle, reasoningEffortPickerOpen, HandleClickReasoningEffortPickerToggle, 'Reasoning', 'Reasoning'), ...(reasoningEffortPickerOpen ? [{
12446
11205
  childCount: 1,
12447
11206
  className: mergeClassNames(ChatModelPicker, CustomSelectPopOver),
12448
11207
  style: `height: ${reasoningEffortPickerHeight}px;`,
@@ -12853,7 +11612,25 @@ const getUsageCostLabel = model => {
12853
11612
  };
12854
11613
 
12855
11614
  const getChatModelListItemVirtualDom = (model, selectedModelId) => {
12856
- return getCustomSelectOptionVirtualDom(getModelPickerItemInputName(model.id), getModelLabel(model), model.id === selectedModelId, getUsageCostLabel(model));
11615
+ const detail = getUsageCostLabel(model);
11616
+ const hasDetail = detail !== '';
11617
+ const selected = model.id === selectedModelId;
11618
+ const className = mergeClassNames(ChatModelPickerItem, selected ? ChatModelPickerItemSelected : '');
11619
+ return [{
11620
+ childCount: hasDetail ? 2 : 1,
11621
+ className,
11622
+ 'data-id': model.id,
11623
+ role: 'option',
11624
+ type: Li
11625
+ }, {
11626
+ childCount: 1,
11627
+ className: ChatModelPickerItemLabel,
11628
+ type: Span
11629
+ }, text(getModelLabel(model)), ...(hasDetail ? [{
11630
+ childCount: 1,
11631
+ className: ChatModelPickerItemUsageCost,
11632
+ type: Span
11633
+ }, text(detail)] : [])];
12857
11634
  };
12858
11635
 
12859
11636
  const parentNode$2 = {
@@ -12876,6 +11653,7 @@ const getChatModelListVirtualDom = (visibleModels, selectedModelId) => {
12876
11653
  onPointerDown: HandlePointerDownModelPickerList,
12877
11654
  onPointerUp: HandlePointerUpModelPickerList,
12878
11655
  onScroll: HandleModelPickerListScroll,
11656
+ role: 'listbox',
12879
11657
  type: Ul
12880
11658
  }, ...visibleModels.flatMap(model => getChatModelListItemVirtualDom(model, selectedModelId))];
12881
11659
  };
@@ -13116,19 +11894,7 @@ const getBlockQuoteDom = (node, useChatMathWorker, getMessageNodeDom) => {
13116
11894
  }, ...node.children.flatMap(child => getMessageNodeDom(child, useChatMathWorker))];
13117
11895
  };
13118
11896
 
13119
- const getTokenDom = token => {
13120
- if (!token.className) {
13121
- return [text(token.text)];
13122
- }
13123
- return [{
13124
- childCount: 1,
13125
- className: token.className,
13126
- type: Span
13127
- }, text(token.text)];
13128
- };
13129
-
13130
11897
  const getCodeBlockDom = node => {
13131
- const tokenDom = node.codeTokens.flatMap(getTokenDom);
13132
11898
  const languageAttribute = node.language ? {
13133
11899
  'data-lang': node.language
13134
11900
  } : {};
@@ -13137,10 +11903,10 @@ const getCodeBlockDom = node => {
13137
11903
  type: Pre,
13138
11904
  ...languageAttribute
13139
11905
  }, {
13140
- childCount: node.codeTokens.length,
11906
+ childCount: 1,
13141
11907
  type: Code,
13142
11908
  ...languageAttribute
13143
- }, ...tokenDom];
11909
+ }, text(node.text)];
13144
11910
  };
13145
11911
 
13146
11912
  const getHeadingElementType = level => {
@@ -14050,7 +12816,7 @@ const getElementType = tagName => {
14050
12816
  case 'section':
14051
12817
  return Section;
14052
12818
  case 'select':
14053
- return Select$1;
12819
+ return Select;
14054
12820
  case 'span':
14055
12821
  return Span;
14056
12822
  case 'strong':
@@ -15048,7 +13814,7 @@ const getSessionDom = (session, focused = false) => {
15048
13814
  type: Div
15049
13815
  }, {
15050
13816
  childCount: 0,
15051
- className: `${ChatListItemStatusIcon} codicon codicon-circle-filled ${sessionStatusClassName}`,
13817
+ className: `${ChatListItemStatusIcon} ${sessionStatusClassName}`,
15052
13818
  type: Div
15053
13819
  }, {
15054
13820
  childCount: 1,
@@ -16195,18 +14961,6 @@ const setUseChatMathWorker = async (state, useChatMathWorker, persist = true) =>
16195
14961
  };
16196
14962
  };
16197
14963
 
16198
- const setUseChatMessageParsingWorker = async (state, useChatMessageParsingWorker, persist = true) => {
16199
- if (persist) {
16200
- await update({
16201
- 'chatView.useChatMessageParsingWorker': useChatMessageParsingWorker
16202
- });
16203
- }
16204
- return {
16205
- ...state,
16206
- useChatMessageParsingWorker
16207
- };
16208
- };
16209
-
16210
14964
  const setUseChatNetworkWorkerForRequests = async (state, useChatNetworkWorkerForRequests, persist = true) => {
16211
14965
  if (persist) {
16212
14966
  await update({
@@ -16358,7 +15112,6 @@ const commandMap = {
16358
15112
  'Chat.setToolEnablement': wrapCommand(setToolEnablement),
16359
15113
  'Chat.setUseChatCoordinatorWorker': wrapCommand(setUseChatCoordinatorWorker),
16360
15114
  'Chat.setUseChatMathWorker': wrapCommand(setUseChatMathWorker),
16361
- 'Chat.setUseChatMessageParsingWorker': wrapCommand(setUseChatMessageParsingWorker),
16362
15115
  'Chat.setUseChatNetworkWorkerForRequests': wrapCommand(setUseChatNetworkWorkerForRequests),
16363
15116
  'Chat.showComposerAttachmentPreviewOverlay': wrapCommand(showComposerAttachmentPreviewOverlay),
16364
15117
  'Chat.terminate': terminate,