@lobehub/lobehub 2.0.0-next.37 → 2.0.0-next.39

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 (127) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/apps/desktop/src/main/modules/networkProxy/__tests__/dispatcher.test.ts +401 -0
  3. package/apps/desktop/src/main/modules/networkProxy/__tests__/tester.test.ts +531 -0
  4. package/apps/desktop/src/main/modules/networkProxy/__tests__/urlBuilder.test.ts +349 -0
  5. package/apps/desktop/src/main/modules/networkProxy/__tests__/validator.test.ts +492 -0
  6. package/changelog/v1.json +14 -0
  7. package/locales/ar/auth.json +45 -1
  8. package/locales/ar/modelProvider.json +13 -1
  9. package/locales/bg-BG/auth.json +45 -1
  10. package/locales/bg-BG/modelProvider.json +13 -1
  11. package/locales/de-DE/auth.json +45 -1
  12. package/locales/de-DE/modelProvider.json +13 -1
  13. package/locales/en-US/auth.json +45 -1
  14. package/locales/en-US/modelProvider.json +13 -1
  15. package/locales/es-ES/auth.json +45 -1
  16. package/locales/es-ES/modelProvider.json +13 -1
  17. package/locales/fa-IR/auth.json +45 -1
  18. package/locales/fa-IR/modelProvider.json +13 -1
  19. package/locales/fr-FR/auth.json +45 -1
  20. package/locales/fr-FR/modelProvider.json +13 -1
  21. package/locales/it-IT/auth.json +45 -1
  22. package/locales/it-IT/modelProvider.json +13 -1
  23. package/locales/ja-JP/auth.json +45 -1
  24. package/locales/ja-JP/modelProvider.json +13 -1
  25. package/locales/ko-KR/auth.json +45 -1
  26. package/locales/ko-KR/modelProvider.json +13 -1
  27. package/locales/nl-NL/auth.json +45 -1
  28. package/locales/nl-NL/modelProvider.json +13 -1
  29. package/locales/pl-PL/auth.json +45 -1
  30. package/locales/pl-PL/modelProvider.json +13 -1
  31. package/locales/pt-BR/auth.json +45 -1
  32. package/locales/pt-BR/modelProvider.json +13 -1
  33. package/locales/ru-RU/auth.json +45 -1
  34. package/locales/ru-RU/modelProvider.json +13 -1
  35. package/locales/tr-TR/auth.json +45 -1
  36. package/locales/tr-TR/modelProvider.json +13 -1
  37. package/locales/vi-VN/auth.json +45 -1
  38. package/locales/vi-VN/modelProvider.json +13 -1
  39. package/locales/zh-CN/auth.json +45 -1
  40. package/locales/zh-CN/modelProvider.json +13 -1
  41. package/locales/zh-TW/auth.json +45 -1
  42. package/locales/zh-TW/modelProvider.json +13 -1
  43. package/package.json +1 -1
  44. package/packages/context-engine/src/processors/MessageCleanup.ts +1 -0
  45. package/packages/context-engine/src/processors/__tests__/MessageCleanup.test.ts +28 -0
  46. package/packages/obervability-otel/package.json +3 -1
  47. package/packages/obervability-otel/src/api.ts +2 -0
  48. package/packages/obervability-otel/src/trpc/convention.ts +16 -0
  49. package/packages/obervability-otel/src/trpc/index.test.ts +38 -0
  50. package/packages/obervability-otel/src/trpc/index.ts +62 -0
  51. package/packages/obervability-otel/src/trpc/metrics.ts +31 -0
  52. package/packages/types/src/usage/usageRecord.ts +54 -0
  53. package/packages/web-crawler/src/crawImpl/browserless.ts +1 -1
  54. package/packages/web-crawler/src/crawImpl/naive.ts +9 -9
  55. package/packages/web-crawler/src/crawler.ts +5 -5
  56. package/packages/web-crawler/src/urlRules.ts +13 -13
  57. package/packages/web-crawler/src/utils/appUrlRules.ts +5 -5
  58. package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +10 -1
  59. package/src/app/[variants]/(main)/profile/usage/Client.tsx +114 -0
  60. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/ModelTable.tsx +175 -0
  61. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/index.tsx +126 -0
  62. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/MonthSpend.tsx +53 -0
  63. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/TodaySpend.tsx +67 -0
  64. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/index.tsx +19 -0
  65. package/src/app/[variants]/(main)/profile/usage/features/UsageTable.tsx +145 -0
  66. package/src/app/[variants]/(main)/profile/usage/features/UsageTrends.tsx +107 -0
  67. package/src/app/[variants]/(main)/profile/usage/features/components/UsageBarChart.tsx +48 -0
  68. package/src/app/[variants]/(main)/profile/usage/page.tsx +23 -0
  69. package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +3 -3
  70. package/src/features/Conversation/Messages/Group/Actions/WithoutContentId.tsx +37 -14
  71. package/src/features/Conversation/Messages/Group/Error/index.tsx +1 -1
  72. package/src/features/Conversation/Messages/Group/GroupChildren.tsx +13 -35
  73. package/src/features/Conversation/Messages/Group/GroupItem.tsx +43 -0
  74. package/src/features/Conversation/Messages/Group/Tool/Inspector/index.tsx +1 -2
  75. package/src/features/Conversation/Messages/Group/Tool/Render/CustomRender.tsx +1 -1
  76. package/src/features/Conversation/Messages/Group/Tool/index.tsx +0 -2
  77. package/src/features/Conversation/Messages/Group/index.tsx +7 -2
  78. package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +3 -0
  79. package/src/features/Conversation/hooks/useChatListActionsBar.tsx +21 -7
  80. package/src/features/PluginsUI/Render/BuiltinType/index.tsx +1 -1
  81. package/src/features/PluginsUI/Render/MCPType/index.tsx +52 -0
  82. package/src/features/PluginsUI/Render/StandaloneType/Iframe.tsx +2 -2
  83. package/src/features/PluginsUI/Render/index.tsx +17 -0
  84. package/src/libs/mcp/client.ts +3 -2
  85. package/src/libs/mcp/types.ts +71 -0
  86. package/src/libs/trpc/lambda/index.ts +5 -2
  87. package/src/libs/trpc/middleware/openTelemetry.ts +141 -0
  88. package/src/locales/default/auth.ts +44 -0
  89. package/src/locales/default/chat.ts +1 -0
  90. package/src/server/routers/desktop/mcp.ts +1 -3
  91. package/src/server/routers/lambda/index.ts +2 -0
  92. package/src/server/routers/lambda/usage.ts +36 -0
  93. package/src/server/routers/tools/mcp.ts +1 -3
  94. package/src/server/services/mcp/index.test.ts +28 -15
  95. package/src/server/services/mcp/index.ts +29 -18
  96. package/src/server/services/usage/index.test.ts +310 -0
  97. package/src/server/services/usage/index.ts +164 -0
  98. package/src/services/chat/contextEngineering.test.ts +4 -0
  99. package/src/services/mcp.test.ts +7 -1
  100. package/src/services/mcp.ts +13 -12
  101. package/src/services/usage.ts +13 -0
  102. package/src/store/chat/agents/createAgentExecutors.ts +2 -3
  103. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +40 -1
  104. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +13 -5
  105. package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +3 -3
  106. package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +6 -6
  107. package/src/store/chat/slices/builtinTool/actions/interpreter.ts +2 -2
  108. package/src/store/chat/slices/builtinTool/actions/localSystem.ts +2 -2
  109. package/src/store/chat/slices/builtinTool/actions/search.ts +6 -6
  110. package/src/store/chat/slices/message/actions/publicApi.ts +19 -1
  111. package/src/store/chat/slices/message/initialState.ts +5 -0
  112. package/src/store/chat/slices/message/selectors/chat.test.ts +22 -602
  113. package/src/store/chat/slices/message/selectors/chat.ts +0 -2
  114. package/src/store/chat/slices/message/selectors/dbMessage.test.ts +51 -0
  115. package/src/store/chat/slices/message/selectors/displayMessage.test.ts +818 -0
  116. package/src/store/chat/slices/message/selectors/displayMessage.ts +52 -1
  117. package/src/store/chat/slices/message/selectors/messageState.ts +2 -0
  118. package/src/store/chat/slices/plugin/action.test.ts +4 -4
  119. package/src/store/chat/slices/plugin/actions/index.ts +39 -0
  120. package/src/store/chat/slices/plugin/actions/internals.ts +83 -0
  121. package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +188 -0
  122. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +213 -0
  123. package/src/store/chat/slices/plugin/actions/publicApi.ts +115 -0
  124. package/src/store/chat/slices/plugin/actions/workflow.ts +121 -0
  125. package/src/store/chat/store.ts +1 -1
  126. package/src/store/global/initialState.ts +1 -0
  127. package/src/store/chat/slices/plugin/action.ts +0 -539
