@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
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
CreateMessageParams,
|
|
7
7
|
GroundingSearch,
|
|
8
8
|
MessageMetadata,
|
|
9
|
+
MessagePluginItem,
|
|
9
10
|
MessageToolCall,
|
|
10
11
|
ModelReasoning,
|
|
11
12
|
UIChatMessage,
|
|
@@ -21,8 +22,7 @@ import { ChatStore } from '@/store/chat/store';
|
|
|
21
22
|
* Context for optimistic updates to specify session/topic isolation
|
|
22
23
|
*/
|
|
23
24
|
export interface OptimisticUpdateContext {
|
|
24
|
-
|
|
25
|
-
topicId?: string | null;
|
|
25
|
+
operationId?: string;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -38,10 +38,8 @@ export interface MessageOptimisticUpdateAction {
|
|
|
38
38
|
params: CreateMessageParams,
|
|
39
39
|
context?: {
|
|
40
40
|
groupMessageId?: string;
|
|
41
|
-
|
|
42
|
-
skipRefresh?: boolean;
|
|
41
|
+
operationId?: string;
|
|
43
42
|
tempMessageId?: string;
|
|
44
|
-
topicId?: string | null;
|
|
45
43
|
},
|
|
46
44
|
) => Promise<{ id: string; messages: UIChatMessage[] } | undefined>;
|
|
47
45
|
|
|
@@ -94,6 +92,16 @@ export interface MessageOptimisticUpdateAction {
|
|
|
94
92
|
context?: OptimisticUpdateContext,
|
|
95
93
|
) => Promise<void>;
|
|
96
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Optimistic update for message pluginIntervention field (frontend only, no database persistence)
|
|
97
|
+
* Use this when you need to update plugin intervention status
|
|
98
|
+
*/
|
|
99
|
+
optimisticUpdateMessagePlugin: (
|
|
100
|
+
id: string,
|
|
101
|
+
value: Partial<MessagePluginItem>,
|
|
102
|
+
context?: OptimisticUpdateContext,
|
|
103
|
+
) => Promise<void>;
|
|
104
|
+
|
|
97
105
|
/**
|
|
98
106
|
* update the message plugin error with optimistic update
|
|
99
107
|
*/
|
|
@@ -136,28 +144,28 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
136
144
|
try {
|
|
137
145
|
const result = await messageService.createMessage(message);
|
|
138
146
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const topicId = context?.topicId !== undefined ? context.topicId : get().activeTopicId;
|
|
143
|
-
replaceMessages(result.messages, { sessionId, topicId });
|
|
144
|
-
}
|
|
147
|
+
// Use the messages returned from createMessage (already grouped)
|
|
148
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
149
|
+
replaceMessages(result.messages, { sessionId, topicId });
|
|
145
150
|
|
|
146
151
|
internal_toggleMessageLoading(false, tempId);
|
|
147
152
|
return result;
|
|
148
153
|
} catch (e) {
|
|
149
154
|
internal_toggleMessageLoading(false, tempId);
|
|
150
|
-
internal_dispatchMessage(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
internal_dispatchMessage(
|
|
156
|
+
{
|
|
157
|
+
id: tempId,
|
|
158
|
+
type: 'updateMessage',
|
|
159
|
+
value: {
|
|
160
|
+
error: {
|
|
161
|
+
body: e,
|
|
162
|
+
message: (e as Error).message,
|
|
163
|
+
type: ChatErrorType.CreateMessageError,
|
|
164
|
+
},
|
|
158
165
|
},
|
|
159
166
|
},
|
|
160
|
-
|
|
167
|
+
context,
|
|
168
|
+
);
|
|
161
169
|
}
|
|
162
170
|
},
|
|
163
171
|
|
|
@@ -172,9 +180,8 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
172
180
|
},
|
|
173
181
|
|
|
174
182
|
optimisticDeleteMessage: async (id: string, context) => {
|
|
175
|
-
get().internal_dispatchMessage({ id, type: 'deleteMessage' });
|
|
176
|
-
const sessionId
|
|
177
|
-
const topicId = context?.topicId !== undefined ? context.topicId : get().activeTopicId;
|
|
183
|
+
get().internal_dispatchMessage({ id, type: 'deleteMessage' }, context);
|
|
184
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
178
185
|
const result = await messageService.removeMessage(id, {
|
|
179
186
|
sessionId,
|
|
180
187
|
topicId,
|
|
@@ -185,9 +192,8 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
185
192
|
},
|
|
186
193
|
|
|
187
194
|
optimisticDeleteMessages: async (ids, context) => {
|
|
188
|
-
get().internal_dispatchMessage({ ids, type: 'deleteMessages' });
|
|
189
|
-
const sessionId
|
|
190
|
-
const topicId = context?.topicId !== undefined ? context.topicId : get().activeTopicId;
|
|
195
|
+
get().internal_dispatchMessage({ ids, type: 'deleteMessages' }, context);
|
|
196
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
191
197
|
const result = await messageService.removeMessages(ids, {
|
|
192
198
|
sessionId,
|
|
193
199
|
topicId,
|
|
@@ -209,21 +215,26 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
209
215
|
// we need to update the message content at the frontend to avoid the update flick
|
|
210
216
|
// refs: https://medium.com/@kyledeguzmanx/what-are-optimistic-updates-483662c3e171
|
|
211
217
|
if (extra?.toolCalls) {
|
|
212
|
-
internal_dispatchMessage(
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
218
|
+
internal_dispatchMessage(
|
|
219
|
+
{
|
|
220
|
+
id,
|
|
221
|
+
type: 'updateMessage',
|
|
222
|
+
value: { tools: internal_transformToolCalls(extra?.toolCalls) },
|
|
223
|
+
},
|
|
224
|
+
context,
|
|
225
|
+
);
|
|
217
226
|
} else {
|
|
218
|
-
internal_dispatchMessage(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
227
|
+
internal_dispatchMessage(
|
|
228
|
+
{
|
|
229
|
+
id,
|
|
230
|
+
type: 'updateMessage',
|
|
231
|
+
value: { content },
|
|
232
|
+
},
|
|
233
|
+
context,
|
|
234
|
+
);
|
|
223
235
|
}
|
|
224
236
|
|
|
225
|
-
const sessionId
|
|
226
|
-
const topicId = context?.topicId !== undefined ? context.topicId : get().activeTopicId;
|
|
237
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
227
238
|
|
|
228
239
|
const result = await messageService.updateMessage(
|
|
229
240
|
id,
|
|
@@ -252,9 +263,8 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
252
263
|
},
|
|
253
264
|
|
|
254
265
|
optimisticUpdateMessageError: async (id, error, context) => {
|
|
255
|
-
get().internal_dispatchMessage({ id, type: 'updateMessage', value: { error } });
|
|
256
|
-
const sessionId
|
|
257
|
-
const topicId = context?.topicId !== undefined ? context.topicId : get().activeTopicId;
|
|
266
|
+
get().internal_dispatchMessage({ id, type: 'updateMessage', value: { error } }, context);
|
|
267
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
258
268
|
const result = await messageService.updateMessage(id, { error }, { sessionId, topicId });
|
|
259
269
|
if (result?.success && result.messages) {
|
|
260
270
|
get().replaceMessages(result.messages, { sessionId, topicId });
|
|
@@ -267,14 +277,16 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
267
277
|
const { internal_dispatchMessage, refreshMessages, replaceMessages } = get();
|
|
268
278
|
|
|
269
279
|
// Optimistic update: update the frontend immediately
|
|
270
|
-
internal_dispatchMessage(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
280
|
+
internal_dispatchMessage(
|
|
281
|
+
{
|
|
282
|
+
id,
|
|
283
|
+
type: 'updateMessageMetadata',
|
|
284
|
+
value: metadata,
|
|
285
|
+
},
|
|
286
|
+
context,
|
|
287
|
+
);
|
|
275
288
|
|
|
276
|
-
const sessionId
|
|
277
|
-
const topicId = context?.topicId !== undefined ? context.topicId : get().activeTopicId;
|
|
289
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
278
290
|
|
|
279
291
|
// Persist to database
|
|
280
292
|
const result = await messageService.updateMessageMetadata(id, metadata, {
|
|
@@ -289,9 +301,31 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
289
301
|
}
|
|
290
302
|
},
|
|
291
303
|
|
|
304
|
+
optimisticUpdateMessagePlugin: async (id, value, context) => {
|
|
305
|
+
const { internal_dispatchMessage, replaceMessages } = get();
|
|
306
|
+
|
|
307
|
+
// Optimistic update: update the frontend immediately
|
|
308
|
+
internal_dispatchMessage(
|
|
309
|
+
{
|
|
310
|
+
id,
|
|
311
|
+
type: 'updateMessagePlugin',
|
|
312
|
+
value,
|
|
313
|
+
},
|
|
314
|
+
context,
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
318
|
+
|
|
319
|
+
// Persist to database
|
|
320
|
+
const result = await messageService.updateMessagePlugin(id, value, { sessionId, topicId });
|
|
321
|
+
|
|
322
|
+
if (result?.success && result.messages) {
|
|
323
|
+
replaceMessages(result.messages, { sessionId, topicId });
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
|
|
292
327
|
optimisticUpdateMessagePluginError: async (id, error, context) => {
|
|
293
|
-
const sessionId
|
|
294
|
-
const topicId = context?.topicId !== undefined ? context.topicId : get().activeTopicId;
|
|
328
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
295
329
|
const result = await messageService.updateMessagePluginError(id, error, {
|
|
296
330
|
sessionId,
|
|
297
331
|
topicId,
|
|
@@ -302,8 +336,7 @@ export const messageOptimisticUpdate: StateCreator<
|
|
|
302
336
|
},
|
|
303
337
|
|
|
304
338
|
optimisticUpdateMessageRAG: async (id, data, context) => {
|
|
305
|
-
const sessionId
|
|
306
|
-
const topicId = context?.topicId !== undefined ? context.topicId : get().activeTopicId;
|
|
339
|
+
const { sessionId, topicId } = get().internal_getSessionContext(context);
|
|
307
340
|
const result = await messageService.updateMessageRAG(id, data, {
|
|
308
341
|
sessionId,
|
|
309
342
|
topicId,
|
|
@@ -15,10 +15,6 @@ export interface ChatMessageState {
|
|
|
15
15
|
* Derived from session.type, used for caching to avoid repeated lookups
|
|
16
16
|
*/
|
|
17
17
|
activeSessionType?: 'agent' | 'group';
|
|
18
|
-
/**
|
|
19
|
-
* is the message is continuing generation (used for disable continue button)
|
|
20
|
-
*/
|
|
21
|
-
continuingIds: string[];
|
|
22
18
|
/**
|
|
23
19
|
* Raw messages from database (flat structure)
|
|
24
20
|
*/
|
|
@@ -52,10 +48,6 @@ export interface ChatMessageState {
|
|
|
52
48
|
* Parsed messages for display (includes assistantGroup from conversation-flow)
|
|
53
49
|
*/
|
|
54
50
|
messagesMap: Record<string, UIChatMessage[]>;
|
|
55
|
-
/**
|
|
56
|
-
* is the message is regenerating (used for disable regenerate button)
|
|
57
|
-
*/
|
|
58
|
-
regeneratingIds: string[];
|
|
59
51
|
/**
|
|
60
52
|
* Supervisor decision debounce timers by group ID
|
|
61
53
|
*/
|
|
@@ -77,7 +69,6 @@ export interface ChatMessageState {
|
|
|
77
69
|
export const initialMessageState: ChatMessageState = {
|
|
78
70
|
activeId: 'inbox',
|
|
79
71
|
activeSessionType: undefined,
|
|
80
|
-
continuingIds: [],
|
|
81
72
|
dbMessagesMap: {},
|
|
82
73
|
groupAgentMaps: {},
|
|
83
74
|
groupMaps: {},
|
|
@@ -87,7 +78,6 @@ export const initialMessageState: ChatMessageState = {
|
|
|
87
78
|
messageLoadingIds: [],
|
|
88
79
|
messagesInit: false,
|
|
89
80
|
messagesMap: {},
|
|
90
|
-
regeneratingIds: [],
|
|
91
81
|
supervisorDebounceTimers: {},
|
|
92
82
|
supervisorDecisionAbortControllers: {},
|
|
93
83
|
supervisorDecisionLoading: [],
|
|
@@ -1,26 +1,50 @@
|
|
|
1
1
|
import type { ChatStoreState } from '../../../initialState';
|
|
2
|
+
import { operationSelectors } from '../../operation/selectors';
|
|
2
3
|
import { mainDisplayChatIDs } from './chat';
|
|
3
4
|
import { getDbMessageByToolCallId } from './dbMessage';
|
|
4
5
|
import { getDisplayMessageById } from './displayMessage';
|
|
5
6
|
|
|
6
7
|
const isMessageEditing = (id: string) => (s: ChatStoreState) => s.messageEditingIds.includes(id);
|
|
7
|
-
const isMessageLoading = (id: string) => (s: ChatStoreState) => s.messageLoadingIds.includes(id);
|
|
8
|
-
const isMessageRegenerating = (id: string) => (s: ChatStoreState) => s.regeneratingIds.includes(id);
|
|
9
|
-
const isMessageContinuing = (id: string) => (s: ChatStoreState) => s.continuingIds.includes(id);
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Check if a message is in loading state
|
|
11
|
+
* Priority: operation system (for AI flows) > legacy messageLoadingIds (for CRUD operations)
|
|
12
|
+
*/
|
|
13
|
+
const isMessageLoading = (id: string) => (s: ChatStoreState) => {
|
|
14
|
+
// First check operation system (sendMessage, etc.)
|
|
15
|
+
const hasOperation = operationSelectors.isMessageProcessing(id)(s);
|
|
16
|
+
if (hasOperation) return true;
|
|
17
|
+
|
|
18
|
+
// Fallback to legacy loading state (for non-operation CRUD)
|
|
19
|
+
return s.messageLoadingIds.includes(id);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Use operation system for AI-related loading states
|
|
23
|
+
const isMessageRegenerating = (id: string) => (s: ChatStoreState) =>
|
|
24
|
+
operationSelectors.isMessageRegenerating(id)(s);
|
|
25
|
+
const isMessageContinuing = (id: string) => (s: ChatStoreState) =>
|
|
26
|
+
operationSelectors.isMessageContinuing(id)(s);
|
|
27
|
+
const isMessageGenerating = (id: string) => (s: ChatStoreState) =>
|
|
28
|
+
operationSelectors.isMessageGenerating(id)(s); // Only check generateAI operations
|
|
29
|
+
const isMessageInChatReasoning = (id: string) => (s: ChatStoreState) =>
|
|
30
|
+
operationSelectors.isMessageInReasoning(id)(s);
|
|
31
|
+
|
|
32
|
+
// Use operation system for message CRUD operations
|
|
33
|
+
const isMessageCreating = (id: string) => (s: ChatStoreState) =>
|
|
34
|
+
operationSelectors.isMessageCreating(id)(s); // Only check sendMessage operations
|
|
35
|
+
|
|
36
|
+
// RAG flow still uses dedicated state
|
|
12
37
|
const isMessageInRAGFlow = (id: string) => (s: ChatStoreState) =>
|
|
13
38
|
s.messageRAGLoadingIds.includes(id);
|
|
14
|
-
const isMessageInChatReasoning = (id: string) => (s: ChatStoreState) =>
|
|
15
|
-
s.reasoningLoadingIds.includes(id);
|
|
16
39
|
|
|
17
40
|
const isMessageCollapsed = (id: string) => (s: ChatStoreState) => {
|
|
18
41
|
const message = getDisplayMessageById(id)(s);
|
|
19
42
|
return message?.metadata?.collapsed ?? false;
|
|
20
43
|
};
|
|
21
44
|
|
|
45
|
+
// Use operation system for plugin API invocation
|
|
22
46
|
const isPluginApiInvoking = (id: string) => (s: ChatStoreState) =>
|
|
23
|
-
|
|
47
|
+
operationSelectors.isMessageInToolCalling(id)(s);
|
|
24
48
|
|
|
25
49
|
const isToolCallStreaming = (id: string, index: number) => (s: ChatStoreState) => {
|
|
26
50
|
const isLoading = s.toolCallingStreamIds[id];
|
|
@@ -33,7 +57,8 @@ const isToolCallStreaming = (id: string, index: number) => (s: ChatStoreState) =
|
|
|
33
57
|
const isInToolsCalling = (id: string, index: number) => (s: ChatStoreState) => {
|
|
34
58
|
const isStreamingToolsCalling = isToolCallStreaming(id, index)(s);
|
|
35
59
|
|
|
36
|
-
|
|
60
|
+
// Check if assistant message has any tool calling operations
|
|
61
|
+
const isInvokingPluginApi = operationSelectors.isMessageInToolCalling(id)(s);
|
|
37
62
|
|
|
38
63
|
return isStreamingToolsCalling || isInvokingPluginApi;
|
|
39
64
|
};
|
|
@@ -47,9 +72,6 @@ const isToolApiNameShining =
|
|
|
47
72
|
return isStreaming || isPluginInvoking;
|
|
48
73
|
};
|
|
49
74
|
|
|
50
|
-
const isAIGenerating = (s: ChatStoreState) =>
|
|
51
|
-
s.chatLoadingIds.some((id) => mainDisplayChatIDs(s).includes(id));
|
|
52
|
-
|
|
53
75
|
const isInRAGFlow = (s: ChatStoreState) =>
|
|
54
76
|
s.messageRAGLoadingIds.some((id) => mainDisplayChatIDs(s).includes(id));
|
|
55
77
|
|
|
@@ -72,13 +94,13 @@ const isSendButtonDisabledByMessage = (s: ChatStoreState) =>
|
|
|
72
94
|
isInRAGFlow(s);
|
|
73
95
|
|
|
74
96
|
export const messageStateSelectors = {
|
|
75
|
-
isAIGenerating,
|
|
76
97
|
isCreatingMessage,
|
|
77
98
|
isHasMessageLoading,
|
|
78
99
|
isInRAGFlow,
|
|
79
100
|
isInToolsCalling,
|
|
80
101
|
isMessageCollapsed,
|
|
81
102
|
isMessageContinuing,
|
|
103
|
+
isMessageCreating,
|
|
82
104
|
isMessageEditing,
|
|
83
105
|
isMessageGenerating,
|
|
84
106
|
isMessageInChatReasoning,
|