@lobehub/lobehub 2.0.0-next.35 → 2.0.0-next.36
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/next.config.ts +5 -6
- package/package.json +2 -2
- package/packages/agent-runtime/src/core/__tests__/runtime.test.ts +112 -77
- package/packages/agent-runtime/src/core/runtime.ts +63 -18
- package/packages/agent-runtime/src/types/generalAgent.ts +55 -0
- package/packages/agent-runtime/src/types/index.ts +1 -0
- package/packages/agent-runtime/src/types/instruction.ts +10 -3
- package/packages/const/src/user.ts +0 -1
- package/packages/context-engine/src/processors/GroupMessageFlatten.ts +8 -6
- package/packages/context-engine/src/processors/__tests__/GroupMessageFlatten.test.ts +12 -12
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/assistant-group-branches.json +249 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/index.ts +4 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/multi-assistant-group.json +260 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/active-index-1.json +4 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/assistant-group-branches.json +481 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/conversation.json +5 -1
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/index.ts +4 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/multi-assistant-group.json +407 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/nested.json +18 -2
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/complex-scenario.json +25 -3
- package/packages/conversation-flow/src/__tests__/parse.test.ts +12 -0
- package/packages/conversation-flow/src/index.ts +1 -1
- package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +112 -34
- package/packages/conversation-flow/src/types/flatMessageList.ts +0 -12
- package/packages/conversation-flow/src/{types.ts → types/index.ts} +3 -14
- package/packages/database/src/models/message.ts +18 -19
- package/packages/types/src/aiChat.ts +2 -0
- package/packages/types/src/importer.ts +2 -2
- package/packages/types/src/message/ui/chat.ts +17 -1
- package/packages/types/src/message/ui/extra.ts +2 -2
- package/packages/types/src/message/ui/params.ts +2 -2
- package/packages/types/src/user/preference.ts +0 -4
- package/packages/utils/src/tokenizer/index.ts +3 -11
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/Desktop/MessageFromUrl.tsx +3 -3
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/V1Mobile/index.tsx +1 -1
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/V1Mobile/useSend.ts +3 -3
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/useSend.ts +6 -6
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatList/Content.tsx +5 -3
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatList/WelcomeChatItem/AgentWelcome/OpeningQuestions.tsx +2 -2
- package/src/app/[variants]/(main)/chat/components/conversation/features/ChatList/WelcomeChatItem/GroupWelcome/GroupUsageSuggest.tsx +2 -2
- package/src/app/[variants]/(main)/labs/page.tsx +0 -9
- package/src/features/ChatInput/ActionBar/STT/browser.tsx +3 -3
- package/src/features/ChatInput/ActionBar/STT/openai.tsx +3 -3
- package/src/features/Conversation/Error/AccessCodeForm.tsx +1 -1
- package/src/features/Conversation/Error/ChatInvalidApiKey.tsx +1 -1
- package/src/features/Conversation/Error/ClerkLogin/index.tsx +1 -1
- package/src/features/Conversation/Error/OAuthForm.tsx +1 -1
- package/src/features/Conversation/Error/index.tsx +0 -5
- package/src/features/Conversation/Messages/Assistant/Actions/index.tsx +13 -10
- package/src/features/Conversation/Messages/Assistant/Extra/index.test.tsx +3 -8
- package/src/features/Conversation/Messages/Assistant/Extra/index.tsx +2 -6
- package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +7 -9
- package/src/features/Conversation/Messages/Assistant/Tool/Inspector/PluginResult.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Inspector/PluginState.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Render/PluginSettings.tsx +4 -1
- package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +2 -3
- package/src/features/Conversation/Messages/Assistant/index.tsx +57 -60
- package/src/features/Conversation/Messages/Default.tsx +1 -0
- package/src/features/Conversation/Messages/Group/Actions/WithContentId.tsx +38 -10
- package/src/features/Conversation/Messages/Group/Actions/index.tsx +1 -1
- package/src/features/Conversation/Messages/Group/ContentBlock.tsx +1 -3
- package/src/features/Conversation/Messages/Group/GroupChildren.tsx +12 -12
- package/src/features/Conversation/Messages/Group/MessageContent.tsx +7 -1
- package/src/features/Conversation/Messages/Group/Tool/Render/PluginSettings.tsx +1 -1
- package/src/features/Conversation/Messages/Group/index.tsx +2 -1
- package/src/features/Conversation/Messages/Supervisor/index.tsx +2 -2
- package/src/features/Conversation/Messages/User/{Actions.tsx → Actions/ActionsBar.tsx} +26 -25
- package/src/features/Conversation/Messages/User/Actions/MessageBranch.tsx +107 -0
- package/src/features/Conversation/Messages/User/Actions/index.tsx +42 -0
- package/src/features/Conversation/Messages/User/index.tsx +43 -44
- package/src/features/Conversation/Messages/index.tsx +3 -3
- package/src/features/Conversation/components/AutoScroll.tsx +3 -3
- package/src/features/Conversation/components/Extras/Usage/UsageDetail/AnimatedNumber.tsx +55 -0
- package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +5 -2
- package/src/features/Conversation/components/VirtualizedList/index.tsx +29 -20
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +8 -10
- package/src/features/Portal/Thread/Chat/ChatInput/useSend.ts +3 -3
- package/src/hooks/useHotkeys/chatScope.ts +15 -7
- package/src/server/routers/lambda/__tests__/aiChat.test.ts +1 -1
- package/src/server/routers/lambda/__tests__/integration/message.integration.test.ts +0 -26
- package/src/server/routers/lambda/aiChat.ts +3 -2
- package/src/server/routers/lambda/message.ts +8 -16
- package/src/server/services/message/__tests__/index.test.ts +29 -39
- package/src/server/services/message/index.ts +41 -36
- package/src/services/electron/desktopNotification.ts +6 -6
- package/src/services/electron/file.ts +6 -6
- package/src/services/file/ClientS3/index.ts +8 -8
- package/src/services/message/__tests__/metadata-race-condition.test.ts +157 -0
- package/src/services/message/index.ts +21 -15
- package/src/services/upload.ts +11 -11
- package/src/services/utils/abortableRequest.test.ts +161 -0
- package/src/services/utils/abortableRequest.ts +67 -0
- package/src/store/chat/agents/GeneralChatAgent.ts +137 -0
- package/src/store/chat/agents/createAgentExecutors.ts +395 -0
- package/src/store/chat/helpers.test.ts +0 -99
- package/src/store/chat/helpers.ts +0 -11
- package/src/store/chat/slices/aiChat/actions/__tests__/conversationControl.test.ts +332 -0
- package/src/store/chat/slices/aiChat/actions/__tests__/conversationLifecycle.test.ts +257 -0
- package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +11 -2
- package/src/store/chat/slices/aiChat/actions/__tests__/rag.test.ts +6 -6
- package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +391 -0
- package/src/store/chat/slices/aiChat/actions/__tests__/streamingStates.test.ts +179 -0
- package/src/store/chat/slices/aiChat/actions/conversationControl.ts +157 -0
- package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +329 -0
- package/src/store/chat/slices/aiChat/actions/generateAIGroupChat.ts +14 -14
- package/src/store/chat/slices/aiChat/actions/index.ts +12 -6
- package/src/store/chat/slices/aiChat/actions/rag.ts +9 -6
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +604 -0
- package/src/store/chat/slices/aiChat/actions/streamingStates.ts +84 -0
- package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +4 -4
- package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +11 -11
- package/src/store/chat/slices/builtinTool/actions/interpreter.ts +8 -8
- package/src/store/chat/slices/builtinTool/actions/localSystem.ts +2 -2
- package/src/store/chat/slices/builtinTool/actions/search.ts +8 -8
- package/src/store/chat/slices/message/action.test.ts +79 -68
- package/src/store/chat/slices/message/actions/index.ts +39 -0
- package/src/store/chat/slices/message/actions/internals.ts +77 -0
- package/src/store/chat/slices/message/actions/optimisticUpdate.ts +260 -0
- package/src/store/chat/slices/message/actions/publicApi.ts +224 -0
- package/src/store/chat/slices/message/actions/query.ts +120 -0
- package/src/store/chat/slices/message/actions/runtimeState.ts +108 -0
- package/src/store/chat/slices/message/initialState.ts +13 -0
- package/src/store/chat/slices/message/reducer.test.ts +48 -370
- package/src/store/chat/slices/message/reducer.ts +17 -81
- package/src/store/chat/slices/message/selectors/chat.test.ts +13 -50
- package/src/store/chat/slices/message/selectors/chat.ts +78 -242
- package/src/store/chat/slices/message/selectors/dbMessage.ts +140 -0
- package/src/store/chat/slices/message/selectors/displayMessage.ts +301 -0
- package/src/store/chat/slices/message/selectors/messageState.ts +5 -2
- package/src/store/chat/slices/plugin/action.test.ts +62 -64
- package/src/store/chat/slices/plugin/action.ts +34 -28
- package/src/store/chat/slices/thread/action.test.ts +28 -31
- package/src/store/chat/slices/thread/action.ts +13 -10
- package/src/store/chat/slices/thread/selectors/index.ts +8 -6
- package/src/store/chat/slices/topic/reducer.ts +11 -3
- package/src/store/chat/store.ts +1 -1
- package/src/store/user/slices/preference/selectors/labPrefer.ts +0 -3
- package/packages/database/src/models/__tests__/message.grouping.test.ts +0 -812
- package/packages/database/src/utils/__tests__/groupMessages.test.ts +0 -1132
- package/packages/database/src/utils/groupMessages.ts +0 -361
- package/packages/utils/src/tokenizer/client.ts +0 -35
- package/packages/utils/src/tokenizer/estimated.ts +0 -4
- package/packages/utils/src/tokenizer/server.ts +0 -11
- package/packages/utils/src/tokenizer/tokenizer.worker.ts +0 -12
- package/src/app/(backend)/webapi/tokenizer/index.test.ts +0 -32
- package/src/app/(backend)/webapi/tokenizer/route.ts +0 -8
- package/src/features/Conversation/Error/InvalidAccessCode.tsx +0 -79
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -975
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +0 -1050
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +0 -720
- package/src/store/chat/slices/aiChat/actions/generateAIChatV2.ts +0 -849
- package/src/store/chat/slices/message/action.ts +0 -629
|
@@ -165,18 +165,74 @@ export class FlatListBuilder {
|
|
|
165
165
|
childMessages,
|
|
166
166
|
this.childrenMap,
|
|
167
167
|
);
|
|
168
|
-
const
|
|
168
|
+
const activeBranchIndex = childMessages.indexOf(activeBranchId);
|
|
169
|
+
const userWithBranches = this.createUserMessageWithBranches(
|
|
170
|
+
message,
|
|
171
|
+
childMessages.length,
|
|
172
|
+
activeBranchIndex,
|
|
173
|
+
);
|
|
169
174
|
flatList.push(userWithBranches);
|
|
170
175
|
processedIds.add(message.id);
|
|
171
176
|
|
|
172
|
-
// Continue with active branch
|
|
177
|
+
// Continue with active branch - check if it's an assistantGroup
|
|
173
178
|
const activeBranchMsg = this.messageMap.get(activeBranchId);
|
|
174
179
|
if (activeBranchMsg) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
+
// Check if active branch is assistant with tools (should be assistantGroup)
|
|
181
|
+
if (
|
|
182
|
+
activeBranchMsg.role === 'assistant' &&
|
|
183
|
+
activeBranchMsg.tools &&
|
|
184
|
+
activeBranchMsg.tools.length > 0
|
|
185
|
+
) {
|
|
186
|
+
// Collect the entire assistant group chain
|
|
187
|
+
const assistantChain: Message[] = [];
|
|
188
|
+
const allToolMessages: Message[] = [];
|
|
189
|
+
this.messageCollector.collectAssistantChain(
|
|
190
|
+
activeBranchMsg,
|
|
191
|
+
allMessages,
|
|
192
|
+
assistantChain,
|
|
193
|
+
allToolMessages,
|
|
194
|
+
processedIds,
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// Create assistantGroup virtual message
|
|
198
|
+
const groupMessage = this.createAssistantGroupMessage(
|
|
199
|
+
assistantChain[0],
|
|
200
|
+
assistantChain,
|
|
201
|
+
allToolMessages,
|
|
202
|
+
);
|
|
203
|
+
flatList.push(groupMessage);
|
|
204
|
+
|
|
205
|
+
// Mark all as processed
|
|
206
|
+
assistantChain.forEach((m) => processedIds.add(m.id));
|
|
207
|
+
allToolMessages.forEach((m) => processedIds.add(m.id));
|
|
208
|
+
|
|
209
|
+
// Continue after the assistant chain
|
|
210
|
+
const lastAssistant = assistantChain.at(-1);
|
|
211
|
+
const toolIds = new Set(allToolMessages.map((t) => t.id));
|
|
212
|
+
|
|
213
|
+
const lastAssistantNonToolChildren = lastAssistant
|
|
214
|
+
? this.childrenMap.get(lastAssistant.id)?.filter((childId) => !toolIds.has(childId))
|
|
215
|
+
: undefined;
|
|
216
|
+
|
|
217
|
+
if (
|
|
218
|
+
lastAssistantNonToolChildren &&
|
|
219
|
+
lastAssistantNonToolChildren.length > 0 &&
|
|
220
|
+
lastAssistant
|
|
221
|
+
) {
|
|
222
|
+
this.buildFlatListRecursive(lastAssistant.id, flatList, processedIds, allMessages);
|
|
223
|
+
} else {
|
|
224
|
+
for (const toolMsg of allToolMessages) {
|
|
225
|
+
this.buildFlatListRecursive(toolMsg.id, flatList, processedIds, allMessages);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
} else {
|
|
229
|
+
// Regular message (not assistantGroup)
|
|
230
|
+
flatList.push(activeBranchMsg);
|
|
231
|
+
processedIds.add(activeBranchId);
|
|
232
|
+
|
|
233
|
+
// Continue with active branch's children
|
|
234
|
+
this.buildFlatListRecursive(activeBranchId, flatList, processedIds, allMessages);
|
|
235
|
+
}
|
|
180
236
|
}
|
|
181
237
|
continue;
|
|
182
238
|
}
|
|
@@ -364,58 +420,80 @@ export class FlatListBuilder {
|
|
|
364
420
|
assistant.tools?.map((tool) => {
|
|
365
421
|
const toolMsg = toolMap.get(tool.id);
|
|
366
422
|
if (toolMsg) {
|
|
423
|
+
const result: any = {
|
|
424
|
+
content: toolMsg.content || '',
|
|
425
|
+
id: toolMsg.id,
|
|
426
|
+
};
|
|
427
|
+
if (toolMsg.error) result.error = toolMsg.error;
|
|
428
|
+
if (toolMsg.pluginState) result.state = toolMsg.pluginState;
|
|
429
|
+
|
|
367
430
|
return {
|
|
368
431
|
...tool,
|
|
369
|
-
result
|
|
370
|
-
content: toolMsg.content || '',
|
|
371
|
-
error: toolMsg.error,
|
|
372
|
-
id: toolMsg.id,
|
|
373
|
-
state: toolMsg.pluginState,
|
|
374
|
-
},
|
|
432
|
+
result,
|
|
375
433
|
result_msg_id: toolMsg.id,
|
|
376
434
|
};
|
|
377
435
|
}
|
|
378
436
|
return tool;
|
|
379
437
|
}) || [];
|
|
380
438
|
|
|
381
|
-
|
|
439
|
+
// Prefer top-level usage/performance fields, fall back to metadata
|
|
440
|
+
const { usage: metaUsage, performance: metaPerformance } =
|
|
382
441
|
this.messageTransformer.splitMetadata(assistant.metadata);
|
|
442
|
+
const msgUsage = assistant.usage || metaUsage;
|
|
443
|
+
const msgPerformance = assistant.performance || metaPerformance;
|
|
383
444
|
|
|
384
|
-
|
|
445
|
+
const childBlock: AssistantContentBlock = {
|
|
385
446
|
content: assistant.content || '',
|
|
386
|
-
error: assistant.error,
|
|
387
447
|
id: assistant.id,
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
448
|
+
} as AssistantContentBlock;
|
|
449
|
+
|
|
450
|
+
if (assistant.error) childBlock.error = assistant.error;
|
|
451
|
+
if (assistant.imageList && assistant.imageList.length > 0)
|
|
452
|
+
childBlock.imageList = assistant.imageList;
|
|
453
|
+
if (msgPerformance) childBlock.performance = msgPerformance;
|
|
454
|
+
if (assistant.reasoning) childBlock.reasoning = assistant.reasoning;
|
|
455
|
+
if (toolsWithResults.length > 0) childBlock.tools = toolsWithResults;
|
|
456
|
+
if (msgUsage) childBlock.usage = msgUsage;
|
|
457
|
+
|
|
458
|
+
children.push(childBlock);
|
|
395
459
|
}
|
|
396
460
|
|
|
397
461
|
const aggregated = this.messageTransformer.aggregateMetadata(children);
|
|
398
462
|
|
|
399
|
-
|
|
463
|
+
const result: Message = {
|
|
400
464
|
...firstAssistant,
|
|
401
465
|
children,
|
|
402
466
|
content: '',
|
|
403
|
-
imageList: undefined,
|
|
404
|
-
metadata: undefined,
|
|
405
|
-
performance: aggregated.performance,
|
|
406
|
-
reasoning: undefined,
|
|
407
467
|
role: 'assistantGroup' as any,
|
|
408
|
-
tools: undefined,
|
|
409
|
-
usage: aggregated.usage,
|
|
410
468
|
};
|
|
469
|
+
|
|
470
|
+
// Remove fields that should not be in assistantGroup
|
|
471
|
+
delete result.imageList;
|
|
472
|
+
delete result.metadata;
|
|
473
|
+
delete result.reasoning;
|
|
474
|
+
delete result.tools;
|
|
475
|
+
|
|
476
|
+
// Add aggregated fields if they exist
|
|
477
|
+
if (aggregated.performance) result.performance = aggregated.performance;
|
|
478
|
+
if (aggregated.usage) result.usage = aggregated.usage;
|
|
479
|
+
|
|
480
|
+
return result;
|
|
411
481
|
}
|
|
412
482
|
|
|
413
483
|
/**
|
|
414
484
|
* Create user message with branch metadata
|
|
415
485
|
*/
|
|
416
|
-
private createUserMessageWithBranches(
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
486
|
+
private createUserMessageWithBranches(
|
|
487
|
+
user: Message,
|
|
488
|
+
count: number,
|
|
489
|
+
activeBranchIndex: number,
|
|
490
|
+
): Message {
|
|
491
|
+
return {
|
|
492
|
+
...user,
|
|
493
|
+
branch: {
|
|
494
|
+
activeBranchIndex,
|
|
495
|
+
count,
|
|
496
|
+
},
|
|
497
|
+
} as Message;
|
|
420
498
|
}
|
|
421
499
|
}
|
|
@@ -41,22 +41,10 @@ export type FlatMessageRole =
|
|
|
41
41
|
*/
|
|
42
42
|
export type FlatMessage = UIChatMessage;
|
|
43
43
|
|
|
44
|
-
/**
|
|
45
|
-
* Branch metadata attached to user messages
|
|
46
|
-
*/
|
|
47
|
-
export interface BranchMetadata {
|
|
48
|
-
/** Active branch message ID */
|
|
49
|
-
activeId: string;
|
|
50
|
-
/** All branch message IDs */
|
|
51
|
-
branchIds: string[];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
44
|
/**
|
|
55
45
|
* Virtual message extra fields for flat list
|
|
56
46
|
*/
|
|
57
47
|
export interface FlatMessageExtra {
|
|
58
|
-
/** Branch information for user messages with multiple children */
|
|
59
|
-
branches?: BranchMetadata;
|
|
60
48
|
/** Optional description for groups */
|
|
61
49
|
description?: string;
|
|
62
50
|
/** Group mode for messageGroup and compare virtual messages */
|
|
@@ -16,21 +16,10 @@ export type {
|
|
|
16
16
|
CompareNode,
|
|
17
17
|
ContextNode,
|
|
18
18
|
MessageNode,
|
|
19
|
-
} from './
|
|
19
|
+
} from './contextTree';
|
|
20
20
|
|
|
21
21
|
// Flat Message List Types
|
|
22
|
-
export type {
|
|
23
|
-
BranchMetadata,
|
|
24
|
-
FlatMessage,
|
|
25
|
-
FlatMessageExtra,
|
|
26
|
-
FlatMessageRole,
|
|
27
|
-
} from './types/flatMessageList';
|
|
22
|
+
export type { FlatMessage, FlatMessageExtra, FlatMessageRole } from './flatMessageList';
|
|
28
23
|
|
|
29
24
|
// Shared Types
|
|
30
|
-
export type {
|
|
31
|
-
HelperMaps,
|
|
32
|
-
IdNode,
|
|
33
|
-
Message,
|
|
34
|
-
MessageGroupMetadata,
|
|
35
|
-
ParseResult,
|
|
36
|
-
} from './types/shared';
|
|
25
|
+
export type { HelperMaps, IdNode, Message, MessageGroupMetadata, ParseResult } from './shared';
|
|
@@ -40,7 +40,6 @@ import {
|
|
|
40
40
|
} from '../schemas';
|
|
41
41
|
import { LobeChatDatabase } from '../type';
|
|
42
42
|
import { genEndDateWhere, genRangeWhere, genStartDateWhere, genWhere } from '../utils/genWhere';
|
|
43
|
-
import { groupAssistantMessages } from '../utils/groupMessages';
|
|
44
43
|
import { idGenerator } from '../utils/idGenerator';
|
|
45
44
|
|
|
46
45
|
export class MessageModel {
|
|
@@ -227,8 +226,8 @@ export class MessageModel {
|
|
|
227
226
|
})),
|
|
228
227
|
|
|
229
228
|
extra: {
|
|
230
|
-
|
|
231
|
-
|
|
229
|
+
model: model,
|
|
230
|
+
provider: provider,
|
|
232
231
|
translate,
|
|
233
232
|
tts: ttsId
|
|
234
233
|
? {
|
|
@@ -269,9 +268,7 @@ export class MessageModel {
|
|
|
269
268
|
},
|
|
270
269
|
);
|
|
271
270
|
|
|
272
|
-
|
|
273
|
-
const { groupAssistantMessages: useGroup = false } = options;
|
|
274
|
-
return useGroup ? groupAssistantMessages(mappedMessages) : mappedMessages;
|
|
271
|
+
return mappedMessages;
|
|
275
272
|
};
|
|
276
273
|
|
|
277
274
|
findById = async (id: string) => {
|
|
@@ -464,8 +461,8 @@ export class MessageModel {
|
|
|
464
461
|
|
|
465
462
|
create = async (
|
|
466
463
|
{
|
|
467
|
-
fromModel,
|
|
468
|
-
fromProvider,
|
|
464
|
+
model: fromModel,
|
|
465
|
+
provider: fromProvider,
|
|
469
466
|
files,
|
|
470
467
|
plugin,
|
|
471
468
|
pluginState,
|
|
@@ -771,17 +768,19 @@ export class MessageModel {
|
|
|
771
768
|
sessionId?: string | null,
|
|
772
769
|
topicId?: string | null,
|
|
773
770
|
groupId?: string | null,
|
|
774
|
-
) =>
|
|
775
|
-
this.
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
771
|
+
) => {
|
|
772
|
+
const conditions = [eq(messages.userId, this.userId), this.matchSession(sessionId)];
|
|
773
|
+
|
|
774
|
+
// For deletion: only filter by topicId/groupId if explicitly provided
|
|
775
|
+
if (topicId !== undefined && topicId !== null) {
|
|
776
|
+
conditions.push(eq(messages.topicId, topicId));
|
|
777
|
+
}
|
|
778
|
+
if (groupId !== undefined && groupId !== null) {
|
|
779
|
+
conditions.push(eq(messages.groupId, groupId));
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
return this.db.delete(messages).where(and(...conditions));
|
|
783
|
+
};
|
|
785
784
|
|
|
786
785
|
deleteAllMessages = async () => {
|
|
787
786
|
return this.db.delete(messages).where(eq(messages.userId, this.userId));
|
|
@@ -9,6 +9,7 @@ export interface SendNewMessage {
|
|
|
9
9
|
content: string;
|
|
10
10
|
// if message has attached with files, then add files to message and the agent
|
|
11
11
|
files?: string[];
|
|
12
|
+
parentId?: string;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export interface SendMessageServerParams {
|
|
@@ -41,6 +42,7 @@ export const AiSendMessageServerSchema = z.object({
|
|
|
41
42
|
newUserMessage: z.object({
|
|
42
43
|
content: z.string(),
|
|
43
44
|
files: z.array(z.string()).optional(),
|
|
45
|
+
parentId: z.string().optional(),
|
|
44
46
|
}),
|
|
45
47
|
sessionId: z.string().optional(),
|
|
46
48
|
threadId: z.string().optional(),
|
|
@@ -13,7 +13,13 @@ import { ChatMessageExtra } from './extra';
|
|
|
13
13
|
import { ChatFileChunk } from './rag';
|
|
14
14
|
import { ChatVideoItem } from './video';
|
|
15
15
|
|
|
16
|
-
export type UIMessageRoleType =
|
|
16
|
+
export type UIMessageRoleType =
|
|
17
|
+
| 'user'
|
|
18
|
+
| 'system'
|
|
19
|
+
| 'assistant'
|
|
20
|
+
| 'tool'
|
|
21
|
+
| 'supervisor'
|
|
22
|
+
| 'assistantGroup';
|
|
17
23
|
|
|
18
24
|
export interface ChatFileItem {
|
|
19
25
|
content?: string;
|
|
@@ -34,10 +40,20 @@ export interface AssistantContentBlock {
|
|
|
34
40
|
tools?: ChatToolPayloadWithResult[];
|
|
35
41
|
usage?: ModelUsage;
|
|
36
42
|
}
|
|
43
|
+
interface UIMessageBranch {
|
|
44
|
+
/** Index of the active branch (0-based) */
|
|
45
|
+
activeBranchIndex: number;
|
|
46
|
+
/** Total number of branches */
|
|
47
|
+
count: number;
|
|
48
|
+
}
|
|
37
49
|
|
|
38
50
|
export interface UIChatMessage {
|
|
39
51
|
// Group chat fields (alphabetically before other fields)
|
|
40
52
|
agentId?: string | 'supervisor';
|
|
53
|
+
/**
|
|
54
|
+
* Branch information for user messages with multiple children
|
|
55
|
+
*/
|
|
56
|
+
branch?: UIMessageBranch;
|
|
41
57
|
/**
|
|
42
58
|
* children messages for grouped display
|
|
43
59
|
* Used to group tool messages under their parent assistant message
|
|
@@ -16,8 +16,8 @@ export interface CreateMessageParams
|
|
|
16
16
|
error?: ChatMessageError | null;
|
|
17
17
|
fileChunks?: MessageSemanticSearchChunk[];
|
|
18
18
|
files?: string[];
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
model?: string;
|
|
20
|
+
provider?: string;
|
|
21
21
|
groupId?: string;
|
|
22
22
|
role: CreateMessageRoleType;
|
|
23
23
|
sessionId: string;
|
|
@@ -35,10 +35,6 @@ export const UserGuideSchema = z.object({
|
|
|
35
35
|
export type UserGuide = z.infer<typeof UserGuideSchema>;
|
|
36
36
|
|
|
37
37
|
export const UserLabSchema = z.object({
|
|
38
|
-
/**
|
|
39
|
-
* enable assistant message grouping in chat display
|
|
40
|
-
*/
|
|
41
|
-
enableAssistantMessageGroup: z.boolean().optional(),
|
|
42
38
|
/**
|
|
43
39
|
* enable multi-agent group chat mode
|
|
44
40
|
*/
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
+
import { estimateTokenCount } from 'tokenx';
|
|
2
|
+
|
|
1
3
|
export const encodeAsync = async (str: string): Promise<number> => {
|
|
2
4
|
if (str.length === 0) return 0;
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
// use approximation way if large then 10000
|
|
6
|
-
if (str.length <= 10_000) {
|
|
7
|
-
const { clientEncodeAsync } = await import('./client');
|
|
8
|
-
|
|
9
|
-
return await clientEncodeAsync(str);
|
|
10
|
-
} else {
|
|
11
|
-
const { estimatedEncodeAsync } = await import('./estimated');
|
|
12
|
-
|
|
13
|
-
return await estimatedEncodeAsync(str);
|
|
14
|
-
}
|
|
6
|
+
return estimateTokenCount(str);
|
|
15
7
|
};
|
|
@@ -8,7 +8,7 @@ import { useChatStore } from '@/store/chat';
|
|
|
8
8
|
import { useSend } from '../useSend';
|
|
9
9
|
|
|
10
10
|
const MessageFromUrl = () => {
|
|
11
|
-
const
|
|
11
|
+
const updateMessageInput = useChatStore((s) => s.updateMessageInput);
|
|
12
12
|
const { send: sendMessage } = useSend();
|
|
13
13
|
const searchParams = useSearchParams();
|
|
14
14
|
|
|
@@ -21,10 +21,10 @@ const MessageFromUrl = () => {
|
|
|
21
21
|
const newUrl = `${window.location.pathname}?${params.toString()}`;
|
|
22
22
|
window.history.replaceState({}, '', newUrl);
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
updateMessageInput(message);
|
|
25
25
|
sendMessage();
|
|
26
26
|
}
|
|
27
|
-
}, [searchParams,
|
|
27
|
+
}, [searchParams, updateMessageInput, sendMessage]);
|
|
28
28
|
|
|
29
29
|
return null;
|
|
30
30
|
};
|
|
@@ -16,9 +16,9 @@ export type UseSendMessageParams = Pick<
|
|
|
16
16
|
>;
|
|
17
17
|
|
|
18
18
|
export const useSendMessage = () => {
|
|
19
|
-
const [sendMessage,
|
|
19
|
+
const [sendMessage, updateMessageInput] = useChatStore((s) => [
|
|
20
20
|
s.sendMessage,
|
|
21
|
-
s.
|
|
21
|
+
s.updateMessageInput,
|
|
22
22
|
]);
|
|
23
23
|
const { analytics } = useAnalytics();
|
|
24
24
|
const checkGeminiChineseWarning = useGeminiChineseWarning();
|
|
@@ -66,7 +66,7 @@ export const useSendMessage = () => {
|
|
|
66
66
|
...params,
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
updateMessageInput('');
|
|
70
70
|
clearChatUploadFileList();
|
|
71
71
|
|
|
72
72
|
// 获取分析数据
|
package/src/app/[variants]/(main)/chat/components/conversation/features/ChatInput/useSend.ts
CHANGED
|
@@ -161,14 +161,14 @@ export const useSendGroupMessage = () => {
|
|
|
161
161
|
const [
|
|
162
162
|
isContentEmpty,
|
|
163
163
|
sendGroupMessage,
|
|
164
|
-
|
|
164
|
+
updateMessageInput,
|
|
165
165
|
stopGenerateMessage,
|
|
166
166
|
isSendButtonDisabledByMessage,
|
|
167
167
|
isCreatingMessage,
|
|
168
168
|
] = useChatStore((s) => [
|
|
169
169
|
!s.inputMessage,
|
|
170
170
|
s.sendGroupMessage,
|
|
171
|
-
s.
|
|
171
|
+
s.updateMessageInput,
|
|
172
172
|
s.stopGenerateMessage,
|
|
173
173
|
messageStateSelectors.isSendButtonDisabledByMessage(s),
|
|
174
174
|
messageStateSelectors.isCreatingMessage(s),
|
|
@@ -255,7 +255,7 @@ export const useSendGroupMessage = () => {
|
|
|
255
255
|
mainInputEditor.setExpand(false);
|
|
256
256
|
mainInputEditor.clearContent();
|
|
257
257
|
mainInputEditor.focus();
|
|
258
|
-
|
|
258
|
+
updateMessageInput('');
|
|
259
259
|
// clear mentioned users after sending
|
|
260
260
|
mentionState.clearMentionedUsers();
|
|
261
261
|
|
|
@@ -284,7 +284,7 @@ export const useSendGroupMessage = () => {
|
|
|
284
284
|
canNotSend,
|
|
285
285
|
fileList,
|
|
286
286
|
clearChatUploadFileList,
|
|
287
|
-
|
|
287
|
+
updateMessageInput,
|
|
288
288
|
analytics,
|
|
289
289
|
checkGeminiChineseWarning,
|
|
290
290
|
],
|
|
@@ -314,8 +314,8 @@ export const useSendGroupMessage = () => {
|
|
|
314
314
|
generating: isSupervisorThinking || isCreatingMessage,
|
|
315
315
|
send: handleSend,
|
|
316
316
|
stop,
|
|
317
|
-
|
|
317
|
+
updateMessageInput,
|
|
318
318
|
}),
|
|
319
|
-
[canNotSend, isSupervisorThinking, isCreatingMessage, handleSend, stop,
|
|
319
|
+
[canNotSend, isSupervisorThinking, isCreatingMessage, handleSend, stop, updateMessageInput],
|
|
320
320
|
);
|
|
321
321
|
};
|
package/src/app/[variants]/(main)/chat/components/conversation/features/ChatList/Content.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { SkeletonList, VirtualizedList } from '@/features/Conversation';
|
|
|
6
6
|
import WideScreenContainer from '@/features/Conversation/components/WideScreenContainer';
|
|
7
7
|
import { useFetchMessages } from '@/hooks/useFetchMessages';
|
|
8
8
|
import { useChatStore } from '@/store/chat';
|
|
9
|
-
import {
|
|
9
|
+
import { displayMessageSelectors } from '@/store/chat/selectors';
|
|
10
10
|
|
|
11
11
|
import MainChatItem from './ChatItem';
|
|
12
12
|
import Welcome from './WelcomeChatItem';
|
|
@@ -16,10 +16,12 @@ interface ListProps {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const Content = memo<ListProps>(({ mobile }) => {
|
|
19
|
-
const [isCurrentChatLoaded] = useChatStore((s) => [
|
|
19
|
+
const [isCurrentChatLoaded] = useChatStore((s) => [
|
|
20
|
+
displayMessageSelectors.isCurrentDisplayChatLoaded(s),
|
|
21
|
+
]);
|
|
20
22
|
|
|
21
23
|
useFetchMessages();
|
|
22
|
-
const data = useChatStore(
|
|
24
|
+
const data = useChatStore(displayMessageSelectors.mainDisplayChatIDs);
|
|
23
25
|
|
|
24
26
|
const itemContent = useCallback(
|
|
25
27
|
(index: number, id: string) => <MainChatItem id={id} index={index} />,
|
|
@@ -40,7 +40,7 @@ interface OpeningQuestionsProps {
|
|
|
40
40
|
|
|
41
41
|
const OpeningQuestions = memo<OpeningQuestionsProps>(({ mobile, questions }) => {
|
|
42
42
|
const { t } = useTranslation('welcome');
|
|
43
|
-
const [
|
|
43
|
+
const [updateMessageInput] = useChatStore((s) => [s.updateMessageInput]);
|
|
44
44
|
|
|
45
45
|
const { styles } = useStyles();
|
|
46
46
|
const { send: sendMessage } = useSend();
|
|
@@ -56,7 +56,7 @@ const OpeningQuestions = memo<OpeningQuestionsProps>(({ mobile, questions }) =>
|
|
|
56
56
|
clickable
|
|
57
57
|
key={question}
|
|
58
58
|
onClick={() => {
|
|
59
|
-
|
|
59
|
+
updateMessageInput(question);
|
|
60
60
|
sendMessage({ isWelcomeQuestion: true });
|
|
61
61
|
}}
|
|
62
62
|
paddingBlock={8}
|
|
@@ -77,7 +77,7 @@ const getFallbackActivities = (t: any) => {
|
|
|
77
77
|
const GroupUsageSuggest = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
78
78
|
const { t } = useTranslation('welcome');
|
|
79
79
|
const { styles } = useStyles();
|
|
80
|
-
const {
|
|
80
|
+
const { updateMessageInput, send } = useSendGroupMessage();
|
|
81
81
|
const templateMatch = useTemplateMatching();
|
|
82
82
|
|
|
83
83
|
const itemsPerPage = mobile ? 2 : 4;
|
|
@@ -139,7 +139,7 @@ const GroupUsageSuggest = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
|
139
139
|
horizontal
|
|
140
140
|
key={activityKey}
|
|
141
141
|
onClick={() => {
|
|
142
|
-
|
|
142
|
+
updateMessageInput(prompt);
|
|
143
143
|
send();
|
|
144
144
|
}}
|
|
145
145
|
variant={'outlined'}
|
|
@@ -24,13 +24,11 @@ const LabsPage = memo(() => {
|
|
|
24
24
|
const [
|
|
25
25
|
isPreferenceInit,
|
|
26
26
|
enableInputMarkdown,
|
|
27
|
-
enableAssistantMessageGroup,
|
|
28
27
|
// enableGroupChat,
|
|
29
28
|
updateLab,
|
|
30
29
|
] = useUserStore((s) => [
|
|
31
30
|
preferenceSelectors.isPreferenceInit(s),
|
|
32
31
|
labPreferSelectors.enableInputMarkdown(s),
|
|
33
|
-
labPreferSelectors.enableAssistantMessageGroup(s),
|
|
34
32
|
// labPreferSelectors.enableGroupChat(s),
|
|
35
33
|
s.updateLab,
|
|
36
34
|
]);
|
|
@@ -43,13 +41,6 @@ const LabsPage = memo(() => {
|
|
|
43
41
|
key: 'enableInputMarkdown',
|
|
44
42
|
title: t('features.inputMarkdown.title'),
|
|
45
43
|
},
|
|
46
|
-
{
|
|
47
|
-
checked: enableAssistantMessageGroup,
|
|
48
|
-
cover: 'https://github.com/user-attachments/assets/ba517751-1f3b-4269-979e-f8471e3ebb89',
|
|
49
|
-
desc: t('features.assistantMessageGroup.desc'),
|
|
50
|
-
key: 'enableAssistantMessageGroup',
|
|
51
|
-
title: t('features.assistantMessageGroup.title'),
|
|
52
|
-
},
|
|
53
44
|
// {
|
|
54
45
|
// checked: enableGroupChat,
|
|
55
46
|
// cover: 'https://github.com/user-attachments/assets/72894d24-a96a-4d7c-a823-ff9e6a1a8b6d',
|
|
@@ -42,9 +42,9 @@ const BrowserSTT = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
|
42
42
|
const [error, setError] = useState<ChatMessageError>();
|
|
43
43
|
const { t } = useTranslation('chat');
|
|
44
44
|
|
|
45
|
-
const [loading,
|
|
45
|
+
const [loading, updateMessageInput] = useChatStore((s) => [
|
|
46
46
|
messageStateSelectors.isAIGenerating(s),
|
|
47
|
-
s.
|
|
47
|
+
s.updateMessageInput,
|
|
48
48
|
]);
|
|
49
49
|
|
|
50
50
|
const setDefaultError = useCallback(
|
|
@@ -76,7 +76,7 @@ const BrowserSTT = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
|
76
76
|
},
|
|
77
77
|
onTextChange: (text) => {
|
|
78
78
|
if (loading) stop();
|
|
79
|
-
if (text)
|
|
79
|
+
if (text) updateMessageInput(text);
|
|
80
80
|
},
|
|
81
81
|
});
|
|
82
82
|
|
|
@@ -53,9 +53,9 @@ const OpenaiSTT = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
|
53
53
|
const [error, setError] = useState<ChatMessageError>();
|
|
54
54
|
const { t } = useTranslation('chat');
|
|
55
55
|
|
|
56
|
-
const [loading,
|
|
56
|
+
const [loading, updateMessageInput] = useChatStore((s) => [
|
|
57
57
|
messageStateSelectors.isAIGenerating(s),
|
|
58
|
-
s.
|
|
58
|
+
s.updateMessageInput,
|
|
59
59
|
]);
|
|
60
60
|
|
|
61
61
|
const setDefaultError = useCallback(
|
|
@@ -87,7 +87,7 @@ const OpenaiSTT = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
|
87
87
|
},
|
|
88
88
|
onTextChange: (text) => {
|
|
89
89
|
if (loading) stop();
|
|
90
|
-
if (text)
|
|
90
|
+
if (text) updateMessageInput(text);
|
|
91
91
|
},
|
|
92
92
|
});
|
|
93
93
|
|