@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
|
@@ -2,18 +2,13 @@
|
|
|
2
2
|
// Disable the auto sort key eslint rule to make the code more logic and readable
|
|
3
3
|
import { type AgentRuntimeContext } from '@lobechat/agent-runtime';
|
|
4
4
|
import { MESSAGE_CANCEL_FLAT } from '@lobechat/const';
|
|
5
|
-
import { produce } from 'immer';
|
|
6
5
|
import { StateCreator } from 'zustand/vanilla';
|
|
7
6
|
|
|
8
7
|
import { ChatStore } from '@/store/chat/store';
|
|
9
|
-
import { setNamespace } from '@/utils/storeDebug';
|
|
10
8
|
|
|
11
9
|
import { displayMessageSelectors } from '../../../selectors';
|
|
12
10
|
import { messageMapKey } from '../../../utils/messageMapKey';
|
|
13
11
|
import { dbMessageSelectors } from '../../message/selectors';
|
|
14
|
-
import { MainSendMessageOperation } from '../initialState';
|
|
15
|
-
|
|
16
|
-
const n = setNamespace('ai');
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Actions for controlling conversation operations like cancellation and error handling
|
|
@@ -47,22 +42,6 @@ export interface ConversationControlAction {
|
|
|
47
42
|
* Reject tool intervention and continue
|
|
48
43
|
*/
|
|
49
44
|
rejectAndContinueToolCalling: (messageId: string, reason?: string) => Promise<void>;
|
|
50
|
-
/**
|
|
51
|
-
* Toggle sendMessage operation state
|
|
52
|
-
*/
|
|
53
|
-
internal_toggleSendMessageOperation: (
|
|
54
|
-
key: string | { sessionId: string; topicId?: string | null },
|
|
55
|
-
loading: boolean,
|
|
56
|
-
cancelReason?: string,
|
|
57
|
-
) => AbortController | undefined;
|
|
58
|
-
/**
|
|
59
|
-
* Update sendMessage operation metadata
|
|
60
|
-
*/
|
|
61
|
-
internal_updateSendMessageOperation: (
|
|
62
|
-
key: string | { sessionId: string; topicId?: string | null },
|
|
63
|
-
value: Partial<MainSendMessageOperation> | null,
|
|
64
|
-
actionName?: any,
|
|
65
|
-
) => void;
|
|
66
45
|
}
|
|
67
46
|
|
|
68
47
|
export const conversationControl: StateCreator<
|
|
@@ -72,13 +51,18 @@ export const conversationControl: StateCreator<
|
|
|
72
51
|
ConversationControlAction
|
|
73
52
|
> = (set, get) => ({
|
|
74
53
|
stopGenerateMessage: () => {
|
|
75
|
-
const {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
54
|
+
const { activeId, activeTopicId, cancelOperations } = get();
|
|
55
|
+
|
|
56
|
+
// Cancel all running execAgentRuntime operations in the current context
|
|
57
|
+
cancelOperations(
|
|
58
|
+
{
|
|
59
|
+
type: 'execAgentRuntime',
|
|
60
|
+
status: 'running',
|
|
61
|
+
sessionId: activeId,
|
|
62
|
+
topicId: activeTopicId,
|
|
63
|
+
},
|
|
64
|
+
MESSAGE_CANCEL_FLAT,
|
|
65
|
+
);
|
|
82
66
|
},
|
|
83
67
|
|
|
84
68
|
cancelSendMessageInServer: (topicId?: string) => {
|
|
@@ -86,66 +70,48 @@ export const conversationControl: StateCreator<
|
|
|
86
70
|
|
|
87
71
|
// Determine which operation to cancel
|
|
88
72
|
const targetTopicId = topicId ?? activeTopicId;
|
|
89
|
-
const
|
|
73
|
+
const contextKey = messageMapKey(activeId, targetTopicId);
|
|
90
74
|
|
|
91
|
-
// Cancel the
|
|
92
|
-
get().
|
|
93
|
-
operationKey,
|
|
94
|
-
false,
|
|
95
|
-
'User cancelled sendMessage operation',
|
|
96
|
-
);
|
|
75
|
+
// Cancel operations in the operation system
|
|
76
|
+
const operationIds = get().operationsByContext[contextKey] || [];
|
|
97
77
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
78
|
+
operationIds.forEach((opId) => {
|
|
79
|
+
const operation = get().operations[opId];
|
|
80
|
+
if (operation && operation.type === 'sendMessage' && operation.status === 'running') {
|
|
81
|
+
get().cancelOperation(opId, 'User cancelled');
|
|
82
|
+
}
|
|
83
|
+
});
|
|
101
84
|
|
|
102
|
-
|
|
85
|
+
// Restore editor state if it's the active session
|
|
86
|
+
if (contextKey === messageMapKey(activeId, activeTopicId)) {
|
|
87
|
+
// Find the latest sendMessage operation with editor state
|
|
88
|
+
for (const opId of [...operationIds].reverse()) {
|
|
89
|
+
const op = get().operations[opId];
|
|
90
|
+
if (op && op.type === 'sendMessage' && op.metadata.inputEditorTempState) {
|
|
91
|
+
get().mainInputEditor?.setJSONState(op.metadata.inputEditorTempState);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
103
95
|
}
|
|
104
96
|
},
|
|
105
97
|
|
|
106
98
|
clearSendMessageError: () => {
|
|
107
|
-
get()
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
99
|
+
const { activeId, activeTopicId } = get();
|
|
100
|
+
const contextKey = messageMapKey(activeId, activeTopicId);
|
|
101
|
+
const operationIds = get().operationsByContext[contextKey] || [];
|
|
102
|
+
|
|
103
|
+
// Clear error message from all sendMessage operations in current context
|
|
104
|
+
operationIds.forEach((opId) => {
|
|
105
|
+
const op = get().operations[opId];
|
|
106
|
+
if (op && op.type === 'sendMessage' && op.metadata.inputSendErrorMsg) {
|
|
107
|
+
get().updateOperationMetadata(opId, { inputSendErrorMsg: undefined });
|
|
108
|
+
}
|
|
109
|
+
});
|
|
112
110
|
},
|
|
113
111
|
|
|
114
112
|
switchMessageBranch: async (messageId, branchIndex) => {
|
|
115
113
|
await get().optimisticUpdateMessageMetadata(messageId, { activeBranchIndex: branchIndex });
|
|
116
114
|
},
|
|
117
|
-
|
|
118
|
-
internal_toggleSendMessageOperation: (key, loading: boolean, cancelReason?: string) => {
|
|
119
|
-
if (loading) {
|
|
120
|
-
const abortController = new AbortController();
|
|
121
|
-
|
|
122
|
-
get().internal_updateSendMessageOperation(
|
|
123
|
-
key,
|
|
124
|
-
{ isLoading: true, abortController },
|
|
125
|
-
n('toggleSendMessageOperation(start)', { key }),
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
return abortController;
|
|
129
|
-
} else {
|
|
130
|
-
const operationKey =
|
|
131
|
-
typeof key === 'string' ? key : messageMapKey(key.sessionId, key.topicId);
|
|
132
|
-
|
|
133
|
-
const operation = get().mainSendMessageOperations[operationKey];
|
|
134
|
-
|
|
135
|
-
// If cancelReason is provided, abort the operation first
|
|
136
|
-
if (cancelReason && operation?.isLoading) {
|
|
137
|
-
operation.abortController?.abort(cancelReason);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
get().internal_updateSendMessageOperation(
|
|
141
|
-
key,
|
|
142
|
-
{ isLoading: false, abortController: null },
|
|
143
|
-
n('toggleSendMessageOperation(stop)', { key, cancelReason }),
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
return undefined;
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
115
|
approveToolCalling: async (toolMessageId) => {
|
|
150
116
|
const { activeThreadId, internal_execAgentRuntime } = get();
|
|
151
117
|
|
|
@@ -251,27 +217,4 @@ export const conversationControl: StateCreator<
|
|
|
251
217
|
console.error('[rejectAndContinueToolCalling] Error executing agent runtime:', error);
|
|
252
218
|
}
|
|
253
219
|
},
|
|
254
|
-
|
|
255
|
-
internal_updateSendMessageOperation: (key, value, actionName) => {
|
|
256
|
-
const operationKey = typeof key === 'string' ? key : messageMapKey(key.sessionId, key.topicId);
|
|
257
|
-
|
|
258
|
-
set(
|
|
259
|
-
produce((draft) => {
|
|
260
|
-
if (!draft.mainSendMessageOperations[operationKey])
|
|
261
|
-
draft.mainSendMessageOperations[operationKey] = value;
|
|
262
|
-
else {
|
|
263
|
-
if (value === null) {
|
|
264
|
-
delete draft.mainSendMessageOperations[operationKey];
|
|
265
|
-
} else {
|
|
266
|
-
draft.mainSendMessageOperations[operationKey] = {
|
|
267
|
-
...draft.mainSendMessageOperations[operationKey],
|
|
268
|
-
...value,
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}),
|
|
273
|
-
false,
|
|
274
|
-
actionName ?? n('updateSendMessageOperation', { operationKey, value }),
|
|
275
|
-
);
|
|
276
|
-
},
|
|
277
220
|
});
|
|
@@ -134,17 +134,31 @@ export const conversationLifecycle: StateCreator<
|
|
|
134
134
|
});
|
|
135
135
|
get().internal_toggleMessageLoading(true, tempId);
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
// Create operation for send message
|
|
138
|
+
const { operationId, abortController } = get().startOperation({
|
|
139
|
+
type: 'sendMessage',
|
|
140
|
+
context: {
|
|
141
|
+
sessionId: activeId,
|
|
142
|
+
topicId: activeTopicId,
|
|
143
|
+
threadId: activeThreadId,
|
|
144
|
+
messageId: tempId,
|
|
145
|
+
},
|
|
146
|
+
label: 'Send Message',
|
|
147
|
+
metadata: {
|
|
148
|
+
// Mark this as main window operation (not thread)
|
|
149
|
+
inThread: false,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
138
152
|
|
|
139
|
-
//
|
|
140
|
-
|
|
153
|
+
// Associate temp message with operation
|
|
154
|
+
get().associateMessageWithOperation(tempId, operationId);
|
|
141
155
|
|
|
156
|
+
// Store editor state in operation metadata for cancel restoration
|
|
142
157
|
const jsonState = mainInputEditor?.getJSONState();
|
|
143
|
-
get().
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
);
|
|
158
|
+
get().updateOperationMetadata(operationId, {
|
|
159
|
+
inputEditorTempState: jsonState,
|
|
160
|
+
inputSendErrorMsg: undefined,
|
|
161
|
+
});
|
|
148
162
|
|
|
149
163
|
let data: SendMessageServerResponse | undefined;
|
|
150
164
|
try {
|
|
@@ -172,6 +186,9 @@ export const conversationLifecycle: StateCreator<
|
|
|
172
186
|
if (data?.topics) {
|
|
173
187
|
get().internal_dispatchTopic({ type: 'updateTopics', value: data.topics });
|
|
174
188
|
topicId = data.topicId;
|
|
189
|
+
|
|
190
|
+
// Record the created topicId in metadata (not context)
|
|
191
|
+
get().updateOperationMetadata(operationId, { createdTopicId: data.topicId });
|
|
175
192
|
}
|
|
176
193
|
|
|
177
194
|
get().replaceMessages(data.messages, {
|
|
@@ -184,33 +201,36 @@ export const conversationLifecycle: StateCreator<
|
|
|
184
201
|
await get().switchTopic(data.topicId, true);
|
|
185
202
|
}
|
|
186
203
|
} catch (e) {
|
|
204
|
+
// Fail operation on error
|
|
205
|
+
get().failOperation(operationId, {
|
|
206
|
+
type: e instanceof Error ? e.name : 'unknown_error',
|
|
207
|
+
message: e instanceof Error ? e.message : 'Unknown error',
|
|
208
|
+
});
|
|
209
|
+
|
|
187
210
|
if (e instanceof TRPCClientError) {
|
|
188
211
|
const isAbort = e.message.includes('aborted') || e.name === 'AbortError';
|
|
189
212
|
// Check if error is due to cancellation
|
|
190
213
|
if (!isAbort) {
|
|
191
|
-
get().
|
|
214
|
+
get().updateOperationMetadata(operationId, { inputSendErrorMsg: e.message });
|
|
192
215
|
get().mainInputEditor?.setJSONState(jsonState);
|
|
193
216
|
}
|
|
194
217
|
}
|
|
195
218
|
} finally {
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
{ type: 'deleteMessages', ids: [tempId, tempAssistantId] },
|
|
204
|
-
{ topicId: activeTopicId, sessionId: activeId },
|
|
205
|
-
);
|
|
219
|
+
// 创建了新topic 或者 用户 cancel 了消息(或者失败了),此时无 data
|
|
220
|
+
if (data?.isCreateNewTopic || !data) {
|
|
221
|
+
get().internal_dispatchMessage(
|
|
222
|
+
{ type: 'deleteMessages', ids: [tempId, tempAssistantId] },
|
|
223
|
+
{ operationId },
|
|
224
|
+
);
|
|
225
|
+
}
|
|
206
226
|
}
|
|
207
227
|
|
|
208
228
|
get().internal_toggleMessageLoading(false, tempId);
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
229
|
+
|
|
230
|
+
// Clear editor temp state after message created
|
|
231
|
+
if (data) {
|
|
232
|
+
get().updateOperationMetadata(operationId, { inputEditorTempState: null });
|
|
233
|
+
}
|
|
214
234
|
|
|
215
235
|
if (!data) return;
|
|
216
236
|
|
|
@@ -251,6 +271,7 @@ export const conversationLifecycle: StateCreator<
|
|
|
251
271
|
parentMessageType: 'assistant',
|
|
252
272
|
sessionId: activeId,
|
|
253
273
|
topicId: data.topicId ?? activeTopicId,
|
|
274
|
+
parentOperationId: operationId, // Pass as parent operation
|
|
254
275
|
ragQuery: get().internal_shouldUseRAG() ? message : undefined,
|
|
255
276
|
threadId: activeThreadId,
|
|
256
277
|
skipCreateFirstMessage: true,
|
|
@@ -267,8 +288,16 @@ export const conversationLifecycle: StateCreator<
|
|
|
267
288
|
if (userFiles.length > 0) {
|
|
268
289
|
await getAgentStoreState().addFilesToAgent(userFiles, false);
|
|
269
290
|
}
|
|
291
|
+
|
|
292
|
+
// Complete operation on success
|
|
293
|
+
get().completeOperation(operationId);
|
|
270
294
|
} catch (e) {
|
|
271
295
|
console.error(e);
|
|
296
|
+
// Fail operation on error
|
|
297
|
+
get().failOperation(operationId, {
|
|
298
|
+
type: e instanceof Error ? e.name : 'unknown_error',
|
|
299
|
+
message: e instanceof Error ? e.message : 'AI generation failed',
|
|
300
|
+
});
|
|
272
301
|
} finally {
|
|
273
302
|
if (data.topicId) get().internal_updateTopicLoading(data.topicId, false);
|
|
274
303
|
}
|
|
@@ -288,16 +317,15 @@ export const conversationLifecycle: StateCreator<
|
|
|
288
317
|
|
|
289
318
|
if (contextMessages.length <= 0) return;
|
|
290
319
|
|
|
291
|
-
|
|
292
|
-
const { internal_execAgentRuntime, activeThreadId } = get();
|
|
320
|
+
const { internal_execAgentRuntime, activeThreadId, activeId, activeTopicId } = get();
|
|
293
321
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
);
|
|
322
|
+
// Create regenerate operation
|
|
323
|
+
const { operationId } = get().startOperation({
|
|
324
|
+
type: 'regenerate',
|
|
325
|
+
context: { sessionId: activeId, topicId: activeTopicId, messageId: id },
|
|
326
|
+
});
|
|
300
327
|
|
|
328
|
+
try {
|
|
301
329
|
const traceId = params?.traceId ?? dbMessageSelectors.getTraceIdByDbMessageId(id)(get());
|
|
302
330
|
|
|
303
331
|
// 切一个新的激活分支
|
|
@@ -307,23 +335,25 @@ export const conversationLifecycle: StateCreator<
|
|
|
307
335
|
messages: contextMessages,
|
|
308
336
|
parentMessageId: id,
|
|
309
337
|
parentMessageType: 'user',
|
|
310
|
-
sessionId:
|
|
311
|
-
topicId:
|
|
338
|
+
sessionId: activeId,
|
|
339
|
+
topicId: activeTopicId,
|
|
312
340
|
traceId,
|
|
313
341
|
ragQuery: get().internal_shouldUseRAG() ? item.content : undefined,
|
|
314
342
|
threadId: activeThreadId,
|
|
343
|
+
parentOperationId: operationId,
|
|
315
344
|
});
|
|
316
345
|
|
|
317
346
|
// trace the regenerate message
|
|
318
347
|
if (!params?.skipTrace)
|
|
319
348
|
get().internal_traceMessage(id, { eventType: TraceEventType.RegenerateMessage });
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
);
|
|
349
|
+
|
|
350
|
+
get().completeOperation(operationId);
|
|
351
|
+
} catch (error) {
|
|
352
|
+
get().failOperation(operationId, {
|
|
353
|
+
type: 'RegenerateError',
|
|
354
|
+
message: error instanceof Error ? error.message : String(error),
|
|
355
|
+
});
|
|
356
|
+
throw error;
|
|
327
357
|
}
|
|
328
358
|
},
|
|
329
359
|
|
|
@@ -350,30 +380,33 @@ export const conversationLifecycle: StateCreator<
|
|
|
350
380
|
const message = dbMessageSelectors.getDbMessageById(id)(get());
|
|
351
381
|
if (!message) return;
|
|
352
382
|
|
|
353
|
-
|
|
354
|
-
// Mark message as continuing
|
|
355
|
-
set(
|
|
356
|
-
{ continuingIds: [...get().continuingIds, messageId] },
|
|
357
|
-
false,
|
|
358
|
-
'continueGenerationMessage/start',
|
|
359
|
-
);
|
|
383
|
+
const { activeId, activeTopicId } = get();
|
|
360
384
|
|
|
385
|
+
// Create continue operation
|
|
386
|
+
const { operationId } = get().startOperation({
|
|
387
|
+
type: 'continue',
|
|
388
|
+
context: { sessionId: activeId, topicId: activeTopicId, messageId },
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
try {
|
|
361
392
|
const chats = displayMessageSelectors.mainAIChatsWithHistoryConfig(get());
|
|
362
393
|
|
|
363
394
|
await get().internal_execAgentRuntime({
|
|
364
395
|
messages: chats,
|
|
365
396
|
parentMessageId: id,
|
|
366
397
|
parentMessageType: message.role as 'assistant' | 'tool' | 'user',
|
|
367
|
-
sessionId:
|
|
368
|
-
topicId:
|
|
398
|
+
sessionId: activeId,
|
|
399
|
+
topicId: activeTopicId,
|
|
400
|
+
parentOperationId: operationId,
|
|
369
401
|
});
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
);
|
|
402
|
+
|
|
403
|
+
get().completeOperation(operationId);
|
|
404
|
+
} catch (error) {
|
|
405
|
+
get().failOperation(operationId, {
|
|
406
|
+
type: 'ContinueError',
|
|
407
|
+
message: error instanceof Error ? error.message : String(error),
|
|
408
|
+
});
|
|
409
|
+
throw error;
|
|
377
410
|
}
|
|
378
411
|
},
|
|
379
412
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
|
|
2
2
|
// Disable the auto sort key eslint rule to make the code more logic and readable
|
|
3
|
+
import { LOADING_FLAT } from '@lobechat/const';
|
|
3
4
|
import {
|
|
4
5
|
GroupMemberInfo,
|
|
5
6
|
buildGroupChatSystemPrompt,
|
|
@@ -14,7 +15,6 @@ import {
|
|
|
14
15
|
import { produce } from 'immer';
|
|
15
16
|
import { StateCreator } from 'zustand/vanilla';
|
|
16
17
|
|
|
17
|
-
import { LOADING_FLAT } from '@/const/message';
|
|
18
18
|
import { DEFAULT_CHAT_GROUP_CHAT_CONFIG } from '@/const/settings';
|
|
19
19
|
import { ChatStore } from '@/store/chat/store';
|
|
20
20
|
import { messageMapKey } from '@/store/chat/utils/messageMapKey';
|
|
@@ -602,8 +602,6 @@ export const chatAiGroupChat: StateCreator<
|
|
|
602
602
|
refreshMessages,
|
|
603
603
|
activeTopicId,
|
|
604
604
|
internal_dispatchMessage,
|
|
605
|
-
internal_toggleChatLoading,
|
|
606
|
-
triggerToolCalls,
|
|
607
605
|
} = get();
|
|
608
606
|
|
|
609
607
|
try {
|
|
@@ -710,30 +708,14 @@ export const chatAiGroupChat: StateCreator<
|
|
|
710
708
|
const messagesForAPI = [systemMessage, ...messagesWithAuthors];
|
|
711
709
|
|
|
712
710
|
if (assistantId) {
|
|
713
|
-
|
|
714
|
-
messages: messagesForAPI,
|
|
711
|
+
await internal_fetchAIChatMessage({
|
|
715
712
|
messageId: assistantId,
|
|
713
|
+
messages: messagesForAPI,
|
|
716
714
|
model: agentModel,
|
|
717
715
|
provider: agentProvider,
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
agentConfig: agentData,
|
|
721
|
-
},
|
|
716
|
+
agentConfig: agentData,
|
|
717
|
+
traceId: `group-${groupId}-agent-${agentId}`,
|
|
722
718
|
});
|
|
723
|
-
|
|
724
|
-
// Handle tool calling in group chat like single chat
|
|
725
|
-
if (isFunctionCall) {
|
|
726
|
-
get().internal_toggleMessageInToolsCalling(true, assistantId);
|
|
727
|
-
await refreshMessages();
|
|
728
|
-
await triggerToolCalls(assistantId, {
|
|
729
|
-
threadId: undefined,
|
|
730
|
-
inPortalThread: false,
|
|
731
|
-
});
|
|
732
|
-
// Change: if an agent message is a tool call, make the same agent speak again
|
|
733
|
-
// instead of asking supervisor for a decision.
|
|
734
|
-
await get().internal_processAgentMessage(groupId, agentId, targetId, instruction);
|
|
735
|
-
return;
|
|
736
|
-
}
|
|
737
719
|
}
|
|
738
720
|
|
|
739
721
|
await refreshMessages();
|
|
@@ -770,8 +752,6 @@ export const chatAiGroupChat: StateCreator<
|
|
|
770
752
|
},
|
|
771
753
|
});
|
|
772
754
|
}
|
|
773
|
-
} finally {
|
|
774
|
-
internal_toggleChatLoading(false, undefined, n('processAgentMessage(end)'));
|
|
775
755
|
}
|
|
776
756
|
},
|
|
777
757
|
|