@lvce-editor/chat-view 6.23.0 → 6.25.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.
@@ -8486,11 +8486,11 @@ const handleMessagesContextMenu = async (state, button, x, y) => {
8486
8486
  return state;
8487
8487
  };
8488
8488
 
8489
- const handleMissingApiKeySubmit = async (state, submitterName = '') => {
8490
- if (!submitterName) {
8491
- return state;
8492
- }
8493
- return handleClick(state, submitterName);
8489
+ const handleMissingOpenAiApiKeyFormSubmit = async state => {
8490
+ return handleClickSaveOpenApiApiKey(state);
8491
+ };
8492
+ const handleMissingOpenRouterApiKeyFormSubmit = async state => {
8493
+ return handleClickSaveOpenRouterApiKey(state);
8494
8494
  };
8495
8495
 
8496
8496
  const handleModelChange = async (state, value) => {
@@ -9268,6 +9268,14 @@ const openMockSession = async (state, mockSessionId, mockChatMessages) => {
9268
9268
  };
9269
9269
  };
9270
9270
 
9271
+ const openModelPicker = state => {
9272
+ return {
9273
+ ...state,
9274
+ modelPickerOpen: !state.modelPickerOpen,
9275
+ modelPickerSearchValue: state.modelPickerOpen ? '' : state.modelPickerSearchValue
9276
+ };
9277
+ };
9278
+
9271
9279
  const pasteInput = async state => {
9272
9280
  const text = await readText();
9273
9281
  return handleInput(state, Composer, text, 'script');
@@ -9308,12 +9316,35 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
9308
9316
  height: ${buttonsHeight}px;
9309
9317
  }
9310
9318
 
9319
+ .ChatInputBox{
9320
+ width: 100%;
9321
+ margin: 0;
9322
+ border: none;
9323
+ outline: none;
9324
+ flex: 1;
9325
+ background: var(--InputBoxBackground);
9326
+ padding: 4px 6px;
9327
+ color: var(--InputBoxForeground);
9328
+ font-size: 13px;
9329
+ height: 24px;
9330
+ contain: strict;
9331
+ resize: none;
9332
+ overflow: hidden;
9333
+ white-space: pre;
9334
+ text-overflow: ellipsis;
9335
+ }
9311
9336
  .ChatSendArea:focus-within{
9312
9337
  border-color: darkcyan;
9313
9338
  }
9314
9339
 
9340
+ .SendButtonDisabled{
9341
+ background: var(--vscode-button-secondaryBackground);
9342
+ color: var(--vscode-disabledForeground);
9343
+ cursor: default;
9344
+ }
9345
+
9315
9346
  .ChatModelPicker{
9316
- border: 1px solid white;
9347
+ border: 1px solid var(--vscode-widget-border, var(--vscode-panel-border));
9317
9348
  }
9318
9349
 
9319
9350
  .ChatListItem{
@@ -9384,6 +9415,63 @@ a.Button{
9384
9415
  text-overflow: ellipsis;
9385
9416
  }
9386
9417
 
9418
+ .ChatModelPickerList{
9419
+ margin:0;
9420
+ scrollbar-width: thin;
9421
+ scrollbar-color: var(--vscode-scrollbarSlider-hoverBackground) var(--vscode-editorWidget-background, var(--vscode-editor-background));
9422
+ }
9423
+
9424
+ .ChatModelPickerList::-webkit-scrollbar{
9425
+ width: 10px;
9426
+ }
9427
+
9428
+ .ChatModelPickerList::-webkit-scrollbar-track{
9429
+ background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
9430
+ }
9431
+
9432
+ .ChatModelPickerList::-webkit-scrollbar-thumb{
9433
+ background: var(--vscode-scrollbarSlider-hoverBackground);
9434
+ border: 2px solid transparent;
9435
+ border-radius: 999px;
9436
+ background-clip: content-box;
9437
+ }
9438
+
9439
+ .ChatModelPickerList::-webkit-scrollbar-thumb:hover{
9440
+ background: var(--vscode-scrollbarSlider-hoverBackground);
9441
+ border: 2px solid transparent;
9442
+ background-clip: content-box;
9443
+ }
9444
+
9445
+ .ChatModelPickerList::-webkit-scrollbar-thumb:active{
9446
+ background: var(--vscode-scrollbarSlider-activeBackground);
9447
+ border: 2px solid transparent;
9448
+ background-clip: content-box;
9449
+ }
9450
+
9451
+ .ChatModelPickerItem{
9452
+ display: block;
9453
+ width: 100%;
9454
+ white-space: nowrap;
9455
+ overflow: hidden;
9456
+ text-overflow: ellipsis;
9457
+ }
9458
+
9459
+ .ChatModelPickerContainer{
9460
+ position: absolute;
9461
+ inset:0;
9462
+ display: flex;
9463
+ flex-direction: column;
9464
+ pointer-events: none;
9465
+ }
9466
+
9467
+ .ChatModelPicker {
9468
+ position: static;
9469
+ background: var(--vscode-editorWidget-background, var(--vscode-editor-background));
9470
+ margin-top: auto;
9471
+ margin-bottom: 90px;
9472
+ pointer-events: auto;
9473
+ }
9474
+
9387
9475
  `;
9388
9476
  return `${baseCss}
9389
9477
 
@@ -9553,7 +9641,8 @@ const ChatUnorderedList = 'ChatUnorderedList';
9553
9641
  const ChatUnorderedListItem = 'ChatUnorderedListItem';
9554
9642
  const MessageUser = 'MessageUser';
9555
9643
  const MessageAssistant = 'MessageAssistant';
9556
- const MultilineInputBox = 'MultilineInputBox';
9644
+ const ChatInputBox = 'ChatInputBox';
9645
+ const MultiLineInputBox = 'MultilineInputBox';
9557
9646
  const Option = 'Option';
9558
9647
  const TokenUsageOverview = 'TokenUsageOverview';
9559
9648
  const TokenUsageRing = 'TokenUsageRing';
@@ -9599,7 +9688,7 @@ const HandleDragEnterChatView = 30;
9599
9688
  const HandleDragOverChatView = 31;
9600
9689
  const HandleProjectListScroll = 32;
9601
9690
  const HandleClickDictationButton = 34;
9602
- const HandleMissingApiKeySubmit = 35;
9691
+ const HandleMissingOpenAiApiKeyFormSubmit = 35;
9603
9692
  const HandleRunModeChange = 36;
9604
9693
  const HandleSearchInput = 37;
9605
9694
  const HandleChatWelcomeContextMenu = 39;
@@ -9608,6 +9697,7 @@ const HandleChatInputContextMenu = 41;
9608
9697
  const HandleContextMenuChatSendAreaBottom = 42;
9609
9698
  const HandleProjectAddButtonContextMenu = 43;
9610
9699
  const HandleProjectListContextMenu = 44;
9700
+ const HandleMissingOpenRouterApiKeyFormSubmit = 45;
9611
9701
 
9612
9702
  const getModelLabel = model => {
9613
9703
  if (model.provider === 'openRouter') {
@@ -9619,13 +9709,11 @@ const getModelLabel = model => {
9619
9709
  return model.name;
9620
9710
  };
9621
9711
 
9622
- const getChatModelPickerVirtualDom = (models, selectedModelId, modelPickerOpen, modelPickerSearchValue) => {
9712
+ const getChatModelPickerToggleVirtualDom = (models, selectedModelId, modelPickerOpen) => {
9623
9713
  const selectedModel = models.find(model => model.id === selectedModelId);
9624
9714
  const selectedModelLabel = selectedModel ? selectedModel.name : selectedModelId;
9625
- const normalizedSearch = modelPickerSearchValue.trim().toLowerCase();
9626
- const visibleModels = normalizedSearch ? models.filter(model => getModelLabel(model).toLowerCase().includes(normalizedSearch)) : models;
9627
9715
  return [{
9628
- childCount: modelPickerOpen ? 2 : 1,
9716
+ childCount: 1,
9629
9717
  className: ChatModelPickerContainer,
9630
9718
  type: Div
9631
9719
  }, {
@@ -9636,10 +9724,24 @@ const getChatModelPickerVirtualDom = (models, selectedModelId, modelPickerOpen,
9636
9724
  title: selectedModelLabel,
9637
9725
  type: Button$1
9638
9726
  }, {
9727
+ childCount: 1,
9728
+ type: Span
9729
+ }, text(selectedModelLabel), {
9639
9730
  childCount: 0,
9640
- className: 'MaskIcon MaskIconChevronUp',
9731
+ className: modelPickerOpen ? 'MaskIcon MaskIconChevronUp' : 'MaskIcon MaskIconChevronDown',
9732
+ role: 'none',
9733
+ type: Div
9734
+ }];
9735
+ };
9736
+ const getChatModelPickerPopOverVirtualDom = (models, selectedModelId, modelPickerSearchValue) => {
9737
+ const normalizedSearch = modelPickerSearchValue.trim().toLowerCase();
9738
+ const visibleModels = normalizedSearch ? models.filter(model => getModelLabel(model).toLowerCase().includes(normalizedSearch)) : models;
9739
+ return [{
9740
+ childCount: 2,
9741
+ className: ChatModelPickerContainer,
9742
+ style: 'position:absolute;',
9641
9743
  type: Div
9642
- }, text(selectedModelLabel), ...(modelPickerOpen ? [{
9744
+ }, {
9643
9745
  childCount: 3 + visibleModels.length,
9644
9746
  className: ChatModelPicker,
9645
9747
  type: Div
@@ -9677,7 +9779,7 @@ const getChatModelPickerVirtualDom = (models, selectedModelId, modelPickerOpen,
9677
9779
  name: getModelPickerItemInputName(model.id),
9678
9780
  onClick: HandleClick,
9679
9781
  type: Li
9680
- }, text(getModelLabel(model))])] : [])];
9782
+ }, text(getModelLabel(model))])];
9681
9783
  };
9682
9784
 
9683
9785
  const getModelOptionDOm = (model, selectedModelId) => {
@@ -9783,6 +9885,16 @@ const getBackToChatsButtonDom = () => {
9783
9885
  }];
9784
9886
  };
