@lobehub/chat 0.154.5 → 0.154.7

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.154.7](https://github.com/lobehub/lobe-chat/compare/v0.154.6...v0.154.7)
6
+
7
+ <sup>Released on **2024-05-07**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor the message slice internal method name.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Refactor the message slice internal method name, closes [#2407](https://github.com/lobehub/lobe-chat/issues/2407) ([8c70bdd](https://github.com/lobehub/lobe-chat/commit/8c70bdd))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 0.154.6](https://github.com/lobehub/lobe-chat/compare/v0.154.5...v0.154.6)
31
+
32
+ <sup>Released on **2024-05-07**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **misc**: Add gemini-1.0-pro-002.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **misc**: Add gemini-1.0-pro-002, closes [#2406](https://github.com/lobehub/lobe-chat/issues/2406) ([44b29a9](https://github.com/lobehub/lobe-chat/commit/44b29a9))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 0.154.5](https://github.com/lobehub/lobe-chat/compare/v0.154.4...v0.154.5)
6
56
 
7
57
  <sup>Released on **2024-05-06**</sup>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.154.5",
3
+ "version": "0.154.7",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -51,6 +51,14 @@ const Google: ModelProviderCard = {
51
51
  maxOutput: 2048,
52
52
  tokens: 30_720 + 2048,
53
53
  },
54
+ {
55
+ description:
56
+ 'The best model for scaling across a wide range of tasks. Released April 9, 2024.',
57
+ displayName: 'Gemini 1.0 Pro 002 (Tuning)',
58
+ id: 'gemini-1.0-pro-002',
59
+ maxOutput: 2048,
60
+ tokens: 30_720 + 2048,
61
+ },
54
62
  {
55
63
  description:
56
64
  'The best model for scaling across a wide range of tasks. This is the latest model.',
@@ -19,7 +19,7 @@ interface APIKeyFormProps {
19
19
  const APIKeyForm = memo<APIKeyFormProps>(({ id, provider }) => {
20
20
  const { t } = useTranslation('error');
21
21
 
22
- const [resend, deleteMessage] = useChatStore((s) => [s.internalResendMessage, s.deleteMessage]);
22
+ const [resend, deleteMessage] = useChatStore((s) => [s.regenerateMessage, s.deleteMessage]);
23
23
 
24
24
  const apiKeyPlaceholder = useMemo(() => {
25
25
  switch (provider) {
@@ -19,7 +19,7 @@ const AccessCodeForm = memo<AccessCodeFormProps>(({ id }) => {
19
19
  settingsSelectors.currentSettings(s).password,
20
20
  s.setSettings,
21
21
  ]);
22
- const [resend, deleteMessage] = useChatStore((s) => [s.internalResendMessage, s.deleteMessage]);
22
+ const [resend, deleteMessage] = useChatStore((s) => [s.regenerateMessage, s.deleteMessage]);
23
23
 
24
24
  return (
25
25
  <>
@@ -15,7 +15,7 @@ const ClerkLogin = memo<{ id: string }>(({ id }) => {
15
15
  const [openSignIn, isSignedIn] = useUserStore((s) => [s.openLogin, s.isSignedIn]);
16
16
  const greeting = useGreeting();
17
17
  const nickName = useUserStore(userProfileSelectors.nickName);
18
- const [resend, deleteMessage] = useChatStore((s) => [s.internalResendMessage, s.deleteMessage]);
18
+ const [resend, deleteMessage] = useChatStore((s) => [s.regenerateMessage, s.deleteMessage]);
19
19
 
20
20
  return (
21
21
  <ErrorActionContainer>
@@ -16,7 +16,7 @@ const OAuthForm = memo<{ id: string }>(({ id }) => {
16
16
 
17
17
  const { user, isOAuthLoggedIn } = useOAuthSession();
18
18
 
19
- const [resend, deleteMessage] = useChatStore((s) => [s.internalResendMessage, s.deleteMessage]);
19
+ const [resend, deleteMessage] = useChatStore((s) => [s.regenerateMessage, s.deleteMessage]);
20
20
 
21
21
  const { message, modal } = App.useApp();
22
22
 
@@ -23,7 +23,7 @@ const PluginSettings = memo<PluginSettingsProps>(({ id, plugin }) => {
23
23
  const { styles } = useStyles();
24
24
  const { t } = useTranslation('error');
25
25
  const theme = useTheme();
26
- const [resend, deleteMessage] = useChatStore((s) => [s.internalResendMessage, s.deleteMessage]);
26
+ const [resend, deleteMessage] = useChatStore((s) => [s.regenerateMessage, s.deleteMessage]);
27
27
  const pluginIdentifier = plugin?.identifier as string;
28
28
  const pluginMeta = useToolStore(pluginSelectors.getPluginMetaById(pluginIdentifier), isEqual);
29
29
  const manifest = useToolStore(pluginSelectors.getPluginManifestById(pluginIdentifier), isEqual);
@@ -49,7 +49,7 @@ export const chatEnhance: StateCreator<
49
49
  ...data,
50
50
  }),
51
51
  translateMessage: async (id, targetLang) => {
52
- const { toggleChatLoading, updateMessageTranslate, dispatchMessage } = get();
52
+ const { internal_toggleChatLoading, updateMessageTranslate, internal_dispatchMessage } = get();
53
53
 
54
54
  const message = chatSelectors.getMessageById(id)(get());
55
55
  if (!message) return;
@@ -57,7 +57,7 @@ export const chatEnhance: StateCreator<
57
57
  // create translate extra
58
58
  await updateMessageTranslate(id, { content: '', from: '', to: targetLang });
59
59
 
60
- toggleChatLoading(true, id, n('translateMessage(start)', { id }) as string);
60
+ internal_toggleChatLoading(true, id, n('translateMessage(start)', { id }) as string);
61
61
 
62
62
  let content = '';
63
63
  let from = '';
@@ -77,7 +77,7 @@ export const chatEnhance: StateCreator<
77
77
  // translate to target language
78
78
  await chatService.fetchPresetTaskResult({
79
79
  onMessageHandle: (text) => {
80
- dispatchMessage({
80
+ internal_dispatchMessage({
81
81
  id,
82
82
  key: 'translate',
83
83
  type: 'updateMessageExtra',
@@ -93,7 +93,7 @@ export const chatEnhance: StateCreator<
93
93
 
94
94
  await updateMessageTranslate(id, { content, from, to: targetLang });
95
95
 
96
- toggleChatLoading(false);
96
+ internal_toggleChatLoading(false);
97
97
  },
98
98
 
99
99
  ttsMessage: async (id, state = {}) => {
@@ -53,7 +53,7 @@ vi.mock('@/store/chat/selectors', () => ({
53
53
  },
54
54
  }));
55
55
 
56
- const realCoreProcessMessage = useChatStore.getState().coreProcessMessage;
56
+ const realCoreProcessMessage = useChatStore.getState().internal_coreProcessMessage;
57
57
  const realRefreshMessages = useChatStore.getState().refreshMessages;
58
58
  // Mock state
59
59
  const mockState = {
@@ -62,7 +62,7 @@ const mockState = {
62
62
  messages: [],
63
63
  refreshMessages: vi.fn(),
64
64
  refreshTopic: vi.fn(),
65
- coreProcessMessage: vi.fn(),
65
+ internal_coreProcessMessage: vi.fn(),
66
66
  saveToTopic: vi.fn(),
67
67
  };
68
68
 
@@ -191,7 +191,7 @@ describe('chatMessage actions', () => {
191
191
 
192
192
  expect(messageService.createMessage).not.toHaveBeenCalled();
193
193
  expect(result.current.refreshMessages).not.toHaveBeenCalled();
194
- expect(result.current.coreProcessMessage).not.toHaveBeenCalled();
194
+ expect(result.current.internal_coreProcessMessage).not.toHaveBeenCalled();
195
195
  });
196
196
 
197
197
  it('should not send message if message is empty and there are no files', async () => {
@@ -204,7 +204,7 @@ describe('chatMessage actions', () => {
204
204
 
205
205
  expect(messageService.createMessage).not.toHaveBeenCalled();
206
206
  expect(result.current.refreshMessages).not.toHaveBeenCalled();
207
- expect(result.current.coreProcessMessage).not.toHaveBeenCalled();
207
+ expect(result.current.internal_coreProcessMessage).not.toHaveBeenCalled();
208
208
  });
209
209
 
210
210
  it('should not send message if message is empty and there are empty files', async () => {
@@ -217,10 +217,10 @@ describe('chatMessage actions', () => {
217
217
 
218
218
  expect(messageService.createMessage).not.toHaveBeenCalled();
219
219
  expect(result.current.refreshMessages).not.toHaveBeenCalled();
220
- expect(result.current.coreProcessMessage).not.toHaveBeenCalled();
220
+ expect(result.current.internal_coreProcessMessage).not.toHaveBeenCalled();
221
221
  });
222
222
 
223
- it('should create message and call coreProcessMessage if message or files are provided', async () => {
223
+ it('should create message and call internal_coreProcessMessage if message or files are provided', async () => {
224
224
  const { result } = renderHook(() => useChatStore());
225
225
  const message = 'Test message';
226
226
  const files = [{ id: 'file-id', url: 'file-url' }];
@@ -240,7 +240,7 @@ describe('chatMessage actions', () => {
240
240
  topicId: mockState.activeTopicId,
241
241
  });
242
242
  expect(result.current.refreshMessages).toHaveBeenCalled();
243
- expect(result.current.coreProcessMessage).toHaveBeenCalled();
243
+ expect(result.current.internal_coreProcessMessage).toHaveBeenCalled();
244
244
  });
245
245
 
246
246
  describe('auto-create topic', () => {
@@ -365,7 +365,7 @@ describe('chatMessage actions', () => {
365
365
  });
366
366
  });
367
367
 
368
- describe('internalResendMessage action', () => {
368
+ describe('internal_resendMessage action', () => {
369
369
  it('should resend a message by id and refresh messages', async () => {
370
370
  const { result } = renderHook(() => useChatStore());
371
371
  const messageId = 'message-id';
@@ -377,15 +377,19 @@ describe('chatMessage actions', () => {
377
377
  // ... other messages
378
378
  ]);
379
379
 
380
- // Mock the coreProcessMessage function to resolve immediately
381
- mockState.coreProcessMessage.mockResolvedValue(undefined);
380
+ // Mock the internal_coreProcessMessage function to resolve immediately
381
+ mockState.internal_coreProcessMessage.mockResolvedValue(undefined);
382
382
 
383
383
  await act(async () => {
384
- await result.current.internalResendMessage(messageId);
384
+ await result.current.internal_resendMessage(messageId);
385
385
  });
386
386
 
387
387
  expect(messageService.removeMessage).not.toHaveBeenCalledWith(messageId);
388
- expect(mockState.coreProcessMessage).toHaveBeenCalledWith(expect.any(Array), messageId, {});
388
+ expect(mockState.internal_coreProcessMessage).toHaveBeenCalledWith(
389
+ expect.any(Array),
390
+ messageId,
391
+ {},
392
+ );
389
393
  });
390
394
 
391
395
  it('should not perform any action if the message id does not exist', async () => {
@@ -398,23 +402,23 @@ describe('chatMessage actions', () => {
398
402
  ]);
399
403
 
400
404
  await act(async () => {
401
- await result.current.internalResendMessage(messageId);
405
+ await result.current.internal_resendMessage(messageId);
402
406
  });
403
407
 
404
408
  expect(messageService.removeMessage).not.toHaveBeenCalledWith(messageId);
405
- expect(mockState.coreProcessMessage).not.toHaveBeenCalled();
409
+ expect(mockState.internal_coreProcessMessage).not.toHaveBeenCalled();
406
410
  expect(mockState.refreshMessages).not.toHaveBeenCalled();
407
411
  });
408
412
  });
409
413
 
410
- describe('internalUpdateMessageContent action', () => {
411
- it('should call messageService.internalUpdateMessageContent with correct parameters', async () => {
414
+ describe('internal_updateMessageContent action', () => {
415
+ it('should call messageService.internal_updateMessageContent with correct parameters', async () => {
412
416
  const { result } = renderHook(() => useChatStore());
413
417
  const messageId = 'message-id';
414
418
  const newContent = 'Updated content';
415
419
 
416
420
  await act(async () => {
417
- await result.current.internalUpdateMessageContent(messageId, newContent);
421
+ await result.current.internal_updateMessageContent(messageId, newContent);
418
422
  });
419
423
 
420
424
  expect(messageService.updateMessage).toHaveBeenCalledWith(messageId, { content: newContent });
@@ -424,13 +428,13 @@ describe('chatMessage actions', () => {
424
428
  const { result } = renderHook(() => useChatStore());
425
429
  const messageId = 'message-id';
426
430
  const newContent = 'Updated content';
427
- const dispatchMessageSpy = vi.spyOn(result.current, 'dispatchMessage');
431
+ const internal_dispatchMessageSpy = vi.spyOn(result.current, 'internal_dispatchMessage');
428
432
 
429
433
  await act(async () => {
430
- await result.current.internalUpdateMessageContent(messageId, newContent);
434
+ await result.current.internal_updateMessageContent(messageId, newContent);
431
435
  });
432
436
 
433
- expect(dispatchMessageSpy).toHaveBeenCalledWith({
437
+ expect(internal_dispatchMessageSpy).toHaveBeenCalledWith({
434
438
  id: messageId,
435
439
  key: 'content',
436
440
  type: 'updateMessage',
@@ -444,16 +448,16 @@ describe('chatMessage actions', () => {
444
448
  const newContent = 'Updated content';
445
449
 
446
450
  await act(async () => {
447
- await result.current.internalUpdateMessageContent(messageId, newContent);
451
+ await result.current.internal_updateMessageContent(messageId, newContent);
448
452
  });
449
453
 
450
454
  expect(result.current.refreshMessages).toHaveBeenCalled();
451
455
  });
452
456
  });
453
457
 
454
- describe('coreProcessMessage action', () => {
458
+ describe('internal_coreProcessMessage action', () => {
455
459
  it('should handle the core AI message processing', async () => {
456
- useChatStore.setState({ coreProcessMessage: realCoreProcessMessage });
460
+ useChatStore.setState({ internal_coreProcessMessage: realCoreProcessMessage });
457
461
 
458
462
  const { result } = renderHook(() => useChatStore());
459
463
  const userMessage = {
@@ -473,7 +477,7 @@ describe('chatMessage actions', () => {
473
477
  (messageService.createMessage as Mock).mockResolvedValue('assistant-message-id');
474
478
 
475
479
  await act(async () => {
476
- await result.current.coreProcessMessage(messages, userMessage.id);
480
+ await result.current.internal_coreProcessMessage(messages, userMessage.id);
477
481
  });
478
482
 
479
483
  // 验证是否创建了代表 AI 响应的消息
@@ -499,7 +503,7 @@ describe('chatMessage actions', () => {
499
503
  describe('stopGenerateMessage action', () => {
500
504
  it('should stop generating message and set loading states correctly', async () => {
501
505
  const { result } = renderHook(() => useChatStore());
502
- const toggleChatLoadingSpy = vi.spyOn(result.current, 'toggleChatLoading');
506
+ const internal_toggleChatLoadingSpy = vi.spyOn(result.current, 'internal_toggleChatLoading');
503
507
  const abortController = new AbortController();
504
508
 
505
509
  act(() => {
@@ -511,7 +515,11 @@ describe('chatMessage actions', () => {
511
515
  });
512
516
 
513
517
  expect(abortController.signal.aborted).toBe(true);
514
- expect(toggleChatLoadingSpy).toHaveBeenCalledWith(false, undefined, expect.any(String));
518
+ expect(internal_toggleChatLoadingSpy).toHaveBeenCalledWith(
519
+ false,
520
+ undefined,
521
+ expect.any(String),
522
+ );
515
523
  });
516
524
 
517
525
  it('should not do anything if there is no abortController', async () => {
@@ -598,7 +606,7 @@ describe('chatMessage actions', () => {
598
606
  });
599
607
  });
600
608
 
601
- describe('fetchAIChatMessage', () => {
609
+ describe('internal_fetchAIChatMessage', () => {
602
610
  it('should fetch AI chat message and return content', async () => {
603
611
  const { result } = renderHook(() => useChatStore());
604
612
  const messages = [{ id: 'message-id', content: 'Hello', role: 'user' }] as ChatMessage[];
@@ -608,7 +616,10 @@ describe('chatMessage actions', () => {
608
616
  (fetch as Mock).mockResolvedValueOnce(new Response(aiResponse));
609
617
 
610
618
  await act(async () => {
611
- const response = await result.current.fetchAIChatMessage(messages, assistantMessageId);
619
+ const response = await result.current.internal_fetchAIChatMessage(
620
+ messages,
621
+ assistantMessageId,
622
+ );
612
623
  expect(response.content).toEqual(aiResponse);
613
624
  expect(response.isFunctionCall).toEqual(false);
614
625
  expect(response.functionCallAtEnd).toEqual(false);
@@ -627,7 +638,10 @@ describe('chatMessage actions', () => {
627
638
  vi.mocked(fetch).mockResolvedValueOnce(new Response(aiResponse));
628
639
 
629
640
  await act(async () => {
630
- const response = await result.current.fetchAIChatMessage(messages, assistantMessageId);
641
+ const response = await result.current.internal_fetchAIChatMessage(
642
+ messages,
643
+ assistantMessageId,
644
+ );
631
645
  expect(response.content).toEqual(aiResponse);
632
646
  expect(response.isFunctionCall).toEqual(true);
633
647
  expect(response.functionCallAtEnd).toEqual(false);
@@ -646,7 +660,10 @@ describe('chatMessage actions', () => {
646
660
  vi.mocked(fetch).mockResolvedValue(new Response(aiResponse));
647
661
 
648
662
  await act(async () => {
649
- const response = await result.current.fetchAIChatMessage(messages, assistantMessageId);
663
+ const response = await result.current.internal_fetchAIChatMessage(
664
+ messages,
665
+ assistantMessageId,
666
+ );
650
667
  expect(response.content).toEqual(aiResponse);
651
668
  expect(response.isFunctionCall).toEqual(true);
652
669
  expect(response.functionCallAtEnd).toEqual(true);
@@ -667,19 +684,19 @@ describe('chatMessage actions', () => {
667
684
 
668
685
  await act(async () => {
669
686
  await expect(
670
- result.current.fetchAIChatMessage(messages, assistantMessageId),
687
+ result.current.internal_fetchAIChatMessage(messages, assistantMessageId),
671
688
  ).rejects.toThrow(errorMessage);
672
689
  });
673
690
  });
674
691
  });
675
692
 
676
- describe('toggleChatLoading', () => {
693
+ describe('internal_toggleChatLoading', () => {
677
694
  it('should set loading state and create an AbortController when loading is true', () => {
678
695
  const { result } = renderHook(() => useChatStore());
679
696
  const action = 'loading-action';
680
697
 
681
698
  act(() => {
682
- result.current.toggleChatLoading(true, 'message-id', action);
699
+ result.current.internal_toggleChatLoading(true, 'message-id', action);
683
700
  });
684
701
 
685
702
  const state = useChatStore.getState();
@@ -693,12 +710,12 @@ describe('chatMessage actions', () => {
693
710
 
694
711
  // Set initial loading state
695
712
  act(() => {
696
- result.current.toggleChatLoading(true, 'message-id', 'start-loading-action');
713
+ result.current.internal_toggleChatLoading(true, 'message-id', 'start-loading-action');
697
714
  });
698
715
 
699
716
  // Stop loading
700
717
  act(() => {
701
- result.current.toggleChatLoading(false, undefined, action);
718
+ result.current.internal_toggleChatLoading(false, undefined, action);
702
719
  });
703
720
 
704
721
  const state = useChatStore.getState();
@@ -711,7 +728,7 @@ describe('chatMessage actions', () => {
711
728
  const addEventListenerSpy = vi.spyOn(window, 'addEventListener');
712
729
 
713
730
  act(() => {
714
- result.current.toggleChatLoading(true, 'message-id', 'loading-action');
731
+ result.current.internal_toggleChatLoading(true, 'message-id', 'loading-action');
715
732
  });
716
733
 
717
734
  expect(addEventListenerSpy).toHaveBeenCalledWith('beforeunload', expect.any(Function));
@@ -723,8 +740,8 @@ describe('chatMessage actions', () => {
723
740
 
724
741
  // Start and then stop loading to trigger the removal of the event listener
725
742
  act(() => {
726
- result.current.toggleChatLoading(true, 'message-id', 'start-loading-action');
727
- result.current.toggleChatLoading(false, undefined, 'stop-loading-action');
743
+ result.current.internal_toggleChatLoading(true, 'message-id', 'start-loading-action');
744
+ result.current.internal_toggleChatLoading(false, undefined, 'stop-loading-action');
728
745
  });
729
746
 
730
747
  expect(removeEventListenerSpy).toHaveBeenCalledWith('beforeunload', expect.any(Function));
@@ -736,7 +753,7 @@ describe('chatMessage actions', () => {
736
753
 
737
754
  act(() => {
738
755
  useChatStore.setState({ abortController });
739
- result.current.toggleChatLoading(true, 'message-id', 'loading-action');
756
+ result.current.internal_toggleChatLoading(true, 'message-id', 'loading-action');
740
757
  });
741
758
 
742
759
  const state = useChatStore.getState();
@@ -71,20 +71,26 @@ export interface ChatMessageAction {
71
71
  useFetchMessages: (sessionId: string, topicId?: string) => SWRResponse<ChatMessage[]>;
72
72
  stopGenerateMessage: () => void;
73
73
  copyMessage: (id: string, content: string) => Promise<void>;
74
+ refreshMessages: () => Promise<void>;
74
75
 
75
76
  // ========= ↓ Internal Method ↓ ========== //
76
77
  // ========================================== //
77
78
  // ========================================== //
78
-
79
+ internal_toggleChatLoading: (
80
+ loading: boolean,
81
+ id?: string,
82
+ action?: string,
83
+ ) => AbortController | undefined;
84
+ internal_toggleMessageLoading: (loading: boolean, id: string) => void;
79
85
  /**
80
86
  * update message at the frontend point
81
87
  * this method will not update messages to database
82
88
  */
83
- dispatchMessage: (payload: MessageDispatch) => void;
89
+ internal_dispatchMessage: (payload: MessageDispatch) => void;
84
90
  /**
85
91
  * core process of the AI message (include preprocess and postprocess)
86
92
  */
87
- coreProcessMessage: (
93
+ internal_coreProcessMessage: (
88
94
  messages: ChatMessage[],
89
95
  parentId: string,
90
96
  params?: ProcessMessageParams,
@@ -94,7 +100,7 @@ export interface ChatMessageAction {
94
100
  * @param messages - 聊天消息数组
95
101
  * @param options - 获取 SSE 选项
96
102
  */
97
- fetchAIChatMessage: (
103
+ internal_fetchAIChatMessage: (
98
104
  messages: ChatMessage[],
99
105
  assistantMessageId: string,
100
106
  params?: ProcessMessageParams,
@@ -105,15 +111,8 @@ export interface ChatMessageAction {
105
111
  isFunctionCall: boolean;
106
112
  traceId?: string;
107
113
  }>;
108
- toggleChatLoading: (
109
- loading: boolean,
110
- id?: string,
111
- action?: string,
112
- ) => AbortController | undefined;
113
- toggleMessageLoading: (loading: boolean, id: string) => void;
114
- refreshMessages: () => Promise<void>;
115
114
  // TODO: 后续 smoothMessage 实现考虑落到 sse 这一层
116
- createSmoothMessage: (id: string) => {
115
+ internal_createSmoothMessage: (id: string) => {
117
116
  startAnimation: (speed?: number) => Promise<void>;
118
117
  stopAnimation: () => void;
119
118
  outputQueue: string[];
@@ -124,10 +123,10 @@ export interface ChatMessageAction {
124
123
  * @param id
125
124
  * @param content
126
125
  */
127
- internalUpdateMessageContent: (id: string, content: string) => Promise<void>;
128
- internalCreateMessage: (params: CreateMessageParams) => Promise<string>;
129
- internalResendMessage: (id: string, traceId?: string) => Promise<void>;
130
- internalTraceMessage: (id: string, payload: TraceEventPayloads) => Promise<void>;
126
+ internal_updateMessageContent: (id: string, content: string) => Promise<void>;
127
+ internal_createMessage: (params: CreateMessageParams) => Promise<string>;
128
+ internal_resendMessage: (id: string, traceId?: string) => Promise<void>;
129
+ internal_traceMessage: (id: string, payload: TraceEventPayloads) => Promise<void>;
131
130
  }
132
131
 
133
132
  const getAgentConfig = () => agentSelectors.currentAgentConfig(useAgentStore.getState());
@@ -145,24 +144,24 @@ export const chatMessage: StateCreator<
145
144
  ChatMessageAction
146
145
  > = (set, get) => ({
147
146
  deleteMessage: async (id) => {
148
- get().dispatchMessage({ type: 'deleteMessage', id });
147
+ get().internal_dispatchMessage({ type: 'deleteMessage', id });
149
148
  await messageService.removeMessage(id);
150
149
  await get().refreshMessages();
151
150
  },
152
151
  delAndRegenerateMessage: async (id) => {
153
152
  const traceId = chatSelectors.getTraceIdByMessageId(id)(get());
154
- get().internalResendMessage(id, traceId);
153
+ get().internal_resendMessage(id, traceId);
155
154
  get().deleteMessage(id);
156
155
 
157
156
  // trace the delete and regenerate message
158
- get().internalTraceMessage(id, { eventType: TraceEventType.DeleteAndRegenerateMessage });
157
+ get().internal_traceMessage(id, { eventType: TraceEventType.DeleteAndRegenerateMessage });
159
158
  },
160
159
  regenerateMessage: async (id: string) => {
161
160
  const traceId = chatSelectors.getTraceIdByMessageId(id)(get());
162
- await get().internalResendMessage(id, traceId);
161
+ await get().internal_resendMessage(id, traceId);
163
162
 
164
163
  // trace the delete and regenerate message
165
- get().internalTraceMessage(id, { eventType: TraceEventType.RegenerateMessage });
164
+ get().internal_traceMessage(id, { eventType: TraceEventType.RegenerateMessage });
166
165
  },
167
166
  clearMessage: async () => {
168
167
  const { activeId, activeTopicId, refreshMessages, refreshTopic, switchTopic } = get();
@@ -184,7 +183,7 @@ export const chatMessage: StateCreator<
184
183
  await refreshMessages();
185
184
  },
186
185
  sendMessage: async ({ message, files, onlyAddUserMessage, isWelcomeQuestion }) => {
187
- const { coreProcessMessage, activeTopicId, activeId } = get();
186
+ const { internal_coreProcessMessage, activeTopicId, activeId } = get();
188
187
  if (!activeId) return;
189
188
 
190
189
  const fileIdList = files?.map((f) => f.id);
@@ -202,7 +201,7 @@ export const chatMessage: StateCreator<
202
201
  topicId: activeTopicId,
203
202
  };
204
203
 
205
- const id = await get().internalCreateMessage(newMessage);
204
+ const id = await get().internal_createMessage(newMessage);
206
205
 
207
206
  // if only add user message, then stop
208
207
  if (onlyAddUserMessage) return;
@@ -210,7 +209,7 @@ export const chatMessage: StateCreator<
210
209
  // Get the current messages to generate AI response
211
210
  const messages = chatSelectors.currentChats(get());
212
211
 
213
- await coreProcessMessage(messages, id, { isWelcomeQuestion });
212
+ await internal_coreProcessMessage(messages, id, { isWelcomeQuestion });
214
213
 
215
214
  // check activeTopic and then auto create topic
216
215
  const chats = chatSelectors.currentChats(get());
@@ -226,11 +225,11 @@ export const chatMessage: StateCreator<
226
225
  }
227
226
  },
228
227
  addAIMessage: async () => {
229
- const { internalCreateMessage, updateInputMessage, activeTopicId, activeId, inputMessage } =
228
+ const { internal_createMessage, updateInputMessage, activeTopicId, activeId, inputMessage } =
230
229
  get();
231
230
  if (!activeId) return;
232
231
 
233
- await internalCreateMessage({
232
+ await internal_createMessage({
234
233
  content: inputMessage,
235
234
  role: 'assistant',
236
235
  sessionId: activeId,
@@ -243,16 +242,16 @@ export const chatMessage: StateCreator<
243
242
  copyMessage: async (id, content) => {
244
243
  await copyToClipboard(content);
245
244
 
246
- get().internalTraceMessage(id, { eventType: TraceEventType.CopyMessage });
245
+ get().internal_traceMessage(id, { eventType: TraceEventType.CopyMessage });
247
246
  },
248
247
 
249
248
  stopGenerateMessage: () => {
250
- const { abortController, toggleChatLoading } = get();
249
+ const { abortController, internal_toggleChatLoading } = get();
251
250
  if (!abortController) return;
252
251
 
253
252
  abortController.abort();
254
253
 
255
- toggleChatLoading(false, undefined, n('stopGenerateMessage') as string);
254
+ internal_toggleChatLoading(false, undefined, n('stopGenerateMessage') as string);
256
255
  },
257
256
  updateInputMessage: (message) => {
258
257
  set({ inputMessage: message }, false, n('updateInputMessage', message));
@@ -260,12 +259,12 @@ export const chatMessage: StateCreator<
260
259
  modifyMessageContent: async (id, content) => {
261
260
  // tracing the diff of update
262
261
  // due to message content will change, so we need send trace before update,or will get wrong data
263
- get().internalTraceMessage(id, {
262
+ get().internal_traceMessage(id, {
264
263
  eventType: TraceEventType.ModifyMessage,
265
264
  nextContent: content,
266
265
  });
267
266
 
268
- await get().internalUpdateMessageContent(id, content);
267
+ await get().internal_updateMessageContent(id, content);
269
268
  },
270
269
  useFetchMessages: (sessionId, activeTopicId) =>
271
270
  useClientDataSWR<ChatMessage[]>(
@@ -292,8 +291,9 @@ export const chatMessage: StateCreator<
292
291
  },
293
292
 
294
293
  // the internal process method of the AI message
295
- coreProcessMessage: async (messages, userMessageId, params) => {
296
- const { fetchAIChatMessage, triggerFunctionCall, refreshMessages, activeTopicId } = get();
294
+ internal_coreProcessMessage: async (messages, userMessageId, params) => {
295
+ const { internal_fetchAIChatMessage, triggerFunctionCall, refreshMessages, activeTopicId } =
296
+ get();
297
297
 
298
298
  const { model, provider } = getAgentConfig();
299
299
 
@@ -309,11 +309,11 @@ export const chatMessage: StateCreator<
309
309
  topicId: activeTopicId, // if there is activeTopicId,then add it to topicId
310
310
  };
311
311
 
312
- const mid = await get().internalCreateMessage(assistantMessage);
312
+ const mid = await get().internal_createMessage(assistantMessage);
313
313
 
314
314
  // 2. fetch the AI response
315
315
  const { isFunctionCall, content, functionCallAtEnd, functionCallContent, traceId } =
316
- await fetchAIChatMessage(messages, mid, params);
316
+ await internal_fetchAIChatMessage(messages, mid, params);
317
317
 
318
318
  // 3. if it's the function call message, trigger the function method
319
319
  if (isFunctionCall) {
@@ -323,7 +323,7 @@ export const chatMessage: StateCreator<
323
323
  if (functionCallAtEnd) {
324
324
  // create a new separate message and remove the function call from the prev message
325
325
 
326
- await get().internalUpdateMessageContent(mid, content.replace(functionCallContent, ''));
326
+ await get().internal_updateMessageContent(mid, content.replace(functionCallContent, ''));
327
327
 
328
328
  const functionMessage: CreateMessageParams = {
329
329
  role: 'function',
@@ -337,14 +337,14 @@ export const chatMessage: StateCreator<
337
337
  traceId,
338
338
  };
339
339
 
340
- functionId = await get().internalCreateMessage(functionMessage);
340
+ functionId = await get().internal_createMessage(functionMessage);
341
341
  }
342
342
 
343
343
  await refreshMessages();
344
344
  await triggerFunctionCall(functionId);
345
345
  }
346
346
  },
347
- dispatchMessage: (payload) => {
347
+ internal_dispatchMessage: (payload) => {
348
348
  const { activeId } = get();
349
349
 
350
350
  if (!activeId) return;
@@ -353,16 +353,16 @@ export const chatMessage: StateCreator<
353
353
 
354
354
  set({ messages }, false, n(`dispatchMessage/${payload.type}`, payload));
355
355
  },
356
- fetchAIChatMessage: async (messages, assistantId, params) => {
356
+ internal_fetchAIChatMessage: async (messages, assistantId, params) => {
357
357
  const {
358
- toggleChatLoading,
358
+ internal_toggleChatLoading,
359
359
  refreshMessages,
360
- internalUpdateMessageContent,
361
- dispatchMessage,
362
- createSmoothMessage,
360
+ internal_updateMessageContent,
361
+ internal_dispatchMessage,
362
+ internal_createSmoothMessage,
363
363
  } = get();
364
364
 
365
- const abortController = toggleChatLoading(
365
+ const abortController = internal_toggleChatLoading(
366
366
  true,
367
367
  assistantId,
368
368
  n('generateMessage(start)', { assistantId, messages }) as string,
@@ -421,7 +421,7 @@ export const chatMessage: StateCreator<
421
421
  let msgTraceId: string | undefined;
422
422
 
423
423
  const { startAnimation, stopAnimation, outputQueue, isAnimationActive } =
424
- createSmoothMessage(assistantId);
424
+ internal_createSmoothMessage(assistantId);
425
425
 
426
426
  await chatService.createAssistantMessageStream({
427
427
  abortController,
@@ -465,7 +465,7 @@ export const chatMessage: StateCreator<
465
465
  }
466
466
 
467
467
  // update the content after fetch result
468
- await internalUpdateMessageContent(assistantId, content);
468
+ await internal_updateMessageContent(assistantId, content);
469
469
  },
470
470
  onMessageHandle: async (text) => {
471
471
  output += text;
@@ -474,7 +474,7 @@ export const chatMessage: StateCreator<
474
474
  // is this message is just a function call
475
475
  if (isFunctionMessageAtStart(output)) {
476
476
  stopAnimation();
477
- dispatchMessage({
477
+ internal_dispatchMessage({
478
478
  id: assistantId,
479
479
  key: 'content',
480
480
  type: 'updateMessage',
@@ -490,7 +490,7 @@ export const chatMessage: StateCreator<
490
490
  },
491
491
  });
492
492
 
493
- toggleChatLoading(false, undefined, n('generateMessage(end)') as string);
493
+ internal_toggleChatLoading(false, undefined, n('generateMessage(end)') as string);
494
494
 
495
495
  // also exist message like this:
496
496
  // 请稍等,我帮您查询一下。{"tool_calls":[{"id":"call_sbca","type":"function","function":{"name":"pluginName____apiName","arguments":{"key":"value"}}}]}
@@ -513,7 +513,7 @@ export const chatMessage: StateCreator<
513
513
  traceId: msgTraceId,
514
514
  };
515
515
  },
516
- toggleChatLoading: (loading, id, action) => {
516
+ internal_toggleChatLoading: (loading, id, action) => {
517
517
  if (loading) {
518
518
  window.addEventListener('beforeunload', preventLeavingFn);
519
519
 
@@ -527,7 +527,7 @@ export const chatMessage: StateCreator<
527
527
  window.removeEventListener('beforeunload', preventLeavingFn);
528
528
  }
529
529
  },
530
- toggleMessageLoading: (loading, id) => {
530
+ internal_toggleMessageLoading: (loading, id) => {
531
531
  set(
532
532
  {
533
533
  messageLoadingIds: produce(get().messageLoadingIds, (draft) => {
@@ -541,11 +541,11 @@ export const chatMessage: StateCreator<
541
541
  }),
542
542
  },
543
543
  false,
544
- 'toggleMessageLoading',
544
+ 'internal_toggleMessageLoading',
545
545
  );
546
546
  },
547
547
 
548
- internalResendMessage: async (messageId, traceId) => {
548
+ internal_resendMessage: async (messageId, traceId) => {
549
549
  // 1. 构造所有相关的历史记录
550
550
  const chats = chatSelectors.currentChats(get());
551
551
 
@@ -574,45 +574,45 @@ export const chatMessage: StateCreator<
574
574
 
575
575
  if (contextMessages.length <= 0) return;
576
576
 
577
- const { coreProcessMessage } = get();
577
+ const { internal_coreProcessMessage } = get();
578
578
 
579
579
  const latestMsg = contextMessages.filter((s) => s.role === 'user').at(-1);
580
580
 
581
581
  if (!latestMsg) return;
582
582
 
583
- await coreProcessMessage(contextMessages, latestMsg.id, { traceId });
583
+ await internal_coreProcessMessage(contextMessages, latestMsg.id, { traceId });
584
584
  },
585
585
 
586
- internalUpdateMessageContent: async (id, content) => {
587
- const { dispatchMessage, refreshMessages } = get();
586
+ internal_updateMessageContent: async (id, content) => {
587
+ const { internal_dispatchMessage, refreshMessages } = get();
588
588
 
589
589
  // Due to the async update method and refresh need about 100ms
590
590
  // we need to update the message content at the frontend to avoid the update flick
591
591
  // refs: https://medium.com/@kyledeguzmanx/what-are-optimistic-updates-483662c3e171
592
- dispatchMessage({ id, key: 'content', type: 'updateMessage', value: content });
592
+ internal_dispatchMessage({ id, key: 'content', type: 'updateMessage', value: content });
593
593
 
594
594
  await messageService.updateMessage(id, { content });
595
595
  await refreshMessages();
596
596
  },
597
597
 
598
- internalCreateMessage: async (message) => {
599
- const { dispatchMessage, refreshMessages, toggleMessageLoading } = get();
598
+ internal_createMessage: async (message) => {
599
+ const { internal_dispatchMessage, refreshMessages, internal_toggleMessageLoading } = get();
600
600
 
601
601
  // use optimistic update to avoid the slow waiting
602
602
  const tempId = 'tmp_' + nanoid();
603
- dispatchMessage({ type: 'createMessage', id: tempId, value: message });
603
+ internal_dispatchMessage({ type: 'createMessage', id: tempId, value: message });
604
604
 
605
- toggleMessageLoading(true, tempId);
605
+ internal_toggleMessageLoading(true, tempId);
606
606
  const id = await messageService.createMessage(message);
607
607
 
608
608
  await refreshMessages();
609
- toggleMessageLoading(false, tempId);
609
+ internal_toggleMessageLoading(false, tempId);
610
610
 
611
611
  return id;
612
612
  },
613
613
 
614
- createSmoothMessage: (id) => {
615
- const { dispatchMessage } = get();
614
+ internal_createSmoothMessage: (id) => {
615
+ const { internal_dispatchMessage } = get();
616
616
 
617
617
  let buffer = '';
618
618
  // why use queue: https://shareg.pt/GLBrjpK
@@ -658,7 +658,7 @@ export const chatMessage: StateCreator<
658
658
  buffer += charsToAdd;
659
659
 
660
660
  // 更新消息内容,这里可能需要结合实际情况调整
661
- dispatchMessage({ id, key: 'content', type: 'updateMessage', value: buffer });
661
+ internal_dispatchMessage({ id, key: 'content', type: 'updateMessage', value: buffer });
662
662
 
663
663
  // 设置下一个字符的延迟
664
664
  animationTimeoutId = setTimeout(updateText, 16); // 16 毫秒的延迟模拟打字机效果
@@ -676,7 +676,7 @@ export const chatMessage: StateCreator<
676
676
  return { startAnimation, stopAnimation, outputQueue, isAnimationActive };
677
677
  },
678
678
 
679
- internalTraceMessage: async (id, payload) => {
679
+ internal_traceMessage: async (id, payload) => {
680
680
  // tracing the diff of update
681
681
  const message = chatSelectors.getMessageById(id)(get());
682
682
  if (!message) return;
@@ -37,7 +37,7 @@ describe('ChatPluginAction', () => {
37
37
  // 设置初始状态
38
38
  const initialState = {
39
39
  messages: [],
40
- coreProcessMessage: vi.fn(),
40
+ internal_coreProcessMessage: vi.fn(),
41
41
  refreshMessages: vi.fn(),
42
42
  };
43
43
  useChatStore.setState(initialState);
@@ -51,14 +51,14 @@ describe('ChatPluginAction', () => {
51
51
  await result.current.fillPluginMessageContent(messageId, newContent, true);
52
52
  });
53
53
 
54
- // 验证 messageService.internalUpdateMessageContent 是否被正确调用
54
+ // 验证 messageService.internal_updateMessageContent 是否被正确调用
55
55
  expect(messageService.updateMessage).toHaveBeenCalledWith(messageId, { content: newContent });
56
56
 
57
57
  // 验证 refreshMessages 是否被调用
58
58
  expect(result.current.refreshMessages).toHaveBeenCalled();
59
59
 
60
60
  // 验证 coreProcessMessage 是否被正确调用
61
- expect(result.current.coreProcessMessage).toHaveBeenCalledWith(
61
+ expect(result.current.internal_coreProcessMessage).toHaveBeenCalledWith(
62
62
  mockCurrentChats,
63
63
  messageId,
64
64
  {},
@@ -86,14 +86,14 @@ describe('ChatPluginAction', () => {
86
86
  await result.current.fillPluginMessageContent(messageId, newContent);
87
87
  });
88
88
 
89
- // 验证 messageService.internalUpdateMessageContent 是否被正确调用
89
+ // 验证 messageService.internal_updateMessageContent 是否被正确调用
90
90
  expect(messageService.updateMessage).toHaveBeenCalledWith(messageId, { content: newContent });
91
91
 
92
92
  // 验证 refreshMessages 是否被调用
93
93
  expect(result.current.refreshMessages).toHaveBeenCalled();
94
94
 
95
95
  // 验证 coreProcessMessage 没有被正确调用
96
- expect(result.current.coreProcessMessage).not.toHaveBeenCalled();
96
+ expect(result.current.internal_coreProcessMessage).not.toHaveBeenCalled();
97
97
  });
98
98
  });
99
99
 
@@ -107,7 +107,7 @@ describe('ChatPluginAction', () => {
107
107
 
108
108
  vi.spyOn(storeState, 'refreshMessages');
109
109
  vi.spyOn(storeState, 'triggerAIMessage').mockResolvedValue(undefined);
110
- vi.spyOn(storeState, 'toggleChatLoading').mockReturnValue(undefined);
110
+ vi.spyOn(storeState, 'internal_toggleChatLoading').mockReturnValue(undefined);
111
111
 
112
112
  const runSpy = vi.spyOn(chatService, 'runPluginApi').mockResolvedValue({
113
113
  text: pluginApiResponse,
@@ -120,7 +120,7 @@ describe('ChatPluginAction', () => {
120
120
  await result.current.invokeDefaultTypePlugin(messageId, pluginPayload);
121
121
  });
122
122
 
123
- expect(storeState.toggleChatLoading).toHaveBeenCalledWith(
123
+ expect(storeState.internal_toggleChatLoading).toHaveBeenCalledWith(
124
124
  true,
125
125
  messageId,
126
126
  expect.any(String),
@@ -131,7 +131,7 @@ describe('ChatPluginAction', () => {
131
131
  });
132
132
  expect(storeState.refreshMessages).toHaveBeenCalled();
133
133
  expect(storeState.triggerAIMessage).toHaveBeenCalled();
134
- expect(storeState.toggleChatLoading).toHaveBeenCalledWith(false);
134
+ expect(storeState.internal_toggleChatLoading).toHaveBeenCalledWith(false);
135
135
  });
136
136
 
137
137
  it('should handle errors when the plugin API call fails', async () => {
@@ -142,7 +142,7 @@ describe('ChatPluginAction', () => {
142
142
  const storeState = useChatStore.getState();
143
143
  vi.spyOn(storeState, 'refreshMessages');
144
144
  vi.spyOn(storeState, 'triggerAIMessage').mockResolvedValue(undefined);
145
- vi.spyOn(storeState, 'toggleChatLoading').mockReturnValue(undefined);
145
+ vi.spyOn(storeState, 'internal_toggleChatLoading').mockReturnValue(undefined);
146
146
 
147
147
  vi.spyOn(chatService, 'runPluginApi').mockRejectedValue(error);
148
148
 
@@ -151,7 +151,7 @@ describe('ChatPluginAction', () => {
151
151
  await result.current.invokeDefaultTypePlugin(messageId, pluginPayload);
152
152
  });
153
153
 
154
- expect(storeState.toggleChatLoading).toHaveBeenCalledWith(
154
+ expect(storeState.internal_toggleChatLoading).toHaveBeenCalledWith(
155
155
  true,
156
156
  messageId,
157
157
  expect.any(String),
@@ -159,7 +159,7 @@ describe('ChatPluginAction', () => {
159
159
  expect(chatService.runPluginApi).toHaveBeenCalledWith(pluginPayload, { trace: {} });
160
160
  expect(messageService.updateMessageError).toHaveBeenCalledWith(messageId, error);
161
161
  expect(storeState.refreshMessages).toHaveBeenCalled();
162
- expect(storeState.toggleChatLoading).toHaveBeenCalledWith(false);
162
+ expect(storeState.internal_toggleChatLoading).toHaveBeenCalledWith(false);
163
163
  expect(storeState.triggerAIMessage).not.toHaveBeenCalled(); // 确保在错误情况下不调用此方法
164
164
  });
165
165
  });
@@ -512,8 +512,8 @@ describe('ChatPluginAction', () => {
512
512
  });
513
513
 
514
514
  useChatStore.setState({
515
- toggleChatLoading: vi.fn(),
516
- internalUpdateMessageContent: vi.fn(),
515
+ internal_toggleChatLoading: vi.fn(),
516
+ internal_updateMessageContent: vi.fn(),
517
517
  text2image: vi.fn(),
518
518
  });
519
519
 
@@ -530,18 +530,18 @@ describe('ChatPluginAction', () => {
530
530
  );
531
531
 
532
532
  // Verify that the message content was updated with the tool response
533
- expect(result.current.internalUpdateMessageContent).toHaveBeenCalledWith(
533
+ expect(result.current.internal_updateMessageContent).toHaveBeenCalledWith(
534
534
  messageId,
535
535
  toolResponse,
536
536
  );
537
537
 
538
538
  // Verify that loading was toggled correctly
539
- expect(result.current.toggleChatLoading).toHaveBeenCalledWith(
539
+ expect(result.current.internal_toggleChatLoading).toHaveBeenCalledWith(
540
540
  true,
541
541
  messageId,
542
542
  expect.any(String),
543
543
  );
544
- expect(result.current.toggleChatLoading).toHaveBeenCalledWith(false);
544
+ expect(result.current.internal_toggleChatLoading).toHaveBeenCalledWith(false);
545
545
  expect(useChatStore.getState().text2image).toHaveBeenCalled();
546
546
  });
547
547
 
@@ -561,9 +561,9 @@ describe('ChatPluginAction', () => {
561
561
  });
562
562
 
563
563
  useChatStore.setState({
564
- toggleChatLoading: vi.fn(),
564
+ internal_toggleChatLoading: vi.fn(),
565
565
  text2image: vi.fn(),
566
- internalUpdateMessageContent: vi.fn(),
566
+ internal_updateMessageContent: vi.fn(),
567
567
  });
568
568
  });
569
569
  const { result } = renderHook(() => useChatStore());
@@ -579,18 +579,18 @@ describe('ChatPluginAction', () => {
579
579
  );
580
580
 
581
581
  // Verify that the message content was updated with the tool response
582
- expect(result.current.internalUpdateMessageContent).toHaveBeenCalledWith(
582
+ expect(result.current.internal_updateMessageContent).toHaveBeenCalledWith(
583
583
  messageId,
584
584
  toolResponse,
585
585
  );
586
586
 
587
587
  // Verify that loading was toggled correctly
588
- expect(result.current.toggleChatLoading).toHaveBeenCalledWith(
588
+ expect(result.current.internal_toggleChatLoading).toHaveBeenCalledWith(
589
589
  true,
590
590
  messageId,
591
591
  expect.any(String),
592
592
  );
593
- expect(result.current.toggleChatLoading).toHaveBeenCalledWith(false);
593
+ expect(result.current.internal_toggleChatLoading).toHaveBeenCalledWith(false);
594
594
  expect(useChatStore.getState().text2image).not.toHaveBeenCalled();
595
595
  });
596
596
 
@@ -608,8 +608,8 @@ describe('ChatPluginAction', () => {
608
608
  });
609
609
 
610
610
  useChatStore.setState({
611
- toggleChatLoading: vi.fn(),
612
- internalUpdateMessageContent: vi.fn(),
611
+ internal_toggleChatLoading: vi.fn(),
612
+ internal_updateMessageContent: vi.fn(),
613
613
  text2image: vi.fn(),
614
614
  refreshMessages: vi.fn(),
615
615
  });
@@ -621,15 +621,15 @@ describe('ChatPluginAction', () => {
621
621
  });
622
622
 
623
623
  // Verify that loading was toggled correctly
624
- expect(result.current.toggleChatLoading).toHaveBeenCalledWith(
624
+ expect(result.current.internal_toggleChatLoading).toHaveBeenCalledWith(
625
625
  true,
626
626
  messageId,
627
627
  expect.any(String),
628
628
  );
629
- expect(result.current.toggleChatLoading).toHaveBeenCalledWith(false);
629
+ expect(result.current.internal_toggleChatLoading).toHaveBeenCalledWith(false);
630
630
 
631
631
  // Verify that the message content was not updated
632
- expect(result.current.internalUpdateMessageContent).not.toHaveBeenCalled();
632
+ expect(result.current.internal_updateMessageContent).not.toHaveBeenCalled();
633
633
 
634
634
  // Verify that messages were not refreshed
635
635
  expect(result.current.refreshMessages).not.toHaveBeenCalled();
@@ -54,28 +54,28 @@ export const chatPlugin: StateCreator<
54
54
  },
55
55
 
56
56
  fillPluginMessageContent: async (id, content, triggerAiMessage) => {
57
- const { triggerAIMessage, internalUpdateMessageContent } = get();
57
+ const { triggerAIMessage, internal_updateMessageContent } = get();
58
58
 
59
- await internalUpdateMessageContent(id, content);
59
+ await internal_updateMessageContent(id, content);
60
60
 
61
61
  if (triggerAiMessage) await triggerAIMessage(id);
62
62
  },
63
63
 
64
64
  invokeBuiltinTool: async (id, payload) => {
65
- const { toggleChatLoading, internalUpdateMessageContent } = get();
65
+ const { internal_toggleChatLoading, internal_updateMessageContent } = get();
66
66
  const params = JSON.parse(payload.arguments);
67
- toggleChatLoading(true, id, n('invokeBuiltinTool') as string);
67
+ internal_toggleChatLoading(true, id, n('invokeBuiltinTool') as string);
68
68
  let data;
69
69
  try {
70
70
  data = await useToolStore.getState().invokeBuiltinTool(payload.apiName, params);
71
71
  } catch (error) {
72
72
  console.log(error);
73
73
  }
74
- toggleChatLoading(false);
74
+ internal_toggleChatLoading(false);
75
75
 
76
76
  if (!data) return;
77
77
 
78
- await internalUpdateMessageContent(id, data);
78
+ await internal_updateMessageContent(id, data);
79
79
 
80
80
  // postToolCalling
81
81
  // @ts-ignore
@@ -131,11 +131,11 @@ export const chatPlugin: StateCreator<
131
131
  },
132
132
 
133
133
  runPluginApi: async (id, payload) => {
134
- const { internalUpdateMessageContent, refreshMessages, toggleChatLoading } = get();
134
+ const { internal_updateMessageContent, refreshMessages, internal_toggleChatLoading } = get();
135
135
  let data: string;
136
136
 
137
137
  try {
138
- const abortController = toggleChatLoading(true, id, n('fetchPlugin') as string);
138
+ const abortController = internal_toggleChatLoading(true, id, n('fetchPlugin') as string);
139
139
 
140
140
  const message = chatSelectors.getMessageById(id)(get());
141
141
 
@@ -162,19 +162,19 @@ export const chatPlugin: StateCreator<
162
162
  data = '';
163
163
  }
164
164
 
165
- toggleChatLoading(false);
165
+ internal_toggleChatLoading(false);
166
166
  // 如果报错则结束了
167
167
  if (!data) return;
168
168
 
169
- await internalUpdateMessageContent(id, data);
169
+ await internal_updateMessageContent(id, data);
170
170
 
171
171
  return data;
172
172
  },
173
173
 
174
174
  triggerAIMessage: async (id, traceId) => {
175
- const { coreProcessMessage } = get();
175
+ const { internal_coreProcessMessage } = get();
176
176
  const chats = chatSelectors.currentChats(get());
177
- await coreProcessMessage(chats, id, { traceId });
177
+ await internal_coreProcessMessage(chats, id, { traceId });
178
178
  },
179
179
 
180
180
  triggerFunctionCall: async (id) => {
@@ -187,7 +187,7 @@ export const chatPlugin: StateCreator<
187
187
  invokeStandaloneTypePlugin,
188
188
  invokeBuiltinTool,
189
189
  refreshMessages,
190
- internalResendMessage,
190
+ internal_resendMessage,
191
191
  deleteMessage,
192
192
  } = get();
193
193
 
@@ -213,7 +213,7 @@ export const chatPlugin: StateCreator<
213
213
 
214
214
  // fix https://github.com/lobehub/lobe-chat/issues/1094, remove and retry after experiencing plugin illusion
215
215
  if (!apiName) {
216
- internalResendMessage(id);
216
+ internal_resendMessage(id);
217
217
  deleteMessage(id);
218
218
  return;
219
219
  }
@@ -60,7 +60,7 @@ describe('chatToolSlice', () => {
60
60
  draft[0].previewUrl = 'new-url';
61
61
  draft[0].imageId = 'new-id';
62
62
  };
63
- vi.spyOn(result.current, 'internalUpdateMessageContent');
63
+ vi.spyOn(result.current, 'internal_updateMessageContent');
64
64
 
65
65
  // 模拟 getMessageById 返回消息内容
66
66
  vi.spyOn(chatSelectors, 'getMessageById').mockImplementationOnce(
@@ -75,8 +75,8 @@ describe('chatToolSlice', () => {
75
75
  await result.current.updateImageItem(messageId, updateFunction);
76
76
  });
77
77
 
78
- // 验证 internalUpdateMessageContent 是否被正确调用以更新内容
79
- expect(result.current.internalUpdateMessageContent).toHaveBeenCalledWith(
78
+ // 验证 internal_updateMessageContent 是否被正确调用以更新内容
79
+ expect(result.current.internal_updateMessageContent).toHaveBeenCalledWith(
80
80
  messageId,
81
81
  JSON.stringify([{ prompt: 'test prompt', previewUrl: 'new-url', imageId: 'new-id' }]),
82
82
  );
@@ -81,6 +81,6 @@ export const chatToolSlice: StateCreator<
81
81
  const data: DallEImageItem[] = JSON.parse(message.content);
82
82
 
83
83
  const nextContent = produce(data, updater);
84
- await get().internalUpdateMessageContent(id, JSON.stringify(nextContent));
84
+ await get().internal_updateMessageContent(id, JSON.stringify(nextContent));
85
85
  },
86
86
  });