@lobehub/lobehub 2.0.0-next.84 → 2.0.0-next.86
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/dispatcher.ts +16 -16
- package/apps/desktop/src/main/modules/networkProxy/tester.ts +11 -11
- package/apps/desktop/src/main/modules/networkProxy/urlBuilder.ts +3 -3
- package/apps/desktop/src/main/modules/networkProxy/validator.ts +10 -10
- package/changelog/v1.json +18 -0
- package/package.json +1 -1
- package/packages/agent-runtime/src/core/runtime.ts +36 -1
- package/packages/agent-runtime/src/types/event.ts +1 -0
- package/packages/agent-runtime/src/types/generalAgent.ts +16 -0
- package/packages/agent-runtime/src/types/instruction.ts +30 -0
- package/packages/agent-runtime/src/types/runtime.ts +7 -0
- package/packages/types/src/message/common/metadata.ts +3 -0
- package/packages/types/src/message/common/tools.ts +2 -2
- package/packages/types/src/tool/search/index.ts +8 -2
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/V1Mobile/index.tsx +2 -2
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/V1Mobile/useSend.ts +7 -2
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/useSend.ts +15 -14
- package/src/app/[variants]/(main)/chat/session/features/SessionListContent/List/Item/index.tsx +2 -2
- package/src/app/[variants]/(main)/discover/(list)/features/Pagination.tsx +1 -1
- package/src/features/ChatInput/ActionBar/STT/browser.tsx +2 -2
- package/src/features/ChatInput/ActionBar/STT/openai.tsx +2 -2
- package/src/features/Conversation/Messages/Group/Tool/Inspector/index.tsx +1 -1
- package/src/features/Conversation/Messages/User/index.tsx +3 -3
- package/src/features/Conversation/Messages/index.tsx +3 -3
- package/src/features/Conversation/components/AutoScroll.tsx +2 -2
- package/src/services/search.ts +2 -2
- package/src/store/chat/agents/GeneralChatAgent.ts +98 -0
- package/src/store/chat/agents/__tests__/GeneralChatAgent.test.ts +366 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/call-llm.test.ts +1217 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/call-tool.test.ts +1976 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/finish.test.ts +453 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/fixtures/index.ts +4 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/fixtures/mockInstructions.ts +126 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/fixtures/mockMessages.ts +94 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/fixtures/mockOperations.ts +96 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/fixtures/mockStore.ts +138 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/helpers/assertions.ts +185 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/helpers/index.ts +3 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/helpers/operationTestUtils.ts +94 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/helpers/testExecutor.ts +139 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/request-human-approve.test.ts +545 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/resolve-aborted-tools.test.ts +686 -0
- package/src/store/chat/agents/createAgentExecutors.ts +313 -80
- package/src/store/chat/selectors.ts +1 -0
- package/src/store/chat/slices/aiChat/__tests__/ai-chat.integration.test.ts +667 -0
- package/src/store/chat/slices/aiChat/actions/__tests__/cancel-functionality.test.ts +137 -27
- package/src/store/chat/slices/aiChat/actions/__tests__/conversationControl.test.ts +163 -125
- package/src/store/chat/slices/aiChat/actions/__tests__/conversationLifecycle.test.ts +12 -2
- package/src/store/chat/slices/aiChat/actions/__tests__/fixtures.ts +0 -2
- package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +0 -2
- package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +286 -19
- package/src/store/chat/slices/aiChat/actions/__tests__/streamingStates.test.ts +0 -112
- package/src/store/chat/slices/aiChat/actions/conversationControl.ts +42 -99
- package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +90 -57
- package/src/store/chat/slices/aiChat/actions/generateAIGroupChat.ts +5 -25
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +220 -98
- package/src/store/chat/slices/aiChat/actions/streamingStates.ts +0 -34
- package/src/store/chat/slices/aiChat/initialState.ts +0 -28
- package/src/store/chat/slices/aiChat/selectors.test.ts +280 -0
- package/src/store/chat/slices/aiChat/selectors.ts +31 -7
- package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +21 -30
- package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +29 -49
- package/src/store/chat/slices/builtinTool/actions/interpreter.ts +83 -48
- package/src/store/chat/slices/builtinTool/actions/localSystem.ts +78 -28
- package/src/store/chat/slices/builtinTool/actions/search.ts +146 -59
- package/src/store/chat/slices/builtinTool/selectors.test.ts +258 -0
- package/src/store/chat/slices/builtinTool/selectors.ts +25 -4
- package/src/store/chat/slices/message/action.test.ts +134 -16
- package/src/store/chat/slices/message/actions/internals.ts +33 -7
- package/src/store/chat/slices/message/actions/optimisticUpdate.ts +85 -52
- package/src/store/chat/slices/message/initialState.ts +0 -10
- package/src/store/chat/slices/message/selectors/messageState.ts +34 -12
- package/src/store/chat/slices/operation/__tests__/actions.test.ts +712 -16
- package/src/store/chat/slices/operation/__tests__/integration.test.ts +342 -0
- package/src/store/chat/slices/operation/__tests__/selectors.test.ts +257 -17
- package/src/store/chat/slices/operation/actions.ts +218 -11
- package/src/store/chat/slices/operation/selectors.ts +135 -6
- package/src/store/chat/slices/operation/types.ts +29 -3
- package/src/store/chat/slices/plugin/action.test.ts +30 -322
- package/src/store/chat/slices/plugin/actions/internals.ts +0 -14
- package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +21 -19
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +45 -27
- package/src/store/chat/slices/plugin/actions/publicApi.ts +3 -4
- package/src/store/chat/slices/plugin/actions/workflow.ts +0 -55
- package/src/store/chat/slices/thread/selectors/index.ts +4 -2
- package/src/store/chat/slices/translate/action.ts +54 -41
- package/src/tools/web-browsing/ExecutionRuntime/index.ts +5 -2
- package/src/tools/web-browsing/Portal/Search/Footer.tsx +11 -9
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
|
|
2
2
|
import { ChatToolPayload } from '@lobechat/types';
|
|
3
3
|
import { PluginErrorType } from '@lobehub/chat-plugin-sdk';
|
|
4
|
+
import debug from 'debug';
|
|
4
5
|
import { t } from 'i18next';
|
|
5
6
|
import { StateCreator } from 'zustand/vanilla';
|
|
6
7
|
|
|
@@ -11,11 +12,10 @@ import { messageService } from '@/services/message';
|
|
|
11
12
|
import { ChatStore } from '@/store/chat/store';
|
|
12
13
|
import { useToolStore } from '@/store/tool';
|
|
13
14
|
import { safeParseJSON } from '@/utils/safeParseJSON';
|
|
14
|
-
import { setNamespace } from '@/utils/storeDebug';
|
|
15
15
|
|
|
16
16
|
import { dbMessageSelectors } from '../../message/selectors';
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const log = debug('lobe-store:plugin-types');
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Plugin type-specific implementations
|
|
@@ -125,7 +125,6 @@ export const pluginTypes: StateCreator<
|
|
|
125
125
|
invokeMCPTypePlugin: async (id, payload) => {
|
|
126
126
|
const {
|
|
127
127
|
optimisticUpdateMessageContent,
|
|
128
|
-
internal_togglePluginApiCalling,
|
|
129
128
|
internal_constructToolsCallingContext,
|
|
130
129
|
optimisticUpdatePluginState,
|
|
131
130
|
optimisticUpdateMessagePluginError,
|
|
@@ -135,13 +134,20 @@ export const pluginTypes: StateCreator<
|
|
|
135
134
|
// Get message to extract sessionId/topicId
|
|
136
135
|
const message = dbMessageSelectors.getDbMessageById(id)(get());
|
|
137
136
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
// Get abort controller from operation
|
|
138
|
+
const operationId = get().messageOperationMap[id];
|
|
139
|
+
const operation = operationId ? get().operations[operationId] : undefined;
|
|
140
|
+
const abortController = operation?.abortController;
|
|
141
|
+
|
|
142
|
+
log(
|
|
143
|
+
'[invokeMCPTypePlugin] messageId=%s, tool=%s, operationId=%s, aborted=%s',
|
|
144
|
+
id,
|
|
145
|
+
payload.apiName,
|
|
146
|
+
operationId,
|
|
147
|
+
abortController?.signal.aborted,
|
|
148
|
+
);
|
|
144
149
|
|
|
150
|
+
try {
|
|
145
151
|
const context = internal_constructToolsCallingContext(id);
|
|
146
152
|
const result = await mcpService.invokeMcpToolCall(payload, {
|
|
147
153
|
signal: abortController?.signal,
|
|
@@ -154,7 +160,9 @@ export const pluginTypes: StateCreator<
|
|
|
154
160
|
const err = error as Error;
|
|
155
161
|
|
|
156
162
|
// ignore the aborted request error
|
|
157
|
-
if (
|
|
163
|
+
if (err.message.includes('The user aborted a request.')) {
|
|
164
|
+
log('[invokeMCPTypePlugin] Request aborted: messageId=%s, tool=%s', id, payload.apiName);
|
|
165
|
+
} else {
|
|
158
166
|
const result = await messageService.updateMessageError(id, error as any, {
|
|
159
167
|
sessionId: message?.sessionId,
|
|
160
168
|
topicId: message?.topicId,
|
|
@@ -168,13 +176,12 @@ export const pluginTypes: StateCreator<
|
|
|
168
176
|
}
|
|
169
177
|
}
|
|
170
178
|
|
|
171
|
-
internal_togglePluginApiCalling(false, id, n('fetchPlugin/end') as string);
|
|
172
|
-
|
|
173
179
|
// 如果报错则结束了
|
|
174
180
|
|
|
175
181
|
if (!data) return;
|
|
176
182
|
|
|
177
|
-
|
|
183
|
+
// operationId already declared above, reuse it
|
|
184
|
+
const context = operationId ? { operationId } : undefined;
|
|
178
185
|
|
|
179
186
|
await Promise.all([
|
|
180
187
|
optimisticUpdateMessageContent(id, data.content, undefined, context),
|
|
@@ -188,19 +195,26 @@ export const pluginTypes: StateCreator<
|
|
|
188
195
|
},
|
|
189
196
|
|
|
190
197
|
internal_callPluginApi: async (id, payload) => {
|
|
191
|
-
const { optimisticUpdateMessageContent
|
|
198
|
+
const { optimisticUpdateMessageContent } = get();
|
|
192
199
|
let data: string;
|
|
193
200
|
|
|
194
201
|
// Get message to extract sessionId/topicId
|
|
195
202
|
const message = dbMessageSelectors.getDbMessageById(id)(get());
|
|
196
203
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
// Get abort controller from operation
|
|
205
|
+
const operationId = get().messageOperationMap[id];
|
|
206
|
+
const operation = operationId ? get().operations[operationId] : undefined;
|
|
207
|
+
const abortController = operation?.abortController;
|
|
208
|
+
|
|
209
|
+
log(
|
|
210
|
+
'[internal_callPluginApi] messageId=%s, plugin=%s, operationId=%s, aborted=%s',
|
|
211
|
+
id,
|
|
212
|
+
payload.identifier,
|
|
213
|
+
operationId,
|
|
214
|
+
abortController?.signal.aborted,
|
|
215
|
+
);
|
|
203
216
|
|
|
217
|
+
try {
|
|
204
218
|
const res = await chatService.runPluginApi(payload, {
|
|
205
219
|
signal: abortController?.signal,
|
|
206
220
|
trace: { observationId: message?.observationId, traceId: message?.traceId },
|
|
@@ -216,7 +230,13 @@ export const pluginTypes: StateCreator<
|
|
|
216
230
|
const err = error as Error;
|
|
217
231
|
|
|
218
232
|
// ignore the aborted request error
|
|
219
|
-
if (
|
|
233
|
+
if (err.message.includes('The user aborted a request.')) {
|
|
234
|
+
log(
|
|
235
|
+
'[internal_callPluginApi] Request aborted: messageId=%s, plugin=%s',
|
|
236
|
+
id,
|
|
237
|
+
payload.identifier,
|
|
238
|
+
);
|
|
239
|
+
} else {
|
|
220
240
|
const result = await messageService.updateMessageError(id, error as any, {
|
|
221
241
|
sessionId: message?.sessionId,
|
|
222
242
|
topicId: message?.topicId,
|
|
@@ -231,15 +251,13 @@ export const pluginTypes: StateCreator<
|
|
|
231
251
|
|
|
232
252
|
data = '';
|
|
233
253
|
}
|
|
234
|
-
|
|
235
|
-
internal_togglePluginApiCalling(false, id, n('fetchPlugin/end') as string);
|
|
236
254
|
// 如果报错则结束了
|
|
237
255
|
if (!data) return;
|
|
238
256
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
257
|
+
// operationId already declared above, reuse it
|
|
258
|
+
const context = operationId ? { operationId } : undefined;
|
|
259
|
+
|
|
260
|
+
await optimisticUpdateMessageContent(id, data, undefined, context);
|
|
243
261
|
|
|
244
262
|
return data;
|
|
245
263
|
},
|
|
@@ -55,10 +55,9 @@ export const pluginPublicApi: StateCreator<
|
|
|
55
55
|
const message = displayMessageSelectors.getDisplayMessageById(id)(get());
|
|
56
56
|
if (!message || message.role !== 'tool' || !message.plugin) return;
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
58
|
+
// Get operationId from messageOperationMap
|
|
59
|
+
const operationId = get().messageOperationMap[id];
|
|
60
|
+
const context = operationId ? { operationId } : undefined;
|
|
62
61
|
|
|
63
62
|
// if there is error content, then clear the error
|
|
64
63
|
if (!!message.pluginError) {
|
|
@@ -28,15 +28,6 @@ export interface PluginWorkflowAction {
|
|
|
28
28
|
inPortalThread?: boolean;
|
|
29
29
|
inSearchWorkflow?: boolean;
|
|
30
30
|
}) => Promise<void>;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Trigger tool calls (V1 deprecated method)
|
|
34
|
-
* @deprecated
|
|
35
|
-
*/
|
|
36
|
-
triggerToolCalls: (
|
|
37
|
-
id: string,
|
|
38
|
-
params?: { threadId?: string; inPortalThread?: boolean; inSearchWorkflow?: boolean },
|
|
39
|
-
) => Promise<void>;
|
|
40
31
|
}
|
|
41
32
|
|
|
42
33
|
export const pluginWorkflow: StateCreator<
|
|
@@ -83,50 +74,4 @@ export const pluginWorkflow: StateCreator<
|
|
|
83
74
|
inSearchWorkflow,
|
|
84
75
|
});
|
|
85
76
|
},
|
|
86
|
-
|
|
87
|
-
triggerToolCalls: async (assistantId, { threadId, inPortalThread, inSearchWorkflow } = {}) => {
|
|
88
|
-
const message = displayMessageSelectors.getDisplayMessageById(assistantId)(get());
|
|
89
|
-
if (!message || !message.tools) return;
|
|
90
|
-
|
|
91
|
-
let shouldCreateMessage = false;
|
|
92
|
-
let latestToolId = '';
|
|
93
|
-
const messagePools = message.tools.map(async (payload) => {
|
|
94
|
-
const toolMessage: CreateMessageParams = {
|
|
95
|
-
content: '',
|
|
96
|
-
parentId: assistantId,
|
|
97
|
-
plugin: payload,
|
|
98
|
-
role: 'tool',
|
|
99
|
-
sessionId: message.sessionId ?? get().activeId,
|
|
100
|
-
tool_call_id: payload.id,
|
|
101
|
-
threadId,
|
|
102
|
-
topicId: message.topicId !== undefined ? message.topicId : get().activeTopicId,
|
|
103
|
-
groupId: message.groupId, // Propagate groupId from parent message for group chat
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const result = await get().optimisticCreateMessage(toolMessage, {
|
|
107
|
-
sessionId: toolMessage.sessionId,
|
|
108
|
-
topicId: toolMessage.topicId,
|
|
109
|
-
});
|
|
110
|
-
if (!result) return;
|
|
111
|
-
|
|
112
|
-
// trigger the plugin call
|
|
113
|
-
const data = await get().internal_invokeDifferentTypePlugin(result.id, payload);
|
|
114
|
-
|
|
115
|
-
if (data && !['markdown', 'standalone'].includes(payload.type)) {
|
|
116
|
-
shouldCreateMessage = true;
|
|
117
|
-
latestToolId = result.id;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
await Promise.all(messagePools);
|
|
122
|
-
|
|
123
|
-
await get().internal_toggleMessageInToolsCalling(false, assistantId);
|
|
124
|
-
|
|
125
|
-
// only default type tool calls should trigger AI message
|
|
126
|
-
if (!shouldCreateMessage) return;
|
|
127
|
-
|
|
128
|
-
const traceId = dbMessageSelectors.getTraceIdByDbMessageId(latestToolId)(get());
|
|
129
|
-
|
|
130
|
-
await get().triggerAIMessage({ traceId, threadId, inPortalThread, inSearchWorkflow });
|
|
131
|
-
},
|
|
132
77
|
});
|
|
@@ -164,8 +164,10 @@ const hasThreadBySourceMsgId = (id: string) => (s: ChatStoreState) => {
|
|
|
164
164
|
return threads.some((t) => t.sourceMessageId === id);
|
|
165
165
|
};
|
|
166
166
|
|
|
167
|
-
const isThreadAIGenerating = (s: ChatStoreState) =>
|
|
168
|
-
|
|
167
|
+
const isThreadAIGenerating = (s: ChatStoreState) => {
|
|
168
|
+
const { operationSelectors } = require('../../operation/selectors');
|
|
169
|
+
return operationSelectors.isAnyMessageLoading(portalDisplayChatIDs(s))(s);
|
|
170
|
+
};
|
|
169
171
|
|
|
170
172
|
const isInRAGFlow = (s: ChatStoreState) =>
|
|
171
173
|
s.messageRAGLoadingIds.some((id) => portalDisplayChatIDs(s).includes(id));
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { chainLangDetect, chainTranslate } from '@lobechat/prompts';
|
|
2
2
|
import { ChatTranslate, TraceNameMap, TracePayload } from '@lobechat/types';
|
|
3
3
|
import { merge } from '@lobechat/utils';
|
|
4
|
-
import { produce } from 'immer';
|
|
5
4
|
import { StateCreator } from 'zustand/vanilla';
|
|
6
5
|
|
|
7
6
|
import { supportLocales } from '@/locales/resources';
|
|
@@ -11,9 +10,6 @@ import { dbMessageSelectors } from '@/store/chat/selectors';
|
|
|
11
10
|
import { ChatStore } from '@/store/chat/store';
|
|
12
11
|
import { useUserStore } from '@/store/user';
|
|
13
12
|
import { systemAgentSelectors } from '@/store/user/selectors';
|
|
14
|
-
import { setNamespace } from '@/utils/storeDebug';
|
|
15
|
-
|
|
16
|
-
const n = setNamespace('enhance');
|
|
17
13
|
|
|
18
14
|
/**
|
|
19
15
|
* chat translate
|
|
@@ -41,7 +37,7 @@ export const chatTranslate: StateCreator<
|
|
|
41
37
|
}),
|
|
42
38
|
|
|
43
39
|
translateMessage: async (id, targetLang) => {
|
|
44
|
-
const {
|
|
40
|
+
const { updateMessageTranslate, internal_dispatchMessage } = get();
|
|
45
41
|
|
|
46
42
|
const message = dbMessageSelectors.getDbMessageById(id)(get());
|
|
47
43
|
if (!message) return;
|
|
@@ -52,47 +48,64 @@ export const chatTranslate: StateCreator<
|
|
|
52
48
|
// create translate extra
|
|
53
49
|
await updateMessageTranslate(id, { content: '', from: '', to: targetLang });
|
|
54
50
|
|
|
55
|
-
|
|
51
|
+
// Create translate operation
|
|
52
|
+
const { operationId } = get().startOperation({
|
|
53
|
+
context: { messageId: id, sessionId: message.sessionId, topicId: message.topicId },
|
|
54
|
+
label: 'Translating message',
|
|
55
|
+
type: 'translate',
|
|
56
|
+
});
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
// Associate message with operation
|
|
59
|
+
get().associateMessageWithOperation(id, operationId);
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (data && supportLocales.includes(data)) from = data;
|
|
61
|
+
try {
|
|
62
|
+
let content = '';
|
|
63
|
+
let from = '';
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
65
|
+
// detect from language
|
|
66
|
+
chatService.fetchPresetTaskResult({
|
|
67
|
+
onFinish: async (data) => {
|
|
68
|
+
if (data && supportLocales.includes(data)) from = data;
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
70
|
+
await updateMessageTranslate(id, { content, from, to: targetLang });
|
|
71
|
+
},
|
|
72
|
+
params: merge(translationSetting, chainLangDetect(message.content)),
|
|
73
|
+
trace: get().getCurrentTracePayload({ traceName: TraceNameMap.LanguageDetect }),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// translate to target language
|
|
77
|
+
await chatService.fetchPresetTaskResult({
|
|
78
|
+
onFinish: async (translatedContent) => {
|
|
79
|
+
await updateMessageTranslate(id, { content: translatedContent, from, to: targetLang });
|
|
80
|
+
get().completeOperation(operationId);
|
|
81
|
+
},
|
|
82
|
+
onMessageHandle: (chunk) => {
|
|
83
|
+
switch (chunk.type) {
|
|
84
|
+
case 'text': {
|
|
85
|
+
content += chunk.text;
|
|
86
|
+
internal_dispatchMessage(
|
|
87
|
+
{
|
|
88
|
+
id,
|
|
89
|
+
key: 'translate',
|
|
90
|
+
type: 'updateMessageExtra',
|
|
91
|
+
value: { content, from, to: targetLang },
|
|
92
|
+
},
|
|
93
|
+
{ operationId },
|
|
94
|
+
);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
90
97
|
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
})
|
|
98
|
+
},
|
|
99
|
+
params: merge(translationSetting, chainTranslate(message.content, targetLang)),
|
|
100
|
+
trace: get().getCurrentTracePayload({ traceName: TraceNameMap.Translator }),
|
|
101
|
+
});
|
|
102
|
+
} catch (error) {
|
|
103
|
+
get().failOperation(operationId, {
|
|
104
|
+
message: error instanceof Error ? error.message : String(error),
|
|
105
|
+
type: 'TranslateError',
|
|
106
|
+
});
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
96
109
|
},
|
|
97
110
|
|
|
98
111
|
updateMessageTranslate: async (id, data) => {
|
|
@@ -17,9 +17,12 @@ export class WebBrowsingExecutionRuntime {
|
|
|
17
17
|
this.searchService = options.searchService;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
async search(
|
|
20
|
+
async search(
|
|
21
|
+
args: SearchQuery,
|
|
22
|
+
options?: { signal?: AbortSignal },
|
|
23
|
+
): Promise<BuiltinServerRuntimeOutput> {
|
|
21
24
|
try {
|
|
22
|
-
const data = await this.searchService.webSearch(args as SearchQuery);
|
|
25
|
+
const data = await this.searchService.webSearch(args as SearchQuery, options);
|
|
23
26
|
|
|
24
27
|
// add LIMITED_COUNT search results to message content
|
|
25
28
|
const searchContent: SearchContent[] = data.results
|
|
@@ -4,15 +4,17 @@ import { useTranslation } from 'react-i18next';
|
|
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
|
5
5
|
|
|
6
6
|
import { useChatStore } from '@/store/chat';
|
|
7
|
-
import { chatPortalSelectors,
|
|
7
|
+
import { chatPortalSelectors, operationSelectors } from '@/store/chat/selectors';
|
|
8
8
|
|
|
9
9
|
const Footer = () => {
|
|
10
|
-
const [messageId,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const [messageId, isAgentRuntimeRunning, triggerAIMessage, saveSearchResult] = useChatStore(
|
|
11
|
+
(s) => [
|
|
12
|
+
chatPortalSelectors.toolMessageId(s),
|
|
13
|
+
operationSelectors.isAgentRuntimeRunning(s),
|
|
14
|
+
s.triggerAIMessage,
|
|
15
|
+
s.saveSearchResult,
|
|
16
|
+
],
|
|
17
|
+
);
|
|
16
18
|
|
|
17
19
|
const { t } = useTranslation('tool');
|
|
18
20
|
|
|
@@ -20,7 +22,7 @@ const Footer = () => {
|
|
|
20
22
|
<Flexbox gap={8} horizontal paddingBlock={12} paddingInline={12}>
|
|
21
23
|
<Button
|
|
22
24
|
icon={LucideNotepadText}
|
|
23
|
-
loading={
|
|
25
|
+
loading={isAgentRuntimeRunning}
|
|
24
26
|
onClick={() => {
|
|
25
27
|
if (!messageId) return;
|
|
26
28
|
|
|
@@ -31,7 +33,7 @@ const Footer = () => {
|
|
|
31
33
|
</Button>
|
|
32
34
|
<ActionIcon
|
|
33
35
|
icon={PlusSquareIcon}
|
|
34
|
-
loading={
|
|
36
|
+
loading={isAgentRuntimeRunning}
|
|
35
37
|
onClick={() => {
|
|
36
38
|
if (!messageId) return;
|
|
37
39
|
|