@lvce-editor/chat-view 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1478,6 +1478,7 @@ const createDefaultState = () => {
1478
1478
  listItemHeight: 40,
1479
1479
  maxComposerRows: 5,
1480
1480
  messagesScrollTop: 0,
1481
+ mockAiResponseDelay: 800,
1481
1482
  mockApiCommandId: '',
1482
1483
  models: getDefaultModels(),
1483
1484
  nextMessageId: 1,
@@ -2138,10 +2139,14 @@ const replaySession$1 = (id, summary, events) => {
2138
2139
  }
2139
2140
  return {
2140
2141
  ...message,
2141
- inProgress: event.inProgress,
2142
+ ...(event.inProgress === undefined ? {} : {
2143
+ inProgress: event.inProgress
2144
+ }),
2142
2145
  text: event.text,
2143
2146
  time: event.time,
2144
- toolCalls: event.toolCalls
2147
+ ...(event.toolCalls === undefined ? {} : {
2148
+ toolCalls: event.toolCalls
2149
+ })
2145
2150
  };
2146
2151
  });
2147
2152
  continue;
@@ -2439,10 +2444,14 @@ const replaySession = (id, title, events) => {
2439
2444
  }
2440
2445
  return {
2441
2446
  ...message,
2442
- inProgress: event.inProgress,
2447
+ ...(event.inProgress === undefined ? {} : {
2448
+ inProgress: event.inProgress
2449
+ }),
2443
2450
  text: event.text,
2444
2451
  time: event.time,
2445
- toolCalls: event.toolCalls
2452
+ ...(event.toolCalls === undefined ? {} : {
2453
+ toolCalls: event.toolCalls
2454
+ })
2446
2455
  };
2447
2456
  });
2448
2457
  continue;
@@ -2656,8 +2665,8 @@ const delay = async ms => {
2656
2665
  await new Promise(resolve => setTimeout(resolve, ms));
2657
2666
  };
2658
2667
 