9785
9887
 
9888
+ const getTodoItemClassName = status => {
9889
+ if (status === 'completed') {
9890
+ return `${ChatTodoListItem} ${ChatTodoListItemCompleted} completed`;
9891
+ }
9892
+ if (status === 'inProgress') {
9893
+ return `${ChatTodoListItem} ${ChatTodoListItemInProgress} inProgress`;
9894
+ }
9895
+ return `${ChatTodoListItem} ${ChatTodoListItemTodo} todo`;
9896
+ };
9897
+
9786
9898
  const clampToPercentage = (tokensUsed, tokensMax) => {
9787
9899
  if (tokensMax <= 0) {
9788
9900
  return 0;
@@ -9818,15 +9930,6 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
9818
9930
  }, text(usageLabel)];
9819
9931
  };
9820
9932
 
9821
- const getTodoItemClassName = status => {
9822
- if (status === 'completed') {
9823
- return `${ChatTodoListItem} ${ChatTodoListItemCompleted} completed`;
9824
- }
9825
- if (status === 'inProgress') {
9826
- return `${ChatTodoListItem} ${ChatTodoListItemInProgress} inProgress`;
9827
- }
9828
- return `${ChatTodoListItem} ${ChatTodoListItemTodo} todo`;
9829
- };
9830
9933
  const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled = false) => {
9831
9934
  const isSendDisabled = composerValue.trim() === '';
9832
9935
  const controlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (showRunMode ? 1 : 0) + (addContextButtonEnabled ? 1 : 0);
@@ -9861,7 +9964,7 @@ const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchVal
9861
9964
  type: Li
9862
9965
  }, text(item.text)])] : []), {
9863
9966
  childCount: 0,
9864
- className: MultilineInputBox,
9967
+ className: mergeClassNames(MultiLineInputBox, ChatInputBox),
9865
9968
  name: Composer,
9866
9969
  onContextMenu: HandleChatInputContextMenu,
9867
9970
  onFocus: HandleFocus,
@@ -9874,7 +9977,7 @@ const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchVal
9874
9977
  className: ChatSendAreaBottom,
9875
9978
  onContextMenu: HandleContextMenuChatSendAreaBottom,
9876
9979
  type: Div
9877
- }, ...(newChatModelPickerEnabled ? getChatModelPickerVirtualDom(models, selectedModelId, modelPickerOpen, modelPickerSearchValue) : getChatSelectVirtualDom(models, selectedModelId)), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
9980
+ }, ...(newChatModelPickerEnabled ? getChatModelPickerToggleVirtualDom(models, selectedModelId, modelPickerOpen) : getChatSelectVirtualDom(models, selectedModelId)), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
9878
9981
  };
