@lobehub/chat 0.156.1 → 0.157.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.
Files changed (115) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/Dockerfile +4 -1
  3. package/package.json +3 -2
  4. package/src/config/modelProviders/anthropic.ts +3 -0
  5. package/src/config/modelProviders/google.ts +3 -0
  6. package/src/config/modelProviders/groq.ts +5 -1
  7. package/src/config/modelProviders/minimax.ts +10 -7
  8. package/src/config/modelProviders/mistral.ts +1 -0
  9. package/src/config/modelProviders/moonshot.ts +3 -0
  10. package/src/config/modelProviders/zhipu.ts +2 -6
  11. package/src/config/server/provider.ts +1 -1
  12. package/src/database/client/core/db.ts +32 -0
  13. package/src/database/client/core/schemas.ts +9 -0
  14. package/src/database/client/models/__tests__/message.test.ts +2 -2
  15. package/src/database/client/schemas/message.ts +8 -1
  16. package/src/features/AgentSetting/store/action.ts +15 -6
  17. package/src/features/Conversation/Actions/Tool.tsx +16 -0
  18. package/src/features/Conversation/Actions/index.ts +2 -2
  19. package/src/features/Conversation/Messages/Assistant/ToolCalls/index.tsx +78 -0
  20. package/src/features/Conversation/Messages/Assistant/ToolCalls/style.ts +25 -0
  21. package/src/features/Conversation/Messages/Assistant/index.tsx +47 -0
  22. package/src/features/Conversation/Messages/Default.tsx +4 -1
  23. package/src/features/Conversation/{Plugins → Messages/Tool}/Inspector/index.tsx +34 -35
  24. package/src/features/Conversation/Messages/Tool/index.tsx +44 -0
  25. package/src/features/Conversation/Messages/index.ts +3 -2
  26. package/src/features/Conversation/Plugins/Render/StandaloneType/Iframe.tsx +1 -1
  27. package/src/features/Conversation/components/SkeletonList.tsx +2 -2
  28. package/src/features/Conversation/index.tsx +2 -3
  29. package/src/libs/agent-runtime/BaseAI.ts +2 -9
  30. package/src/libs/agent-runtime/anthropic/index.test.ts +195 -0
  31. package/src/libs/agent-runtime/anthropic/index.ts +71 -15
  32. package/src/libs/agent-runtime/azureOpenai/index.ts +12 -13
  33. package/src/libs/agent-runtime/bedrock/index.ts +24 -18
  34. package/src/libs/agent-runtime/google/index.test.ts +154 -0
  35. package/src/libs/agent-runtime/google/index.ts +91 -10
  36. package/src/libs/agent-runtime/groq/index.test.ts +41 -72
  37. package/src/libs/agent-runtime/groq/index.ts +7 -0
  38. package/src/libs/agent-runtime/minimax/index.test.ts +2 -2
  39. package/src/libs/agent-runtime/minimax/index.ts +14 -37
  40. package/src/libs/agent-runtime/mistral/index.test.ts +0 -53
  41. package/src/libs/agent-runtime/mistral/index.ts +1 -0
  42. package/src/libs/agent-runtime/moonshot/index.test.ts +1 -71
  43. package/src/libs/agent-runtime/ollama/index.test.ts +197 -0
  44. package/src/libs/agent-runtime/ollama/index.ts +3 -3
  45. package/src/libs/agent-runtime/openai/index.test.ts +0 -53
  46. package/src/libs/agent-runtime/openrouter/index.test.ts +1 -53
  47. package/src/libs/agent-runtime/perplexity/index.test.ts +0 -71
  48. package/src/libs/agent-runtime/perplexity/index.ts +2 -3
  49. package/src/libs/agent-runtime/togetherai/__snapshots__/index.test.ts.snap +886 -0
  50. package/src/libs/agent-runtime/togetherai/fixtures/models.json +8111 -0
  51. package/src/libs/agent-runtime/togetherai/index.test.ts +16 -54
  52. package/src/libs/agent-runtime/types/chat.ts +19 -3
  53. package/src/libs/agent-runtime/utils/anthropicHelpers.test.ts +120 -1
  54. package/src/libs/agent-runtime/utils/anthropicHelpers.ts +67 -4
  55. package/src/libs/agent-runtime/utils/debugStream.test.ts +70 -0
  56. package/src/libs/agent-runtime/utils/debugStream.ts +39 -9
  57. package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.test.ts +521 -0
  58. package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +76 -5
  59. package/src/libs/agent-runtime/utils/response.ts +12 -0
  60. package/src/libs/agent-runtime/utils/streams/anthropic.test.ts +197 -0
  61. package/src/libs/agent-runtime/utils/streams/anthropic.ts +91 -0
  62. package/src/libs/agent-runtime/utils/streams/bedrock/claude.ts +21 -0
  63. package/src/libs/agent-runtime/utils/streams/bedrock/common.ts +32 -0
  64. package/src/libs/agent-runtime/utils/streams/bedrock/index.ts +3 -0
  65. package/src/libs/agent-runtime/utils/streams/bedrock/llama.test.ts +196 -0
  66. package/src/libs/agent-runtime/utils/streams/bedrock/llama.ts +51 -0
  67. package/src/libs/agent-runtime/utils/streams/google-ai.test.ts +97 -0
  68. package/src/libs/agent-runtime/utils/streams/google-ai.ts +68 -0
  69. package/src/libs/agent-runtime/utils/streams/index.ts +7 -0
  70. package/src/libs/agent-runtime/utils/streams/minimax.ts +39 -0
  71. package/src/libs/agent-runtime/utils/streams/ollama.test.ts +77 -0
  72. package/src/libs/agent-runtime/utils/streams/ollama.ts +38 -0
  73. package/src/libs/agent-runtime/utils/streams/openai.test.ts +263 -0
  74. package/src/libs/agent-runtime/utils/streams/openai.ts +79 -0
  75. package/src/libs/agent-runtime/utils/streams/protocol.ts +100 -0
  76. package/src/libs/agent-runtime/zeroone/index.test.ts +1 -53
  77. package/src/libs/agent-runtime/zhipu/index.test.ts +1 -1
  78. package/src/libs/agent-runtime/zhipu/index.ts +3 -2
  79. package/src/locales/default/plugin.ts +3 -4
  80. package/src/migrations/FromV4ToV5/fixtures/from-v1-to-v5-output.json +245 -0
  81. package/src/migrations/FromV4ToV5/fixtures/function-input-v4.json +96 -0
  82. package/src/migrations/FromV4ToV5/fixtures/function-output-v5.json +120 -0
  83. package/src/migrations/FromV4ToV5/index.ts +58 -0
  84. package/src/migrations/FromV4ToV5/migrations.test.ts +49 -0
  85. package/src/migrations/FromV4ToV5/types/v4.ts +21 -0
  86. package/src/migrations/FromV4ToV5/types/v5.ts +27 -0
  87. package/src/migrations/index.ts +8 -1
  88. package/src/services/__tests__/chat.test.ts +10 -20
  89. package/src/services/chat.ts +78 -65
  90. package/src/store/chat/slices/enchance/action.ts +15 -10
  91. package/src/store/chat/slices/message/action.test.ts +36 -86
  92. package/src/store/chat/slices/message/action.ts +70 -79
  93. package/src/store/chat/slices/message/reducer.ts +18 -1
  94. package/src/store/chat/slices/message/selectors.test.ts +38 -68
  95. package/src/store/chat/slices/message/selectors.ts +1 -22
  96. package/src/store/chat/slices/plugin/action.test.ts +147 -203
  97. package/src/store/chat/slices/plugin/action.ts +96 -82
  98. package/src/store/chat/slices/share/action.test.ts +3 -3
  99. package/src/store/chat/slices/share/action.ts +1 -1
  100. package/src/store/chat/slices/topic/action.ts +7 -2
  101. package/src/store/tool/selectors/tool.ts +6 -24
  102. package/src/store/tool/slices/builtin/action.test.ts +90 -0
  103. package/src/types/llm.ts +1 -1
  104. package/src/types/message/index.ts +9 -4
  105. package/src/types/message/tools.ts +57 -0
  106. package/src/types/openai/chat.ts +6 -0
  107. package/src/utils/fetch.test.ts +245 -1
  108. package/src/utils/fetch.ts +120 -44
  109. package/src/utils/toolCall.ts +21 -0
  110. package/src/features/Conversation/Messages/Assistant.tsx +0 -26
  111. package/src/features/Conversation/Messages/Function.tsx +0 -35
  112. package/src/libs/agent-runtime/ollama/stream.ts +0 -31
  113. /package/src/features/Conversation/{Plugins → Messages/Tool}/Inspector/PluginResultJSON.tsx +0 -0
  114. /package/src/features/Conversation/{Plugins → Messages/Tool}/Inspector/Settings.tsx +0 -0
  115. /package/src/features/Conversation/{Plugins → Messages/Tool}/Inspector/style.ts +0 -0
