@lvce-editor/chat-view 6.15.0 → 6.17.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.
@@ -1702,7 +1702,10 @@ const createDefaultState = () => {
1702
1702
  messagesScrollTop: 0,
1703
1703
  mockAiResponseDelay: 800,
1704
1704
  mockApiCommandId: '',
1705
+ modelPickerOpen: false,
1706
+ modelPickerSearchValue: '',
1705
1707
  models: getDefaultModels(),
1708
+ newChatModelPickerEnabled: false,
1706
1709
  nextMessageId: 1,
1707
1710
  openApiApiBaseUrl: 'https://api.openai.com/v1',
1708
1711
  openApiApiKey: '',
@@ -2560,7 +2563,7 @@ const isEqualProjectExpandedIds = (a, b) => {
2560
2563
  return true;
2561
2564
  };
2562
2565
  const isEqual = (oldState, newState) => {
2563
- return oldState.addContextButtonEnabled === newState.addContextButtonEnabled && oldState.authEnabled === newState.authEnabled && oldState.authErrorMessage === newState.authErrorMessage && oldState.authStatus === newState.authStatus && oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.initial === newState.initial && isEqualProjectExpandedIds(oldState.projectExpandedIds, newState.projectExpandedIds) && oldState.projectListScrollTop === newState.projectListScrollTop && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedProjectId === newState.selectedProjectId && oldState.selectedSessionId === newState.selectedSessionId && oldState.showRunMode === newState.showRunMode && oldState.runMode === newState.runMode && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.useChatMathWorker === newState.useChatMathWorker && oldState.viewMode === newState.viewMode && oldState.voiceDictationEnabled === newState.voiceDictationEnabled;
2566
+ return oldState.addContextButtonEnabled === newState.addContextButtonEnabled && oldState.authEnabled === newState.authEnabled && oldState.authErrorMessage === newState.authErrorMessage && oldState.authStatus === newState.authStatus && oldState.composerDropActive === newState.composerDropActive && oldState.composerDropEnabled === newState.composerDropEnabled && oldState.composerValue === newState.composerValue && oldState.initial === newState.initial && oldState.modelPickerOpen === newState.modelPickerOpen && oldState.modelPickerSearchValue === newState.modelPickerSearchValue && oldState.newChatModelPickerEnabled === newState.newChatModelPickerEnabled && isEqualProjectExpandedIds(oldState.projectExpandedIds, newState.projectExpandedIds) && oldState.projectListScrollTop === newState.projectListScrollTop && oldState.renamingSessionId === newState.renamingSessionId && oldState.selectedModelId === newState.selectedModelId && oldState.selectedProjectId === newState.selectedProjectId && oldState.selectedSessionId === newState.selectedSessionId && oldState.showRunMode === newState.showRunMode && oldState.runMode === newState.runMode && oldState.sessions === newState.sessions && oldState.tokensMax === newState.tokensMax && oldState.tokensUsed === newState.tokensUsed && oldState.usageOverviewEnabled === newState.usageOverviewEnabled && oldState.useChatMathWorker === newState.useChatMathWorker && oldState.viewMode === newState.viewMode && oldState.voiceDictationEnabled === newState.voiceDictationEnabled;
2564
2567
  };
2565
2568
 
2566
2569
  const diffScrollTop = (oldState, newState) => {
@@ -7688,6 +7691,9 @@ const Dictate = 'dictate';
7688
7691
  const Send = 'send';
7689
7692
  const Back = 'back';
7690
7693
  const Model = 'model';
7694
+ const ModelPickerToggle = 'model-picker-toggle';
7695
+ const ModelPickerSearch = 'model-picker-search';
7696
+ const ModelPickerSettings = 'model-picker-settings';
7691
7697
  const RunMode = 'runMode';
7692
7698
  const ToggleChatFocus = 'toggle-chat-focus';
7693
7699
  const ToggleSearch = 'toggle-search';
@@ -7703,6 +7709,7 @@ const SessionDelete = 'SessionDelete';
7703
7709
  const ProjectPrefix = 'project:';
7704
7710
  const SessionPrefix = 'session:';
7705
7711
  const RenamePrefix = 'session-rename:';
7712
+ const ModelPickerItemPrefix = 'model-picker-item:';
7706
7713
  const getProjectInputName = projectId => {
7707
7714
  return `${ProjectPrefix}${projectId}`;
7708
7715
  };
@@ -7736,6 +7743,15 @@ const isRenameInputName = name => {
7736
7743
  const getRenameIdFromInputName = name => {
7737
7744
  return name.slice(RenamePrefix.length);
7738
7745
  };
7746
+ const getModelPickerItemInputName = modelId => {
7747
+ return `${ModelPickerItemPrefix}${modelId}`;
7748
+ };
7749
+ const isModelPickerItemInputName = name => {
7750
+ return name.startsWith(ModelPickerItemPrefix);
7751
+ };
7752
+ const getModelIdFromModelPickerItemInputName = name => {
7753
+ return name.slice(ModelPickerItemPrefix.length);
7754
+ };
7739
7755
 
7740
7756
  const OpenApiApiKeyInput = 'open-api-api-key';
7741
7757
  const SaveOpenApiApiKey = 'save-openapi-api-key';
@@ -7875,6 +7891,22 @@ const handleClick = async (state, name, id = '') => {
7875
7891
  searchFieldVisible: !state.searchFieldVisible,
7876
7892
  searchValue: state.searchFieldVisible ? '' : state.searchValue
7877
7893
  };
7894
+ case name === ModelPickerToggle:
7895
+ return {
7896
+ ...state,
7897
+ modelPickerOpen: !state.modelPickerOpen,
7898
+ modelPickerSearchValue: state.modelPickerOpen ? '' : state.modelPickerSearchValue
7899
+ };
7900
+ case isModelPickerItemInputName(name):
7901
+ {
7902
+ const modelId = getModelIdFromModelPickerItemInputName(name);
7903
+ return {
7904
+ ...state,
7905
+ modelPickerOpen: false,
7906
+ modelPickerSearchValue: '',
7907
+ selectedModelId: modelId
7908
+ };
7909
+ }
7878
7910
  case isProjectInputName(name):
7879
7911
  {
7880
7912
  const projectId = getProjectIdFromInputName(name);
@@ -7940,19 +7972,13 @@ const handleClickDictationButton = async state => {
7940
7972
  return state;
7941
7973
  };
7942
7974
 
7943
- const handleClickNew = async state => {
7944
- const newState = await createSession(state);
7945
- const clearedState = await clearInput(newState);
7946
- return focusInput(clearedState);
7947
- };
7948
-
7949
7975
  const normalizeFileReferenceUri = uri => {
7950
7976
  if (uri.startsWith('vscode-references://')) {
7951
7977
  return `file://${uri.slice('vscode-references://'.length)}`;
7952
7978
  }
7953
7979
  return uri;
7954
7980
  };
7955
- const handleClickReadFile = async uri => {
7981
+ const handleClickFileName = async uri => {
7956
7982
  if (!uri) {
7957
7983
  return;
7958
7984
  }
@@ -7960,6 +7986,12 @@ const handleClickReadFile = async uri => {
7960
7986
  await invoke$1('Main.openUri', normalizedUri);
7961
7987
  };
7962
7988
 
7989
+ const handleClickNew = async state => {
7990
+ const newState = await createSession(state);
7991
+ const clearedState = await clearInput(newState);
7992
+ return focusInput(clearedState);
7993
+ };
7994
+
7963
7995
  const handleClickSessionDebug = async state => {
7964
7996
  await invoke$1('Main.openUri', `chat-debug://${state.selectedSessionId}`);
7965
7997
  return state;
@@ -8078,6 +8110,12 @@ const handleInput = async (state, name, value, inputSource = 'user') => {
8078
8110
  if (name === Search) {
8079
8111
  return handleSearchValueChange(state, value);
8080
8112
  }
8113
+ if (name === ModelPickerSearch) {
8114
+ return {
8115
+ ...state,
8116
+ modelPickerSearchValue: value
8117
+ };
8118
+ }
8081
8119
  if (name !== Composer) {
8082
8120
  return state;
8083
8121
  }
@@ -8208,6 +8246,8 @@ const handleMissingApiKeySubmit = async (state, submitterName = '') => {
8208
8246
  const handleModelChange = async (state, value) => {
8209
8247
  return {
8210
8248
  ...state,
8249
+ modelPickerOpen: false,
8250
+ modelPickerSearchValue: '',
8211
8251
  selectedModelId: value
8212
8252
  };
8213
8253
  };
@@ -8779,6 +8819,9 @@ const loadContent = async (state, savedState) => {
8779
8819
  initial: false,
8780
8820
  lastNormalViewMode,
8781
8821
  messagesScrollTop,
8822
+ modelPickerOpen: false,
8823
+ modelPickerSearchValue: '',
8824
+ newChatModelPickerEnabled: state.newChatModelPickerEnabled,
8782
8825
  openApiApiKey,
8783
8826
  openApiApiKeyInput: openApiApiKey,
8784
8827
  openRouterApiKey,
@@ -8914,7 +8957,10 @@ const registerMockResponse = (state, mockResponse) => {
8914
8957
  };
8915
8958
 
8916
8959
  const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessageLineHeight, chatMessageFontFamily, textAreaPaddingTop, textAreaPaddingLeft, textAreaPaddingRight, textAreaPaddingBottom, chatSendAreaPaddingTop, chatSendAreaPaddingLeft, chatSendAreaPaddingRight, chatSendAreaPaddingBottom, renderHtmlCss) => {
8917
- const chatSendAreaHeight = composerHeight + chatSendAreaPaddingTop + chatSendAreaPaddingBottom;
8960
+ const buttonsHeight = 20;
8961
+ const gap = 10;
8962
+ const contentPadding = 10;
8963
+ const chatSendAreaHeight = composerHeight + chatSendAreaPaddingTop + chatSendAreaPaddingBottom + buttonsHeight + gap + contentPadding * 2;
8918
8964
  const baseCss = `:root {
8919
8965
  --ChatInputBoxHeight: ${composerHeight}px;
8920
8966
  --ChatTextAreaHeight: ${composerHeight}px;
@@ -8931,168 +8977,14 @@ const getCss = (composerHeight, listItemHeight, chatMessageFontSize, chatMessage
8931
8977
  --ChatMessageFontSize: ${chatMessageFontSize}px;
8932
8978
  --ChatMessageLineHeight: ${chatMessageLineHeight}px;
8933
8979
  --ChatMessageFontFamily: ${chatMessageFontFamily};
8934
- }`;
8935
- if (!renderHtmlCss.trim()) {
8936
- return `${baseCss}
8937
-
8938
- .ChatTodoList {
8939
- background: var(--vscode-editorWidget-background);
8940
- border: 1px solid var(--vscode-editorWidget-border);
8941
- border-radius: 6px;
8942
- margin-bottom: 8px;
8943
- overflow: hidden;
8944
- }
8945
-
8946
- .ChatTodoListHeader {
8947
- border-bottom: 1px solid var(--vscode-editorWidget-border);
8948
- color: var(--vscode-descriptionForeground);
8949
- font-size: 12px;
8950
- line-height: 18px;
8951
- padding: 6px 10px;
8952
- }
8953
-
8954
- .ChatTodoListItems {
8955
- list-style: none;
8956
- margin: 0;
8957
- max-height: 180px;
8958
- overflow: auto;
8959
- padding: 4px 0;
8960
- }
8961
-
8962
- .ChatTodoListItem {
8963
- align-items: center;
8964
- color: var(--vscode-foreground);
8965
- display: flex;
8966
- font-size: 12px;
8967
- line-height: 18px;
8968
- min-height: 24px;
8969
- padding: 0 10px;
8970
- }
8971
-
8972
- .ChatTodoListItem::before {
8973
- color: var(--vscode-descriptionForeground);
8974
- content: "○";
8975
- display: inline-block;
8976
- margin-right: 8px;
8977
- width: 1em;
8978
8980
  }
8979
8981
 
8980
- .ChatTodoListItemTodo::before {
8981
- content: "○";
8982
+ .ChatSendAreaBottom{
8983
+ height: ${buttonsHeight}px;
8982
8984
  }
8983
-
8984
- .ChatTodoListItem.todo::before {
8985
- content: "○";
8986
- }
8987
-
8988
- .ChatTodoListItemInProgress::before {
8989
- color: var(--vscode-textLink-foreground);
8990
- content: "◐";
8991
- }
8992
-
8993
- .ChatTodoListItem.inProgress::before {
8994
- color: var(--vscode-textLink-foreground);
8995
- content: "◐";
8996
- }
8997
-
8998
- .ChatTodoListItemCompleted {
8999
- color: var(--vscode-disabledForeground);
9000
- }
9001
-
9002
- .ChatTodoListItem.completed {
9003
- color: var(--vscode-disabledForeground);
9004
- }
9005
-
9006
- .ChatTodoListItemCompleted::before {
9007
- color: var(--vscode-testing-iconPassed);
9008
- content: "✓";
9009
- }
9010
-
9011
- .ChatTodoListItem.completed::before {
9012
- color: var(--vscode-testing-iconPassed);
9013
- content: "✓";
9014
- }`;
9015
- }
8985
+ `;
9016
8986
  return `${baseCss}
9017
8987
 
9018
- .ChatTodoList {
9019
- background: var(--vscode-editorWidget-background);
9020
- border: 1px solid var(--vscode-editorWidget-border);
9021
- border-radius: 6px;
9022
- margin-bottom: 8px;
9023
- overflow: hidden;
9024
- }
9025
-
9026
- .ChatTodoListHeader {
9027
- border-bottom: 1px solid var(--vscode-editorWidget-border);
9028
- color: var(--vscode-descriptionForeground);
9029
- font-size: 12px;
9030
- line-height: 18px;
9031
- padding: 6px 10px;
9032
- }
9033
-
9034
- .ChatTodoListItems {
9035
- list-style: none;
9036
- margin: 0;
9037
- max-height: 180px;
9038
- overflow: auto;
9039
- padding: 4px 0;
9040
- }
9041
-
9042
- .ChatTodoListItem {
9043
- align-items: center;
9044
- color: var(--vscode-foreground);
9045
- display: flex;
9046
- font-size: 12px;
9047
- line-height: 18px;
9048
- min-height: 24px;
9049
- padding: 0 10px;
9050
- }
9051
-
9052
- .ChatTodoListItem::before {
9053
- color: var(--vscode-descriptionForeground);
9054
- content: "○";
9055
- display: inline-block;
9056
- margin-right: 8px;
9057
- width: 1em;
9058
- }
9059
-
9060
- .ChatTodoListItemTodo::before {
9061
- content: "○";
9062
- }
9063
-
9064
- .ChatTodoListItem.todo::before {
9065
- content: "○";
9066
- }
9067
-
9068
- .ChatTodoListItemInProgress::before {
9069
- color: var(--vscode-textLink-foreground);
9070
- content: "◐";
9071
- }
9072
-
9073
- .ChatTodoListItem.inProgress::before {
9074
- color: var(--vscode-textLink-foreground);
9075
- content: "◐";
9076
- }
9077
-
9078
- .ChatTodoListItemCompleted {
9079
- color: var(--vscode-disabledForeground);
9080
- }
9081
-
9082
- .ChatTodoListItem.completed {
9083
- color: var(--vscode-disabledForeground);
9084
- }
9085
-
9086
- .ChatTodoListItemCompleted::before {
9087
- color: var(--vscode-testing-iconPassed);
9088
- content: "✓";
9089
- }
9090
-
9091
- .ChatTodoListItem.completed::before {
9092
- color: var(--vscode-testing-iconPassed);
9093
- content: "✓";
9094
- }
9095
-
9096
8988
  /* render_html tool css */
9097
8989
  ${renderHtmlCss}`;
9098
8990
  };
@@ -9157,6 +9049,12 @@ const ChatViewDropOverlay = 'ChatViewDropOverlay';
9157
9049
  const ChatViewDropOverlayActive = 'ChatViewDropOverlayActive';
9158
9050
  const SendButtonDisabled = 'SendButtonDisabled';
9159
9051
  const ChatSendAreaBottom = 'ChatSendAreaBottom';
9052
+ const ChatModelPickerContainer = 'ChatModelPickerContainer';
9053
+ const ChatModelPicker = 'ChatModelPicker';
9054
+ const ChatModelPickerHeader = 'ChatModelPickerHeader';
9055
+ const ChatModelPickerList = 'ChatModelPickerList';
9056
+ const ChatModelPickerItem = 'ChatModelPickerItem';
9057
+ const ChatModelPickerItemSelected = 'ChatModelPickerItemSelected';
9160
9058
  const ChatSendAreaContent = 'ChatSendAreaContent';
9161
9059
  const ChatTodoList = 'ChatTodoList';
9162
9060
  const ChatTodoListHeader = 'ChatTodoListHeader';
@@ -9201,6 +9099,7 @@ const Markdown = 'Markdown';
9201
9099
  const MarkdownQuote = 'MarkdownQuote';
9202
9100
  const MarkdownMathBlock = 'MarkdownMathBlock';
9203
9101
  const MarkdownTable = 'MarkdownTable';
9102
+ const ChatTableWrapper = 'ChatTableWrapper';
9204
9103
  const Message = 'Message';
9205
9104
  const ChatMessageContent = 'ChatMessageContent';
9206
9105
  const ChatToolCalls = 'ChatToolCalls';
@@ -9256,6 +9155,7 @@ const HandleChatListScroll = 21;
9256
9155
  const HandleMessagesScroll = 22;
9257
9156
  const HandleClickSessionDebug = 23;
9258
9157
  const HandleClickReadFile = 24;
9158
+ const HandleClickFileName = 38;
9259
9159
  const HandleMessagesContextMenu = 25;
9260
9160
  const HandleDragEnter = 26;
9261
9161
  const HandleDragOver = 27;
@@ -9280,6 +9180,66 @@ const getModelLabel = model => {
9280
9180
  return model.name;
9281
9181
  };
9282
9182
 
9183
+ const getChatModelPickerVirtualDom = (models, selectedModelId, modelPickerOpen, modelPickerSearchValue) => {
9184
+ const selectedModel = models.find(model => model.id === selectedModelId);
9185
+ const selectedModelLabel = selectedModel ? selectedModel.name : selectedModelId;
9186
+ const normalizedSearch = modelPickerSearchValue.trim().toLowerCase();
9187
+ const visibleModels = normalizedSearch ? models.filter(model => getModelLabel(model).toLowerCase().includes(normalizedSearch)) : models;
9188
+ return [{
9189
+ childCount: modelPickerOpen ? 2 : 1,
9190
+ className: ChatModelPickerContainer,
9191
+ type: Div
9192
+ }, {
9193
+ childCount: 2,
9194
+ className: Select,
9195
+ name: ModelPickerToggle,
9196
+ onClick: HandleClick,
9197
+ title: selectedModelLabel,
9198
+ type: Button$1
9199
+ }, {
9200
+ childCount: 0,
9201
+ className: 'MaskIcon MaskIconChevronUp',
9202
+ type: Div
9203
+ }, text(selectedModelLabel), ...(modelPickerOpen ? [{
9204
+ childCount: 3 + visibleModels.length,
9205
+ className: ChatModelPicker,
9206
+ type: Div
9207
+ }, {
9208
+ childCount: 2,
9209
+ className: ChatModelPickerHeader,
9210
+ type: Div
9211
+ }, {
9212
+ childCount: 0,
9213
+ className: InputBox,
9214
+ name: ModelPickerSearch,
9215
+ onInput: HandleInput,
9216
+ placeholder: 'Search models',
9217
+ type: Input,
9218
+ value: modelPickerSearchValue
9219
+ }, {
9220
+ childCount: 1,
9221
+ className: IconButton,
9222
+ name: ModelPickerSettings,
9223
+ onClick: HandleClick,
9224
+ title: 'Settings',
9225
+ type: Button$1
9226
+ }, {
9227
+ childCount: 0,
9228
+ className: 'MaskIcon MaskIconSettingsGear',
9229
+ type: Div
9230
+ }, {
9231
+ childCount: visibleModels.length,
9232
+ className: ChatModelPickerList,
9233
+ type: Div
9234
+ }, ...visibleModels.flatMap(model => [{
9235
+ childCount: 1,
9236
+ className: `${ChatModelPickerItem}${model.id === selectedModelId ? ` ${ChatModelPickerItemSelected}` : ''}`,
9237
+ name: getModelPickerItemInputName(model.id),
9238
+ onClick: HandleClick,
9239
+ type: Button$1
9240
+ }, text(getModelLabel(model))])] : [])];
9241
+ };
9242
+
9283
9243
  const getModelOptionDOm = (model, selectedModelId) => {
9284
9244
  return [{
9285
9245
  childCount: 1,
@@ -9403,7 +9363,7 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
9403
9363
  }, text(usageLabel)];
9404
9364
  };
9405
9365
 
9406
- const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled = false) => {
9366
+ const getChatSendAreaDom = (composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled = false) => {
9407
9367
  const isSendDisabled = composerValue.trim() === '';
9408
9368
  const controlsCount = 2 + (usageOverviewEnabled ? 1 : 0) + (showRunMode ? 1 : 0) + (addContextButtonEnabled ? 1 : 0);
9409
9369
  const hasTodoList = todoListToolEnabled && todoListItems.length > 0;
@@ -9457,7 +9417,7 @@ const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOvervie
9457
9417
  childCount: voiceDictationEnabled ? controlsCount + 1 : controlsCount,
9458
9418
  className: ChatSendAreaBottom,
9459
9419
  type: Div
9460
- }, ...getChatSelectVirtualDom(models, selectedModelId), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
9420
+ }, ...(newChatModelPickerEnabled ? getChatModelPickerVirtualDom(models, selectedModelId, modelPickerOpen, modelPickerSearchValue) : getChatSelectVirtualDom(models, selectedModelId)), ...(showRunMode ? getRunModeSelectVirtualDom(runMode) : []), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...(addContextButtonEnabled ? getAddContextButtonDom() : []), ...getSendButtonDom(isSendDisabled, voiceDictationEnabled)];
9461
9421
  };
9462
9422
 
9463
9423
  const getImageAltText = alt => {
@@ -9694,6 +9654,9 @@ const highlightCode = (code, language) => {
9694
9654
  }];
9695
9655
  };
9696
9656
 
9657
+ const hasVisibleInlineContent = children => {
9658
+ return children.some(child => child.type !== 'text' || child.text.trim() !== '');
9659
+ };
9697
9660
  const getTokenDom = token => {
9698
9661
  if (!token.className) {
9699
9662
  return [text(token.text)];
@@ -9755,6 +9718,11 @@ const getTableRowDom = (row, useChatMathWorker) => {
9755
9718
  };
9756
9719
  const getTableDom = (node, useChatMathWorker) => {
9757
9720
  return [{
9721
+ childCount: 1,
9722
+ className: ChatTableWrapper,
9723
+ style: 'padding-bottom: 8px;',
9724
+ type: Div
9725
+ }, {
9758
9726
  childCount: 2,
9759
9727
  className: MarkdownTable,
9760
9728
  type: Table
@@ -9800,6 +9768,9 @@ const getBlockQuoteDom = (node, useChatMathWorker) => {
9800
9768
  };
9801
9769
  const getMessageNodeDom = (node, useChatMathWorker = false) => {
9802
9770
  if (node.type === 'text') {
9771
+ if (!hasVisibleInlineContent(node.children)) {
9772
+ return [];
9773
+ }
9803
9774
  return [{
9804
9775
  childCount: node.children.length,
9805
9776
  className: Markdown,
@@ -10106,7 +10077,7 @@ const getToolCallEditFileVirtualDom = toolCall => {
10106
10077
  const fileName = getFileNameFromUri(target.title);
10107
10078
  const fileNameClickableProps = target.clickableUri ? {
10108
10079
  'data-uri': target.clickableUri,
10109
- onClick: HandleClickReadFile
10080
+ onClick: HandleClickFileName
10110
10081
  } : {};
10111
10082
  return [{
10112
10083
  childCount: 3,
@@ -10126,6 +10097,7 @@ const getToolCallEditFileVirtualDom = toolCall => {
10126
10097
  }, {
10127
10098
  childCount: 1,
10128
10099
  className: ChatToolCallFileName,
10100
+ ...fileNameClickableProps,
10129
10101
  type: Span
10130
10102
  }, text(fileName)];
10131
10103
  };
@@ -10136,6 +10108,10 @@ const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
10136
10108
  }
10137
10109
  const statusLabel = getToolCallStatusLabel(toolCall);
10138
10110
  const fileName = getFileNameFromUri(toolCall.result);
10111
+ const fileNameClickableProps = {
10112
+ 'data-uri': toolCall.result,
10113
+ onClick: HandleClickFileName
10114
+ };
10139
10115
  return [{
10140
10116
  childCount: statusLabel ? 4 : 3,
10141
10117
  className: ChatOrderedListItem,
@@ -10148,12 +10124,12 @@ const getToolCallGetWorkspaceUriVirtualDom = toolCall => {
10148
10124
  }, text('get_workspace_uri '), {
10149
10125
  childCount: 1,
10150
10126
  className: ChatToolCallReadFileLink,
10151
- 'data-uri': toolCall.result,
10152
- onClick: HandleClickReadFile,
10127
+ ...fileNameClickableProps,
10153
10128
  type: Span
10154
10129
  }, {
10155
10130
  childCount: 1,
10156
10131
  className: ChatToolCallFileName,
10132
+ ...fileNameClickableProps,
10157
10133
  type: Span
10158
10134
  }, text(fileName), ...(statusLabel ? [text(statusLabel)] : [])];
10159
10135
  };
@@ -10224,7 +10200,7 @@ const getToolCallReadFileVirtualDom = toolCall => {
10224
10200
  const statusLabel = getToolCallStatusLabel(toolCall);
10225
10201
  const fileNameClickableProps = target.clickableUri ? {
10226
10202
  'data-uri': target.clickableUri,
10227
- onClick: HandleClickReadFile
10203
+ onClick: HandleClickFileName
10228
10204
  } : {};
10229
10205
  return [{
10230
10206
  childCount: statusLabel ? 4 : 3,
@@ -10243,6 +10219,7 @@ const getToolCallReadFileVirtualDom = toolCall => {
10243
10219
  }, {
10244
10220
  childCount: 1,
10245
10221
  className: ChatToolCallFileName,
10222
+ ...fileNameClickableProps,
10246
10223
  type: Span
10247
10224
  }, text(fileName), ...(statusLabel ? [text(statusLabel)] : [])];
10248
10225
  };
@@ -10602,7 +10579,7 @@ const getToolCallWriteFileVirtualDom = toolCall => {
10602
10579
  } = parseWriteFileLineCounts(toolCall.result);
10603
10580
  const fileNameClickableProps = target.clickableUri ? {
10604
10581
  'data-uri': target.clickableUri,
10605
- onClick: HandleClickReadFile
10582
+ onClick: HandleClickFileName
10606
10583
  } : {};
10607
10584
  return [{
10608
10585
  childCount: showDiffStats ? statusLabel ? 6 : 5 : statusLabel ? 4 : 3,
@@ -10621,6 +10598,7 @@ const getToolCallWriteFileVirtualDom = toolCall => {
10621
10598
  }, {
10622
10599
  childCount: 1,
10623
10600
  className: ChatToolCallFileName,
10601
+ ...fileNameClickableProps,
10624
10602
  type: Span
10625
10603
  }, text(fileName), ...(showDiffStats ? [{
10626
10604
  childCount: 1,
@@ -10706,7 +10684,8 @@ const getChatMessageDom = (message, parsedMessageContent, _openRouterApiKeyInput
10706
10684
  const messageDom = getMessageContentDom(parsedMessageContent, useChatMathWorker);
10707
10685
  const toolCallsDom = getToolCallsDom(message);
10708
10686
  const toolCallsChildCount = toolCallsDom.length > 0 ? 1 : 0;
10709
- const extraChildCount = isOpenApiApiKeyMissingMessage || isOpenRouterApiKeyMissingMessage || isOpenRouterRequestFailedMessage || isOpenRouterTooManyRequestsMessage ? parsedMessageContent.length + 1 + toolCallsChildCount : parsedMessageContent.length + toolCallsChildCount;
10687
+ const messageDomChildCount = messageDom.filter(node => node.type !== Text).length;
10688
+ const extraChildCount = isOpenApiApiKeyMissingMessage || isOpenRouterApiKeyMissingMessage || isOpenRouterRequestFailedMessage || isOpenRouterTooManyRequestsMessage ? messageDomChildCount + 1 + toolCallsChildCount : messageDomChildCount + toolCallsChildCount;
10710
10689
  return [{
10711
10690
  childCount: 1,
10712
10691
  className: mergeClassNames(Message, roleClassName),
@@ -10880,7 +10859,10 @@ const getChatModeChatFocusVirtualDom = ({
10880
10859
  composerLineHeight = 20,
10881
10860
  composerValue,
10882
10861
  messagesScrollTop = 0,
10862
+ modelPickerOpen = false,
10863
+ modelPickerSearchValue = '',
10883
10864
  models,
10865
+ newChatModelPickerEnabled = false,
10884
10866
  openApiApiKeyInput,
10885
10867
  openRouterApiKeyInput,
10886
10868
  openRouterApiKeyState = 'idle',
@@ -10911,7 +10893,7 @@ const getChatModeChatFocusVirtualDom = ({
10911
10893
  onDragEnter: HandleDragEnterChatView,
10912
10894
  onDragOver: HandleDragOverChatView,
10913
10895
  type: Div
10914
- }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
10896
+ }, ...getProjectListDom(projects, sessions, projectExpandedIds, selectedProjectId, selectedSessionId, projectListScrollTop), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker, true), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
10915
10897
  childCount: 1,
10916
10898
  className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
10917
10899
  name: ComposerDropTarget,
@@ -11045,7 +11027,10 @@ const getChatModeDetailVirtualDom = ({
11045
11027
  composerLineHeight = 20,
11046
11028
  composerValue,
11047
11029
  messagesScrollTop = 0,
11030
+ modelPickerOpen = false,
11031
+ modelPickerSearchValue = '',
11048
11032
  models,
11033
+ newChatModelPickerEnabled = false,
11049
11034
  openApiApiKeyInput,
11050
11035
  openRouterApiKeyInput,
11051
11036
  openRouterApiKeyState = 'idle',
@@ -11073,7 +11058,7 @@ const getChatModeDetailVirtualDom = ({
11073
11058
  onDragEnter: HandleDragEnterChatView,
11074
11059
  onDragOver: HandleDragOverChatView,
11075
11060
  type: Div
11076
- }, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, authStatus, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
11061
+ }, ...getChatHeaderDomDetailMode(selectedSessionTitle, authEnabled, authStatus, authErrorMessage), ...getMessagesDom(messages, parsedMessages, openRouterApiKeyInput, openApiApiKeyInput, openRouterApiKeyState, messagesScrollTop, useChatMathWorker), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
11077
11062
  childCount: 1,
11078
11063
  className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
11079
11064
  name: ComposerDropTarget,
@@ -11187,7 +11172,10 @@ const getChatModeListVirtualDom = ({
11187
11172
  composerHeight = 28,
11188
11173
  composerLineHeight = 20,
11189
11174
  composerValue,
11175
+ modelPickerOpen = false,
11176
+ modelPickerSearchValue = '',
11190
11177
  models,
11178
+ newChatModelPickerEnabled = false,
11191
11179
  runMode,
11192
11180
  searchEnabled = false,
11193
11181
  searchFieldVisible = false,
@@ -11212,7 +11200,7 @@ const getChatModeListVirtualDom = ({
11212
11200
  onDragEnter: HandleDragEnterChatView,
11213
11201
  onDragOver: HandleDragOverChatView,
11214
11202
  type: Div
11215
- }, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
11203
+ }, ...getChatHeaderListModeDom(authEnabled, authStatus, authErrorMessage, searchEnabled, searchFieldVisible, searchValue), ...getChatListDom(visibleSessions, selectedSessionId, chatListScrollTop), ...getChatSendAreaDom(composerValue, modelPickerOpen, modelPickerSearchValue, models, newChatModelPickerEnabled, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, addContextButtonEnabled, showRunMode, runMode, todoListToolEnabled, todoListItems, voiceDictationEnabled), ...(isDropOverlayVisible ? [{
11216
11204
  childCount: 1,
11217
11205
  className: mergeClassNames(ChatViewDropOverlay, ChatViewDropOverlayActive),
11218
11206
  name: ComposerDropTarget,
@@ -11320,7 +11308,10 @@ const getChatVirtualDom = options => {
11320
11308
  composerLineHeight,
11321
11309
  composerValue,
11322
11310
  messagesScrollTop,
11311
+ modelPickerOpen = false,
11312
+ modelPickerSearchValue = '',
11323
11313
  models,
11314
+ newChatModelPickerEnabled = false,
11324
11315
  openApiApiKeyInput,
11325
11316
  openRouterApiKeyInput,
11326
11317
  openRouterApiKeyState,
@@ -11362,7 +11353,10 @@ const getChatVirtualDom = options => {
11362
11353
  composerLineHeight,
11363
11354
  composerValue,
11364
11355
  messagesScrollTop,
11356
+ modelPickerOpen,
11357
+ modelPickerSearchValue,
11365
11358
  models,
11359
+ newChatModelPickerEnabled,
11366
11360
  openApiApiKeyInput,
11367
11361
  openRouterApiKeyInput,
11368
11362
  openRouterApiKeyState,
@@ -11398,7 +11392,10 @@ const getChatVirtualDom = options => {
11398
11392
  composerLineHeight,
11399
11393
  composerValue,
11400
11394
  messagesScrollTop,
11395
+ modelPickerOpen,
11396
+ modelPickerSearchValue,
11401
11397
  models,
11398
+ newChatModelPickerEnabled,
11402
11399
  openApiApiKeyInput,
11403
11400
  openRouterApiKeyInput,
11404
11401
  openRouterApiKeyState,
@@ -11430,7 +11427,10 @@ const getChatVirtualDom = options => {
11430
11427
  composerHeight,
11431
11428
  composerLineHeight,
11432
11429
  composerValue,
11430
+ modelPickerOpen,
11431
+ modelPickerSearchValue,
11433
11432
  models,
11433
+ newChatModelPickerEnabled,
11434
11434
  runMode,
11435
11435
  searchEnabled,
11436
11436
  searchFieldVisible,
@@ -11467,7 +11467,10 @@ const renderItems = (oldState, newState) => {
11467
11467
  composerValue,
11468
11468
  initial,
11469
11469
  messagesScrollTop,
11470
+ modelPickerOpen,
11471
+ modelPickerSearchValue,
11470
11472
  models,
11473
+ newChatModelPickerEnabled,
11471
11474
  openApiApiKeyInput,
11472
11475
  openRouterApiKeyInput,
11473
11476
  openRouterApiKeyState,
@@ -11510,7 +11513,10 @@ const renderItems = (oldState, newState) => {
11510
11513
  composerLineHeight,
11511
11514
  composerValue,
11512
11515
  messagesScrollTop,
11516
+ modelPickerOpen,
11517
+ modelPickerSearchValue,
11513
11518
  models,
11519
+ newChatModelPickerEnabled,
11514
11520
  openApiApiKeyInput,
11515
11521
  openRouterApiKeyInput,
11516
11522
  openRouterApiKeyState,
@@ -11686,7 +11692,10 @@ const renderEventListeners = () => {
11686
11692
  params: ['handleClickDictationButton', handleDictateClickExpression]
11687
11693
  }, {
11688
11694
  name: HandleClickReadFile,
11689
- params: ['handleClickReadFile', 'event.target.dataset.uri']
11695
+ params: ['handleClickFileName', 'event.target.dataset.uri']
11696
+ }, {
11697
+ name: HandleClickFileName,
11698
+ params: ['handleClickFileName', 'event.target.dataset.uri']
11690
11699
  }, {
11691
11700
  name: HandleClickDelete,
11692
11701
  params: ['handleClickDelete', 'event.target.dataset.id']
@@ -11789,6 +11798,8 @@ const reset = async state => {
11789
11798
  composerHeight: getMinComposerHeightForState(state),
11790
11799
  composerValue: '',
11791
11800
  mockAiResponseDelay: 0,
11801
+ modelPickerOpen: false,
11802
+ modelPickerSearchValue: '',
11792
11803
  openApiApiKey: '',
11793
11804
  openRouterApiKey: '',
11794
11805
  openRouterApiKeyInput: '',
@@ -11897,6 +11908,15 @@ const setEmitStreamingFunctionCallEvents = (state, emitStreamingFunctionCallEven
11897
11908
  };
11898
11909
  };
11899
11910
 
11911
+ const setNewChatModelPickerEnabled = (state, newChatModelPickerEnabled) => {
11912
+ return {
11913
+ ...state,
11914
+ modelPickerOpen: newChatModelPickerEnabled ? state.modelPickerOpen : false,
11915
+ modelPickerSearchValue: newChatModelPickerEnabled ? state.modelPickerSearchValue : '',
11916
+ newChatModelPickerEnabled
11917
+ };
11918
+ };
11919
+
11900
11920
  const setQuestionToolEnabled = (state, questionToolEnabled) => {
11901
11921
  return {
11902
11922
  ...state,
@@ -12005,9 +12025,10 @@ const commandMap = {
12005
12025
  'Chat.handleClickClose': handleClickClose,
12006
12026
  'Chat.handleClickDelete': wrapCommand(handleClickDelete),
12007
12027
  'Chat.handleClickDictationButton': wrapCommand(handleClickDictationButton),
12028
+ 'Chat.handleClickFileName': handleClickFileName,
12008
12029
  'Chat.handleClickList': wrapCommand(handleClickList),
12009
12030
  'Chat.handleClickNew': wrapCommand(handleClickNew),
12010
- 'Chat.handleClickReadFile': handleClickReadFile,
12031
+ 'Chat.handleClickReadFile': handleClickFileName,
12011
12032
  'Chat.handleClickSessionDebug': wrapCommand(handleClickSessionDebug),
12012
12033
  'Chat.handleClickSettings': handleClickSettings,
12013
12034
  'Chat.handleDragEnter': wrapCommand(handleDragEnter),
@@ -12050,6 +12071,7 @@ const commandMap = {
12050
12071
  'Chat.setBackendUrl': wrapCommand(setBackendUrl),
12051
12072
  'Chat.setChatList': wrapCommand(setChatList),
12052
12073
  'Chat.setEmitStreamingFunctionCallEvents': wrapCommand(setEmitStreamingFunctionCallEvents),
12074
+ 'Chat.setNewChatModelPickerEnabled': wrapCommand(setNewChatModelPickerEnabled),
12053
12075
  'Chat.setOpenRouterApiKey': wrapCommand(setOpenRouterApiKey),
12054
12076
  'Chat.setQuestionToolEnabled': wrapCommand(setQuestionToolEnabled),
12055
12077
  'Chat.setSearchEnabled': wrapCommand(setSearchEnabled),
@@ -12097,6 +12119,18 @@ const initializeChatNetworkWorker = async () => {
12097
12119
  set$6(rpc);
12098
12120
  };
12099
12121
 
12122
+ const sendMessagePortToChatStorageWorker = async port => {
12123
+ // @ts-ignore
12124
+ await undefined(port, 0);
12125
+ };
12126
+ const initializeChatStorageWorker = async () => {
12127
+ const rpc = await create$4({
12128
+ commandMap: {},
12129
+ send: sendMessagePortToChatStorageWorker
12130
+ });
12131
+ set$3(rpc);
12132
+ };
12133
+
12100
12134
  const send = port => {
12101
12135
  return sendMessagePortToChatToolWorker(port);
12102
12136
  };
@@ -12125,7 +12159,7 @@ const listen = async () => {
12125
12159
  commandMap: commandMap
12126
12160
  });
12127
12161
  set$2(rpc);
12128
- await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker(), initializeChatCoordinatorWorker(), initializeChatToolWorker(), initializeOpenerWorker()]);
12162
+ await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker(), initializeChatCoordinatorWorker(), initializeChatToolWorker(), initializeOpenerWorker(), initializeChatStorageWorker()]);
12129
12163
  };
12130
12164
 
12131
12165
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-view",
3
- "version": "6.15.0",
3
+ "version": "6.17.0",
4
4
  "description": "Chat View Worker",
5
5
  "repository": {
6
6
  "type": "git",