@lvce-editor/chat-view 6.63.0 → 6.65.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.
@@ -1198,6 +1198,7 @@ const Reference = 100;
1198
1198
 
1199
1199
  const ClientX = 'event.clientX';
1200
1200
  const ClientY = 'event.clientY';
1201
+ const DataTransferFiles2 = 'event.dataTransfer.files2';
1201
1202
  const DefaultPrevented = 'event.defaultPrevented';
1202
1203
  const Key = 'event.key';
1203
1204
  const ShiftKey = 'event.shiftKey';
@@ -1307,6 +1308,10 @@ const showContextMenu2 = async (uid, menuId, x, y, args) => {
1307
1308
  number(y);
1308
1309
  await invoke('ContextMenu.show2', uid, menuId, x, y, args);
1309
1310
  };
1311
+ const getFileHandles = async fileIds => {
1312
+ const files = await invoke('FileSystemHandle.getFileHandles', fileIds);
1313
+ return files;
1314
+ };
1310
1315
  const sendMessagePortToClipBoardWorker$1 = async (port, rpcId) => {
1311
1316
  const command = 'ClipBoard.handleMessagePort';
1312
1317
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToClipBoardWorker', port, command, rpcId);
@@ -1860,7 +1865,8 @@ const StartConversationByTypingBelow = 'Start a conversation by typing below.';
1860
1865
  const NoMatchingModelsFound = 'No matching models have been found.';
1861
1866
  const ComposePlaceholder = 'Type your message. Enter to send.';
1862
1867
  const AttachImageAsContext = 'Attach Image as Context';
1863
- const RemoveImageAttachment = 'Remove image attachment';
1868
+ const OpenImageInNewTab = 'Open image in new tab';
1869
+ const RemoveAttachment = 'Remove attachment';
1864
1870
  const ImageCouldNotBeLoaded = 'image could not be loaded';
1865
1871
  const OpenRouterApiKeyPlaceholder = 'Enter OpenRouter API key';
1866
1872
  const OpenApiApiKeyPlaceholder = 'Enter OpenAI API key';
@@ -1955,8 +1961,11 @@ const composePlaceholder = () => {
1955
1961
  const attachImageAsContext = () => {
1956
1962
  return i18nString(AttachImageAsContext);
1957
1963
  };
1958
- const removeImageAttachment = () => {
1959
- return i18nString(RemoveImageAttachment);
1964
+ const openImageInNewTab = () => {
1965
+ return i18nString(OpenImageInNewTab);
1966
+ };
1967
+ const removeAttachment = () => {
1968
+ return i18nString(RemoveAttachment);
1960
1969
  };
1961
1970
  const imageCouldNotBeLoaded = () => {
1962
1971
  return i18nString(ImageCouldNotBeLoaded);
@@ -3240,6 +3249,24 @@ const getKeyBindings = () => {
3240
3249
  }];
3241
3250
  };
3242
3251
 
3252
+ const getMenuEntriesChatAttachment = (attachmentId, previewSrc) => {
3253
+ return [{
3254
+ args: [previewSrc],
3255
+ command: 'Chat.openChatAttachmentInNewTab',
3256
+ flags: None,
3257
+ id: 'openImageInNewTab',
3258
+ // @ts-ignore
3259
+ label: openImageInNewTab()
3260
+ }, {
3261
+ args: [attachmentId],
3262
+ command: 'Chat.removeComposerAttachment',
3263
+ flags: None,
3264
+ id: 'removeAttachment',
3265
+ // @ts-ignore
3266
+ label: removeAttachment()
3267
+ }];
3268
+ };
3269
+
3243
3270
  const getMenuEntriesChatHeader = () => {
3244
3271
  // TODO
3245
3272
  return [{
@@ -3299,6 +3326,7 @@ const Composer = 'composer';
3299
3326
  const Search = 'search';
3300
3327
  const ComposerDropTarget = 'composer-drop-target';
3301
3328
  const ComposerAttachmentPrefix = 'composer-attachment:';
3329
+ const ComposerAttachmentPreviewPrefix = 'composer-attachment-preview:';
3302
3330
  const ComposerAttachmentRemovePrefix = 'composer-attachment-remove:';
3303
3331
  const AddContext = 'add-context';
3304
3332
  const Dictate = 'dictate';
@@ -3372,6 +3400,12 @@ const getComposerAttachmentInputName = attachmentId => {
3372
3400
  const getComposerAttachmentRemoveInputName = attachmentId => {
3373
3401
  return `${ComposerAttachmentRemovePrefix}${attachmentId}`;
3374
3402
  };
3403
+ const isComposerAttachmentPreviewInputName = name => {
3404
+ return name.startsWith(ComposerAttachmentPreviewPrefix);
3405
+ };
3406
+ const getAttachmentIdFromComposerAttachmentPreviewInputName = name => {
3407
+ return name.slice(ComposerAttachmentPreviewPrefix.length);
3408
+ };
3375
3409
  const isComposerAttachmentRemoveInputName = name => {
3376
3410
  return name.startsWith(ComposerAttachmentRemovePrefix);
3377
3411
  };
@@ -3447,12 +3481,15 @@ const MenuChatHeader = 2179;
3447
3481
  const MenuChatInput = 2180;
3448
3482
  const MenuProjectAddButton = 2181;
3449
3483
  const MenuChatProjectList = 2182;
3484
+ const MenuChatAttachment = 2183;
3450
3485
  const getMenuEntryIds = () => {
3451
- return [Chat$2, MenuChatList, MenuChatHeader, MenuChatInput, MenuProjectAddButton, MenuChatProjectList];
3486
+ return [Chat$2, MenuChatList, MenuChatHeader, MenuChatInput, MenuProjectAddButton, MenuChatProjectList, MenuChatAttachment];
3452
3487
  };
3453
3488
 
3454
3489
  const getMenuEntries = (menuId, props) => {
3455
3490
  switch (props.menuId) {
3491
+ case MenuChatAttachment:
3492
+ return getMenuEntriesChatAttachment(props.attachmentId, props.previewSrc);
3456
3493
  case MenuChatHeader:
3457
3494
  return getMenuEntriesChatHeader();
3458
3495
  case MenuChatInput:
@@ -6519,9 +6556,11 @@ const ChatModelPickerItemSelected = 'ChatModelPickerItemSelected';
6519
6556
  const ChatModelPickerItemUsageCost = 'ChatModelPickerItemUsageCost';
6520
6557
  const ChatModelPickerList = 'ChatModelPickerList';
6521
6558
  const ChatName = 'ChatName';
6559
+ const ChatOverlays = 'ChatOverlays';
6522
6560
  const ChatOrderedList = 'ChatOrderedList';
6523
6561
  const ChatOrderedListItem = 'ChatOrderedListItem';
6524
6562
  const ChatOrderedListItemContent = 'ChatOrderedListItemContent';
6563
+ const ChatOrderedListItemPrefix = 'ChatOrderedListItemPrefix';
6525
6564
  const ChatOrderedListMarker = 'ChatOrderedListMarker';
6526
6565
  const ChatComposerAttachment = 'ChatComposerAttachment';
6527
6566
  const ChatComposerAttachmentImage = 'ChatComposerAttachmentImage';
@@ -8973,7 +9012,8 @@ const handleRemoveComposerAttachment = async (state, attachmentId) => {
8973
9012
  }
8974
9013
  return {
8975
9014
  ...state,
8976
- composerAttachments: nextComposerAttachments
9015
+ composerAttachments: nextComposerAttachments,
9016
+ composerAttachmentsHeight: getComposerAttachmentsHeight(nextComposerAttachments, state.width)
8977
9017
  };
8978
9018
  };
8979
9019
 
@@ -9417,7 +9457,23 @@ const handleClickSettings = async () => {
9417
9457
  await invoke('Main.openUri', 'app://settings.json');
9418
9458
  };
9419
9459
 
9420
- const handleContextMenuChatImageAttachment = async state => {
9460
+ const handleContextMenuChatImageAttachment = async (state, name, eventX, eventY) => {
9461
+ const getFallbackAttachment = () => {
9462
+ const attachmentsWithPreview = state.composerAttachments.filter(attachment => attachment.previewSrc);
9463
+ if (attachmentsWithPreview.length !== 1) {
9464
+ return undefined;
9465
+ }
9466
+ return attachmentsWithPreview[0];
9467
+ };
9468
+ const attachment = isComposerAttachmentPreviewInputName(name) ? state.composerAttachments.find(item => item.attachmentId === getAttachmentIdFromComposerAttachmentPreviewInputName(name)) : getFallbackAttachment();
9469
+ if (!attachment?.previewSrc) {
9470
+ return state;
9471
+ }
9472
+ await showContextMenu2(state.uid, MenuChatAttachment, eventX, eventY, {
9473
+ attachmentId: attachment.attachmentId,
9474
+ menuId: MenuChatAttachment,
9475
+ previewSrc: attachment.previewSrc
9476
+ });
9421
9477
  return state;
9422
9478
  };
9423
9479
 
@@ -9488,7 +9544,23 @@ const handleDragOver = async (state, name, hasFiles = true) => {
9488
9544
  };
9489
9545
  };
9490
9546
 
9491
- const handleDropFiles = async (state, name, files = []) => {
9547
+ const getDroppedFiles = async fileHandles => {
9548
+ // TODO adjust e2e test and remove this code
9549
+ if (fileHandles.some(item => typeof item !== 'number')) {
9550
+ return fileHandles.map(item => {
9551
+ return {
9552
+ getFile() {
9553
+ return item;
9554
+ }
9555
+ };
9556
+ });
9557
+ }
9558
+ const actualHandles = await getFileHandles(fileHandles);
9559
+ return actualHandles.map(item => item.value).filter(item => item.kind === 'file');
9560
+ };
9561
+
9562
+ const handleDropFiles = async (state, name, fileHandles = []) => {
9563
+ const droppedFileHandles = await getDroppedFiles(fileHandles);
9492
9564
  const {
9493
9565
  composerDropActive,
9494
9566
  composerDropEnabled,
@@ -9508,11 +9580,12 @@ const handleDropFiles = async (state, name, files = []) => {
9508
9580
  ...state,
9509
9581
  composerDropActive: false
9510
9582
  };
9511
- if (!selectedSessionId || files.length === 0) {
9583
+ if (!selectedSessionId || fileHandles.length === 0) {
9512
9584
  return nextState;
9513
9585
  }
9514
9586
  const nextAttachments = [];
9515
- for (const file of files) {
9587
+ for (const droppedFileHandle of droppedFileHandles) {
9588
+ const file = await droppedFileHandle.getFile();
9516
9589
  const attachmentId = crypto.randomUUID();
9517
9590
  const displayType = await getComposerAttachmentDisplayType(file, file.name, file.type);
9518
9591
  const previewSrc = await getComposerAttachmentPreviewSrc(file, displayType, file.type);
@@ -10649,6 +10722,10 @@ const registerMockResponse = (state, mockResponse) => {
10649
10722
  return state;
10650
10723
  };
10651
10724
 
10725
+ const removeComposerAttachment = async (state, attachmentId) => {
10726
+ return handleRemoveComposerAttachment(state, attachmentId);
10727
+ };
10728
+
10652
10729
  const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, chatFocusContentMaxWidth, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss) => {
10653
10730
  const buttonsHeight = 20;
10654
10731
  const gap = 10;
@@ -10758,6 +10835,16 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
10758
10835
  justify-content: flex-end;
10759
10836
  }
10760
10837
 
10838
+ .ChatOverlays{
10839
+ position: absolute;
10840
+ inset: 0;
10841
+ pointer-events: none;
10842
+ }
10843
+
10844
+ .ChatOverlays > *{
10845
+ pointer-events: auto;
10846
+ }
10847
+
10761
10848
  .RunModePickerPopOver{
10762
10849
  overflow: hidden;
10763
10850
  border: 1px solid var(--vscode-widget-border, var(--vscode-panel-border));
@@ -10770,6 +10857,26 @@ const getCss = (composerHeight, composerAttachmentsHeight, modelPickerHeight, li
10770
10857
  color: var(--vscode-textLink-foreground);
10771
10858
  }
10772
10859
 
10860
+ .ChatOrderedListItem{
10861
+ align-items: flex-start;
10862
+ display: flex;
10863
+ gap: 8px;
10864
+ }
10865
+
10866
+ .ChatOrderedListMarker{
10867
+ flex: none;
10868
+ min-width: 1.5em;
10869
+ }
10870
+
10871
+ .ChatOrderedListItemContent{
10872
+ flex: 1;
10873
+ min-width: 0;
10874
+ }
10875
+
10876
+ .ChatOrderedListItemPrefix{
10877
+ white-space: nowrap;
10878
+ }
10879
+
10773
10880
  .ChatToolCalls .ChatOrderedList{
10774
10881
  list-style: none;
10775
10882
  margin: 0;
@@ -10929,57 +11036,6 @@ const HandleClickReasoningEffortPickerToggle = 56;
10929
11036
  const HandleClickAgentModePickerToggle = 57;
10930
11037
  const HandleContextMenuChatImageAttachment = 58;
10931
11038
 
10932
- const getCustomSelectOptionVirtualDom = (name, label, selected, detail = '') => {
10933
- const className = mergeClassNames(ChatModelPickerItem, selected ? ChatModelPickerItemSelected : '');
10934
- const hasDetail = detail !== '';
10935
- return [{
10936
- childCount: 1,
10937
- type: Li
10938
- }, {
10939
- childCount: hasDetail ? 2 : 1,
10940
- className,
10941
- inputType: 'button',
10942
- name,
10943
- onClick: HandleClick,
10944
- type: Button$1
10945
- }, {
10946
- childCount: 1,
10947
- className: ChatModelPickerItemLabel,
10948
- name,
10949
- type: Span
10950
- }, text(label), ...(hasDetail ? [{
10951
- childCount: 1,
10952
- className: ChatModelPickerItemUsageCost,
10953
- name,
10954
- type: Span
10955
- }, text(detail)] : [])];
10956
- };
10957
-
10958
- const getCustomSelectPopOverVirtualDom = (optionCount, height, optionNodes, containerClassName = '', popOverClassName = '') => {
10959
- return [{
10960
- childCount: 1,
10961
- className: mergeClassNames(ChatModelPickerContainer, containerClassName),
10962
- type: Div
10963
- }, {
10964
- childCount: 1,
10965
- className: mergeClassNames(ChatModelPicker, popOverClassName),
10966
- style: `height: ${height}px;`,
10967
- type: Div
10968
- }, {
10969
- childCount: optionCount,
10970
- className: ChatModelPickerList,
10971
- type: Ul
10972
- }, ...optionNodes];
10973
- };
10974
-
10975
- const agentModePickerHeight = agentModes.length * 28;
10976
- const getAgentModeOptionsVirtualDom = selectedAgentMode => {
10977
- return agentModes.flatMap(agentMode => getCustomSelectOptionVirtualDom(getAgentModePickerItemInputName(agentMode), getAgentModeLabel(agentMode), agentMode === selectedAgentMode));
10978
- };
10979
- const getAgentModePickerPopOverVirtualDom = selectedAgentMode => {
10980
- return getCustomSelectPopOverVirtualDom(agentModes.length, agentModePickerHeight, getAgentModeOptionsVirtualDom(selectedAgentMode));
10981
- };
10982
-
10983
11039
  const getAddContextButtonDom = () => {
10984
11040
  return [{
10985
11041
  childCount: 1,
@@ -11052,6 +11108,32 @@ const getCreatePullRequestButtonDom = () => {
11052
11108
  }];
11053
11109
  };
11054
11110
 
11111
+ const getCustomSelectOptionVirtualDom = (name, label, selected, detail = '') => {
11112
+ const className = mergeClassNames(ChatModelPickerItem, selected ? ChatModelPickerItemSelected : '');
11113
+ const hasDetail = detail !== '';
11114
+ return [{
11115
+ childCount: 1,
11116
+ type: Li
11117
+ }, {
11118
+ childCount: hasDetail ? 2 : 1,
11119
+ className,
11120
+ inputType: 'button',
11121
+ name,
11122
+ onClick: HandleClick,
11123
+ type: Button$1
11124
+ }, {
11125
+ childCount: 1,
11126
+ className: ChatModelPickerItemLabel,
11127
+ name,
11128
+ type: Span
11129
+ }, text(label), ...(hasDetail ? [{
11130
+ childCount: 1,
11131
+ className: ChatModelPickerItemUsageCost,
11132
+ name,
11133
+ type: Span
11134
+ }, text(detail)] : [])];
11135
+ };
11136
+
11055
11137
  const reasoningEffortPickerHeight = reasoningEfforts.length * 28;
11056
11138
  const getReasoningEffortOptionsVirtualDom = selectedReasoningEffort => {
11057
11139
  return reasoningEfforts.flatMap(reasoningEffort => {
@@ -11210,16 +11292,13 @@ const getComposerAttachmentClassName = displayType => {
11210
11292
  }
11211
11293
  };
11212
11294
  const getComposerAttachmentRemoveButtonDom = attachment => {
11213
- if (attachment.displayType !== 'image') {
11214
- return [];
11215
- }
11216
11295
  return [{
11217
11296
  buttonType: 'button',
11218
11297
  childCount: 1,
11219
11298
  className: ChatComposerAttachmentRemoveButton,
11220
11299
  name: getComposerAttachmentRemoveInputName(attachment.attachmentId),
11221
11300
  onClick: HandleClick,
11222
- title: removeImageAttachment(),
11301
+ title: removeAttachment(),
11223
11302
  type: Button$1
11224
11303
  }, {
11225
11304
  text: 'x',
@@ -11234,6 +11313,8 @@ const getComposerAttachmentPreviewDom = attachment => {
11234
11313
  alt: `Image preview for ${attachment.name}`,
11235
11314
  childCount: 0,
11236
11315
  className: ChatComposerAttachmentPreview,
11316
+ name: getComposerAttachmentInputName(attachment.attachmentId),
11317
+ onContextMenu: HandleContextMenuChatImageAttachment,
11237
11318
  src: attachment.previewSrc,
11238
11319
  type: Img
11239
11320
  }];
@@ -11309,6 +11390,31 @@ const getChatSendAreaDom = (composerValue, composerAttachments, agentMode, agent
11309
11390
  }, ...(showAgentModePicker ? getAgentModePickerVirtualDom(agentMode, agentModePickerOpen) : []), ...getChatModelPickerToggleVirtualDom(models, selectedModelId, modelPickerOpen), ...(reasoningPickerEnabled ? getReasoningEffortPickerVirtualDom(reasoningEffort, reasoningEffortPickerOpen) : []), ...(showResponsiveRunModePicker ? getRunModePickerVirtualDom(runMode, runModePickerOpen) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...(showCreatePullRequestButton ? getCreatePullRequestButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
11310
11391
  };
11311
11392
 
11393
+ const getCustomSelectPopOverVirtualDom = (optionCount, height, optionNodes, containerClassName = '', popOverClassName = '') => {
11394
+ return [{
11395
+ childCount: 1,
11396
+ className: mergeClassNames(ChatModelPickerContainer, containerClassName),
11397
+ type: Div
11398
+ }, {
11399
+ childCount: 1,
11400
+ className: mergeClassNames(ChatModelPicker, popOverClassName),
11401
+ style: `height: ${height}px;`,
11402
+ type: Div
11403
+ }, {
11404
+ childCount: optionCount,
11405
+ className: ChatModelPickerList,
11406
+ type: Ul
11407
+ }, ...optionNodes];
11408
+ };
11409
+
11410
+ const agentModePickerHeight = agentModes.length * 28;
11411
+ const getAgentModeOptionsVirtualDom = selectedAgentMode => {
11412
+ return agentModes.flatMap(agentMode => getCustomSelectOptionVirtualDom(getAgentModePickerItemInputName(agentMode), getAgentModeLabel(agentMode), agentMode === selectedAgentMode));
11413
+ };
11414
+ const getAgentModePickerPopOverVirtualDom = selectedAgentMode => {
11415
+ return getCustomSelectPopOverVirtualDom(agentModes.length, agentModePickerHeight, getAgentModeOptionsVirtualDom(selectedAgentMode));
11416
+ };
11417
+
11312
11418
  const getUsageCostLabel = model => {
11313
11419
  return `${model.usageCost ?? 1}x`;
11314
11420
  };
@@ -11375,6 +11481,51 @@ const getChatModelPickerPopOverVirtualDom = (models, selectedModelId, modelPicke
11375
11481
  }, ...getModelPickerHeaderDom(modelPickerSearchValue), ...getChatModelListVirtualDom(visibleModels, selectedModelId)];
11376
11482
  };
11377
11483
 
11484
+ const runModes = ['local', 'background', 'cloud'];
11485
+ const runModePickerHeight = runModes.length * 28;
11486
+ const getRunModeOptionsVirtualDom = selectedRunMode => {
11487
+ return runModes.flatMap(runMode => getCustomSelectOptionVirtualDom(getRunModePickerItemInputName(runMode), runMode, runMode === selectedRunMode));
11488
+ };
11489
+ const getRunModePickerPopOverVirtualDom = selectedRunMode => {
11490
+ return getCustomSelectPopOverVirtualDom(runModes.length, runModePickerHeight, getRunModeOptionsVirtualDom(selectedRunMode), RunModePickerContainer, RunModePickerPopOver);
11491
+ };
11492
+
11493
+ const getDropOverlayVirtualDom = () => {
11494
+ return [{
11495
+ childCount: 1,
11496
+ className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
11497
+ name: ComposerDropTarget,
11498
+ onDragLeave: HandleDragLeave,
11499
+ onDragOver: HandleDragOver,
11500
+ onDrop: HandleDrop,
11501
+ type: Div
11502
+ }, {
11503
+ text: attachImageAsContext(),
11504
+ type: Text
11505
+ }];
11506
+ };
11507
+ const getChatOverlaysVirtualDom = ({
11508
+ agentMode,
11509
+ agentModePickerVisible,
11510
+ dropOverlayVisible,
11511
+ modelPickerSearchValue,
11512
+ modelPickerVisible,
11513
+ runMode,
11514
+ runModePickerVisible,
11515
+ selectedModelId,
11516
+ visibleModels
11517
+ }) => {
11518
+ const overlayChildCount = (dropOverlayVisible ? 1 : 0) + (agentModePickerVisible ? 1 : 0) + (modelPickerVisible ? 1 : 0) + (runModePickerVisible ? 1 : 0);
11519
+ if (!overlayChildCount) {
11520
+ return [];
11521
+ }
11522
+ return [{
11523
+ childCount: overlayChildCount,
11524
+ className: ChatOverlays,
11525
+ type: Div
11526
+ }, ...(dropOverlayVisible ? getDropOverlayVirtualDom() : []), ...(agentModePickerVisible ? getAgentModePickerPopOverVirtualDom(agentMode) : []), ...(modelPickerVisible ? getChatModelPickerPopOverVirtualDom(visibleModels, selectedModelId, modelPickerSearchValue) : []), ...(runModePickerVisible ? getRunModePickerPopOverVirtualDom(runMode) : [])];
11527
+ };
11528
+
11378
11529
  const getBoldInlineNodeDom = (inlineNode, useChatMathWorker, renderInlineNodeDom) => {
11379
11530
  return [{
11380
11531
  childCount: inlineNode.children.length,
@@ -11538,24 +11689,69 @@ const getHeadingDom = (node, useChatMathWorker) => {
11538
11689
  }, ...node.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
11539
11690
  };
11540
11691
 
11692
+ const leadingPunctuationRegex = /^([:;,.!?]+)([\s\S]*)$/;
11693
+ const splitLeadingPunctuation = children => {
11694
+ const [firstChild, secondChild, ...restChildren] = children;
11695
+ if (firstChild?.type !== 'bold' || secondChild?.type !== 'text') {
11696
+ return {
11697
+ prefixChildren: [],
11698
+ remainingChildren: children
11699
+ };
11700
+ }
11701
+ const match = secondChild.text.match(leadingPunctuationRegex);
11702
+ if (!match) {
11703
+ return {
11704
+ prefixChildren: [],
11705
+ remainingChildren: children
11706
+ };
11707
+ }
11708
+ const [, punctuation, remainingText] = match;
11709
+ const nextChildren = restChildren;
11710
+ if (remainingText) {
11711
+ nextChildren.unshift({
11712
+ text: remainingText,
11713
+ type: 'text'
11714
+ });
11715
+ }
11716
+ return {
11717
+ prefixChildren: [firstChild, {
11718
+ text: punctuation,
11719
+ type: 'text'
11720
+ }],
11721
+ remainingChildren: nextChildren
11722
+ };
11723
+ };
11541
11724
  const getOrderedListItemDom = (item, useChatMathWorker, fallbackIndex, recurseOrdered, recurseUnordered) => {
11542
11725
  const hasNestedList = (item.nestedItems?.length || 0) > 0;
11543
11726
  const nestedListType = item.nestedListType || 'unordered-list';
11727
+ const {
11728
+ prefixChildren,
11729
+ remainingChildren
11730
+ } = splitLeadingPunctuation(item.children);
11544
11731
  const nestedListDom = hasNestedList ? [{
11545
11732
  childCount: item.nestedItems?.length || 0,
11546
11733
  className: nestedListType === 'ordered-list' ? ChatOrderedList : ChatUnorderedList,
11547
11734
  type: nestedListType === 'ordered-list' ? Ol : Ul
11548
11735
  }, ...(item.nestedItems || []).flatMap((nestedItem, index) => nestedListType === 'ordered-list' ? recurseOrdered(nestedItem, useChatMathWorker, index + 1) : recurseUnordered(nestedItem, useChatMathWorker))] : [];
11549
11736
  const marker = `${item.index ?? fallbackIndex}.`;
11737
+ const prefixDom = prefixChildren.length === 0 ? [] : [{
11738
+ childCount: prefixChildren.length,
11739
+ className: ChatOrderedListItemPrefix,
11740
+ type: Span
11741
+ }, ...prefixChildren.flatMap(child => getInlineNodeDom(child, useChatMathWorker))];
11550
11742
  return [{
11551
- childCount: item.children.length + (hasNestedList ? 1 : 0) + 1,
11743
+ childCount: 2,
11552
11744
  className: ChatOrderedListItem,
11553
11745
  type: Li
11554
11746
  }, {
11555
11747
  childCount: 1,
11556
11748
  className: ChatOrderedListMarker,
11557
11749
  type: Span
11558
- }, text(marker), ...item.children.flatMap(child => getInlineNodeDom(child, useChatMathWorker)), ...nestedListDom];
11750
+ }, text(marker), {
11751
+ childCount: (prefixDom.length === 0 ? 0 : 1) + remainingChildren.length + (hasNestedList ? 1 : 0),
11752
+ className: ChatOrderedListItemContent,
11753
+ type: Div
11754
+ }, ...prefixDom, ...remainingChildren.flatMap(child => getInlineNodeDom(child, useChatMathWorker)), ...nestedListDom];
11559
11755
  };
11560
11756
 
11561
11757
  const getTableHeadCellDom = (cell, useChatMathWorker) => {
@@ -12761,6 +12957,7 @@ const getMessagesDom = (messages, parsedMessages, openRouterApiKeyInput, openApi
12761
12957
  className: 'ChatMessages',
12762
12958
  onContextMenu: HandleMessagesContextMenu,
12763
12959
  onScroll: HandleMessagesScroll,
12960
+ role: 'log',
12764
12961
  scrollTop: messagesScrollTop,
12765
12962
  type: Div
12766
12963
  }, ...displayMessages.flatMap(item => getChatMessageDom(item.message, item.parsedContent, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, useChatMathWorker))];
@@ -12870,15 +13067,6 @@ const getProjectListDom = (projects, sessions, projectExpandedIds, selectedProje
12870
13067
  }, text('+ Add Project'), ...(showBackToChatsButton ? getBackToChatsButtonDom() : [])];
12871
13068
  };
12872
13069
 
12873
- const runModes = ['local', 'background', 'cloud'];
12874
- const runModePickerHeight = runModes.length * 28;
12875
- const getRunModeOptionsVirtualDom = selectedRunMode => {
12876
- return runModes.flatMap(runMode => getCustomSelectOptionVirtualDom(getRunModePickerItemInputName(runMode), runMode, runMode === selectedRunMode));
12877
- };
12878
- const getRunModePickerPopOverVirtualDom = selectedRunMode => {
12879
- return getCustomSelectPopOverVirtualDom(runModes.length, runModePickerHeight, getRunModeOptionsVirtualDom(selectedRunMode), RunModePickerContainer, RunModePickerPopOver);
12880
- };
12881
-
12882
13070
  const getChatModeChatFocusVirtualDom = ({
12883
13071
  addContextButtonEnabled,
12884
13072
  agentMode,
@@ -12936,25 +13124,25 @@ const getChatModeChatFocusVirtualDom = ({
12936
13124
  const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
12937
13125
  const isNewModelPickerVisible = modelPickerOpen;
12938
13126
  const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
12939
- const chatRootChildCount = 3 + (isDropOverlayVisible ? 1 : 0) + (isAgentModePickerVisible ? 1 : 0) + (isNewModelPickerVisible ? 1 : 0) + (isRunModePickerVisible ? 1 : 0);
13127
+ const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
13128
+ const chatRootChildCount = 3 + (hasVisibleOverlays ? 1 : 0);
12940
13129
  return [{
12941
13130
  childCount: chatRootChildCount,
12942
13131
  className: mergeClassNames(Viewlet, Chat, ChatFocus),
12943
13132
  onDragEnter: HandleDragEnterChatView,
12944
13133
  onDragOver: HandleDragOverChatView,
12945
13134
  type: Div
12946
- }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop, true), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
12947
- childCount: 1,
12948
- className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
12949
- name: ComposerDropTarget,
12950
- onDragLeave: HandleDragLeave,
12951
- onDragOver: HandleDragOver,
12952
- onDrop: HandleDrop,
12953
- type: Div
12954
- }, {
12955
- text: attachImageAsContext(),
12956
- type: Text
12957
- }] : []), ...(isAgentModePickerVisible ? getAgentModePickerPopOverVirtualDom(agentMode) : []), ...(isNewModelPickerVisible ? getChatModelPickerPopOverVirtualDom(visibleModels, selectedModelId, modelPickerSearchValue) : []), ...(isRunModePickerVisible ? getRunModePickerPopOverVirtualDom(runMode) : [])];
13135
+ }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop, true), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled), ...getChatOverlaysVirtualDom({
13136
+ agentMode,
13137
+ agentModePickerVisible: isAgentModePickerVisible,
13138
+ dropOverlayVisible: isDropOverlayVisible,
13139
+ modelPickerSearchValue,
13140
+ modelPickerVisible: isNewModelPickerVisible,
13141
+ runMode,
13142
+ runModePickerVisible: isRunModePickerVisible,
13143
+ selectedModelId,
13144
+ visibleModels
13145
+ })];
12958
13146
  };
12959
13147
 
12960
13148
  const arrowLeft = {
@@ -13041,6 +13229,7 @@ const getChatHeaderActionsDom = (viewMode, authEnabled = false, authStatus = 'si
13041
13229
  title: closeChat()
13042
13230
  }];
13043
13231
  return [{
13232
+ 'aria-label': 'chat actions',
13044
13233
  childCount: items.length,
13045
13234
  className: ChatActions,
13046
13235
  role: ToolBar,
@@ -13130,25 +13319,25 @@ const getChatModeDetailVirtualDom = ({
13130
13319
  const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
13131
13320
  const isNewModelPickerVisible = modelPickerOpen;
13132
13321
  const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
13133
- const chatRootChildCount = 3 + (isDropOverlayVisible ? 1 : 0) + (isAgentModePickerVisible ? 1 : 0) + (isNewModelPickerVisible ? 1 : 0) + (isRunModePickerVisible ? 1 : 0);
13322
+ const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
13323
+ const chatRootChildCount = 3 + (hasVisibleOverlays ? 1 : 0);
13134
13324
  return [{
13135
13325
  childCount: chatRootChildCount,
13136
13326
  className: mergeClassNames(Viewlet, Chat),
13137
13327
  onDragEnter: HandleDragEnterChatView,
13138
13328
  onDragOver: HandleDragOverChatView,
13139
13329
  type: Div
13140
- }, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, authStatus, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
13141
- childCount: 1,
13142
- className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
13143
- name: ComposerDropTarget,
13144
- onDragLeave: HandleDragLeave,
13145
- onDragOver: HandleDragOver,
13146
- onDrop: HandleDrop,
13147
- type: Div
13148
- }, {
13149
- text: attachImageAsContext(),
13150
- type: Text
13151
- }] : []), ...(isAgentModePickerVisible ? getAgentModePickerPopOverVirtualDom(agentMode) : []), ...(isNewModelPickerVisible ? getChatModelPickerPopOverVirtualDom(visibleModels, selectedModelId, modelPickerSearchValue) : []), ...(isRunModePickerVisible ? getRunModePickerPopOverVirtualDom(runMode) : [])];
13330
+ }, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, authStatus, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openApiApiKeyState, openApiApiKeysSettingsUrl, openApiApiKeyInputPattern, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, showCreatePullRequestButton, voiceDictationEnabled), ...getChatOverlaysVirtualDom({
13331
+ agentMode,
13332
+ agentModePickerVisible: isAgentModePickerVisible,
13333
+ dropOverlayVisible: isDropOverlayVisible,
13334
+ modelPickerSearchValue,
13335
+ modelPickerVisible: isNewModelPickerVisible,
13336
+ runMode,
13337
+ runModePickerVisible: isRunModePickerVisible,
13338
+ selectedModelId,
13339
+ visibleModels
13340
+ })];
13152
13341
  };
13153
13342
 
13154
13343
  const getChatSearchDom = (hasSearchField, searchValue) => {
@@ -13277,23 +13466,6 @@ const getChatListDom = (sessions, selectedSessionId, listFocusedIndex, chatListS
13277
13466
  }, ...sessions.flatMap((session, index) => getSessionDom(session, index === listFocusedIndex))];
13278
13467
  };
13279
13468
 
13280
- const getDropOverlayVirtualDom = isDropOverlayVisible => {
13281
- if (!isDropOverlayVisible) {
13282
- return [];
13283
- }
13284
- return [{
13285
- childCount: 1,
13286
- className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
13287
- name: ComposerDropTarget,
13288
- onDragLeave: HandleDragLeave,
13289
- onDragOver: HandleDragOver,
13290
- onDrop: HandleDrop,
13291
- type: Div
13292
- }, {
13293
- text: attachImageAsContext(),
13294
- type: Text
13295
- }];
13296
- };
13297
13469
  const getChatModeListVirtualDom = ({
13298
13470
  addContextButtonEnabled,
13299
13471
  agentMode,
@@ -13340,7 +13512,8 @@ const getChatModeListVirtualDom = ({
13340
13512
  const isAgentModePickerVisible = hasSpaceForAgentModePicker && agentModePickerOpen;
13341
13513
  const isNewModelPickerVisible = modelPickerOpen;
13342
13514
  const isRunModePickerVisible = showRunMode && hasSpaceForRunModePicker && runModePickerOpen;
13343
- const chatRootChildCount = 3 + (isDropOverlayVisible ? 1 : 0) + (isAgentModePickerVisible ? 1 : 0) + (isNewModelPickerVisible ? 1 : 0) + (isRunModePickerVisible ? 1 : 0);
13515
+ const hasVisibleOverlays = isDropOverlayVisible || isAgentModePickerVisible || isNewModelPickerVisible || isRunModePickerVisible;
13516
+ const chatRootChildCount = 3 + (hasVisibleOverlays ? 1 : 0);
13344
13517
  const searchValueTrimmed = searchValue.trim().toLowerCase();
13345
13518
  const visibleSessions = searchEnabled && searchValueTrimmed ? sessions.filter(session => session.title.toLowerCase().includes(searchValueTrimmed)) : sessions;
13346
13519
  return [{
@@ -13349,7 +13522,17 @@ const getChatModeListVirtualDom = ({
13349
13522
  onDragEnter: HandleDragEnterChatView,
13350
13523
  onDragOver: HandleDragOverChatView,
13351
13524
  type: Div
13352
- }, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, listFocusedIndex, chatListScrollTop), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, false, voiceDictationEnabled), ...getDropOverlayVirtualDom(isDropOverlayVisible), ...(isAgentModePickerVisible ? getAgentModePickerPopOverVirtualDom(agentMode) : []), ...(isNewModelPickerVisible ? getChatModelPickerPopOverVirtualDom(visibleModels, selectedModelId, modelPickerSearchValue) : []), ...(isRunModePickerVisible ? getRunModePickerPopOverVirtualDom(runMode) : [])];
13525
+ }, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, listFocusedIndex, chatListScrollTop), ...getChatSendAreaDom(composerValue, composerAttachments, agentMode, agentModePickerOpen, hasSpaceForAgentModePicker, modelPickerOpen, models, selectedModelId, reasoningPickerEnabled, reasoningEffort, reasoningEffortPickerOpen, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, hasSpaceForRunModePicker, runMode, runModePickerOpen, todoListToolEnabled, todoListItems, false, voiceDictationEnabled), ...getChatOverlaysVirtualDom({
13526
+ agentMode,
13527
+ agentModePickerVisible: isAgentModePickerVisible,
13528
+ dropOverlayVisible: isDropOverlayVisible,
13529
+ modelPickerSearchValue,
13530
+ modelPickerVisible: isNewModelPickerVisible,
13531
+ runMode,
13532
+ runModePickerVisible: isRunModePickerVisible,
13533
+ selectedModelId,
13534
+ visibleModels
13535
+ })];
13353
13536
  };
13354
13537
 
13355
13538
  const getChatModeUnsupportedVirtualDom = () => {
@@ -13909,11 +14092,11 @@ const renderEventListeners = () => {
13909
14092
  params: ['handleSearchValueChange', TargetValue]
13910
14093
  }, {
13911
14094
  name: HandleDragEnter,
13912
- params: ['handleDragEnter', TargetName, 'Array.from(event.dataTransfer?.files || []).length > 0'],
14095
+ params: ['handleDragEnter', TargetName, DataTransferFiles2],
13913
14096
  preventDefault: true
13914
14097
  }, {
13915
14098
  name: HandleDragOver,
13916
- params: ['handleDragOver', TargetName, 'Array.from(event.dataTransfer?.files || []).length > 0'],
14099
+ params: ['handleDragOver', TargetName, DataTransferFiles2],
13917
14100
  preventDefault: true
13918
14101
  }, {
13919
14102
  name: HandleDragLeave,
@@ -13921,15 +14104,15 @@ const renderEventListeners = () => {
13921
14104
  preventDefault: true
13922
14105
  }, {
13923
14106
  name: HandleDrop,
13924
- params: ['handleDropFiles', TargetName, 'Array.from(event.dataTransfer?.files || [])'],
14107
+ params: ['handleDropFiles', TargetName, DataTransferFiles2],
13925
14108
  preventDefault: true
13926
14109
  }, {
13927
14110
  name: HandleDragEnterChatView,
13928
- params: ['handleDragEnter', 'composer-drop-target', 'Array.from(event.dataTransfer?.files || []).length > 0'],
14111
+ params: ['handleDragEnter', 'composer-drop-target', DataTransferFiles2],
13929
14112
  preventDefault: true
13930
14113
  }, {
13931
14114
  name: HandleDragOverChatView,
13932
- params: ['handleDragOver', 'composer-drop-target', 'Array.from(event.dataTransfer?.files || []).length > 0'],
14115
+ params: ['handleDragOver', 'composer-drop-target', DataTransferFiles2],
13933
14116
  preventDefault: true
13934
14117
  }, {
13935
14118
  name: HandleModelChange,
@@ -14017,7 +14200,7 @@ const renderEventListeners = () => {
14017
14200
  params: ['handleModelInputBlur']
14018
14201
  }, {
14019
14202
  name: HandleContextMenuChatImageAttachment,
14020
- params: ['handleContextMenuChatImageAttachment'],
14203
+ params: ['handleContextMenuChatImageAttachment', TargetName, ClientX, ClientY],
14021
14204
  preventDefault: true
14022
14205
  }];
14023
14206
  };
@@ -14418,6 +14601,7 @@ const commandMap = {
14418
14601
  'Chat.openRunModePicker': wrapCommand(openRunModePicker),
14419
14602
  'Chat.pasteInput': wrapCommand(pasteInput),
14420
14603
  'Chat.registerMockResponse': wrapCommand(registerMockResponse),
14604
+ 'Chat.removeComposerAttachment': wrapCommand(removeComposerAttachment),
14421
14605
  'Chat.render2': render2,
14422
14606
  'Chat.renderEventListeners': renderEventListeners,
14423
14607
  'Chat.rerender': wrapCommand(rerender),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-view",
3
- "version": "6.63.0",
3
+ "version": "6.65.0",
4
4
  "description": "Chat View Worker",
5
5
  "repository": {
6
6
  "type": "git",