@@ -6,7 +6,7 @@ import { template } from 'lodash-es';
6
6
  import { SWRResponse, mutate } from 'swr';
7
7
  import { StateCreator } from 'zustand/vanilla';
8
8
 
9
- import { LOADING_FLAT, isFunctionMessageAtStart, testFunctionMessageAtEnd } from '@/const/message';
9
+ import { LOADING_FLAT } from '@/const/message';
10
10
  import { TraceEventType, TraceNameMap } from '@/const/trace';
11
11
  import { useClientDataSWR } from '@/libs/swr';
12
12
  import { chatService } from '@/services/chat';
@@ -17,7 +17,7 @@ import { useAgentStore } from '@/store/agent';
17
17
  import { agentSelectors } from '@/store/agent/selectors';
18
18
  import { chatHelpers } from '@/store/chat/helpers';
19
19
  import { ChatStore } from '@/store/chat/store';
20
- import { ChatMessage } from '@/types/message';
20
+ import { ChatMessage, MessageToolCall } from '@/types/message';
21
21
  import { TraceEventPayloads } from '@/types/trace';
22
22
  import { setNamespace } from '@/utils/storeDebug';
23
23
  import { nanoid } from '@/utils/uuid';
@@ -105,9 +105,6 @@ export interface ChatMessageAction {
105
105
  assistantMessageId: string,
106
106
  params?: ProcessMessageParams,
107
107
  ) => Promise<{
108
- content: string;
109
- functionCallAtEnd: boolean;
110
- functionCallContent: string;
111
108
  isFunctionCall: boolean;
112
109
  traceId?: string;
113
110
  }>;