@@ -1,539 +0,0 @@
1
- /* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
2
- import { ToolNameResolver } from '@lobechat/context-engine';
3
- import {
4
- ChatMessageError,
5
- ChatToolPayload,
6
- CreateMessageParams,
7
- MessageToolCall,
8
- ToolsCallingContext,
9
- UIChatMessage,
10
- } from '@lobechat/types';
11
- import { LobeChatPluginManifest, PluginErrorType } from '@lobehub/chat-plugin-sdk';
12
- import isEqual from 'fast-deep-equal';
13
- import { t } from 'i18next';
14
- import { StateCreator } from 'zustand/vanilla';
15
-
16
- import { chatService } from '@/services/chat';
17
- import { mcpService } from '@/services/mcp';
18
- import { messageService } from '@/services/message';
19
- import { ChatStore } from '@/store/chat/store';
20
- import { useToolStore } from '@/store/tool';
21
- import { pluginSelectors } from '@/store/tool/selectors';
22
- import { builtinTools } from '@/tools';
23
- import { merge } from '@/utils/merge';
24
- import { safeParseJSON } from '@/utils/safeParseJSON';
25
- import { setNamespace } from '@/utils/storeDebug';
26
-
27
- import { dbMessageSelectors, displayMessageSelectors } from '../message/selectors';
28
- import { threadSelectors } from '../thread/selectors';
29
-
30
- const n = setNamespace('plugin');
31
-
32
- export interface ChatPluginAction {
33
- createAssistantMessageByPlugin: (content: string, parentId: string) => Promise<void>;
34
- fillPluginMessageContent: (
35
- id: string,
36
- content: string,
37
- triggerAiMessage?: boolean,
38
- ) => Promise<void>;
39
-
40
- invokeBuiltinTool: (id: string, payload: ChatToolPayload) => Promise<void>;
41
- invokeDefaultTypePlugin: (id: string, payload: any) => Promise<string | undefined>;
42
- invokeMarkdownTypePlugin: (id: string, payload: ChatToolPayload) => Promise<void>;
43
- invokeMCPTypePlugin: (id: string, payload: ChatToolPayload) => Promise<string | undefined>;
44
-
45
- invokeStandaloneTypePlugin: (id: string, payload: ChatToolPayload) => Promise<void>;
46
-
47
- reInvokeToolMessage: (id: string) => Promise<void>;
48
- triggerAIMessage: (params: {
49
- parentId?: string;
50
- traceId?: string;
51
- threadId?: string;
52
- inPortalThread?: boolean;
53
- inSearchWorkflow?: boolean;
54
- }) => Promise<void>;
55
- summaryPluginContent: (id: string) => Promise<void>;
56
-
57
- /**
58
- * @deprecated V1 method
59
- */
60
- triggerToolCalls: (
61
- id: string,
62
- params?: { threadId?: string; inPortalThread?: boolean; inSearchWorkflow?: boolean },
63
- ) => Promise<void>;
64
- updatePluginState: (id: string, value: any) => Promise<void>;
65
- updatePluginArguments: <T = any>(id: string, value: T, replace?: boolean) => Promise<void>;
66
-
67
- internal_addToolToAssistantMessage: (id: string, tool: ChatToolPayload) => Promise<void>;
68
- internal_removeToolToAssistantMessage: (id: string, tool_call_id?: string) => Promise<void>;
69
- /**
70
- * use the optimistic update value to update the message tools to database
71
- */
72
- internal_refreshToUpdateMessageTools: (id: string) => Promise<void>;
73
-
74
- internal_callPluginApi: (id: string, payload: ChatToolPayload) => Promise<string | undefined>;
75
- internal_invokeDifferentTypePlugin: (id: string, payload: ChatToolPayload) => Promise<any>;
76
- internal_togglePluginApiCalling: (
77
- loading: boolean,
78
- id?: string,
79
- action?: string,
80
- ) => AbortController | undefined;
81
- internal_transformToolCalls: (toolCalls: MessageToolCall[]) => ChatToolPayload[];
82
- internal_updatePluginError: (id: string, error: ChatMessageError) => Promise<void>;
83
- internal_constructToolsCallingContext: (id: string) => ToolsCallingContext | undefined;
84
- }
85
-
86
- export const chatPlugin: StateCreator<
87
- ChatStore,
88
- [['zustand/devtools', never]],
89
- [],
90
- ChatPluginAction
91
- > = (set, get) => ({
92
- createAssistantMessageByPlugin: async (content, parentId) => {
93
- const newMessage: CreateMessageParams = {
94
- content,
95
- parentId,
96
- role: 'assistant',
97
- sessionId: get().activeId,
98
- topicId: get().activeTopicId, // if there is activeTopicId,then add it to topicId
99
- };
100
-
101
- const result = await messageService.createMessage(newMessage);
102
- get().replaceMessages(result.messages);
103
- },
104
-
105
- fillPluginMessageContent: async (id, content, triggerAiMessage) => {
106
- const { triggerAIMessage, optimisticUpdateMessageContent } = get();
107
-
108
- await optimisticUpdateMessageContent(id, content);
109
-
110
- if (triggerAiMessage) await triggerAIMessage({ parentId: id });
111
- },
112
- invokeBuiltinTool: async (id, payload) => {
113
- // run tool api call
114
- // @ts-ignore
115
- const { [payload.apiName]: action } = get();
116
- if (!action) return;
117
-
118
- const content = safeParseJSON(payload.arguments);
119
-
120
- if (!content) return;
121
-
122
- return await action(id, content);
123
- },
124
-
125
- invokeDefaultTypePlugin: async (id, payload) => {
126
- const { internal_callPluginApi } = get();
127
-
128
- const data = await internal_callPluginApi(id, payload);
129
-
130
- if (!data) return;
131
-
132
- return data;
133
- },
134
-
135
- invokeMarkdownTypePlugin: async (id, payload) => {
136
- const { internal_callPluginApi } = get();
137
-
138
- await internal_callPluginApi(id, payload);
139
- },
140
-
141
- invokeStandaloneTypePlugin: async (id, payload) => {
142
- const result = await useToolStore.getState().validatePluginSettings(payload.identifier);
143
- if (!result) return;
144
-
145
- // if the plugin settings is not valid, then set the message with error type
146
- if (!result.valid) {
147
- const updateResult = await messageService.updateMessageError(id, {
148
- body: {
149
- error: result.errors,
150
- message: '[plugin] your settings is invalid with plugin manifest setting schema',
151
- },
152
- message: t('response.PluginSettingsInvalid', { ns: 'error' }),
153
- type: PluginErrorType.PluginSettingsInvalid as any,
154
- });
155
-
156
- if (updateResult?.success && updateResult.messages) {
157
- get().replaceMessages(updateResult.messages);
158
- }
159
- return;
160
- }
161
- },
162
-
163
- reInvokeToolMessage: async (id) => {
164
- const message = displayMessageSelectors.getDisplayMessageById(id)(get());
165
- if (!message || message.role !== 'tool' || !message.plugin) return;
166
-
167
- // if there is error content, then clear the error
168
- if (!!message.pluginError) {
169
- get().optimisticUpdateMessagePluginError(id, null);
170
- }
171
-
172
- const payload: ChatToolPayload = { ...message.plugin, id: message.tool_call_id! };
173
-
174
- await get().internal_invokeDifferentTypePlugin(id, payload);
175
- },
176
-
177
- triggerAIMessage: async ({ parentId, traceId, threadId, inPortalThread, inSearchWorkflow }) => {
178
- const { internal_execAgentRuntime } = get();
179
-
180
- const chats = inPortalThread
181
- ? threadSelectors.portalAIChatsWithHistoryConfig(get())
182
- : displayMessageSelectors.mainAIChatsWithHistoryConfig(get());
183
-
184
- await internal_execAgentRuntime({
185
- messages: chats,
186
- parentMessageId: parentId ?? chats.at(-1)!.id,
187
- parentMessageType: 'user',
188
- traceId,
189
- threadId,
190
- inPortalThread,
191
- inSearchWorkflow,
192
- });
193
- },
194
-
195
- summaryPluginContent: async (id) => {
196
- const message = displayMessageSelectors.getDisplayMessageById(id)(get());
197
- if (!message || message.role !== 'tool') return;
198
-
199
- await get().internal_execAgentRuntime({
200
- messages: [
201
- {
202
- role: 'assistant',
203
- content: '作为一名总结专家,请结合以上系统提示词,将以下内容进行总结:',
204
- },
205
- {
206
- ...message,
207
- content: message.content,
208
- role: 'assistant',
209
- name: undefined,
210
- tool_call_id: undefined,
211
- },
212
- ] as UIChatMessage[],
213
- parentMessageId: message.id,
214
- parentMessageType: 'assistant',
215
- });
216
- },
217
-
218
- triggerToolCalls: async (assistantId, { threadId, inPortalThread, inSearchWorkflow } = {}) => {
219
- const message = displayMessageSelectors.getDisplayMessageById(assistantId)(get());
220
- if (!message || !message.tools) return;
221
-
222
- let shouldCreateMessage = false;
223
- let latestToolId = '';
224
- const messagePools = message.tools.map(async (payload) => {
225
- const toolMessage: CreateMessageParams = {
226
- content: '',
227
- parentId: assistantId,
228
- plugin: payload,
229
- role: 'tool',
230
- sessionId: get().activeId,
231
- tool_call_id: payload.id,
232
- threadId,
233
- topicId: get().activeTopicId, // if there is activeTopicId,then add it to topicId
234
- groupId: message.groupId, // Propagate groupId from parent message for group chat
235
- };
236
-
237
- const result = await get().optimisticCreateMessage(toolMessage);
238
- if (!result) return;
239
-
240
- // trigger the plugin call
241
- const data = await get().internal_invokeDifferentTypePlugin(result.id, payload);
242
-
243
- if (data && !['markdown', 'standalone'].includes(payload.type)) {
244
- shouldCreateMessage = true;
245
- latestToolId = result.id;
246
- }
247
- });
248
-
249
- await Promise.all(messagePools);
250
-
251
- await get().internal_toggleMessageInToolsCalling(false, assistantId);
252
-
253
- // only default type tool calls should trigger AI message
254
- if (!shouldCreateMessage) return;
255
-
256
- const traceId = dbMessageSelectors.getTraceIdByDbMessageId(latestToolId)(get());
257
-
258
- await get().triggerAIMessage({ traceId, threadId, inPortalThread, inSearchWorkflow });
259
- },
260
- updatePluginState: async (id, value) => {
261
- const { replaceMessages } = get();
262
-
263
- // optimistic update
264
- get().internal_dispatchMessage({ id, type: 'updateMessage', value: { pluginState: value } });
265
-
266
- const result = await messageService.updateMessagePluginState(id, value, {
267
- sessionId: get().activeId,
268
- topicId: get().activeTopicId,
269
- });
270
-
271
- if (result?.success && result.messages) {
272
- replaceMessages(result.messages);
273
- }
274
- },
275
-
276
- updatePluginArguments: async (id, value, replace = false) => {
277
- const { refreshMessages } = get();
278
- const toolMessage = displayMessageSelectors.getDisplayMessageById(id)(get());
279
- if (!toolMessage || !toolMessage?.tool_call_id) return;
280
-
281
- let assistantMessage = displayMessageSelectors.getDisplayMessageById(
282
- toolMessage?.parentId || '',
283
- )(get());
284
-
285
- const prevArguments = toolMessage?.plugin?.arguments;
286
- const prevJson = safeParseJSON(prevArguments || '');
287
- const nextValue = replace ? (value as any) : merge(prevJson || {}, value);
288
- if (isEqual(prevJson, nextValue)) return;
289
-
290
- // optimistic update
291
- get().internal_dispatchMessage({
292
- id,
293
- type: 'updateMessagePlugin',
294
- value: { arguments: JSON.stringify(nextValue) },
295
- });
296
-
297
- // 同样需要更新 assistantMessage 的 pluginArguments
298
- if (assistantMessage) {
299
- get().internal_dispatchMessage({
300
- id: assistantMessage.id,
301
- type: 'updateMessageTools',
302
- tool_call_id: toolMessage?.tool_call_id,
303
- value: { arguments: JSON.stringify(nextValue) },
304
- });
305
- assistantMessage = displayMessageSelectors.getDisplayMessageById(assistantMessage?.id)(get());
306
- }
307
-
308
- const updateAssistantMessage = async () => {
309
- if (!assistantMessage) return;
310
- await messageService.updateMessage(assistantMessage!.id, {
311
- tools: assistantMessage?.tools,
312
- });
313
- };
314
-
315
- await Promise.all([
316
- messageService.updateMessagePluginArguments(id, nextValue),
317
- updateAssistantMessage(),
318
- ]);
319
-
320
- await refreshMessages();
321
- },
322
-
323
- internal_addToolToAssistantMessage: async (id, tool) => {
324
- const assistantMessage = displayMessageSelectors.getDisplayMessageById(id)(get());
325
- if (!assistantMessage) return;
326
-
327
- const { internal_dispatchMessage, internal_refreshToUpdateMessageTools } = get();
328
- internal_dispatchMessage({
329
- type: 'addMessageTool',
330
- value: tool,
331
- id: assistantMessage.id,
332
- });
333
-
334
- await internal_refreshToUpdateMessageTools(id);
335
- },
336
-
337
- internal_removeToolToAssistantMessage: async (id, tool_call_id) => {
338
- const message = displayMessageSelectors.getDisplayMessageById(id)(get());
339
- if (!message || !tool_call_id) return;
340
-
341
- const { internal_dispatchMessage, internal_refreshToUpdateMessageTools } = get();
342
-
343
- // optimistic update
344
- internal_dispatchMessage({ type: 'deleteMessageTool', tool_call_id, id: message.id });
345
-
346
- // update the message tools
347
- await internal_refreshToUpdateMessageTools(id);
348
- },
349
- internal_refreshToUpdateMessageTools: async (id) => {
350
- const message = dbMessageSelectors.getDbMessageById(id)(get());
351
- if (!message || !message.tools) return;
352
-
353
- const { internal_toggleMessageLoading, replaceMessages } = get();
354
-
355
- internal_toggleMessageLoading(true, id);
356
- const result = await messageService.updateMessage(
357
- id,
358
- { tools: message.tools },
359
- {
360
- sessionId: get().activeId,
361
- topicId: get().activeTopicId,
362
- },
363
- );
364
- internal_toggleMessageLoading(false, id);
365
-
366
- if (result?.success && result.messages) {
367
- replaceMessages(result.messages);
368
- }
369
- },
370
-
371
- internal_callPluginApi: async (id, payload) => {
372
- const { optimisticUpdateMessageContent, internal_togglePluginApiCalling } = get();
373
- let data: string;
374
-
375
- try {
376
- const abortController = internal_togglePluginApiCalling(
377
- true,
378
- id,
379
- n('fetchPlugin/start') as string,
380
- );
381
-
382
- const message = displayMessageSelectors.getDisplayMessageById(id)(get());
383
-
384
- const res = await chatService.runPluginApi(payload, {
385
- signal: abortController?.signal,
386
- trace: { observationId: message?.observationId, traceId: message?.traceId },
387
- });
388
- data = res.text;
389
-
390
- // save traceId
391
- if (res.traceId) {
392
- await messageService.updateMessage(id, { traceId: res.traceId });
393
- }
394
- } catch (error) {
395
- console.log(error);
396
- const err = error as Error;
397
-
398
- // ignore the aborted request error
399
- if (!err.message.includes('The user aborted a request.')) {
400
- const result = await messageService.updateMessageError(id, error as any);
401
- if (result?.success && result.messages) {
402
- get().replaceMessages(result.messages);
403
- }
404
- }
405
-
406
- data = '';
407
- }
408
-
409
- internal_togglePluginApiCalling(false, id, n('fetchPlugin/end') as string);
410
- // 如果报错则结束了
411
- if (!data) return;
412
-
413
- await optimisticUpdateMessageContent(id, data);
414
-
415
- return data;
416
- },
417
-
418
- internal_invokeDifferentTypePlugin: async (id, payload) => {
419
- switch (payload.type) {
420
- case 'standalone': {
421
- return await get().invokeStandaloneTypePlugin(id, payload);
422
- }
423
-
424
- case 'markdown': {
425
- return await get().invokeMarkdownTypePlugin(id, payload);
426
- }
427
-
428
- case 'builtin': {
429
- return await get().invokeBuiltinTool(id, payload);
430
- }
431
-
432
- // @ts-ignore
433
- case 'mcp': {
434
- return await get().invokeMCPTypePlugin(id, payload);
435
- }
436
-
437
- default: {
438
- return await get().invokeDefaultTypePlugin(id, payload);
439
- }
440
- }
441
- },
442
- invokeMCPTypePlugin: async (id, payload) => {
443
- const {
444
- optimisticUpdateMessageContent,
445
- internal_togglePluginApiCalling,
446
- internal_constructToolsCallingContext,
447
- } = get();
448
- let data: string = '';
449
-
450
- try {
451
- const abortController = internal_togglePluginApiCalling(
452
- true,
453
- id,
454
- n('fetchPlugin/start') as string,
455
- );
456
-
457
- const context = internal_constructToolsCallingContext(id);
458
- const result = await mcpService.invokeMcpToolCall(payload, {
459
- signal: abortController?.signal,
460
- topicId: context?.topicId,
461
- });
462
-
463
- if (!!result) data = result;
464
- } catch (error) {
465
- console.log(error);
466
- const err = error as Error;
467
-
468
- // ignore the aborted request error
469
- if (!err.message.includes('The user aborted a request.')) {
470
- const result = await messageService.updateMessageError(id, error as any);
471
- if (result?.success && result.messages) {
472
- get().replaceMessages(result.messages);
473
- }
474
- }
475
- }
476
-
477
- internal_togglePluginApiCalling(false, id, n('fetchPlugin/end') as string);
478
- // 如果报错则结束了
479
- if (!data) return;
480
-
481
- await optimisticUpdateMessageContent(id, data);
482
-
483
- return data;
484
- },
485
-
486
- internal_togglePluginApiCalling: (loading, id, action) => {
487
- return get().internal_toggleLoadingArrays('pluginApiLoadingIds', loading, id, action);
488
- },
489
-
490
- internal_transformToolCalls: (toolCalls) => {
491
- const toolNameResolver = new ToolNameResolver();
492
-
493
- // Build manifests map from tool store
494
- const toolStoreState = useToolStore.getState();
495
- const manifests: Record<string, LobeChatPluginManifest> = {};
496
-
497
- // Get all installed plugins
498
- const installedPlugins = pluginSelectors.installedPlugins(toolStoreState);
499
- for (const plugin of installedPlugins) {
500
- if (plugin.manifest) {
501
- manifests[plugin.identifier] = plugin.manifest as LobeChatPluginManifest;
502
- }
503
- }
504
-
505
- // Get all builtin tools
506
- for (const tool of builtinTools) {
507
- if (tool.manifest) {
508
- manifests[tool.identifier] = tool.manifest as LobeChatPluginManifest;
509
- }
510
- }
511
-
512
- return toolNameResolver.resolve(toolCalls, manifests);
513
- },
514
- internal_updatePluginError: async (id, error) => {
515
- const { replaceMessages } = get();
516
-
517
- get().internal_dispatchMessage({ id, type: 'updateMessage', value: { error } });
518
- const result = await messageService.updateMessage(
519
- id,
520
- { error },
521
- {
522
- sessionId: get().activeId,
523
- topicId: get().activeTopicId,
524
- },
525
- );
526
- if (result?.success && result.messages) {
527
- replaceMessages(result.messages);
528
- }
529
- },
530
-
531
- internal_constructToolsCallingContext: (id: string) => {
532
- const message = displayMessageSelectors.getDisplayMessageById(id)(get());
533
- if (!message) return;
534
-
535
- return {
536
- topicId: message.topicId,
537
- };
538
- },
539
- });