9879
9982
 
9880
9983
  const getBoldInlineNodeDom = (inlineNode, useChatMathWorker, renderInlineNodeDom) => {
@@ -10345,6 +10448,7 @@ const getMissingApiKeyDom = ({
10345
10448
  inputName,
10346
10449
  inputPattern,
10347
10450
  inputRequired = false,
10451
+ onSubmit,
10348
10452
  openSettingsButtonName,
10349
10453
  openSettingsUrl,
10350
10454
  placeholder,
@@ -10356,7 +10460,7 @@ const getMissingApiKeyDom = ({
10356
10460
  childCount: 2,
10357
10461
  className: MissingApiKeyForm,
10358
10462
  method: 'GET',
10359
- onSubmit: HandleMissingApiKeySubmit,
10463
+ onSubmit,
10360
10464
  type: Form
10361
10465
  }, {
10362
10466
  autocapitalize: 'off',
@@ -10389,6 +10493,7 @@ const getMissingOpenApiApiKeyDom = () => {
10389
10493
  inputName: OpenApiApiKeyInput,
10390
10494
  inputPattern: '^sk-.+',
10391
10495
  inputRequired: true,
10496
+ onSubmit: HandleMissingOpenAiApiKeyFormSubmit,
10392
10497
  openSettingsButtonName: OpenOpenApiApiKeyWebsite,
10393
10498
  openSettingsUrl: 'https://platform.openai.com/api-keys',
10394
10499
  placeholder: openApiApiKeyPlaceholder(),
@@ -10401,6 +10506,7 @@ const getMissingOpenRouterApiKeyDom = (openRouterApiKeyState = 'idle') => {
10401
10506
  return getMissingApiKeyDom({
10402
10507
  getApiKeyText: getOpenRouterApiKey(),
10403
10508
  inputName: OpenRouterApiKeyInput,
10509
+ onSubmit: HandleMissingOpenRouterApiKeyFormSubmit,
10404
10510
  openSettingsButtonName: OpenOpenRouterApiKeySettings,
10405
10511
  openSettingsUrl: 'https://openrouter.ai/settings/keys',
10406
10512
  placeholder: openRouterApiKeyPlaceholder(),
@@ -11404,8 +11510,10 @@ const getChatModeChatFocusVirtualDom = ({
11404
11510
  const selectedSession = sessions.find(session => session.id === selectedSessionId);
11405
11511
  const messages = selectedSession ? selectedSession.messages : [];
11406
11512
  const isDropOverlayVisible = composerDropEnabled && composerDropActive;
11513
+ const isNewModelPickerVisible = newChatModelPickerEnabled && modelPickerOpen;
11514
+ const chatRootChildCount = 3 + (isDropOverlayVisible ? 1 : 0) + (isNewModelPickerVisible ? 1 : 0);
11407
11515
  return [{
11408
- childCount: isDropOverlayVisible ? 4 : 3,
11516
+ childCount: chatRootChildCount,
11409
11517
  className: mergeClassNames(Viewlet, Chat, 'ChatFocus'),
11410
11518
  onDragEnter: HandleDragEnterChatView,
11411
11519
  onDragOver: HandleDragOverChatView,
@@ -11421,7 +11529,7 @@ const getChatModeChatFocusVirtualDom = ({
11421
11529
  }, {
11422
11530
  text: attachImageAsContext(),
11423
11531
  type: Text
11424
- }] : [])];
11532
+ }] : []), ...(isNewModelPickerVisible ? getChatModelPickerPopOverVirtualDom(models, selectedModelId, modelPickerSearchValue) : [])];
11425
11533
  };
11426
11534
 
11427
11535
  const getBackButtonVirtualDom = () => {
@@ -11571,8 +11679,10 @@ const getChatModeDetailVirtualDom = ({
11571
11679
  const selectedSessionTitle = selectedSession?.title || chatTitle();
11572
11680
  const messages = selectedSession ? selectedSession.messages : [];
11573
11681
  const isDropOverlayVisible = composerDropEnabled && composerDropActive;
11682
+ const isNewModelPickerVisible = newChatModelPickerEnabled && modelPickerOpen;
11683
+ const chatRootChildCount = 3 + (isDropOverlayVisible ? 1 : 0) + (isNewModelPickerVisible ? 1 : 0);
11574
11684
  return [{
11575
- childCount: isDropOverlayVisible ? 4 : 3,
11685
+ childCount: chatRootChildCount,
11576
11686
  className: mergeClassNames(Viewlet, Chat),
11577
11687
  onDragEnter: HandleDragEnterChatView,
11578
11688
  onDragOver: HandleDragOverChatView,
@@ -11588,7 +11698,7 @@ const getChatModeDetailVirtualDom = ({
11588
11698
  }, {
11589
11699
  text: attachImageAsContext(),
11590
11700
  type: Text
11591
- }] : [])];
11701
+ }] : []), ...(isNewModelPickerVisible ? getChatModelPickerPopOverVirtualDom(models, selectedModelId, modelPickerSearchValue) : [])];
11592
11702
  };
11593
11703
 
11594
11704
  const getChatHeaderListModeDom = (authEnabled = false, authStatus = 'signed-out', authErrorMessage = '', searchEnabled = false, searchFieldVisible = false, searchValue = '') => {
@@ -11742,10 +11852,12 @@ const getChatModeListVirtualDom = ({
11742
11852
  voiceDictationEnabled = false
11743
11853
  }) => {
11744
11854
  const isDropOverlayVisible = composerDropEnabled && composerDropActive;
11855
+ const isNewModelPickerVisible = newChatModelPickerEnabled && modelPickerOpen;
11856
+ const chatRootChildCount = 3 + (isDropOverlayVisible ? 1 : 0) + (isNewModelPickerVisible ? 1 : 0);
11745
11857
  const searchValueTrimmed = searchValue.trim().toLowerCase();
11746
11858
  const visibleSessions = searchEnabled && searchValueTrimmed ? sessions.filter(session => session.title.toLowerCase().includes(searchValueTrimmed)) : sessions;
11747
11859
  return [{
11748
- childCount: isDropOverlayVisible ? 4 : 3,
11860
+ childCount: chatRootChildCount,
11749
11861
  className: mergeClassNames(Viewlet, Chat),
11750
11862
  onDragEnter: HandleDragEnterChatView,
11751
11863
  onDragOver: HandleDragOverChatView,
@@ -11761,7 +11873,7 @@ const getChatModeListVirtualDom = ({
11761
11873
  }, {
11762
11874
  text: attachImageAsContext(),
11763
11875
  type: Text
11764
- }] : [])];
11876
+ }] : []), ...(isNewModelPickerVisible ? getChatModelPickerPopOverVirtualDom(models, selectedModelId, modelPickerSearchValue) : [])];
11765
11877
  };
11766
11878
 
11767
11879
  const getChatModeUnsupportedVirtualDom = () => {
@@ -12355,8 +12467,12 @@ const renderEventListeners = () => {
12355
12467
  params: ['handleSubmit'],
12356
12468
  preventDefault: true
12357
12469
  }, {
12358
- name: HandleMissingApiKeySubmit,
12359
- params: ['handleMissingApiKeySubmit', 'event.submitter?.name || ""'],
12470
+ name: HandleMissingOpenAiApiKeyFormSubmit,
12471
+ params: ['handleMissingOpenAiApiKeyFormSubmit'],
12472
+ preventDefault: true
12473
+ }, {
12474
+ name: HandleMissingOpenRouterApiKeyFormSubmit,
12475
+ params: ['handleMissingOpenRouterApiKeyFormSubmit'],
12360
12476
  preventDefault: true
12361
12477
  }];
12362
12478
  };