@@ -123,7 +120,11 @@ export interface ChatMessageAction {
123
120
  * @param id
124
121
  * @param content
125
122
  */
126
- internal_updateMessageContent: (id: string, content: string) => Promise<void>;
123
+ internal_updateMessageContent: (
124
+ id: string,
125
+ content: string,
126
+ toolCalls?: MessageToolCall[],
127
+ ) => Promise<void>;
127
128
  internal_createMessage: (params: CreateMessageParams) => Promise<string>;
128
129
  internal_resendMessage: (id: string, traceId?: string) => Promise<void>;
129
130
  internal_traceMessage: (id: string, payload: TraceEventPayloads) => Promise<void>;
@@ -156,8 +157,29 @@ export const chatMessage: StateCreator<
156
157
  ChatMessageAction
157
158
  > = (set, get) => ({
158
159
  deleteMessage: async (id) => {
159
- get().internal_dispatchMessage({ type: 'deleteMessage', id });
160
- await messageService.removeMessage(id);
160
+ const message = chatSelectors.getMessageById(id)(get());
161
+ if (!message) return;
162
+
163
+ const deleteFn = async (id: string) => {
164
+ get().internal_dispatchMessage({ type: 'deleteMessage', id });
165
+ await messageService.removeMessage(id);
166
+ };
167
+
168
+ // if the message is a tool calls, then delete all the related messages
169
+ // TODO: maybe we need to delete it in the DB?
170
+ if (message.tools) {
171
+ const pools = message.tools
172
+ .flatMap((tool) => {
173
+ const messages = get().messages.filter((m) => m.tool_call_id === tool.id);
174
+
175
+ return messages.map((m) => m.id);
176
+ })
177
+ .map((i) => deleteFn(i));
178
+
179
+ await Promise.all(pools);
180
+ }
181
+
182
+ await deleteFn(id);
161
183
  await get().refreshMessages();
162
184
  },
163
185
  delAndRegenerateMessage: async (id) => {
@@ -310,8 +332,7 @@ export const chatMessage: StateCreator<
310
332
 
311
333
  // the internal process method of the AI message
312
334
  internal_coreProcessMessage: async (messages, userMessageId, params) => {
313
- const { internal_fetchAIChatMessage, triggerFunctionCall, refreshMessages, activeTopicId } =
314
- get();
335
+ const { internal_fetchAIChatMessage, triggerToolCalls, refreshMessages, activeTopicId } = get();
315
336
 
316
337
  const { model, provider } = getAgentConfig();
317
338
 
@@ -327,39 +348,15 @@ export const chatMessage: StateCreator<
327
348
  topicId: activeTopicId, // if there is activeTopicId,then add it to topicId
328
349
  };
329
350
 
330
- const mid = await get().internal_createMessage(assistantMessage);
351
+ const assistantId = await get().internal_createMessage(assistantMessage);
331
352
 
332
353
  // 2. fetch the AI response
333
- const { isFunctionCall, content, functionCallAtEnd, functionCallContent, traceId } =
334
- await internal_fetchAIChatMessage(messages, mid, params);
354
+ const { isFunctionCall } = await internal_fetchAIChatMessage(messages, assistantId, params);
335
355
 
336
356
  // 3. if it's the function call message, trigger the function method
337
357
  if (isFunctionCall) {
338
- let functionId = mid;
339
-
340
- // if the function call is at the end of the message, then create a new function message
341
- if (functionCallAtEnd) {
342
- // create a new separate message and remove the function call from the prev message
343
-
344
- await get().internal_updateMessageContent(mid, content.replace(functionCallContent, ''));
345
-
346
- const functionMessage: CreateMessageParams = {
347
- role: 'function',
348
- content: functionCallContent,
349
- fromModel: model,
350
- fromProvider: provider,
351
-
352
- parentId: userMessageId,
353
- sessionId: get().activeId,
354
- topicId: activeTopicId,
355
- traceId,
356
- };
357
-
358
- functionId = await get().internal_createMessage(functionMessage);
359
- }
360
-
361
358
  await refreshMessages();
362
- await triggerFunctionCall(functionId);
359
+ await triggerToolCalls(assistantId);
363
360
  }
364
361
  },
365
362
  internal_dispatchMessage: (payload) => {
@@ -369,7 +366,7 @@ export const chatMessage: StateCreator<
369
366
 
370
367
  const messages = messagesReducer(get().messages, payload);
371
368
 
372
- set({ messages }, false, n(`dispatchMessage/${payload.type}`, payload));
369
+ set({ messages }, false, { type: `dispatchMessage/${payload.type}`, payload });
373
370
  },
374
371
  internal_fetchAIChatMessage: async (messages, assistantId, params) => {
375
372
  const {
@@ -432,10 +429,7 @@ export const chatMessage: StateCreator<
432
429
  config.params.max_tokens = 2048;
433
430
  }
434
431
 
435
- let output = '';
436
432
  let isFunctionCall = false;
437
- let functionCallAtEnd = false;
438
- let functionCallContent = '';
439
433
  let msgTraceId: string | undefined;
440
434
 
441
435
  const { startAnimation, stopAnimation, outputQueue, isAnimationActive } =
@@ -464,7 +458,7 @@ export const chatMessage: StateCreator<
464
458
  onAbort: async () => {
465
459
  stopAnimation();
466
460
  },
467
- onFinish: async (content, { traceId, observationId }) => {
461
+ onFinish: async (content, { traceId, observationId, toolCalls }) => {
468
462
  stopAnimation();
469
463
  // if there is traceId, update it
470
464
  if (traceId) {
@@ -483,22 +477,24 @@ export const chatMessage: StateCreator<
483
477
  }
484
478
 
485
479
  // update the content after fetch result
486
- await internal_updateMessageContent(assistantId, content);
480
+ await internal_updateMessageContent(assistantId, content, toolCalls);
487
481
  },
488
- onMessageHandle: async (text) => {
489
- output += text;
490
- outputQueue.push(...text.split(''));
491
-
492
- // is this message is just a function call
493
- if (isFunctionMessageAtStart(output)) {
494
- stopAnimation();
495
- internal_dispatchMessage({
496
- id: assistantId,
497
- key: 'content',
498
- type: 'updateMessage',
499
- value: output,
500
- });
501
- isFunctionCall = true;
482
+ onMessageHandle: async (chunk) => {
483
+ switch (chunk.type) {
484
+ case 'text': {
485
+ outputQueue.push(...chunk.text.split(''));
486
+ break;
487
+ }
488
+
489
+ // is this message is just a tool call
490
+ case 'tool_calls': {
491
+ internal_dispatchMessage({
492
+ id: assistantId,
493
+ type: 'updateMessages',
494
+ value: { tools: get().internal_transformToolCalls(chunk.tool_calls) },
495
+ });
496
+ isFunctionCall = true;
497
+ }
502
498
  }
503
499
 
504
500
  // if it's the first time to receive the message,
@@ -510,23 +506,7 @@ export const chatMessage: StateCreator<
510
506
 
511
507
  internal_toggleChatLoading(false, undefined, n('generateMessage(end)') as string);
512
508
 
513
- // also exist message like this:
514
- // 请稍等,我帮您查询一下。{"tool_calls":[{"id":"call_sbca","type":"function","function":{"name":"pluginName____apiName","arguments":{"key":"value"}}}]}
515
- if (!isFunctionCall) {
516
- const { content, valid } = testFunctionMessageAtEnd(output);
517
-
518
- // if fc at end, replace the message
519
- if (valid) {
520
- isFunctionCall = true;
521
- functionCallAtEnd = true;
522
- functionCallContent = content;
523
- }
524
- }
525
-
526
509
  return {
527
- content: output,
528
- functionCallAtEnd,
529
- functionCallContent,
530
510
  isFunctionCall,
531
511
  traceId: msgTraceId,
532
512
  };
@@ -584,7 +564,7 @@ export const chatMessage: StateCreator<
584
564
  let contextMessages: ChatMessage[] = [];
585
565
 
586
566
  switch (currentMessage.role) {
587
- case 'function':
567
+ case 'tool':
588
568
  case 'user': {
589
569
  contextMessages = chats.slice(0, currentIndex + 1);
590
570
  break;
@@ -610,15 +590,26 @@ export const chatMessage: StateCreator<
610
590
  await internal_coreProcessMessage(contextMessages, latestMsg.id, { traceId });
611
591
  },
612
592
 
613
- internal_updateMessageContent: async (id, content) => {
614
- const { internal_dispatchMessage, refreshMessages } = get();
593
+ internal_updateMessageContent: async (id, content, toolCalls) => {
594
+ const { internal_dispatchMessage, refreshMessages, internal_transformToolCalls } = get();
615
595
 
616
596
  // Due to the async update method and refresh need about 100ms
617
597
  // we need to update the message content at the frontend to avoid the update flick
618
598
  // refs: https://medium.com/@kyledeguzmanx/what-are-optimistic-updates-483662c3e171
619
- internal_dispatchMessage({ id, key: 'content', type: 'updateMessage', value: content });
599
+ if (toolCalls) {
600
+ internal_dispatchMessage({
601
+ id,
602
+ type: 'updateMessages',
603
+ value: { tools: internal_transformToolCalls(toolCalls) },
604
+ });
605
+ } else {
606
+ internal_dispatchMessage({ id, type: 'updateMessages', value: { content } });
607
+ }
620
608
 
621
- await messageService.updateMessage(id, { content });
609
+ await messageService.updateMessage(id, {
610
+ content,
611
+ tools: toolCalls ? internal_transformToolCalls(toolCalls) : undefined,
612
+ });
622
613
  await refreshMessages();
623
614
  },
624
615
 
@@ -685,7 +676,7 @@ export const chatMessage: StateCreator<
685
676
  buffer += charsToAdd;
686
677
 
687
678
  // 更新消息内容,这里可能需要结合实际情况调整
688
- internal_dispatchMessage({ id, key: 'content', type: 'updateMessage', value: buffer });
679
+ internal_dispatchMessage({ id, type: 'updateMessages', value: { content: buffer } });
689
680
 
690
681
  // 设置下一个字符的延迟
691
682
  animationTimeoutId = setTimeout(updateText, 16); // 16 毫秒的延迟模拟打字机效果
@@ -11,6 +11,13 @@ interface UpdateMessage {
11
11
  type: 'updateMessage';
12
12
  value: ChatMessage[keyof ChatMessage];
13
13
  }
14
+
15
+ interface UpdateMessages {
16
+ id: string;
17
+ type: 'updateMessages';
18
+ value: Partial<ChatMessage>;
19
+ }
20
+
14
21
  interface CreateMessage {
15
22
  id: string;
16
23
  type: 'createMessage';
@@ -37,6 +44,7 @@ interface UpdateMessageExtra {
37
44
  export type MessageDispatch =
38
45
  | CreateMessage
39
46
  | UpdateMessage
47
+ | UpdateMessages
40
48
  | UpdatePluginState
41
49
  | UpdateMessageExtra
42
50
  | DeleteMessage;
@@ -54,6 +62,15 @@ export const messagesReducer = (state: ChatMessage[], payload: MessageDispatch):
54
62
  message.updatedAt = Date.now();
55
63
  });
56
64
  }
65
+ case 'updateMessages': {
66
+ return produce(state, (draftState) => {
67
+ const { id, value } = payload;
68
+ const index = draftState.findIndex((i) => i.id === id);
69
+ if (index < 0) return;
70
+
71
+ draftState[index] = merge(draftState[index], { ...value, updatedAt: Date.now() });
72
+ });
73
+ }
57
74
 
58
75
  case 'updateMessageExtra': {
59
76
  return produce(state, (draftState) => {
@@ -67,7 +84,7 @@ export const messagesReducer = (state: ChatMessage[], payload: MessageDispatch):
67
84
  message.extra[key] = value;
68
85
  }
69
86
 
70
- message.updateAt = Date.now();
87
+ message.updatedAt = Date.now();
71
88
  });
72
89
  }
73
90
 
@@ -35,12 +35,16 @@ const mockMessages = [
35
35
  {
36
36
  id: 'msg3',
37
37
  content: 'Function Message',
38
- role: 'function',
39
- plugin: {
40
- arguments: ['arg1', 'arg2'],
41
- identifier: 'func1',
42
- type: 'pluginType',
43
- },
38
+ role: 'tool',
39
+ tools: [
40
+ {
41
+ arguments: ['arg1', 'arg2'],
42
+ identifier: 'func1',
43
+ apiName: 'ttt',
44
+ type: 'pluginType',
45
+ id: 'abc',
46
+ },
47
+ ],
44
48
  },
45
49
  ] as ChatMessage[];
46
50
 
@@ -64,16 +68,22 @@ const mockedChats = [
64
68
  {
65
69
  id: 'msg3',
66
70
  content: 'Function Message',
67
- role: 'function',
71
+ role: 'tool',
68
72
  meta: {
69
- avatar: '🧩',
70
- title: 'plugin-unknown',
71
- },
72
- plugin: {
73
- arguments: ['arg1', 'arg2'],
74
- identifier: 'func1',
75
- type: 'pluginType',
73
+ avatar: '🤯',
74
+ backgroundColor: 'rgba(0,0,0,0)',
75
+ description: 'inbox.desc',
76
+ title: 'inbox.title',
76
77
  },
78
+ tools: [
79
+ {
80
+ arguments: ['arg1', 'arg2'],
81
+ identifier: 'func1',
82
+ apiName: 'ttt',
83
+ type: 'pluginType',
84
+ id: 'abc',
85
+ },
86
+ ],
77
87
  },
78
88
  ] as ChatMessage[];
79
89
 
@@ -103,52 +113,6 @@ describe('chatSelectors', () => {
103
113
  });
104
114
  });
105
115
 
106
- describe('getFunctionMessageProps', () => {
107
- it('should return the properties of a function message', () => {
108
- const state = merge(initialStore, {
109
- messages: mockMessages,
110
- chatLoadingIds: ['msg3'], // Assuming this id represents a loading state
111
- });
112
- const props = chatSelectors.getFunctionMessageProps(mockMessages[2])(state);
113
- expect(props).toEqual({
114
- arguments: ['arg1', 'arg2'],
115
- command: mockMessages[2].plugin,
116
- content: 'Function Message',
117
- id: 'func1',
118
- loading: true,
119
- type: 'pluginType',
120
- });
121
- });
122
-
123
- it('should return loading as false if the message id is not the current loading id', () => {
124
- const state = merge(initialStore, { messages: mockMessages, chatLoadingId: 'msg1' });
125
- const props = chatSelectors.getFunctionMessageProps(mockMessages[2])(state);
126
- expect(props.loading).toBe(false);
127
- });
128
-
129
- it('should return correct properties when no plugin is present', () => {
130
- const messageWithoutPlugin = {
131
- id: 'msg4',
132
- content: 'No Plugin Message',
133
- role: 'function',
134
- // No plugin property
135
- };
136
- const state = merge(initialStore, {
137
- messages: [...mockMessages, messageWithoutPlugin],
138
- chatLoadingId: 'msg1',
139
- });
140
- const props = chatSelectors.getFunctionMessageProps(messageWithoutPlugin)(state);
141
- expect(props).toEqual({
142
- arguments: undefined,
143
- command: undefined,
144
- content: 'No Plugin Message',
145
- id: undefined,
146
- loading: false,
147
- type: undefined,
148
- });
149
- });
150
- });
151
-
152
116
  describe('currentChatsWithHistoryConfig', () => {
153
117
  it('should slice the messages according to the current agent config', () => {
154
118
  const state = merge(initialStore, { messages: mockMessages });
@@ -185,16 +149,22 @@ describe('chatSelectors', () => {
185
149
  {
186
150
  id: 'msg3',
187
151
  content: 'Function Message',
188
- role: 'function',
152
+ role: 'tool',
189
153
  meta: {
190
- avatar: '🧩',
191
- title: 'plugin-unknown',
192
- },
193
- plugin: {
194
- arguments: ['arg1', 'arg2'],
195
- identifier: 'func1',
196
- type: 'pluginType',
154
+ avatar: '🤯',
155
+ backgroundColor: 'rgba(0,0,0,0)',
156
+ description: 'inbox.desc',
157
+ title: 'inbox.title',
197
158
  },
159
+ tools: [
160
+ {
161
+ apiName: 'ttt',
162
+ arguments: ['arg1', 'arg2'],
163
+ identifier: 'func1',
164
+ id: 'abc',
165
+ type: 'pluginType',
166
+ },
167
+ ],
198
168
  },
199
169
  ]);
200
170
  });
@@ -1,4 +1,3 @@
1
- import { LobePluginType } from '@lobehub/chat-plugin-sdk';
2
1
  import { t } from 'i18next';
3
2
 
4
3
  import { DEFAULT_INBOX_AVATAR, DEFAULT_USER_AVATAR } from '@/const/meta';
@@ -28,17 +27,9 @@ const getMeta = (message: ChatMessage) => {
28
27
  return message.meta;
29
28
  }
30
29
 
31
- case 'assistant': {
30
+ default: {
32
31
  return sessionMetaSelectors.currentAgentMeta(useSessionStore.getState());
33
32
  }
34
-
35
- case 'function': {
36
- // TODO: 后续改成将 plugin metadata 写入 message metadata 的方案
37
- return {
38
- avatar: '🧩',
39
- title: 'plugin-unknown',
40
- };
41
- }
42
33
  }
43
34
  };
44
35
 
@@ -116,17 +107,6 @@ const chatsMessageString = (s: ChatStore): string => {
116
107
  return chats.map((m) => m.content).join('');
117
108
  };
118
109
 
119
- const getFunctionMessageProps =
120
- ({ plugin, content, id }: Pick<ChatMessage, 'plugin' | 'content' | 'id'>) =>
121
- (s: ChatStore) => ({
122
- arguments: plugin?.arguments,
123
- command: plugin,
124
- content,
125
- id: plugin?.identifier,
126
- loading: s.chatLoadingIds.includes(id),
127
- type: plugin?.type as LobePluginType,
128
- });
129
-
130
110
  const getMessageById = (id: string) => (s: ChatStore) => chatHelpers.getMessageById(s.messages, id);
131
111
  const getTraceIdByMessageId = (id: string) => (s: ChatStore) => getMessageById(id)(s)?.traceId;
132
112
 
@@ -147,7 +127,6 @@ export const chatSelectors = {
147
127
  currentChats,
148
128
  currentChatsWithGuideMessage,
149
129
  currentChatsWithHistoryConfig,
150
- getFunctionMessageProps,
151
130
  getMessageById,
152
131
  getTraceIdByMessageId,
153
132
  isAIGenerating,