@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.
- package/CHANGELOG.md +50 -0
- package/apps/desktop/src/main/modules/networkProxy/__tests__/dispatcher.test.ts +401 -0
- package/apps/desktop/src/main/modules/networkProxy/__tests__/tester.test.ts +531 -0
- package/apps/desktop/src/main/modules/networkProxy/__tests__/urlBuilder.test.ts +349 -0
- package/apps/desktop/src/main/modules/networkProxy/__tests__/validator.test.ts +492 -0
- package/changelog/v1.json +14 -0
- package/locales/ar/auth.json +45 -1
- package/locales/ar/modelProvider.json +13 -1
- package/locales/bg-BG/auth.json +45 -1
- package/locales/bg-BG/modelProvider.json +13 -1
- package/locales/de-DE/auth.json +45 -1
- package/locales/de-DE/modelProvider.json +13 -1
- package/locales/en-US/auth.json +45 -1
- package/locales/en-US/modelProvider.json +13 -1
- package/locales/es-ES/auth.json +45 -1
- package/locales/es-ES/modelProvider.json +13 -1
- package/locales/fa-IR/auth.json +45 -1
- package/locales/fa-IR/modelProvider.json +13 -1
- package/locales/fr-FR/auth.json +45 -1
- package/locales/fr-FR/modelProvider.json +13 -1
- package/locales/it-IT/auth.json +45 -1
- package/locales/it-IT/modelProvider.json +13 -1
- package/locales/ja-JP/auth.json +45 -1
- package/locales/ja-JP/modelProvider.json +13 -1
- package/locales/ko-KR/auth.json +45 -1
- package/locales/ko-KR/modelProvider.json +13 -1
- package/locales/nl-NL/auth.json +45 -1
- package/locales/nl-NL/modelProvider.json +13 -1
- package/locales/pl-PL/auth.json +45 -1
- package/locales/pl-PL/modelProvider.json +13 -1
- package/locales/pt-BR/auth.json +45 -1
- package/locales/pt-BR/modelProvider.json +13 -1
- package/locales/ru-RU/auth.json +45 -1
- package/locales/ru-RU/modelProvider.json +13 -1
- package/locales/tr-TR/auth.json +45 -1
- package/locales/tr-TR/modelProvider.json +13 -1
- package/locales/vi-VN/auth.json +45 -1
- package/locales/vi-VN/modelProvider.json +13 -1
- package/locales/zh-CN/auth.json +45 -1
- package/locales/zh-CN/modelProvider.json +13 -1
- package/locales/zh-TW/auth.json +45 -1
- package/locales/zh-TW/modelProvider.json +13 -1
- package/package.json +1 -1
- package/packages/context-engine/src/processors/MessageCleanup.ts +1 -0
- package/packages/context-engine/src/processors/__tests__/MessageCleanup.test.ts +28 -0
- package/packages/obervability-otel/package.json +3 -1
- package/packages/obervability-otel/src/api.ts +2 -0
- package/packages/obervability-otel/src/trpc/convention.ts +16 -0
- package/packages/obervability-otel/src/trpc/index.test.ts +38 -0
- package/packages/obervability-otel/src/trpc/index.ts +62 -0
- package/packages/obervability-otel/src/trpc/metrics.ts +31 -0
- package/packages/types/src/usage/usageRecord.ts +54 -0
- package/packages/web-crawler/src/crawImpl/browserless.ts +1 -1
- package/packages/web-crawler/src/crawImpl/naive.ts +9 -9
- package/packages/web-crawler/src/crawler.ts +5 -5
- package/packages/web-crawler/src/urlRules.ts +13 -13
- package/packages/web-crawler/src/utils/appUrlRules.ts +5 -5
- package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +10 -1
- package/src/app/[variants]/(main)/profile/usage/Client.tsx +114 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/ModelTable.tsx +175 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/index.tsx +126 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/MonthSpend.tsx +53 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/TodaySpend.tsx +67 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/index.tsx +19 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageTable.tsx +145 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageTrends.tsx +107 -0
- package/src/app/[variants]/(main)/profile/usage/features/components/UsageBarChart.tsx +48 -0
- package/src/app/[variants]/(main)/profile/usage/page.tsx +23 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +3 -3
- package/src/features/Conversation/Messages/Group/Actions/WithoutContentId.tsx +37 -14
- package/src/features/Conversation/Messages/Group/Error/index.tsx +1 -1
- package/src/features/Conversation/Messages/Group/GroupChildren.tsx +13 -35
- package/src/features/Conversation/Messages/Group/GroupItem.tsx +43 -0
- package/src/features/Conversation/Messages/Group/Tool/Inspector/index.tsx +1 -2
- package/src/features/Conversation/Messages/Group/Tool/Render/CustomRender.tsx +1 -1
- package/src/features/Conversation/Messages/Group/Tool/index.tsx +0 -2
- package/src/features/Conversation/Messages/Group/index.tsx +7 -2
- package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +3 -0
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +21 -7
- package/src/features/PluginsUI/Render/BuiltinType/index.tsx +1 -1
- package/src/features/PluginsUI/Render/MCPType/index.tsx +52 -0
- package/src/features/PluginsUI/Render/StandaloneType/Iframe.tsx +2 -2
- package/src/features/PluginsUI/Render/index.tsx +17 -0
- package/src/libs/mcp/client.ts +3 -2
- package/src/libs/mcp/types.ts +71 -0
- package/src/libs/trpc/lambda/index.ts +5 -2
- package/src/libs/trpc/middleware/openTelemetry.ts +141 -0
- package/src/locales/default/auth.ts +44 -0
- package/src/locales/default/chat.ts +1 -0
- package/src/server/routers/desktop/mcp.ts +1 -3
- package/src/server/routers/lambda/index.ts +2 -0
- package/src/server/routers/lambda/usage.ts +36 -0
- package/src/server/routers/tools/mcp.ts +1 -3
- package/src/server/services/mcp/index.test.ts +28 -15
- package/src/server/services/mcp/index.ts +29 -18
- package/src/server/services/usage/index.test.ts +310 -0
- package/src/server/services/usage/index.ts +164 -0
- package/src/services/chat/contextEngineering.test.ts +4 -0
- package/src/services/mcp.test.ts +7 -1
- package/src/services/mcp.ts +13 -12
- package/src/services/usage.ts +13 -0
- package/src/store/chat/agents/createAgentExecutors.ts +2 -3
- package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +40 -1
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +13 -5
- package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +3 -3
- package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +6 -6
- package/src/store/chat/slices/builtinTool/actions/interpreter.ts +2 -2
- package/src/store/chat/slices/builtinTool/actions/localSystem.ts +2 -2
- package/src/store/chat/slices/builtinTool/actions/search.ts +6 -6
- package/src/store/chat/slices/message/actions/publicApi.ts +19 -1
- package/src/store/chat/slices/message/initialState.ts +5 -0
- package/src/store/chat/slices/message/selectors/chat.test.ts +22 -602
- package/src/store/chat/slices/message/selectors/chat.ts +0 -2
- package/src/store/chat/slices/message/selectors/dbMessage.test.ts +51 -0
- package/src/store/chat/slices/message/selectors/displayMessage.test.ts +818 -0
- package/src/store/chat/slices/message/selectors/displayMessage.ts +52 -1
- package/src/store/chat/slices/message/selectors/messageState.ts +2 -0
- package/src/store/chat/slices/plugin/action.test.ts +4 -4
- package/src/store/chat/slices/plugin/actions/index.ts +39 -0
- package/src/store/chat/slices/plugin/actions/internals.ts +83 -0
- package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +188 -0
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +213 -0
- package/src/store/chat/slices/plugin/actions/publicApi.ts +115 -0
- package/src/store/chat/slices/plugin/actions/workflow.ts +121 -0
- package/src/store/chat/store.ts +1 -1
- package/src/store/global/initialState.ts +1 -0
- 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
|
-
});
|