@@ -12644,7 +12760,8 @@ const commandMap = {
12644
12760
  'Chat.handleKeyDown': wrapCommand(handleKeyDown),
12645
12761
  'Chat.handleMessagesContextMenu': wrapCommand(handleMessagesContextMenu),
12646
12762
  'Chat.handleMessagesScroll': wrapCommand(handleMessagesScroll),
12647
- 'Chat.handleMissingApiKeySubmit': wrapCommand(handleMissingApiKeySubmit),
12763
+ 'Chat.handleMissingOpenAiApiKeyFormSubmit': wrapCommand(handleMissingOpenAiApiKeyFormSubmit),
12764
+ 'Chat.handleMissingOpenRouterApiKeyFormSubmit': wrapCommand(handleMissingOpenRouterApiKeyFormSubmit),
12648
12765
  'Chat.handleModelChange': wrapCommand(handleModelChange),
12649
12766
  'Chat.handleProjectAddButtonContextMenu': wrapCommand(handleProjectAddButtonContextMenu),
12650
12767
  'Chat.handleProjectListContextMenu': wrapCommand(handleProjectListContextMenu),
@@ -12664,6 +12781,7 @@ const commandMap = {
12664
12781
  'Chat.mockOpenApiStreamPushChunk': wrapCommand(mockOpenApiStreamPushChunk),
12665
12782
  'Chat.mockOpenApiStreamReset': wrapCommand(mockOpenApiStreamReset),
12666
12783
  'Chat.openMockSession': wrapCommand(openMockSession),
12784
+ 'Chat.openModelPicker': wrapCommand(openModelPicker),
12667
12785
  'Chat.pasteInput': wrapCommand(pasteInput),
12668
12786
  'Chat.registerMockResponse': wrapCommand(registerMockResponse),
12669
12787
  'Chat.render2': render2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-view",
3
- "version": "6.23.0",
3
+ "version": "6.25.0",
4
4
  "description": "Chat View Worker",
5
5
  "repository": {
6
6
  "type": "git",