2659
- const getMockAiResponse = async userMessage => {
2660
- await delay(800);
2668
+ const getMockAiResponse = async (userMessage, delayInMs) => {
2669
+ await delay(delayInMs);
2661
2670
  return `Mock AI response: I received "${userMessage}".`;
2662
2671
  };
2663
2672
 
@@ -2750,13 +2759,23 @@ const normalizeLimitInfo = value => {
2750
2759
  const usage = Reflect.get(value, 'usage');
2751
2760
  const usageDaily = Reflect.get(value, 'usageDaily');
2752
2761
  const normalized = {
2753
- limitRemaining: typeof limitRemaining === 'number' || limitRemaining === null ? limitRemaining : undefined,
2754
- limitReset: typeof limitReset === 'string' || limitReset === null ? limitReset : undefined,
2755
- retryAfter: typeof retryAfter === 'string' || retryAfter === null ? retryAfter : undefined,
2756
- usage: typeof usage === 'number' ? usage : undefined,
2757
- usageDaily: typeof usageDaily === 'number' ? usageDaily : undefined
2762
+ ...(typeof limitRemaining === 'number' || limitRemaining === null ? {
2763
+ limitRemaining
2764
+ } : {}),
2765
+ ...(typeof limitReset === 'string' || limitReset === null ? {
2766
+ limitReset
2767
+ } : {}),
2768
+ ...(typeof retryAfter === 'string' || retryAfter === null ? {
2769
+ retryAfter
2770
+ } : {}),
2771
+ ...(typeof usage === 'number' ? {
2772
+ usage
2773
+ } : {}),
2774
+ ...(typeof usageDaily === 'number' ? {
2775
+ usageDaily
2776
+ } : {})
2758
2777
  };
2759
- const hasDetails = normalized.limitRemaining !== undefined || normalized.limitReset !== undefined || normalized.retryAfter !== undefined || normalized.usage !== undefined || normalized.usageDaily !== undefined;
2778
+ const hasDetails = typeof limitRemaining === 'number' || limitRemaining === null || typeof limitReset === 'string' || limitReset === null || typeof retryAfter === 'string' || retryAfter === null || typeof usage === 'number' || typeof usageDaily === 'number';
2760
2779
  return hasDetails ? normalized : undefined;
2761
2780
  };
2762
2781
 
@@ -2792,11 +2811,18 @@ const normalizeMockResult = value => {
2792
2811
  if (details === 'request-failed' || details === 'too-many-requests' || details === 'http-error') {
2793
2812
  const rawMessage = Reflect.get(value, 'rawMessage');
2794
2813
  const statusCode = Reflect.get(value, 'statusCode');
2814
+ const limitInfo = normalizeLimitInfo(Reflect.get(value, 'limitInfo'));
2795
2815
  return {
2796
2816
  details,
2797
- limitInfo: normalizeLimitInfo(Reflect.get(value, 'limitInfo')),
2798
- rawMessage: typeof rawMessage === 'string' ? rawMessage : undefined,
2799
- statusCode: typeof statusCode === 'number' ? statusCode : undefined,
2817
+ ...(limitInfo ? {
2818
+ limitInfo
2819
+ } : {}),
2820
+ ...(typeof rawMessage === 'string' ? {
2821
+ rawMessage
2822
+ } : {}),
2823
+ ...(typeof statusCode === 'number' ? {
2824
+ statusCode
2825
+ } : {}),
2800
2826
  type: 'error'
2801
2827
  };
2802
2828
  }
@@ -3130,7 +3156,11 @@ const updateToolCallAccumulator = (accumulator, chunk) => {
3130
3156
  }
3131
3157
  const next = {
3132
3158
  arguments: args,
3133
- id: typeof id === 'string' ? id : current.id,
3159
+ ...(typeof id === 'string' ? {
3160
+ id
3161
+ } : current.id ? {
3162
+ id: current.id
3163
+ } : {}),
3134
3164
  name
3135
3165
  };
3136
3166
  if (JSON.stringify(next) !== JSON.stringify(current)) {
@@ -3310,9 +3340,15 @@ const getOpenApiErrorDetails = async response => {
3310
3340
  const errorMessage = Reflect.get(error, 'message');
3311
3341
  const errorType = Reflect.get(error, 'type');
3312
3342
  return {
3313
- errorCode: typeof errorCode === 'string' ? errorCode : undefined,
3314
- errorMessage: typeof errorMessage === 'string' ? errorMessage : undefined,
3315
- errorType: typeof errorType === 'string' ? errorType : undefined
3343
+ ...(typeof errorCode === 'string' ? {
3344
+ errorCode
3345
+ } : {}),
3346
+ ...(typeof errorMessage === 'string' ? {
3347
+ errorMessage
3348
+ } : {}),
3349
+ ...(typeof errorType === 'string' ? {
3350
+ errorType
3351
+ } : {})
3316
3352
  };
3317
3353
  };
3318
3354
  const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApiApiBaseUrl, assetDir, platform, options) => {
@@ -3358,9 +3394,15 @@ const getOpenApiAssistantText = async (messages, modelId, openApiApiKey, openApi
3358
3394
  } = await getOpenApiErrorDetails(response);
3359
3395
  return {
3360
3396
  details: 'http-error',
3361
- errorCode,
3362
- errorMessage,
3363
- errorType,
3397
+ ...(errorCode ? {
3398
+ errorCode
3399
+ } : {}),
3400
+ ...(errorMessage ? {
3401
+ errorMessage
3402
+ } : {}),
3403
+ ...(errorType ? {
3404
+ errorType
3405
+ } : {}),
3364
3406
  statusCode: response.status,
3365
3407
  type: 'error'
3366
3408
  };
@@ -3568,10 +3610,18 @@ const getOpenRouterLimitInfo = async (openRouterApiKey, openRouterApiBaseUrl) =>
3568
3610
  const usage = Reflect.get(data, 'usage');
3569
3611
  const usageDaily = Reflect.get(data, 'usage_daily');
3570
3612
  const normalizedLimitInfo = {
3571
- limitRemaining: typeof limitRemaining === 'number' || limitRemaining === null ? limitRemaining : undefined,
3572
- limitReset: typeof limitReset === 'string' || limitReset === null ? limitReset : undefined,
3573
- usage: typeof usage === 'number' ? usage : undefined,
3574
- usageDaily: typeof usageDaily === 'number' ? usageDaily : undefined
3613
+ ...(typeof limitRemaining === 'number' || limitRemaining === null ? {
3614
+ limitRemaining
3615
+ } : {}),
3616
+ ...(typeof limitReset === 'string' || limitReset === null ? {
3617
+ limitReset
3618
+ } : {}),
3619
+ ...(typeof usage === 'number' ? {
3620
+ usage
3621
+ } : {}),
3622
+ ...(typeof usageDaily === 'number' ? {
3623
+ usageDaily
3624
+ } : {})
3575
3625
  };
3576
3626
  const hasLimitInfo = normalizedLimitInfo.limitRemaining !== undefined || normalizedLimitInfo.limitReset !== undefined || normalizedLimitInfo.usage !== undefined || normalizedLimitInfo.usageDaily !== undefined;
3577
3627
  if (!hasLimitInfo) {
@@ -3616,11 +3666,17 @@ const getOpenRouterAssistantText = async (messages, modelId, openRouterApiKey, o
3616
3666
  const limitInfo = await getOpenRouterLimitInfo(openRouterApiKey, openRouterApiBaseUrl);
3617
3667
  return {
3618
3668
  details: 'too-many-requests',
3619
- limitInfo: limitInfo || retryAfter ? {
3620
- ...limitInfo,
3621
- retryAfter
3622
- } : undefined,
3623
- rawMessage,
3669
+ ...(limitInfo || retryAfter ? {
3670
+ limitInfo: {
3671
+ ...limitInfo,
3672
+ ...(retryAfter ? {
3673
+ retryAfter
3674
+ } : {})
3675
+ }
3676
+ } : {}),
3677
+ ...(rawMessage ? {
3678
+ rawMessage
3679
+ } : {}),
3624
3680
  statusCode: 429,
3625
3681
  type: 'error'
3626
3682
  };
@@ -3782,6 +3838,7 @@ const getAiResponse = async ({
3782
3838
  assetDir,
3783
3839
  messageId,
3784
3840
  messages,
3841
+ mockAiResponseDelay = 800,
3785
3842
  mockApiCommandId,
3786
3843
  models,
3787
3844
  onDataEvent,
@@ -3816,10 +3873,18 @@ const getAiResponse = async ({
3816
3873
  } else if (openApiApiKey) {
3817
3874
  const result = await getOpenApiAssistantText(messages, getOpenApiModelId(selectedModelId), openApiApiKey, openApiApiBaseUrl, assetDir, platform, {
3818
3875
  includeObfuscation: passIncludeObfuscation,
3819
- onDataEvent,
3820
- onEventStreamFinished,
3821
- onTextChunk,
3822
- onToolCallsChunk,
3876
+ ...(onDataEvent ? {
3877
+ onDataEvent
3878
+ } : {}),
3879
+ ...(onEventStreamFinished ? {
3880
+ onEventStreamFinished
3881
+ } : {}),
3882
+ ...(onTextChunk ? {
3883
+ onTextChunk
3884
+ } : {}),
3885
+ ...(onToolCallsChunk ? {
3886
+ onToolCallsChunk
3887
+ } : {}),
3823
3888
  stream: streamingEnabled
3824
3889
  });
3825
3890
  if (result.type === 'success') {
@@ -3860,7 +3925,7 @@ const getAiResponse = async ({
3860
3925
  }
3861
3926
  }
3862
3927
  if (!text && !usesOpenApiModel && !usesOpenRouterModel) {
3863
- text = await getMockAiResponse(userText);
3928
+ text = await getMockAiResponse(userText, mockAiResponseDelay);
3864
3929
  }
3865
3930
  const assistantTime = new Date().toLocaleTimeString([], {
3866
3931
  hour: '2-digit',
@@ -3920,6 +3985,7 @@ const handleClickSaveOpenApiApiKey = async state => {
3920
3985
  const assistantMessage = await getAiResponse({
3921
3986
  assetDir: updatedState.assetDir,
3922
3987
  messages: retryMessages,
3988
+ mockAiResponseDelay: updatedState.mockAiResponseDelay,
3923
3989
  mockApiCommandId: updatedState.mockApiCommandId,
3924
3990
  models: updatedState.models,
3925
3991
  openApiApiBaseUrl: updatedState.openApiApiBaseUrl,
@@ -3999,6 +4065,7 @@ const handleClickSaveOpenRouterApiKey = async state => {
3999
4065
  const assistantMessage = await getAiResponse({
4000
4066
  assetDir: updatedState.assetDir,
4001
4067
  messages: retryMessages,
4068
+ mockAiResponseDelay: updatedState.mockAiResponseDelay,
4002
4069
  mockApiCommandId: updatedState.mockApiCommandId,
4003
4070
  models: updatedState.models,
4004
4071
  openApiApiBaseUrl: updatedState.openApiApiBaseUrl,
@@ -4156,6 +4223,7 @@ const handleSubmit = async state => {
4156
4223
  const {
4157
4224
  assetDir,
4158
4225
  composerValue,
4226
+ mockAiResponseDelay,
4159
4227
  mockApiCommandId,
4160
4228
  models,
4161
4229
  nextMessageId,
@@ -4276,13 +4344,14 @@ const handleSubmit = async state => {
4276
4344
  assetDir,
4277
4345
  messageId: assistantMessageId,
4278
4346
  messages,
4347
+ mockAiResponseDelay,
4279
4348
  mockApiCommandId,
4280
4349
  models,
4281
4350
  onDataEvent: async value => {
4282
4351
  await appendChatViewEvent({
4283
4352
  sessionId: optimisticState.selectedSessionId,
4284
4353
  timestamp: new Date().toISOString(),
4285
- type: 'data-event',
4354
+ type: 'sse-response-part',
4286
4355
  value
4287
4356
  });
4288
4357
  },
@@ -4294,7 +4363,9 @@ const handleSubmit = async state => {
4294
4363
  value: '[DONE]'
4295
4364
  });
4296
4365
  },
4297
- onTextChunk: handleTextChunkFunctionRef,
4366
+ ...(handleTextChunkFunctionRef ? {
4367
+ onTextChunk: handleTextChunkFunctionRef
4368
+ } : {}),
4298
4369
  onToolCallsChunk: async toolCalls => {
4299
4370
  handleTextChunkState = await handleToolCallsChunkFunction(state.uid, assistantMessageId, toolCalls, handleTextChunkState);
4300
4371
  },
@@ -5060,6 +5131,18 @@ const getModelOptionDOm = (model, selectedModelId) => {
5060
5131
  }, text(getModelLabel(model))];
5061
5132
  };
5062
5133
 
5134
+ const getChatSelectVirtualDom = (models, selectedModelId) => {
5135
+ const modelOptions = models.flatMap(model => getModelOptionDOm(model, selectedModelId));
5136
+ return [{
5137
+ childCount: models.length,
5138
+ className: Select,
5139
+ name: Model,
5140
+ onInput: HandleModelChange,
5141
+ type: Select$1,
5142
+ value: selectedModelId
5143
+ }, ...modelOptions];
5144
+ };
5145
+
5063
5146
  const getSendButtonClassName = isSendDisabled => {
5064
5147
  return isSendDisabled ? `${IconButton} ${SendButtonDisabled}` : `${IconButton}`;
5065
5148
  };
@@ -5119,7 +5202,6 @@ const getUsageOverviewDom = (tokensUsed, tokensMax) => {
5119
5202
 
5120
5203
  const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20) => {
5121
5204
  const isSendDisabled = composerValue.trim() === '';
5122
- const modelOptions = models.flatMap(model => getModelOptionDOm(model, selectedModelId));
5123
5205
  return [{
5124
5206
  childCount: 1,
5125
5207
  className: ChatSendArea,
@@ -5135,21 +5217,13 @@ const getChatSendAreaDom = (composerValue, models, selectedModelId, usageOvervie
5135
5217
  onFocus: HandleFocus,
5136
5218
  onInput: HandleInput,
5137
5219
  placeholder: composePlaceholder(),
5138
- // style: `height:${composerHeight}px;font-size:${composerFontSize}px;font-family:${composerFontFamily};line-height:${composerLineHeight}px;`,
5139
5220
  type: TextArea,
5140
5221
  value: composerValue
5141
5222
  }, {
5142
5223
  childCount: usageOverviewEnabled ? 3 : 2,
5143
5224
  className: ChatSendAreaBottom,
5144
5225
  type: Div
5145
- }, {
5146
- childCount: models.length,
5147
- className: Select,
5148
- name: Model,
5149
- onInput: HandleModelChange,
5150
- type: Select$1,
5151
- value: selectedModelId
5152
- }, ...modelOptions, ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...getSendButtonDom(isSendDisabled)];
5226
+ }, ...getChatSelectVirtualDom(models, selectedModelId), ...(usageOverviewEnabled ? getUsageOverviewDom(tokensUsed, tokensMax) : []), ...getSendButtonDom(isSendDisabled)];
5153
5227
  };
5154
5228
 
5155
5229
  const getBackButtonVirtualDom = () => {
@@ -5577,7 +5651,7 @@ const getChatModeUnsupportedVirtualDom = () => {
5577
5651
  }, text(unknownViewMode())];
5578
5652
  };
5579
5653
 
5580
- const getChatVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput = '', openRouterApiKeyState = 'idle', composerHeight = 28, composerFontSize = 13, composerFontFamily = 'system-ui', composerLineHeight = 20, chatListScrollTop = 0, messagesScrollTop = 0) => {
5654
+ const getChatVirtualDom = (sessions, selectedSessionId, composerValue, openRouterApiKeyInput, viewMode, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openApiApiKeyInput, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, chatListScrollTop, messagesScrollTop) => {
5581
5655
  switch (viewMode) {
5582
5656
  case 'detail':
5583
5657
  return getChatModeDetailVirtualDom(sessions, selectedSessionId, composerValue, openRouterApiKeyInput, openApiApiKeyInput, models, selectedModelId, usageOverviewEnabled, tokensUsed, tokensMax, openRouterApiKeyState, composerHeight, composerFontSize, composerFontFamily, composerLineHeight, messagesScrollTop);
@@ -5746,6 +5820,7 @@ const reset = async state => {
5746
5820
  ...state,
5747
5821
  composerHeight: getMinComposerHeightForState(state),
5748
5822
  composerValue: '',
5823
+ mockAiResponseDelay: 0,
5749
5824
  openRouterApiKey: '',
5750
5825
  selectedModelId: 'test',
5751
5826
  selectedSessionId: '',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-view",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "Chat View Worker",
5
5
  "repository": {
6
6
  "type": "git",