@lobehub/lobehub 2.0.0-next.24 → 2.0.0-next.25
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 +25 -0
- package/changelog/v1.json +9 -0
- package/package.json +1 -1
- package/src/app/[variants]/(main)/labs/page.tsx +9 -8
- package/src/features/Conversation/Messages/Group/Actions/WithContentId.tsx +152 -0
- package/src/features/Conversation/Messages/Group/Actions/WithoutContentId.tsx +70 -0
- package/src/features/Conversation/Messages/Group/Actions/index.tsx +21 -0
- package/src/features/Conversation/Messages/Group/ContentBlock.tsx +91 -0
- package/src/features/Conversation/Messages/Group/EditState.tsx +51 -0
- package/src/features/Conversation/Messages/Group/Error/index.tsx +53 -0
- package/src/features/Conversation/Messages/Group/GroupChildren.tsx +73 -0
- package/src/features/Conversation/Messages/Group/MessageContent.tsx +39 -0
- package/src/features/Conversation/Messages/Group/Tool/Inspector/BuiltinPluginTitle.tsx +49 -0
- package/src/features/Conversation/Messages/Group/Tool/Inspector/Debug.tsx +70 -0
- package/src/features/Conversation/Messages/Group/Tool/Inspector/PluginResult.tsx +34 -0
- package/src/features/Conversation/Messages/Group/Tool/Inspector/PluginState.tsx +18 -0
- package/src/features/Conversation/Messages/Group/Tool/Inspector/Settings.tsx +40 -0
- package/src/features/Conversation/Messages/Group/Tool/Inspector/ToolTitle.tsx +92 -0
- package/src/features/Conversation/Messages/Group/Tool/Inspector/index.tsx +176 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/Arguments/ObjectEntity.tsx +81 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/Arguments/ValueCell.tsx +43 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/Arguments/index.tsx +134 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/CustomRender.tsx +88 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/ErrorResponse.tsx +35 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/LoadingPlaceholder/index.tsx +29 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/PluginSettings.tsx +66 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/index.tsx +105 -0
- package/src/features/Conversation/Messages/Group/Tool/index.tsx +75 -0
- package/src/features/Conversation/Messages/Group/Tools.tsx +46 -0
- package/src/features/Conversation/Messages/Group/index.tsx +140 -0
- package/src/features/Conversation/Messages/index.tsx +12 -0
- package/src/features/Conversation/components/ShareMessageModal/ShareImage/Preview.tsx +2 -2
- package/src/services/chat/contextEngineering.ts +6 -5
- package/src/services/message/server.ts +10 -0
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +309 -2
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +2 -22
- package/src/store/chat/slices/aiChat/actions/generateAIChatV2.ts +272 -14
|
@@ -1,11 +1,17 @@
|
|
|
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 {
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_AGENT_CHAT_CONFIG,
|
|
5
|
+
INBOX_SESSION_ID,
|
|
6
|
+
LOADING_FLAT,
|
|
7
|
+
isDesktop,
|
|
8
|
+
} from '@lobechat/const';
|
|
4
9
|
import { knowledgeBaseQAPrompts } from '@lobechat/prompts';
|
|
5
10
|
import {
|
|
6
11
|
ChatImageItem,
|
|
7
12
|
ChatTopic,
|
|
8
13
|
ChatVideoItem,
|
|
14
|
+
CreateNewMessageParams,
|
|
9
15
|
MessageSemanticSearchChunk,
|
|
10
16
|
SendMessageParams,
|
|
11
17
|
SendMessageServerResponse,
|
|
@@ -13,8 +19,10 @@ import {
|
|
|
13
19
|
UIChatMessage,
|
|
14
20
|
} from '@lobechat/types';
|
|
15
21
|
import { TRPCClientError } from '@trpc/client';
|
|
22
|
+
import debug from 'debug';
|
|
16
23
|
import { t } from 'i18next';
|
|
17
24
|
import { produce } from 'immer';
|
|
25
|
+
import pMap from 'p-map';
|
|
18
26
|
import { StateCreator } from 'zustand/vanilla';
|
|
19
27
|
|
|
20
28
|
import { aiChatService } from '@/services/aiChat';
|
|
@@ -30,21 +38,36 @@ import { getSessionStoreState } from '@/store/session';
|
|
|
30
38
|
import { WebBrowsingManifest } from '@/tools/web-browsing';
|
|
31
39
|
import { setNamespace } from '@/utils/storeDebug';
|
|
32
40
|
|
|
33
|
-
import { chatSelectors, topicSelectors } from '../../../selectors';
|
|
41
|
+
import { chatSelectors, threadSelectors, topicSelectors } from '../../../selectors';
|
|
34
42
|
import { messageMapKey } from '../../../utils/messageMapKey';
|
|
35
43
|
|
|
36
44
|
const n = setNamespace('ai');
|
|
45
|
+
const log = debug('lobe-store:ai-chat-v2');
|
|
37
46
|
|
|
38
47
|
export interface AIGenerateV2Action {
|
|
39
48
|
/**
|
|
40
49
|
* Sends a new message to the AI chat system
|
|
41
50
|
*/
|
|
42
|
-
|
|
51
|
+
sendMessage: (params: SendMessageParams) => Promise<void>;
|
|
43
52
|
/**
|
|
44
|
-
* Cancels
|
|
53
|
+
* Cancels sendMessage operation for a specific topic/session
|
|
45
54
|
*/
|
|
46
55
|
cancelSendMessageInServer: (topicId?: string) => void;
|
|
47
56
|
clearSendMessageError: () => void;
|
|
57
|
+
/**
|
|
58
|
+
*/
|
|
59
|
+
triggerToolsCalling: (
|
|
60
|
+
id: string,
|
|
61
|
+
params?: { threadId?: string; inPortalThread?: boolean; inSearchWorkflow?: boolean },
|
|
62
|
+
) => Promise<void>;
|
|
63
|
+
callToolFollowAssistantMessage: (params: {
|
|
64
|
+
parentId: string;
|
|
65
|
+
traceId?: string;
|
|
66
|
+
threadId?: string;
|
|
67
|
+
inPortalThread?: boolean;
|
|
68
|
+
inSearchWorkflow?: boolean;
|
|
69
|
+
}) => Promise<void>;
|
|
70
|
+
|
|
48
71
|
internal_refreshAiChat: (params: {
|
|
49
72
|
topics?: ChatTopic[];
|
|
50
73
|
messages: UIChatMessage[];
|
|
@@ -57,7 +80,7 @@ export interface AIGenerateV2Action {
|
|
|
57
80
|
*/
|
|
58
81
|
internal_execAgentRuntime: (params: {
|
|
59
82
|
messages: UIChatMessage[];
|
|
60
|
-
userMessageId
|
|
83
|
+
userMessageId?: string;
|
|
61
84
|
assistantMessageId: string;
|
|
62
85
|
isWelcomeQuestion?: boolean;
|
|
63
86
|
inSearchWorkflow?: boolean;
|
|
@@ -70,7 +93,7 @@ export interface AIGenerateV2Action {
|
|
|
70
93
|
traceId?: string;
|
|
71
94
|
}) => Promise<void>;
|
|
72
95
|
/**
|
|
73
|
-
* Toggle
|
|
96
|
+
* Toggle sendMessage operation state
|
|
74
97
|
*/
|
|
75
98
|
internal_toggleSendMessageOperation: (
|
|
76
99
|
key: string | { sessionId: string; topicId?: string | null },
|
|
@@ -90,7 +113,7 @@ export const generateAIChatV2: StateCreator<
|
|
|
90
113
|
[],
|
|
91
114
|
AIGenerateV2Action
|
|
92
115
|
> = (set, get) => ({
|
|
93
|
-
|
|
116
|
+
sendMessage: async ({ message, files, onlyAddUserMessage, isWelcomeQuestion }) => {
|
|
94
117
|
const { activeTopicId, activeId, activeThreadId, internal_execAgentRuntime, mainInputEditor } =
|
|
95
118
|
get();
|
|
96
119
|
if (!activeId) return;
|
|
@@ -151,7 +174,7 @@ export const generateAIChatV2: StateCreator<
|
|
|
151
174
|
|
|
152
175
|
const operationKey = messageMapKey(activeId, activeTopicId);
|
|
153
176
|
|
|
154
|
-
// Start tracking
|
|
177
|
+
// Start tracking sendMessage operation with AbortController
|
|
155
178
|
const abortController = get().internal_toggleSendMessageOperation(operationKey, true)!;
|
|
156
179
|
|
|
157
180
|
const jsonState = mainInputEditor?.getJSONState();
|
|
@@ -205,7 +228,7 @@ export const generateAIChatV2: StateCreator<
|
|
|
205
228
|
}
|
|
206
229
|
}
|
|
207
230
|
} finally {
|
|
208
|
-
// Stop tracking
|
|
231
|
+
// Stop tracking sendMessage operation
|
|
209
232
|
get().internal_toggleSendMessageOperation(operationKey, false);
|
|
210
233
|
}
|
|
211
234
|
|
|
@@ -290,7 +313,7 @@ export const generateAIChatV2: StateCreator<
|
|
|
290
313
|
get().internal_toggleSendMessageOperation(
|
|
291
314
|
operationKey,
|
|
292
315
|
false,
|
|
293
|
-
'User cancelled
|
|
316
|
+
'User cancelled sendMessage operation',
|
|
294
317
|
);
|
|
295
318
|
|
|
296
319
|
// Only clear creating message state if it's the active session
|
|
@@ -325,9 +348,16 @@ export const generateAIChatV2: StateCreator<
|
|
|
325
348
|
ragQuery,
|
|
326
349
|
messages: originalMessages,
|
|
327
350
|
} = params;
|
|
351
|
+
|
|
352
|
+
log(
|
|
353
|
+
'[internal_execAgentRuntime] start, assistantId: %s, messages count: %d',
|
|
354
|
+
assistantId,
|
|
355
|
+
originalMessages.length,
|
|
356
|
+
);
|
|
357
|
+
|
|
328
358
|
const {
|
|
329
359
|
internal_fetchAIChatMessage,
|
|
330
|
-
|
|
360
|
+
triggerToolsCalling,
|
|
331
361
|
refreshMessages,
|
|
332
362
|
internal_updateMessageRAG,
|
|
333
363
|
} = get();
|
|
@@ -338,11 +368,14 @@ export const generateAIChatV2: StateCreator<
|
|
|
338
368
|
const agentStoreState = getAgentStoreState();
|
|
339
369
|
const { model, provider, chatConfig } = agentSelectors.currentAgentConfig(agentStoreState);
|
|
340
370
|
|
|
371
|
+
log('[internal_execAgentRuntime] Agent config: model=%s, provider=%s', model, provider);
|
|
372
|
+
|
|
341
373
|
let fileChunks: MessageSemanticSearchChunk[] | undefined;
|
|
342
374
|
let ragQueryId;
|
|
343
375
|
|
|
344
376
|
// go into RAG flow if there is ragQuery flag
|
|
345
|
-
if (ragQuery) {
|
|
377
|
+
if (ragQuery && userMessageId) {
|
|
378
|
+
log('[internal_execAgentRuntime] Entering RAG flow with query: %s', ragQuery);
|
|
346
379
|
// 1. get the relative chunks from semantic search
|
|
347
380
|
const { chunks, queryId, rewriteQuery } = await get().internal_retrieveChunks(
|
|
348
381
|
userMessageId,
|
|
@@ -470,7 +503,7 @@ export const generateAIChatV2: StateCreator<
|
|
|
470
503
|
if (isToolsCalling) {
|
|
471
504
|
get().internal_toggleMessageInToolsCalling(true, assistantId);
|
|
472
505
|
await refreshMessages();
|
|
473
|
-
await
|
|
506
|
+
await triggerToolsCalling(assistantId, {
|
|
474
507
|
threadId: params?.threadId,
|
|
475
508
|
inPortalThread: params?.inPortalThread,
|
|
476
509
|
});
|
|
@@ -481,6 +514,7 @@ export const generateAIChatV2: StateCreator<
|
|
|
481
514
|
}
|
|
482
515
|
|
|
483
516
|
// 4. fetch the AI response
|
|
517
|
+
log('[internal_execAgentRuntime] Fetching AI response for assistantId: %s', assistantId);
|
|
484
518
|
const { isFunctionCall, content } = await internal_fetchAIChatMessage({
|
|
485
519
|
messages,
|
|
486
520
|
messageId: assistantId,
|
|
@@ -491,13 +525,18 @@ export const generateAIChatV2: StateCreator<
|
|
|
491
525
|
|
|
492
526
|
// 5. if it's the function call message, trigger the function method
|
|
493
527
|
if (isFunctionCall) {
|
|
528
|
+
log('[internal_execAgentRuntime] AI response is function call, triggering tools calling');
|
|
494
529
|
get().internal_toggleMessageInToolsCalling(true, assistantId);
|
|
495
530
|
await refreshMessages();
|
|
496
|
-
await
|
|
531
|
+
await triggerToolsCalling(assistantId, {
|
|
497
532
|
threadId: params?.threadId,
|
|
498
533
|
inPortalThread: params?.inPortalThread,
|
|
499
534
|
});
|
|
500
535
|
} else {
|
|
536
|
+
log(
|
|
537
|
+
'[internal_execAgentRuntime] AI response completed, content length: %d',
|
|
538
|
+
content?.length || 0,
|
|
539
|
+
);
|
|
501
540
|
// 显示桌面通知(仅在桌面端且窗口隐藏时)
|
|
502
541
|
if (isDesktop) {
|
|
503
542
|
try {
|
|
@@ -534,6 +573,225 @@ export const generateAIChatV2: StateCreator<
|
|
|
534
573
|
await get().internal_summaryHistory(historyMessages);
|
|
535
574
|
}
|
|
536
575
|
},
|
|
576
|
+
triggerToolsCalling: async (assistantId, { threadId, inPortalThread, inSearchWorkflow } = {}) => {
|
|
577
|
+
log('[triggerToolsCalling] start, assistantId (block ID): %s', assistantId);
|
|
578
|
+
|
|
579
|
+
const foundMessage = chatSelectors.getMessageById(assistantId)(get());
|
|
580
|
+
if (!foundMessage) {
|
|
581
|
+
log('[triggerToolsCalling] Message not found, returning');
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Determine if this is a group message or a block
|
|
586
|
+
let groupMessage: UIChatMessage;
|
|
587
|
+
let latestBlock: UIChatMessage;
|
|
588
|
+
|
|
589
|
+
if (foundMessage.role === 'group') {
|
|
590
|
+
// Case 1: assistantId matches a group message ID directly
|
|
591
|
+
// Find the block within children that matches assistantId
|
|
592
|
+
groupMessage = foundMessage;
|
|
593
|
+
const block = foundMessage.children?.find((item) => item.id === assistantId);
|
|
594
|
+
|
|
595
|
+
if (!block) {
|
|
596
|
+
log(
|
|
597
|
+
'[triggerToolsCalling] Block with id %s not found in group message children, returning',
|
|
598
|
+
assistantId,
|
|
599
|
+
);
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
latestBlock = block as UIChatMessage;
|
|
603
|
+
} else if (foundMessage.parentId) {
|
|
604
|
+
// Case 2: assistantId is a block ID, need to get parent group message
|
|
605
|
+
const parentMsg = chatSelectors.getMessageById(foundMessage.parentId)(get());
|
|
606
|
+
if (!parentMsg || parentMsg.role !== 'group') {
|
|
607
|
+
log('[triggerToolsCalling] Parent group message not found, returning');
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
groupMessage = parentMsg;
|
|
611
|
+
latestBlock = foundMessage;
|
|
612
|
+
} else {
|
|
613
|
+
log(
|
|
614
|
+
'[triggerToolsCalling] Message is neither a group message nor a block with parentId, returning',
|
|
615
|
+
);
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
log('[triggerToolsCalling] Found group message: %O', {
|
|
620
|
+
id: groupMessage.id,
|
|
621
|
+
groupId: groupMessage.groupId,
|
|
622
|
+
childrenCount: groupMessage.children?.length,
|
|
623
|
+
latestBlockId: latestBlock.id,
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
if (!latestBlock.tools) {
|
|
627
|
+
log('[triggerToolsCalling] Latest block has no tools, returning');
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
log(
|
|
632
|
+
'[triggerToolsCalling] Latest block found with %d tools: %O',
|
|
633
|
+
latestBlock.tools.length,
|
|
634
|
+
latestBlock.tools.map((t) => ({ id: t.id, type: t.type, identifier: t.identifier })),
|
|
635
|
+
);
|
|
636
|
+
|
|
637
|
+
let shouldCreateMessage = false;
|
|
638
|
+
let latestToolId = '';
|
|
639
|
+
|
|
640
|
+
await pMap(
|
|
641
|
+
latestBlock.tools,
|
|
642
|
+
async (payload) => {
|
|
643
|
+
log(
|
|
644
|
+
'[triggerToolsCalling] Processing tool: %s (type: %s)',
|
|
645
|
+
payload.identifier,
|
|
646
|
+
payload.type,
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
// 2. 使用 createNewMessage 创建 tool 消息
|
|
650
|
+
const toolMessage: CreateNewMessageParams = {
|
|
651
|
+
content: '',
|
|
652
|
+
parentId: assistantId,
|
|
653
|
+
plugin: payload,
|
|
654
|
+
role: 'tool',
|
|
655
|
+
sessionId: get().activeId,
|
|
656
|
+
tool_call_id: payload.id,
|
|
657
|
+
threadId,
|
|
658
|
+
topicId: get().activeTopicId, // if there is activeTopicId,then add it to topicId
|
|
659
|
+
groupId: groupMessage.groupId, // Propagate groupId from parent message for group chat
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
const result = await get().internal_createNewMessage(toolMessage);
|
|
663
|
+
|
|
664
|
+
if (!result) {
|
|
665
|
+
log('[triggerToolsCalling] Failed to create tool message for %s', payload.identifier);
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
log('[triggerToolsCalling] Tool message created: %s', result.id);
|
|
670
|
+
|
|
671
|
+
// 3. 执行 tool(这时 tool 消息已经创建,且 UI 已更新)
|
|
672
|
+
const data = await get().internal_invokeDifferentTypePlugin(result.id, payload);
|
|
673
|
+
|
|
674
|
+
if (data && !['markdown', 'standalone'].includes(payload.type)) {
|
|
675
|
+
shouldCreateMessage = true;
|
|
676
|
+
latestToolId = result.id;
|
|
677
|
+
log(
|
|
678
|
+
'[triggerToolsCalling] Tool %s requires follow-up assistant message',
|
|
679
|
+
payload.identifier,
|
|
680
|
+
);
|
|
681
|
+
} else {
|
|
682
|
+
log('[triggerToolsCalling] Tool %s completed without follow-up', payload.identifier);
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
{ concurrency: 5 },
|
|
686
|
+
);
|
|
687
|
+
|
|
688
|
+
await get().internal_toggleMessageInToolsCalling(false, assistantId);
|
|
689
|
+
|
|
690
|
+
if (!shouldCreateMessage) {
|
|
691
|
+
log('[triggerToolsCalling] No follow-up message needed, completed');
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const traceId = chatSelectors.getTraceIdByMessageId(latestToolId)(get());
|
|
696
|
+
log(
|
|
697
|
+
'[triggerToolsCalling] Calling follow-up assistant message with latestToolId: %s',
|
|
698
|
+
latestToolId,
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
await get().callToolFollowAssistantMessage({
|
|
702
|
+
traceId,
|
|
703
|
+
threadId,
|
|
704
|
+
inPortalThread,
|
|
705
|
+
inSearchWorkflow,
|
|
706
|
+
parentId: latestToolId,
|
|
707
|
+
});
|
|
708
|
+
log('[triggerToolsCalling] completed');
|
|
709
|
+
},
|
|
710
|
+
|
|
711
|
+
callToolFollowAssistantMessage: async ({
|
|
712
|
+
parentId,
|
|
713
|
+
traceId,
|
|
714
|
+
threadId,
|
|
715
|
+
inPortalThread,
|
|
716
|
+
inSearchWorkflow,
|
|
717
|
+
}) => {
|
|
718
|
+
log('[callToolFollowAssistantMessage] start, parentId: %s', parentId);
|
|
719
|
+
|
|
720
|
+
const chats = inPortalThread
|
|
721
|
+
? threadSelectors.portalAIChatsWithHistoryConfig(get())
|
|
722
|
+
: chatSelectors.mainAIChatsWithHistoryConfig(get());
|
|
723
|
+
|
|
724
|
+
let assistantMessageId: string;
|
|
725
|
+
|
|
726
|
+
// 获取 agent 配置
|
|
727
|
+
const agentStoreState = getAgentStoreState();
|
|
728
|
+
const { model, provider } = agentSelectors.currentAgentConfig(agentStoreState);
|
|
729
|
+
|
|
730
|
+
// 查找包含 parentId 的 group message
|
|
731
|
+
// parentId 是 tool result message 的 id,它存储在 assistant block 的 tools[].result_msg_id 中
|
|
732
|
+
let groupMessageId: string | undefined;
|
|
733
|
+
|
|
734
|
+
// 遍历所有 group messages,找到包含该 tool result 的那个
|
|
735
|
+
for (const msg of chats) {
|
|
736
|
+
if (msg.role === 'group' && msg.children) {
|
|
737
|
+
for (const child of msg.children) {
|
|
738
|
+
// 检查 child 的 tools 中是否有 result_msg_id === parentId
|
|
739
|
+
if (child.tools?.some((tool) => tool.result_msg_id === parentId)) {
|
|
740
|
+
groupMessageId = msg.id;
|
|
741
|
+
log('[callToolFollowAssistantMessage] Found group message: %s', groupMessageId);
|
|
742
|
+
break;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (groupMessageId) break;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// 创建新的 assistant message,作为 group message 的新 block
|
|
750
|
+
const assistantMessage: CreateNewMessageParams = {
|
|
751
|
+
role: 'assistant',
|
|
752
|
+
content: LOADING_FLAT,
|
|
753
|
+
parentId,
|
|
754
|
+
sessionId: get().activeId,
|
|
755
|
+
topicId: get().activeTopicId,
|
|
756
|
+
threadId,
|
|
757
|
+
traceId,
|
|
758
|
+
model,
|
|
759
|
+
provider,
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
log('[callToolFollowAssistantMessage] Creating new assistant message block with params: %O', {
|
|
763
|
+
parentId,
|
|
764
|
+
groupMessageId,
|
|
765
|
+
model,
|
|
766
|
+
provider,
|
|
767
|
+
sessionId: get().activeId,
|
|
768
|
+
topicId: get().activeTopicId,
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
const result = await get().internal_createNewMessage(assistantMessage, { groupMessageId });
|
|
772
|
+
|
|
773
|
+
if (!result) {
|
|
774
|
+
log('[callToolFollowAssistantMessage] Failed to create assistant message');
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
assistantMessageId = result.id;
|
|
779
|
+
log(
|
|
780
|
+
'[callToolFollowAssistantMessage] Assistant message created successfully, id: %s',
|
|
781
|
+
assistantMessageId,
|
|
782
|
+
);
|
|
783
|
+
|
|
784
|
+
log('[callToolFollowAssistantMessage] Starting agent runtime with %d messages', chats.length);
|
|
785
|
+
await get().internal_execAgentRuntime({
|
|
786
|
+
messages: chats,
|
|
787
|
+
assistantMessageId,
|
|
788
|
+
traceId,
|
|
789
|
+
threadId,
|
|
790
|
+
inPortalThread,
|
|
791
|
+
inSearchWorkflow,
|
|
792
|
+
});
|
|
793
|
+
log('[callToolFollowAssistantMessage] completed');
|
|
794
|
+
},
|
|
537
795
|
|
|
538
796
|
internal_updateSendMessageOperation: (key, value, actionName) => {
|
|
539
797
|
const operationKey = typeof key === 'string' ? key : messageMapKey(key.sessionId, key.topicId);
|