@lvce-editor/chat-view 5.2.0 → 6.0.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.
@@ -1027,7 +1027,7 @@ const createMockRpc = ({
1027
1027
  };
1028
1028
 
1029
1029
  const rpcs = Object.create(null);
1030
- const set$5 = (id, rpc) => {
1030
+ const set$6 = (id, rpc) => {
1031
1031
  rpcs[id] = rpc;
1032
1032
  };
1033
1033
  const get$2 = id => {
@@ -1060,7 +1060,7 @@ const create$2 = rpcId => {
1060
1060
  const mockRpc = createMockRpc({
1061
1061
  commandMap
1062
1062
  });
1063
- set$5(rpcId, mockRpc);
1063
+ set$6(rpcId, mockRpc);
1064
1064
  // @ts-ignore
1065
1065
  mockRpc[Symbol.dispose] = () => {
1066
1066
  remove(rpcId);
@@ -1069,20 +1069,20 @@ const create$2 = rpcId => {
1069
1069
  return mockRpc;
1070
1070
  },
1071
1071
  set(rpc) {
1072
- set$5(rpcId, rpc);
1072
+ set$6(rpcId, rpc);
1073
1073
  }
1074
1074
  };
1075
1075
  };
1076
1076
 
1077
1077
  const {
1078
- invoke: invoke$3,
1079
- set: set$4
1078
+ invoke: invoke$4,
1079
+ set: set$5
1080
1080
  } = create$2(6007);
1081
1081
  const getMathBlockDom = async node => {
1082
- return invoke$3('ChatMath.getMathBlockDom', node);
1082
+ return invoke$4('ChatMath.getMathBlockDom', node);
1083
1083
  };
1084
1084
  const getMathInlineDom = async node => {
1085
- return invoke$3('ChatMath.getMathInlineDom', node);
1085
+ return invoke$4('ChatMath.getMathInlineDom', node);
1086
1086
  };
1087
1087
 
1088
1088
  const Button$2 = 'button';
@@ -1171,26 +1171,26 @@ const SetPatches = 'Viewlet.setPatches';
1171
1171
  const FocusChatInput = 8000;
1172
1172
 
1173
1173
  const {
1174
- invoke: invoke$2,
1175
- set: set$3
1174
+ invoke: invoke$3,
1175
+ set: set$4
1176
1176
  } = create$2(ChatNetworkWorker);
1177
1177
 
1178
1178
  const {
1179
- invoke: invoke$1,
1180
- set: set$2
1179
+ invoke: invoke$2,
1180
+ set: set$3
1181
1181
  } = create$2(ExtensionHostWorker);
1182
1182
 
1183
1183
  const {
1184
- invoke,
1184
+ invoke: invoke$1,
1185
1185
  invokeAndTransfer,
1186
- set: set$1
1186
+ set: set$2
1187
1187
  } = create$2(RendererWorker);
1188
1188
  const sendMessagePortToChatMathWorker$1 = async (port, rpcId) => {
1189
1189
  const command = 'HandleMessagePort.handleMessagePort';
1190
1190
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatMathWorker', port, command, rpcId);
1191
1191
  };
1192
1192
  const readFile = async uri => {
1193
- return invoke('FileSystem.readFile', uri);
1193
+ return invoke$1('FileSystem.readFile', uri);
1194
1194
  };
1195
1195
  const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
1196
1196
  const command = 'HandleMessagePort.handleMessagePort2';
@@ -1200,22 +1200,22 @@ const sendMessagePortToChatNetworkWorker = async port => {
1200
1200
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatNetworkWorker', port, 'HandleMessagePort.handleMessagePort');
1201
1201
  };
1202
1202
  const writeFile = async (uri, text) => {
1203
- await invoke('FileSystem.writeFile', uri, text);
1203
+ await invoke$1('FileSystem.writeFile', uri, text);
1204
1204
  };
1205
1205
  const activateByEvent$1 = (event, assetDir, platform) => {
1206
- return invoke('ExtensionHostManagement.activateByEvent', event, assetDir, platform);
1206
+ return invoke$1('ExtensionHostManagement.activateByEvent', event, assetDir, platform);
1207
1207
  };
1208
1208
  const getWorkspacePath = () => {
1209
- return invoke('Workspace.getPath');
1209
+ return invoke$1('Workspace.getPath');
1210
1210
  };
1211
1211
  const getPreference = async key => {
1212
- return await invoke('Preferences.get', key);
1212
+ return await invoke$1('Preferences.get', key);
1213
1213
  };
1214
1214
  const openExternal = async uri => {
1215
- await invoke('Open.openExternal', uri);
1215
+ await invoke$1('Open.openExternal', uri);
1216
1216
  };
1217
1217
  const measureTextBlockHeight$1 = async (actualInput, fontFamily, fontSize, lineHeightPx, width) => {
1218
- return invoke(`MeasureTextHeight.measureTextBlockHeight`, actualInput, fontFamily, fontSize, lineHeightPx, width);
1218
+ return invoke$1(`MeasureTextHeight.measureTextBlockHeight`, actualInput, fontFamily, fontSize, lineHeightPx, width);
1219
1219
  };
1220
1220
 
1221
1221
  const toCommandId = key => {
@@ -1604,6 +1604,7 @@ const createDefaultState = () => {
1604
1604
  lastSubmittedSessionId: '',
1605
1605
  listItemHeight: 40,
1606
1606
  maxComposerRows: 5,
1607
+ messagesAutoScrollEnabled: true,
1607
1608
  messagesScrollTop: 0,
1608
1609
  mockAiResponseDelay: 800,
1609
1610
  mockApiCommandId: '',
@@ -1643,6 +1644,7 @@ const createDefaultState = () => {
1643
1644
  tokensUsed: 0,
1644
1645
  uid: 0,
1645
1646
  usageOverviewEnabled: false,
1647
+ useChatCoordinatorWorker: true,
1646
1648
  useChatMathWorker: true,
1647
1649
  useChatNetworkWorkerForRequests: false,
1648
1650
  useMockApi: false,
@@ -1660,7 +1662,7 @@ const {
1660
1662
  get: get$1,
1661
1663
  getCommandIds,
1662
1664
  registerCommands,
1663
- set,
1665
+ set: set$1,
1664
1666
  wrapCommand,
1665
1667
  wrapGetter
1666
1668
  } = create$1();
@@ -1676,7 +1678,7 @@ const create = (uid, x, y, width, height, platform, assetDir) => {
1676
1678
  x,
1677
1679
  y
1678
1680
  };
1679
- set(uid, state, state);
1681
+ set$1(uid, state, state);
1680
1682
  };
1681
1683
 
1682
1684
  const toError = error => {
@@ -2952,7 +2954,7 @@ const handleChatListContextMenu = async (state, eventX, eventY) => {
2952
2954
  if (!item) {
2953
2955
  return state;
2954
2956
  }
2955
- await invoke('ContextMenu.show', eventX, eventY, CHAT_LIST_ITEM_CONTEXT_MENU, item.id);
2957
+ await invoke$1('ContextMenu.show', eventX, eventY, CHAT_LIST_ITEM_CONTEXT_MENU, item.id);
2956
2958
  return state;
2957
2959
  };
2958
2960
 
@@ -2983,7 +2985,7 @@ const createSession = async (state, projectIdOverride = '') => {
2983
2985
 
2984
2986
  const openFolder = async () => {
2985
2987
  try {
2986
- return await invoke('FilePicker.showDirectoryPicker');
2988
+ return await invoke$1('FilePicker.showDirectoryPicker');
2987
2989
  } catch {
2988
2990
  return '';
2989
2991
  }
@@ -3060,7 +3062,7 @@ const handleClickCreateProject = async state => {
3060
3062
  };
3061
3063
 
3062
3064
  const handleClickOpenApiApiKeySettings = async state => {
3063
- await invoke('Main.openUri', 'app://settings.json');
3065
+ await invoke$1('Main.openUri', 'app://settings.json');
3064
3066
  return state;
3065
3067
  };
3066
3068
 
@@ -3070,7 +3072,7 @@ const handleClickOpenApiApiKeyWebsite = async state => {
3070
3072
  };
3071
3073
 
3072
3074
  const handleClickOpenRouterApiKeySettings = async state => {
3073
- await invoke('Main.openUri', 'app://settings.json');
3075
+ await invoke$1('Main.openUri', 'app://settings.json');
3074
3076
  return state;
3075
3077
  };
3076
3078
 
@@ -3088,6 +3090,21 @@ const openRouterTooManyRequestsMessage = 'OpenRouter rate limit reached (429). P
3088
3090
  const openRouterRequestFailureReasons = ['ContentSecurityPolicyViolation: Check DevTools for details.', 'OpenRouter server offline: Check DevTools for details.', 'Check your internet connection.'];
3089
3091
  const openRouterTooManyRequestsReasons = ['Wait a short time and retry your request.', 'Reduce request frequency to avoid rate limits.', 'Use a different model if this one is saturated.'];
3090
3092
 
3093
+ let rpc;
3094
+ const set = value => {
3095
+ rpc = value;
3096
+ };
3097
+ const invoke = async (method, ...params) => {
3098
+ if (!rpc) {
3099
+ throw new Error('ChatCoordinatorWorker is not initialized');
3100
+ }
3101
+ return rpc.invoke(method, ...params);
3102
+ };
3103
+
3104
+ const getAiResponse$1 = async options => {
3105
+ return invoke('ChatCoordinator.getAiResponse', options);
3106
+ };
3107
+
3091
3108
  const getToolErrorPayload = error => {
3092
3109
  const rawStack = error && typeof error === 'object' ? Reflect.get(error, 'stack') : undefined;
3093
3110
  return {
@@ -3121,7 +3138,7 @@ const executeListFilesTool = async (args, _options) => {
3121
3138
  });
3122
3139
  }
3123
3140
  try {
3124
- const entries = await invoke('FileSystem.readDirWithFileTypes', uri);
3141
+ const entries = await invoke$1('FileSystem.readDirWithFileTypes', uri);
3125
3142
  return JSON.stringify({
3126
3143
  entries,
3127
3144
  uri
@@ -3442,6 +3459,15 @@ const setHttpErrorResponse = (statusCode, body) => {
3442
3459
  type: 'error'
3443
3460
  };
3444
3461
  };
3462
+ const setRequestFailedResponse = (isOffline = false) => {
3463
+ errorResult = {
3464
+ details: 'request-failed',
3465
+ ...(isOffline ? {
3466
+ isOffline: true
3467
+ } : {}),
3468
+ type: 'error'
3469
+ };
3470
+ };
3445
3471
  const takeErrorResponse = () => {
3446
3472
  const error = errorResult;
3447
3473
  errorResult = undefined;
@@ -3713,7 +3739,7 @@ const executeProvider = async ({
3713
3739
  }) => {
3714
3740
  await activateByEvent(event, assetDir, platform);
3715
3741
  // @ts-ignore
3716
- const result = invoke$1(method, ...params);
3742
+ const result = invoke$2(method, ...params);
3717
3743
  return result;
3718
3744
  };
3719
3745
 
@@ -3845,10 +3871,10 @@ const getOpenApiApiEndpoint = openApiApiBaseUrl => {
3845
3871
  };
3846
3872
 
3847
3873
  const makeApiRequest = async options => {
3848
- return invoke$2('ChatNetwork.makeApiRequest', options);
3874
+ return invoke$3('ChatNetwork.makeApiRequest', options);
3849
3875
  };
3850
3876
  const makeStreamingApiRequest = async options => {
3851
- return invoke$2('ChatNetwork.makeStreamingApiRequest', options);
3877
+ return invoke$3('ChatNetwork.makeStreamingApiRequest', options);
3852
3878
  };
3853
3879
 
3854
3880
  const getTextContent = content => {
@@ -4894,7 +4920,7 @@ const getOpenApiErrorMessage = errorResult => {
4894
4920
  return openApiRequestFailedMessage;
4895
4921
  }
4896
4922
  case 'request-failed':
4897
- if (isOffline()) {
4923
+ if (errorResult.isOffline || isOffline()) {
4898
4924
  return openApiRequestFailedOfflineMessage;
4899
4925
  }
4900
4926
  return openApiRequestFailedMessage;
@@ -5309,6 +5335,7 @@ const getAiResponse = async ({
5309
5335
  mockAiResponseDelay = 800,
5310
5336
  mockApiCommandId,
5311
5337
  models,
5338
+ nextMessageId,
5312
5339
  onDataEvent,
5313
5340
  onEventStreamFinished,
5314
5341
  onTextChunk,
@@ -5321,11 +5348,50 @@ const getAiResponse = async ({
5321
5348
  platform,
5322
5349
  selectedModelId,
5323
5350
  streamingEnabled = true,
5351
+ useChatCoordinatorWorker = false,
5324
5352
  useChatNetworkWorkerForRequests = false,
5325
5353
  useMockApi,
5326
5354
  userText,
5327
5355
  webSearchEnabled = false
5328
5356
  }) => {
5357
+ if (useChatCoordinatorWorker) {
5358
+ try {
5359
+ const result = await getAiResponse$1({
5360
+ assetDir,
5361
+ ...(messageId ? {
5362
+ messageId
5363
+ } : {}),
5364
+ messages,
5365
+ mockAiResponseDelay,
5366
+ mockApiCommandId,
5367
+ models,
5368
+ nextMessageId,
5369
+ openApiApiBaseUrl,
5370
+ openApiApiKey,
5371
+ openRouterApiBaseUrl,
5372
+ openRouterApiKey,
5373
+ passIncludeObfuscation,
5374
+ platform,
5375
+ selectedModelId,
5376
+ streamingEnabled,
5377
+ useChatNetworkWorkerForRequests,
5378
+ useMockApi,
5379
+ userText,
5380
+ webSearchEnabled
5381
+ });
5382
+ if (streamingEnabled) {
5383
+ if (onTextChunk) {
5384
+ await onTextChunk(result.text);
5385
+ }
5386
+ if (onEventStreamFinished) {
5387
+ await onEventStreamFinished();
5388
+ }
5389
+ }
5390
+ return result;
5391
+ } catch {
5392
+ // Fall back to the local implementation if coordinator worker RPC is unavailable.
5393
+ }
5394
+ }
5329
5395
  let text = '';
5330
5396
  const usesOpenApiModel = isOpenApiModel(selectedModelId, models);
5331
5397
  const usesOpenRouterModel = isOpenRouterModel(selectedModelId, models);
@@ -5448,7 +5514,7 @@ const get = async key => {
5448
5514
  return getPreference(key);
5449
5515
  };
5450
5516
  const update = async settings => {
5451
- await invoke('Preferences.update', settings);
5517
+ await invoke$1('Preferences.update', settings);
5452
5518
  };
5453
5519
 
5454
5520
  const setOpenApiApiKey = async (state, openApiApiKey, persist = true) => {
@@ -5493,6 +5559,7 @@ const handleClickSaveOpenApiApiKey = async state => {
5493
5559
  mockAiResponseDelay: updatedState.mockAiResponseDelay,
5494
5560
  mockApiCommandId: updatedState.mockApiCommandId,
5495
5561
  models: updatedState.models,
5562
+ nextMessageId: updatedState.nextMessageId,
5496
5563
  openApiApiBaseUrl: updatedState.openApiApiBaseUrl,
5497
5564
  openApiApiKey: updatedState.openApiApiKey,
5498
5565
  openRouterApiBaseUrl: updatedState.openRouterApiBaseUrl,
@@ -5500,6 +5567,7 @@ const handleClickSaveOpenApiApiKey = async state => {
5500
5567
  platform: updatedState.platform,
5501
5568
  selectedModelId: updatedState.selectedModelId,
5502
5569
  streamingEnabled: updatedState.streamingEnabled,
5570
+ useChatCoordinatorWorker: updatedState.useChatCoordinatorWorker,
5503
5571
  useChatNetworkWorkerForRequests: updatedState.useChatNetworkWorkerForRequests,
5504
5572
  useMockApi: updatedState.useMockApi,
5505
5573
  userText: previousUserMessage.text
@@ -5547,9 +5615,9 @@ const handleClickSaveOpenRouterApiKey = async state => {
5547
5615
  ...state,
5548
5616
  openRouterApiKeyState: 'saving'
5549
5617
  };
5550
- set(state.uid, state, optimisticState);
5618
+ set$1(state.uid, state, optimisticState);
5551
5619
  // @ts-ignore
5552
- await invoke('Chat.rerender');
5620
+ await invoke$1('Chat.rerender');
5553
5621
  const persistedState = await setOpenRouterApiKey(optimisticState, openRouterApiKey);
5554
5622
  const updatedState = {
5555
5623
  ...persistedState,
@@ -5575,12 +5643,14 @@ const handleClickSaveOpenRouterApiKey = async state => {
5575
5643
  mockAiResponseDelay: updatedState.mockAiResponseDelay,
5576
5644
  mockApiCommandId: updatedState.mockApiCommandId,
5577
5645
  models: updatedState.models,
5646
+ nextMessageId: updatedState.nextMessageId,
5578
5647
  openApiApiBaseUrl: updatedState.openApiApiBaseUrl,
5579
5648
  openApiApiKey: updatedState.openApiApiKey,
5580
5649
  openRouterApiBaseUrl: updatedState.openRouterApiBaseUrl,
5581
5650
  openRouterApiKey,
5582
5651
  platform: updatedState.platform,
5583
5652
  selectedModelId: updatedState.selectedModelId,
5653
+ useChatCoordinatorWorker: updatedState.useChatCoordinatorWorker,
5584
5654
  useChatNetworkWorkerForRequests: updatedState.useChatNetworkWorkerForRequests,
5585
5655
  useMockApi: updatedState.useMockApi,
5586
5656
  userText: previousUserMessage.text
@@ -6511,6 +6581,7 @@ Assistant: ${assistantText}`;
6511
6581
  mockAiResponseDelay: state.mockAiResponseDelay,
6512
6582
  mockApiCommandId: state.mockApiCommandId,
6513
6583
  models,
6584
+ nextMessageId: state.nextMessageId,
6514
6585
  openApiApiBaseUrl,
6515
6586
  openApiApiKey,
6516
6587
  openRouterApiBaseUrl,
@@ -6519,6 +6590,7 @@ Assistant: ${assistantText}`;
6519
6590
  platform: state.platform,
6520
6591
  selectedModelId,
6521
6592
  streamingEnabled: false,
6593
+ useChatCoordinatorWorker: state.useChatCoordinatorWorker,
6522
6594
  useChatNetworkWorkerForRequests: state.useChatNetworkWorkerForRequests,
6523
6595
  useMockApi,
6524
6596
  userText: titlePrompt,
@@ -6578,6 +6650,12 @@ const getMentionContextMessage = async value => {
6578
6650
  };
6579
6651
  };
6580
6652
 
6653
+ const AutoScrollTopA = Number.MAX_SAFE_INTEGER;
6654
+ const AutoScrollTopB = Number.MAX_SAFE_INTEGER - 1;
6655
+ const getNextAutoScrollTop = currentScrollTop => {
6656
+ return currentScrollTop === AutoScrollTopA ? AutoScrollTopB : AutoScrollTopA;
6657
+ };
6658
+
6581
6659
  const slashCommandRegex = /^\/(clear|export|help|new)(?:\s+.*)?$/;
6582
6660
  const getSlashCommand = value => {
6583
6661
  const trimmed = value.trim();
@@ -6667,12 +6745,15 @@ const handleTextChunkFunction = async (uid, assistantMessageId, chunk, handleTex
6667
6745
  const updated = await updateMessageTextInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, updatedText, true);
6668
6746
  const nextState = {
6669
6747
  ...handleTextChunkState.latestState,
6748
+ ...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
6749
+ messagesScrollTop: getNextAutoScrollTop(handleTextChunkState.latestState.messagesScrollTop)
6750
+ } : {}),
6670
6751
  parsedMessages: updated.parsedMessages,
6671
6752
  sessions: updated.sessions
6672
6753
  };
6673
- set(uid, handleTextChunkState.previousState, nextState);
6754
+ set$1(uid, handleTextChunkState.previousState, nextState);
6674
6755
  // @ts-ignore
6675
- await invoke('Chat.rerender');
6756
+ await invoke$1('Chat.rerender');
6676
6757
  return {
6677
6758
  latestState: nextState,
6678
6759
  previousState: nextState
@@ -6696,12 +6777,15 @@ const handleToolCallsChunkFunction = async (uid, assistantMessageId, toolCalls,
6696
6777
  const updated = updateMessageToolCallsInSelectedSession(handleTextChunkState.latestState.sessions, handleTextChunkState.latestState.parsedMessages, handleTextChunkState.latestState.selectedSessionId, assistantMessageId, toolCalls);
6697
6778
  const nextState = {
6698
6779
  ...handleTextChunkState.latestState,
6780
+ ...(handleTextChunkState.latestState.messagesAutoScrollEnabled ? {
6781
+ messagesScrollTop: getNextAutoScrollTop(handleTextChunkState.latestState.messagesScrollTop)
6782
+ } : {}),
6699
6783
  parsedMessages: updated.parsedMessages,
6700
6784
  sessions: updated.sessions
6701
6785
  };
6702
- set(uid, handleTextChunkState.previousState, nextState);
6786
+ set$1(uid, handleTextChunkState.previousState, nextState);
6703
6787
  // @ts-ignore
6704
- await invoke('Chat.rerender');
6788
+ await invoke$1('Chat.rerender');
6705
6789
  return {
6706
6790
  latestState: nextState,
6707
6791
  previousState: nextState
@@ -6761,6 +6845,15 @@ const updateSessionTitle = (sessions, selectedSessionId, title) => {
6761
6845
  });
6762
6846
  };
6763
6847
 
6848
+ const withUpdatedMessageScrollTop = state => {
6849
+ if (!state.messagesAutoScrollEnabled) {
6850
+ return state;
6851
+ }
6852
+ return {
6853
+ ...state,
6854
+ messagesScrollTop: getNextAutoScrollTop(state.messagesScrollTop)
6855
+ };
6856
+ };
6764
6857
  const handleSubmit = async state => {
6765
6858
  const {
6766
6859
  aiSessionTitleGenerationEnabled,
@@ -6781,6 +6874,7 @@ const handleSubmit = async state => {
6781
6874
  selectedSessionId,
6782
6875
  sessions,
6783
6876
  streamingEnabled,
6877
+ useChatCoordinatorWorker,
6784
6878
  useChatNetworkWorkerForRequests,
6785
6879
  useMockApi,
6786
6880
  viewMode,
@@ -6850,7 +6944,7 @@ const handleSubmit = async state => {
6850
6944
  title: `Chat ${workingSessions.length + 1}`
6851
6945
  };
6852
6946
  await saveChatSession(newSession);
6853
- optimisticState = focusInput({
6947
+ optimisticState = withUpdatedMessageScrollTop(focusInput({
6854
6948
  ...state,
6855
6949
  composerHeight: getMinComposerHeightForState(state),
6856
6950
  composerValue: '',
@@ -6861,7 +6955,7 @@ const handleSubmit = async state => {
6861
6955
  selectedSessionId: newSessionId,
6862
6956
  sessions: [...workingSessions, newSession],
6863
6957
  viewMode: 'detail'
6864
- });
6958
+ }));
6865
6959
  } else {
6866
6960
  await appendChatViewEvent({
6867
6961
  sessionId: selectedSessionId,
@@ -6875,7 +6969,7 @@ const handleSubmit = async state => {
6875
6969
  if (selectedSession) {
6876
6970
  await saveChatSession(selectedSession);
6877
6971
  }
6878
- optimisticState = focusInput({
6972
+ optimisticState = withUpdatedMessageScrollTop(focusInput({
6879
6973
  ...state,
6880
6974
  composerHeight: getMinComposerHeightForState(state),
6881
6975
  composerValue: '',
@@ -6884,11 +6978,11 @@ const handleSubmit = async state => {
6884
6978
  nextMessageId: nextMessageId + 1,
6885
6979
  parsedMessages,
6886
6980
  sessions: updatedSessions
6887
- });
6981
+ }));
6888
6982
  }
6889
- set(state.uid, state, optimisticState);
6983
+ set$1(state.uid, state, optimisticState);
6890
6984
  // @ts-ignore
6891
- await invoke('Chat.rerender');
6985
+ await invoke$1('Chat.rerender');
6892
6986
  let handleTextChunkState = {
6893
6987
  latestState: optimisticState,
6894
6988
  previousState: optimisticState
@@ -6907,6 +7001,7 @@ const handleSubmit = async state => {
6907
7001
  mockAiResponseDelay,
6908
7002
  mockApiCommandId,
6909
7003
  models,
7004
+ nextMessageId: optimisticState.nextMessageId,
6910
7005
  onDataEvent: async value => {
6911
7006
  if (!emitStreamingFunctionCallEvents && isStreamingFunctionCallEvent(value)) {
6912
7007
  return;
@@ -6941,6 +7036,7 @@ const handleSubmit = async state => {
6941
7036
  platform,
6942
7037
  selectedModelId,
6943
7038
  streamingEnabled,
7039
+ useChatCoordinatorWorker,
6944
7040
  useChatNetworkWorkerForRequests,
6945
7041
  useMockApi,
6946
7042
  userText,
@@ -6972,12 +7068,12 @@ const handleSubmit = async state => {
6972
7068
  if (selectedSession) {
6973
7069
  await saveChatSession(selectedSession);
6974
7070
  }
6975
- return focusInput({
7071
+ return withUpdatedMessageScrollTop(focusInput({
6976
7072
  ...latestState,
6977
7073
  nextMessageId: latestState.nextMessageId + 1,
6978
7074
  parsedMessages: finalParsedMessages,
6979
7075
  sessions: updatedSessions
6980
- });
7076
+ }));
6981
7077
  };
6982
7078
 
6983
7079
  const handleClickSend = async state => {
@@ -7227,7 +7323,7 @@ const handleClickBack = async state => {
7227
7323
 
7228
7324
  const handleClickClose = async () => {
7229
7325
  // @ts-ignore
7230
- await invoke('Layout.hideSecondarySideBar');
7326
+ await invoke$1('Layout.hideSecondarySideBar');
7231
7327
  };
7232
7328
 
7233
7329
  const handleClickDelete = async (state, sessionId = '') => {
@@ -7246,17 +7342,17 @@ const handleClickReadFile = async uri => {
7246
7342
  if (!uri) {
7247
7343
  return;
7248
7344
  }
7249
- await invoke('Main.openUri', uri);
7345
+ await invoke$1('Main.openUri', uri);
7250
7346
  };
7251
7347
 
7252
7348
  const handleClickSessionDebug = async state => {
7253
- await invoke('Main.openUri', `chat-debug://${state.selectedSessionId}`);
7349
+ await invoke$1('Main.openUri', `chat-debug://${state.selectedSessionId}`);
7254
7350
  return state;
7255
7351
  };
7256
7352
 
7257
7353
  const handleClickSettings = async () => {
7258
7354
  // TODO
7259
- await invoke('Main.openUri', 'app://settings.json');
7355
+ await invoke$1('Main.openUri', 'app://settings.json');
7260
7356
  };
7261
7357
 
7262
7358
  const handleDragEnter = async (state, name, hasFiles = true) => {
@@ -7469,7 +7565,7 @@ const handleKeyDown = async (state, key, shiftKey) => {
7469
7565
  };
7470
7566
 
7471
7567
  const handleMessagesContextMenu = async state => {
7472
- await invoke('ContextMenu.show', 1234);
7568
+ await invoke$1('ContextMenu.show', 1234);
7473
7569
  return state;
7474
7570
  };
7475
7571
 
@@ -7500,12 +7596,14 @@ const handleChatListScroll = async (state, chatListScrollTop) => {
7500
7596
  chatListScrollTop
7501
7597
  };
7502
7598
  };
7503
- const handleMessagesScroll = async (state, messagesScrollTop) => {
7504
- if (state.messagesScrollTop === messagesScrollTop) {
7599
+ const handleMessagesScroll = async (state, messagesScrollTop, scrollHeight, clientHeight) => {
7600
+ const messagesAutoScrollEnabled = messagesScrollTop + clientHeight >= scrollHeight - 8;
7601
+ if (state.messagesScrollTop === messagesScrollTop && state.messagesAutoScrollEnabled === messagesAutoScrollEnabled) {
7505
7602
  return state;
7506
7603
  }
7507
7604
  return {
7508
7605
  ...state,
7606
+ messagesAutoScrollEnabled,
7509
7607
  messagesScrollTop
7510
7608
  };
7511
7609
  };
@@ -7538,7 +7636,7 @@ const createExtensionHostRpc = async () => {
7538
7636
 
7539
7637
  const initialize = async () => {
7540
7638
  const rpc = await createExtensionHostRpc();
7541
- set$2(rpc);
7639
+ set$3(rpc);
7542
7640
  };
7543
7641
 
7544
7642
  const isObject = value => {
@@ -7694,6 +7792,15 @@ const loadStreamingEnabled = async () => {
7694
7792
  }
7695
7793
  };
7696
7794
 
7795
+ const loadUseChatCoordinatorWorker = async () => {
7796
+ try {
7797
+ const savedUseChatCoordinatorWorker = await get('chatView.useChatCoordinatorWorker');
7798
+ return typeof savedUseChatCoordinatorWorker === 'boolean' ? savedUseChatCoordinatorWorker : true;
7799
+ } catch {
7800
+ return true;
7801
+ }
7802
+ };
7803
+
7697
7804
  const loadUseChatMathWorker = async () => {
7698
7805
  try {
7699
7806
  const savedUseChatMathWorker = await get('chatView.useChatMathWorker');
@@ -7722,7 +7829,7 @@ const loadVoiceDictationEnabled = async () => {
7722
7829
  };
7723
7830
 
7724
7831
  const loadPreferences = async () => {
7725
- const [aiSessionTitleGenerationEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation, useChatMathWorker, useChatNetworkWorkerForRequests, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation(), loadUseChatMathWorker(), loadUseChatNetworkWorkerForRequests(), loadVoiceDictationEnabled()]);
7832
+ const [aiSessionTitleGenerationEnabled, composerDropEnabled, openApiApiKey, openRouterApiKey, emitStreamingFunctionCallEvents, streamingEnabled, passIncludeObfuscation, useChatCoordinatorWorker, useChatMathWorker, useChatNetworkWorkerForRequests, voiceDictationEnabled] = await Promise.all([loadAiSessionTitleGenerationEnabled(), loadComposerDropEnabled(), loadOpenApiApiKey(), loadOpenRouterApiKey(), loadEmitStreamingFunctionCallEvents(), loadStreamingEnabled(), loadPassIncludeObfuscation(), loadUseChatCoordinatorWorker(), loadUseChatMathWorker(), loadUseChatNetworkWorkerForRequests(), loadVoiceDictationEnabled()]);
7726
7833
  return {
7727
7834
  aiSessionTitleGenerationEnabled,
7728
7835
  composerDropEnabled,
@@ -7731,6 +7838,7 @@ const loadPreferences = async () => {
7731
7838
  openRouterApiKey,
7732
7839
  passIncludeObfuscation,
7733
7840
  streamingEnabled,
7841
+ useChatCoordinatorWorker,
7734
7842
  useChatMathWorker,
7735
7843
  useChatNetworkWorkerForRequests,
7736
7844
  voiceDictationEnabled
@@ -7870,6 +7978,7 @@ const loadContent = async (state, savedState) => {
7870
7978
  openRouterApiKey,
7871
7979
  passIncludeObfuscation,
7872
7980
  streamingEnabled,
7981
+ useChatCoordinatorWorker,
7873
7982
  useChatMathWorker,
7874
7983
  useChatNetworkWorkerForRequests,
7875
7984
  voiceDictationEnabled
@@ -7945,6 +8054,7 @@ const loadContent = async (state, savedState) => {
7945
8054
  selectedSessionId,
7946
8055
  sessions,
7947
8056
  streamingEnabled,
8057
+ useChatCoordinatorWorker,
7948
8058
  useChatMathWorker,
7949
8059
  useChatNetworkWorkerForRequests,
7950
8060
  viewMode,
@@ -7966,6 +8076,11 @@ const mockOpenApiSetHttpErrorResponse = (state, statusCode, body) => {
7966
8076
  return state;
7967
8077
  };
7968
8078
 
8079
+ const mockOpenApiSetRequestFailedResponse = (state, isOffline = false) => {
8080
+ setRequestFailedResponse(isOffline);
8081
+ return state;
8082
+ };
8083
+
7969
8084
  const mockOpenApiStreamFinish = state => {
7970
8085
  finish();
7971
8086
  return state;
@@ -8879,6 +8994,7 @@ const getMissingApiKeyDom = ({
8879
8994
  }, text(saveButtonText), {
8880
8995
  childCount: 1,
8881
8996
  className: mergeClassNames(Button, ButtonSecondary),
8997
+ inputType: 'button',
8882
8998
  name: openSettingsButtonName,
8883
8999
  onClick: HandleClick,
8884
9000
  type: Button$1
@@ -9975,7 +10091,7 @@ const render2 = (uid, diffResult) => {
9975
10091
  newState,
9976
10092
  oldState
9977
10093
  } = get$1(uid);
9978
- set(uid, newState, newState);
10094
+ set$1(uid, newState, newState);
9979
10095
  const commands = applyRender(oldState, newState, diffResult);
9980
10096
  return commands;
9981
10097
  };
@@ -10107,7 +10223,7 @@ const renderEventListeners = () => {
10107
10223
  params: ['handleChatListScroll', 'event.target.scrollTop']
10108
10224
  }, {
10109
10225
  name: HandleMessagesScroll,
10110
- params: ['handleMessagesScroll', 'event.target.scrollTop']
10226
+ params: ['handleMessagesScroll', 'event.target.scrollTop', 'event.target.scrollHeight', 'event.target.clientHeight']
10111
10227
  }, {
10112
10228
  name: HandleProjectListScroll,
10113
10229
  params: ['handleProjectListScroll', 'event.target.scrollTop']
@@ -10142,7 +10258,9 @@ const reset = async state => {
10142
10258
  composerHeight: getMinComposerHeightForState(state),
10143
10259
  composerValue: '',
10144
10260
  mockAiResponseDelay: 0,
10261
+ openApiApiKey: '',
10145
10262
  openRouterApiKey: '',
10263
+ openRouterApiKeyInput: '',
10146
10264
  selectedModelId: 'test',
10147
10265
  selectedSessionId: '',
10148
10266
  sessions: [],
@@ -10227,6 +10345,18 @@ const setStreamingEnabled = (state, streamingEnabled) => {
10227
10345
  };
10228
10346
  };
10229
10347
 
10348
+ const setUseChatCoordinatorWorker = async (state, useChatCoordinatorWorker, persist = true) => {
10349
+ if (persist) {
10350
+ await update({
10351
+ 'chatView.useChatCoordinatorWorker': useChatCoordinatorWorker
10352
+ });
10353
+ }
10354
+ return {
10355
+ ...state,
10356
+ useChatCoordinatorWorker
10357
+ };
10358
+ };
10359
+
10230
10360
  const setUseChatMathWorker = async (state, useChatMathWorker, persist = true) => {
10231
10361
  if (persist) {
10232
10362
  await update({
@@ -10309,6 +10439,7 @@ const commandMap = {
10309
10439
  'Chat.mockOpenApiRequestGetAll': wrapGetter(mockOpenApiRequestGetAll),
10310
10440
  'Chat.mockOpenApiRequestReset': wrapCommand(mockOpenApiRequestReset),
10311
10441
  'Chat.mockOpenApiSetHttpErrorResponse': wrapCommand(mockOpenApiSetHttpErrorResponse),
10442
+ 'Chat.mockOpenApiSetRequestFailedResponse': wrapCommand(mockOpenApiSetRequestFailedResponse),
10312
10443
  'Chat.mockOpenApiStreamFinish': wrapCommand(mockOpenApiStreamFinish),
10313
10444
  'Chat.mockOpenApiStreamPushChunk': wrapCommand(mockOpenApiStreamPushChunk),
10314
10445
  'Chat.mockOpenApiStreamReset': wrapCommand(mockOpenApiStreamReset),
@@ -10324,6 +10455,7 @@ const commandMap = {
10324
10455
  'Chat.setEmitStreamingFunctionCallEvents': wrapCommand(setEmitStreamingFunctionCallEvents),
10325
10456
  'Chat.setOpenRouterApiKey': wrapCommand(setOpenRouterApiKey),
10326
10457
  'Chat.setStreamingEnabled': wrapCommand(setStreamingEnabled),
10458
+ 'Chat.setUseChatCoordinatorWorker': wrapCommand(setUseChatCoordinatorWorker),
10327
10459
  'Chat.setUseChatMathWorker': wrapCommand(setUseChatMathWorker),
10328
10460
  'Chat.setUseChatNetworkWorkerForRequests': wrapCommand(setUseChatNetworkWorkerForRequests),
10329
10461
  'Chat.terminate': terminate,
@@ -10331,15 +10463,15 @@ const commandMap = {
10331
10463
  };
10332
10464
 
10333
10465
  const sendMessagePortToChatCoordinatorWorker = async port => {
10334
- // TODO:
10335
- await sendMessagePortToChatMathWorker$1(port, 0);
10466
+ const command = 'HandleMessagePort.handleMessagePort';
10467
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToChatCoordinatorWorker', port, command);
10336
10468
  };
10337
10469
  const initializeChatCoordinatorWorker = async () => {
10338
10470
  const rpc = await create$4({
10339
10471
  commandMap: {},
10340
10472
  send: sendMessagePortToChatCoordinatorWorker
10341
10473
  });
10342
- set$4(rpc);
10474
+ set(rpc);
10343
10475
  };
10344
10476
 
10345
10477
  const sendMessagePortToChatMathWorker = async port => {
@@ -10350,7 +10482,7 @@ const initializeChatMathWorker = async () => {
10350
10482
  commandMap: {},
10351
10483
  send: sendMessagePortToChatMathWorker
10352
10484
  });
10353
- set$4(rpc);
10485
+ set$5(rpc);
10354
10486
  };
10355
10487
 
10356
10488
  const send = port => {
@@ -10361,7 +10493,7 @@ const initializeChatNetworkWorker = async () => {
10361
10493
  commandMap: {},
10362
10494
  send
10363
10495
  });
10364
- set$3(rpc);
10496
+ set$4(rpc);
10365
10497
  };
10366
10498
 
10367
10499
  const listen = async () => {
@@ -10369,7 +10501,7 @@ const listen = async () => {
10369
10501
  const rpc = await create$3({
10370
10502
  commandMap: commandMap
10371
10503
  });
10372
- set$1(rpc);
10504
+ set$2(rpc);
10373
10505
  await Promise.all([initializeChatNetworkWorker(), initializeChatMathWorker(), initializeChatCoordinatorWorker()]);
10374
10506
  };
10375
10507
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-view",
3
- "version": "5.2.0",
3
+ "version": "6.0.0",
4
4
  "description": "Chat View Worker",
5
5
  "repository": {
6
6
  "type": "git",