@lobehub/lobehub 2.0.0-next.1 → 2.0.0-next.10
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/.github/workflows/desktop-pr-build.yml +12 -10
- package/.github/workflows/docker.yml +25 -20
- package/.github/workflows/e2e.yml +3 -3
- package/.github/workflows/release-desktop-beta.yml +8 -8
- package/.github/workflows/release.yml +1 -1
- package/.github/workflows/test.yml +4 -4
- package/CHANGELOG.md +236 -0
- package/apps/desktop/src/main/utils/next-electron-rsc.ts +7 -5
- package/changelog/v1.json +73 -0
- package/docs/development/database-schema.dbml +11 -1
- package/docs/self-hosting/advanced/auth/next-auth/auth0.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/auth0.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/authelia.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/authelia.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/authentik.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/authentik.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/github.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/github.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/google.mdx +32 -29
- package/docs/self-hosting/advanced/auth/next-auth/keycloak.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/keycloak.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +5 -3
- package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +5 -3
- package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/okta.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/okta.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/wechat.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/wechat.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/zitadel.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/zitadel.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth.mdx +32 -21
- package/docs/self-hosting/advanced/auth.zh-CN.mdx +30 -19
- package/docs/self-hosting/advanced/online-search.mdx +30 -25
- package/docs/self-hosting/advanced/online-search.zh-CN.mdx +25 -23
- package/locales/ar/models.json +15 -6
- package/locales/bg-BG/models.json +15 -6
- package/locales/de-DE/models.json +15 -6
- package/locales/en-US/models.json +15 -6
- package/locales/es-ES/models.json +15 -6
- package/locales/fa-IR/models.json +15 -6
- package/locales/fr-FR/models.json +15 -6
- package/locales/it-IT/models.json +15 -6
- package/locales/ja-JP/models.json +15 -6
- package/locales/ko-KR/models.json +15 -6
- package/locales/nl-NL/models.json +15 -6
- package/locales/pl-PL/models.json +15 -6
- package/locales/pt-BR/models.json +15 -6
- package/locales/ru-RU/models.json +15 -6
- package/locales/tr-TR/models.json +15 -6
- package/locales/vi-VN/models.json +15 -6
- package/locales/zh-CN/models.json +15 -6
- package/locales/zh-TW/models.json +15 -6
- package/next.config.ts +2 -3
- package/package.json +13 -19
- package/packages/const/src/index.ts +0 -1
- package/packages/const/src/models.ts +13 -0
- package/packages/const/src/url.ts +1 -4
- package/packages/context-engine/src/index.ts +1 -6
- package/packages/context-engine/src/processors/GroupMessageFlatten.ts +12 -2
- package/packages/context-engine/src/processors/__tests__/GroupMessageFlatten.test.ts +73 -9
- package/packages/context-engine/src/providers/index.ts +0 -2
- package/packages/database/migrations/0041_improve_index.sql +10 -0
- package/packages/database/migrations/meta/0041_snapshot.json +7784 -0
- package/packages/database/migrations/meta/_journal.json +7 -0
- package/packages/database/package.json +1 -1
- package/packages/database/src/core/migrations.json +17 -0
- package/packages/database/src/models/__tests__/message.grouping.test.ts +812 -0
- package/packages/database/src/models/__tests__/message.test.ts +322 -170
- package/packages/database/src/models/message.ts +62 -24
- package/packages/database/src/models/session.ts +60 -19
- package/packages/database/src/schemas/agent.ts +10 -11
- package/packages/database/src/schemas/message.ts +5 -1
- package/packages/database/src/schemas/relations.ts +6 -4
- package/packages/database/src/schemas/session.ts +2 -0
- package/packages/database/src/schemas/topic.ts +6 -1
- package/packages/database/src/utils/__tests__/groupMessages.test.ts +145 -2
- package/packages/database/src/utils/groupMessages.ts +7 -5
- package/packages/electron-client-ipc/package.json +4 -1
- package/packages/file-loaders/package.json +1 -0
- package/packages/model-bank/src/aiModels/anthropic.ts +0 -63
- package/packages/model-bank/src/aiModels/azure.ts +155 -0
- package/packages/model-bank/src/aiModels/bedrock.ts +44 -0
- package/packages/model-bank/src/aiModels/higress.ts +0 -55
- package/packages/model-bank/src/aiModels/infiniai.ts +21 -0
- package/packages/model-bank/src/aiModels/ollamacloud.ts +13 -0
- package/packages/model-bank/src/aiModels/siliconcloud.ts +19 -0
- package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +1 -1
- package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +33 -3
- package/packages/model-runtime/src/core/parameterResolver.ts +3 -0
- package/packages/model-runtime/src/core/streams/openai/__snapshots__/responsesStream.test.ts.snap +0 -38
- package/packages/model-runtime/src/providers/azureOpenai/index.ts +2 -1
- package/packages/model-runtime/src/providers/minimax/index.ts +5 -5
- package/packages/model-runtime/src/providers/search1api/index.test.ts +2 -2
- package/packages/types/src/message/common/base.ts +13 -0
- package/packages/types/src/message/common/image.ts +8 -0
- package/packages/types/src/message/common/metadata.ts +39 -0
- package/packages/types/src/message/common/tools.ts +10 -0
- package/packages/types/src/message/db/params.ts +47 -1
- package/packages/types/src/message/ui/chat.ts +4 -1
- package/packages/types/src/search.ts +16 -0
- package/packages/web-crawler/src/crawImpl/firecrawl.ts +39 -12
- package/scripts/migrateServerDB/index.ts +2 -1
- package/src/app/(backend)/oidc/consent/route.ts +0 -1
- package/src/app/(backend)/webapi/revalidate/route.ts +1 -1
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/V1Mobile/index.tsx +2 -2
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/V1Mobile/useSend.ts +6 -4
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/useSend.ts +15 -10
- package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/List/Item/index.tsx +4 -2
- package/src/app/[variants]/(main)/settings/_layout/SettingsContent.tsx +0 -3
- package/src/app/[variants]/layout.tsx +1 -0
- package/src/app/sitemap.tsx +7 -1
- package/src/components/Thinking/index.tsx +4 -3
- package/src/config/modelProviders/anthropic.ts +0 -23
- package/src/config/modelProviders/higress.ts +0 -23
- package/src/config/modelProviders/minimax.ts +1 -1
- package/src/config/modelProviders/qiniu.ts +1 -1
- package/src/envs/auth.ts +0 -179
- package/src/features/AgentSetting/AgentPlugin/index.tsx +21 -13
- package/src/features/ChatInput/ActionBar/STT/browser.tsx +2 -2
- package/src/features/ChatInput/ActionBar/STT/openai.tsx +2 -2
- package/src/features/ChatInput/ActionBar/Tools/useControls.tsx +1 -3
- package/src/features/Conversation/Error/ErrorJsonViewer.tsx +4 -3
- package/src/features/Conversation/Error/OllamaBizError/index.tsx +7 -2
- package/src/features/Conversation/Error/index.tsx +15 -5
- package/src/features/Conversation/MarkdownElements/LobeArtifact/Render/index.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/Extra/index.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +5 -3
- package/src/features/Conversation/Messages/Assistant/Tool/Inspector/BuiltinPluginTitle.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Inspector/ToolTitle.tsx +4 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/Tool/index.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/index.tsx +4 -4
- package/src/features/Conversation/Messages/Default.tsx +2 -2
- package/src/features/Conversation/Messages/User/Extra.tsx +2 -2
- package/src/features/Conversation/Messages/User/index.tsx +4 -4
- package/src/features/Conversation/Messages/index.tsx +3 -3
- package/src/features/Conversation/components/AutoScroll.tsx +2 -2
- package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +9 -6
- package/src/features/PluginTag/index.tsx +1 -3
- package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +37 -28
- package/src/features/Portal/Artifacts/Body/index.tsx +2 -2
- package/src/libs/next-auth/auth.config.ts +1 -1
- package/src/libs/next-auth/sso-providers/auth0.ts +0 -7
- package/src/libs/next-auth/sso-providers/authelia.ts +3 -5
- package/src/libs/next-auth/sso-providers/authentik.ts +0 -7
- package/src/libs/next-auth/sso-providers/cloudflare-zero-trust.ts +3 -6
- package/src/libs/next-auth/sso-providers/cognito.ts +1 -5
- package/src/libs/next-auth/sso-providers/generic-oidc.ts +3 -5
- package/src/libs/next-auth/sso-providers/github.ts +0 -6
- package/src/libs/next-auth/sso-providers/google.ts +0 -2
- package/src/libs/next-auth/sso-providers/index.ts +0 -2
- package/src/libs/next-auth/sso-providers/keycloak.ts +0 -3
- package/src/libs/next-auth/sso-providers/logto.ts +3 -5
- package/src/libs/next-auth/sso-providers/okta.ts +0 -4
- package/src/libs/next-auth/sso-providers/zitadel.ts +0 -7
- package/src/libs/oidc-provider/provider.ts +1 -1
- package/src/server/modules/AssistantStore/index.ts +1 -1
- package/src/server/modules/ModelRuntime/trace.ts +11 -4
- package/src/server/routers/lambda/message.ts +14 -3
- package/src/server/routers/lambda/session.ts +8 -5
- package/src/server/services/search/impls/firecrawl/index.ts +51 -11
- package/src/server/services/search/impls/firecrawl/type.ts +60 -9
- package/src/services/chat/chat.test.ts +1 -40
- package/src/services/chat/contextEngineering.test.ts +0 -30
- package/src/services/chat/contextEngineering.ts +1 -12
- package/src/services/chat/index.ts +2 -7
- package/src/services/chat/types.ts +1 -1
- package/src/services/message/_deprecated.ts +1 -1
- package/src/services/message/client.ts +8 -2
- package/src/services/message/server.ts +7 -2
- package/src/services/message/type.ts +6 -1
- package/src/services/user/client.test.ts +4 -1
- package/src/store/chat/helpers.test.ts +99 -0
- package/src/store/chat/helpers.ts +21 -2
- package/src/store/chat/selectors.ts +1 -1
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +3 -3
- package/src/store/chat/slices/builtinTool/actions/index.ts +1 -4
- package/src/store/chat/slices/message/action.test.ts +5 -1
- package/src/store/chat/slices/message/action.ts +102 -14
- package/src/store/chat/slices/message/reducer.test.ts +363 -5
- package/src/store/chat/slices/message/reducer.ts +87 -3
- package/src/store/chat/slices/message/{selectors.test.ts → selectors/chat.test.ts} +266 -30
- package/src/store/chat/slices/message/{selectors.ts → selectors/chat.ts} +29 -79
- package/src/store/chat/slices/message/selectors/index.ts +2 -0
- package/src/store/chat/slices/message/selectors/messageState.test.ts +36 -0
- package/src/store/chat/slices/message/selectors/messageState.ts +80 -0
- package/src/store/chat/slices/plugin/action.test.ts +34 -132
- package/src/store/chat/slices/plugin/action.ts +1 -44
- package/src/store/tool/selectors/tool.test.ts +1 -1
- package/src/store/tool/selectors/tool.ts +6 -8
- package/src/store/tool/slices/builtin/action.test.ts +83 -35
- package/src/store/tool/slices/builtin/action.ts +0 -9
- package/src/store/tool/slices/builtin/selectors.test.ts +4 -30
- package/src/store/tool/slices/builtin/selectors.ts +15 -21
- package/src/tools/index.ts +0 -6
- package/src/tools/renders.ts +0 -3
- package/src/tools/web-browsing/Portal/Search/Footer.tsx +2 -2
- package/tsconfig.json +9 -2
- package/packages/const/src/guide.ts +0 -89
- package/packages/context-engine/src/providers/InboxGuide.ts +0 -102
- package/packages/context-engine/src/providers/__tests__/InboxGuideProvider.test.ts +0 -121
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Azure/index.tsx +0 -93
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Bedrock/index.tsx +0 -70
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Cloudflare/index.tsx +0 -39
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Github/index.tsx +0 -52
- package/src/app/[variants]/(main)/settings/llm/ProviderList/HuggingFace/index.tsx +0 -52
- package/src/app/[variants]/(main)/settings/llm/ProviderList/Ollama/index.tsx +0 -20
- package/src/app/[variants]/(main)/settings/llm/ProviderList/OpenAI/index.tsx +0 -17
- package/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +0 -132
- package/src/app/[variants]/(main)/settings/llm/components/Checker.tsx +0 -118
- package/src/app/[variants]/(main)/settings/llm/components/ProviderConfig/index.tsx +0 -303
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/CustomModelOption.tsx +0 -98
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/Form.tsx +0 -104
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/index.tsx +0 -77
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +0 -105
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/Option.tsx +0 -68
- package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/index.tsx +0 -146
- package/src/app/[variants]/(main)/settings/llm/const.ts +0 -20
- package/src/app/[variants]/(main)/settings/llm/features/Footer.tsx +0 -35
- package/src/app/[variants]/(main)/settings/llm/index.tsx +0 -30
- package/src/app/[variants]/(main)/settings/llm/type.ts +0 -5
- package/src/envs/__tests__/auth.test.ts +0 -200
- package/src/libs/next-auth/sso-providers/azure-ad.ts +0 -33
- package/src/services/chat/__snapshots__/chat.test.ts.snap +0 -110
- package/src/store/chat/slices/builtinTool/actions/__tests__/dalle.test.ts +0 -121
- package/src/store/chat/slices/builtinTool/actions/dalle.ts +0 -124
- package/src/tools/dalle/Render/GalleyGrid.tsx +0 -60
- package/src/tools/dalle/Render/Item/EditMode.tsx +0 -66
- package/src/tools/dalle/Render/Item/Error.tsx +0 -49
- package/src/tools/dalle/Render/Item/Image.tsx +0 -44
- package/src/tools/dalle/Render/Item/ImageFileItem.tsx +0 -57
- package/src/tools/dalle/Render/Item/index.tsx +0 -88
- package/src/tools/dalle/Render/ToolBar.tsx +0 -56
- package/src/tools/dalle/Render/index.tsx +0 -52
- package/src/tools/dalle/index.ts +0 -92
- /package/src/{middleware.ts → proxy.ts} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { INBOX_SESSION_ID } from '@lobechat/const';
|
|
1
2
|
import {
|
|
2
3
|
ChatFileItem,
|
|
3
4
|
ChatImageItem,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
UIChatMessage,
|
|
15
16
|
UpdateMessageParams,
|
|
16
17
|
UpdateMessageRAGParams,
|
|
18
|
+
UpdateMessageResult,
|
|
17
19
|
} from '@lobechat/types';
|
|
18
20
|
import type { HeatmapsProps } from '@lobehub/charts';
|
|
19
21
|
import dayjs from 'dayjs';
|
|
@@ -39,6 +41,7 @@ import {
|
|
|
39
41
|
} from '../schemas';
|
|
40
42
|
import { LobeChatDatabase } from '../type';
|
|
41
43
|
import { genEndDateWhere, genRangeWhere, genStartDateWhere, genWhere } from '../utils/genWhere';
|
|
44
|
+
import { groupAssistantMessages } from '../utils/groupMessages';
|
|
42
45
|
import { idGenerator } from '../utils/idGenerator';
|
|
43
46
|
|
|
44
47
|
export class MessageModel {
|
|
@@ -54,6 +57,7 @@ export class MessageModel {
|
|
|
54
57
|
query = async (
|
|
55
58
|
{ current = 0, pageSize = 1000, sessionId, topicId, groupId }: QueryMessageParams = {},
|
|
56
59
|
options: {
|
|
60
|
+
groupAssistantMessages?: boolean;
|
|
57
61
|
postProcessUrl?: (path: string | null, file: { fileType: string }) => Promise<string>;
|
|
58
62
|
} = {},
|
|
59
63
|
) => {
|
|
@@ -211,7 +215,7 @@ export class MessageModel {
|
|
|
211
215
|
.from(messageQueries)
|
|
212
216
|
.where(inArray(messageQueries.messageId, messageIds));
|
|
213
217
|
|
|
214
|
-
|
|
218
|
+
const mappedMessages = result.map(
|
|
215
219
|
({ model, provider, translate, ttsId, ttsFile, ttsContentMd5, ttsVoice, ...item }) => {
|
|
216
220
|
const messageQuery = messageQueriesList.find((relation) => relation.messageId === item.id);
|
|
217
221
|
return {
|
|
@@ -246,13 +250,15 @@ export class MessageModel {
|
|
|
246
250
|
size: size!,
|
|
247
251
|
url,
|
|
248
252
|
})),
|
|
249
|
-
|
|
250
253
|
imageList: imageList
|
|
251
254
|
.filter((relation) => relation.messageId === item.id)
|
|
252
255
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
253
256
|
.map<ChatImageItem>(({ id, url, name }) => ({ alt: name!, id, url })),
|
|
254
|
-
|
|
255
257
|
meta: {},
|
|
258
|
+
|
|
259
|
+
model,
|
|
260
|
+
|
|
261
|
+
provider,
|
|
256
262
|
ragQuery: messageQuery?.rewriteQuery,
|
|
257
263
|
ragQueryId: messageQuery?.id,
|
|
258
264
|
ragRawQuery: messageQuery?.userQuery,
|
|
@@ -263,6 +269,10 @@ export class MessageModel {
|
|
|
263
269
|
} as unknown as UIChatMessage;
|
|
264
270
|
},
|
|
265
271
|
);
|
|
272
|
+
|
|
273
|
+
// Group assistant messages with their tool results
|
|
274
|
+
const { groupAssistantMessages: useGroup = false } = options;
|
|
275
|
+
return useGroup ? groupAssistantMessages(mappedMessages) : mappedMessages;
|
|
266
276
|
};
|
|
267
277
|
|
|
268
278
|
findById = async (id: string) => {
|
|
@@ -560,7 +570,7 @@ export class MessageModel {
|
|
|
560
570
|
sessionId: params.sessionId,
|
|
561
571
|
topicId: params.topicId, // Get all messages
|
|
562
572
|
},
|
|
563
|
-
options,
|
|
573
|
+
{ ...options, groupAssistantMessages: true },
|
|
564
574
|
);
|
|
565
575
|
|
|
566
576
|
// 3. Return the result
|
|
@@ -589,27 +599,52 @@ export class MessageModel {
|
|
|
589
599
|
};
|
|
590
600
|
// **************** Update *************** //
|
|
591
601
|
|
|
592
|
-
update = async (
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
602
|
+
update = async (
|
|
603
|
+
id: string,
|
|
604
|
+
{ imageList, ...message }: Partial<UpdateMessageParams>,
|
|
605
|
+
options?: {
|
|
606
|
+
postProcessUrl?: (path: string | null, file: { fileType: string }) => Promise<string>;
|
|
607
|
+
sessionId?: string | null;
|
|
608
|
+
topicId?: string | null;
|
|
609
|
+
},
|
|
610
|
+
): Promise<UpdateMessageResult> => {
|
|
611
|
+
try {
|
|
612
|
+
await this.db.transaction(async (trx) => {
|
|
613
|
+
// 1. insert message files
|
|
614
|
+
if (imageList && imageList.length > 0) {
|
|
615
|
+
await trx
|
|
616
|
+
.insert(messagesFiles)
|
|
617
|
+
.values(
|
|
618
|
+
imageList.map((file) => ({ fileId: file.id, messageId: id, userId: this.userId })),
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
|
|
596
622
|
await trx
|
|
597
|
-
.
|
|
598
|
-
.
|
|
599
|
-
|
|
600
|
-
|
|
623
|
+
.update(messages)
|
|
624
|
+
.set({ ...message })
|
|
625
|
+
.where(and(eq(messages.id, id), eq(messages.userId, this.userId)));
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
// if sessionId or topicId provided, return the updated message list
|
|
629
|
+
if (options?.sessionId !== undefined || options?.topicId !== undefined) {
|
|
630
|
+
const messageList = await this.query(
|
|
631
|
+
{
|
|
632
|
+
sessionId: options.sessionId,
|
|
633
|
+
topicId: options.topicId,
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
postProcessUrl: options.postProcessUrl,
|
|
637
|
+
},
|
|
638
|
+
);
|
|
639
|
+
|
|
640
|
+
return { messages: messageList, success: true };
|
|
601
641
|
}
|
|
602
642
|
|
|
603
|
-
return
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
// TODO: but I forget why 🤡
|
|
609
|
-
role: message.role as any,
|
|
610
|
-
})
|
|
611
|
-
.where(and(eq(messages.id, id), eq(messages.userId, this.userId)));
|
|
612
|
-
});
|
|
643
|
+
return { success: true };
|
|
644
|
+
} catch (error) {
|
|
645
|
+
console.error('Update message error:', error);
|
|
646
|
+
return { success: false };
|
|
647
|
+
}
|
|
613
648
|
};
|
|
614
649
|
|
|
615
650
|
updateMetadata = async (id: string, metadata: Record<string, any>) => {
|
|
@@ -778,8 +813,11 @@ export class MessageModel {
|
|
|
778
813
|
|
|
779
814
|
private genId = () => idGenerator('messages', 14);
|
|
780
815
|
|
|
781
|
-
private matchSession = (sessionId?: string | null) =>
|
|
782
|
-
|
|
816
|
+
private matchSession = (sessionId?: string | null) => {
|
|
817
|
+
if (sessionId === INBOX_SESSION_ID) return isNull(messages.sessionId);
|
|
818
|
+
|
|
819
|
+
return sessionId ? eq(messages.sessionId, sessionId) : isNull(messages.sessionId);
|
|
820
|
+
};
|
|
783
821
|
|
|
784
822
|
private matchTopic = (topicId?: string | null) =>
|
|
785
823
|
topicId ? eq(messages.topicId, topicId) : isNull(messages.topicId);
|
|
@@ -53,13 +53,44 @@ export class SessionModel {
|
|
|
53
53
|
query = async ({ current = 0, pageSize = 9999 } = {}) => {
|
|
54
54
|
const offset = current * pageSize;
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
// Use leftJoin instead of nested with for better performance
|
|
57
|
+
const result = await this.db
|
|
58
|
+
.select({
|
|
59
|
+
// Agent fields (from agentsToSessions join)
|
|
60
|
+
agent: agents,
|
|
61
|
+
// Group fields
|
|
62
|
+
group: sessionGroups,
|
|
63
|
+
// Session fields
|
|
64
|
+
session: sessions,
|
|
65
|
+
})
|
|
66
|
+
.from(sessions)
|
|
67
|
+
.leftJoin(agentsToSessions, eq(sessions.id, agentsToSessions.sessionId))
|
|
68
|
+
.leftJoin(agents, eq(agentsToSessions.agentId, agents.id))
|
|
69
|
+
.leftJoin(sessionGroups, eq(sessions.groupId, sessionGroups.id))
|
|
70
|
+
.where(and(eq(sessions.userId, this.userId), not(eq(sessions.slug, INBOX_SESSION_ID))))
|
|
71
|
+
.orderBy(desc(sessions.updatedAt))
|
|
72
|
+
.limit(pageSize)
|
|
73
|
+
.offset(offset);
|
|
74
|
+
|
|
75
|
+
// Group results by session (since leftJoin can create multiple rows per session)
|
|
76
|
+
// Use Map to preserve order
|
|
77
|
+
const groupedResults = new Map<string, any>();
|
|
78
|
+
|
|
79
|
+
for (const row of result) {
|
|
80
|
+
const sessionId = row.session.id;
|
|
81
|
+
if (!groupedResults.has(sessionId)) {
|
|
82
|
+
groupedResults.set(sessionId, {
|
|
83
|
+
...row.session,
|
|
84
|
+
agentsToSessions: [],
|
|
85
|
+
group: row.group,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (row.agent) {
|
|
89
|
+
groupedResults.get(sessionId)!.agentsToSessions.push({ agent: row.agent });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return Array.from(groupedResults.values());
|
|
63
94
|
};
|
|
64
95
|
|
|
65
96
|
queryWithGroups = async (): Promise<ChatSessionList> => {
|
|
@@ -71,9 +102,11 @@ export class SessionModel {
|
|
|
71
102
|
where: eq(sessions.userId, this.userId),
|
|
72
103
|
});
|
|
73
104
|
|
|
105
|
+
const mappedSessions = result.map((item) => this.mapSessionItem(item as any));
|
|
106
|
+
|
|
74
107
|
return {
|
|
75
108
|
sessionGroups: groups as unknown as ChatSessionList['sessionGroups'],
|
|
76
|
-
sessions:
|
|
109
|
+
sessions: mappedSessions,
|
|
77
110
|
};
|
|
78
111
|
};
|
|
79
112
|
|
|
@@ -332,7 +365,7 @@ export class SessionModel {
|
|
|
332
365
|
.delete(agentsToSessions)
|
|
333
366
|
.where(and(eq(agentsToSessions.sessionId, id), eq(agentsToSessions.userId, this.userId)));
|
|
334
367
|
|
|
335
|
-
// Delete the session
|
|
368
|
+
// Delete the session (this will cascade delete messages, topics, etc.)
|
|
336
369
|
const result = await trx
|
|
337
370
|
.delete(sessions)
|
|
338
371
|
.where(and(eq(sessions.id, id), eq(sessions.userId, this.userId)));
|
|
@@ -397,17 +430,25 @@ export class SessionModel {
|
|
|
397
430
|
};
|
|
398
431
|
|
|
399
432
|
clearOrphanAgent = async (agentIds: string[], trx: any) => {
|
|
400
|
-
|
|
401
|
-
for (const agentId of agentIds) {
|
|
402
|
-
const remaining = await trx
|
|
403
|
-
.select()
|
|
404
|
-
.from(agentsToSessions)
|
|
405
|
-
.where(eq(agentsToSessions.agentId, agentId))
|
|
406
|
-
.limit(1);
|
|
433
|
+
if (agentIds.length === 0) return;
|
|
407
434
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
435
|
+
// Batch query to find which agents still have sessions
|
|
436
|
+
const remainingLinks = (await trx
|
|
437
|
+
.select({ agentId: agentsToSessions.agentId })
|
|
438
|
+
.from(agentsToSessions)
|
|
439
|
+
.where(inArray(agentsToSessions.agentId, agentIds))) as { agentId: string }[];
|
|
440
|
+
|
|
441
|
+
const linkedAgentIds = new Set(remainingLinks.map((link) => link.agentId));
|
|
442
|
+
|
|
443
|
+
// Find orphaned agents (those not in the linked set)
|
|
444
|
+
const orphanedAgentIds = agentIds.filter((id) => !linkedAgentIds.has(id));
|
|
445
|
+
|
|
446
|
+
// Batch delete orphaned agents (this will cascade to agentsFiles, agentsKnowledgeBases, etc.)
|
|
447
|
+
// and SET NULL on messages.agentId
|
|
448
|
+
if (orphanedAgentIds.length > 0) {
|
|
449
|
+
await trx
|
|
450
|
+
.delete(agents)
|
|
451
|
+
.where(and(inArray(agents.id, orphanedAgentIds), eq(agents.userId, this.userId)));
|
|
411
452
|
}
|
|
412
453
|
};
|
|
413
454
|
|
|
@@ -62,11 +62,11 @@ export const agents = pgTable(
|
|
|
62
62
|
|
|
63
63
|
...timestamps,
|
|
64
64
|
},
|
|
65
|
-
(t) =>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
(t) => [
|
|
66
|
+
uniqueIndex('client_id_user_id_unique').on(t.clientId, t.userId),
|
|
67
|
+
index('agents_title_idx').on(t.title),
|
|
68
|
+
index('agents_description_idx').on(t.description),
|
|
69
|
+
],
|
|
70
70
|
);
|
|
71
71
|
|
|
72
72
|
export const insertAgentSchema = createInsertSchema(agents);
|
|
@@ -90,9 +90,7 @@ export const agentsKnowledgeBases = pgTable(
|
|
|
90
90
|
|
|
91
91
|
...timestamps,
|
|
92
92
|
},
|
|
93
|
-
(t) => ({
|
|
94
|
-
pk: primaryKey({ columns: [t.agentId, t.knowledgeBaseId] }),
|
|
95
|
-
}),
|
|
93
|
+
(t) => [primaryKey({ columns: [t.agentId, t.knowledgeBaseId] })],
|
|
96
94
|
);
|
|
97
95
|
|
|
98
96
|
export const agentsFiles = pgTable(
|
|
@@ -111,7 +109,8 @@ export const agentsFiles = pgTable(
|
|
|
111
109
|
|
|
112
110
|
...timestamps,
|
|
113
111
|
},
|
|
114
|
-
(t) =>
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
(t) => [
|
|
113
|
+
primaryKey({ columns: [t.fileId, t.agentId, t.userId] }),
|
|
114
|
+
index('agents_files_agent_id_idx').on(t.agentId),
|
|
115
|
+
],
|
|
117
116
|
);
|
|
@@ -62,7 +62,10 @@ export const messageGroups = pgTable(
|
|
|
62
62
|
|
|
63
63
|
...timestamps,
|
|
64
64
|
},
|
|
65
|
-
(t) => [
|
|
65
|
+
(t) => [
|
|
66
|
+
uniqueIndex('message_groups_client_id_user_id_unique').on(t.clientId, t.userId),
|
|
67
|
+
index('message_groups_topic_id_idx').on(t.topicId),
|
|
68
|
+
],
|
|
66
69
|
);
|
|
67
70
|
|
|
68
71
|
export const insertMessageGroupSchema = createInsertSchema(messageGroups);
|
|
@@ -130,6 +133,7 @@ export const messages = pgTable(
|
|
|
130
133
|
index('messages_user_id_idx').on(table.userId),
|
|
131
134
|
index('messages_session_id_idx').on(table.sessionId),
|
|
132
135
|
index('messages_thread_id_idx').on(table.threadId),
|
|
136
|
+
index('messages_agent_id_idx').on(table.agentId),
|
|
133
137
|
],
|
|
134
138
|
);
|
|
135
139
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
|
2
2
|
import { relations } from 'drizzle-orm';
|
|
3
|
-
import { pgTable, primaryKey, text, uuid, varchar } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { index, pgTable, primaryKey, text, uuid, varchar } from 'drizzle-orm/pg-core';
|
|
4
4
|
|
|
5
5
|
import { createdAt } from './_helpers';
|
|
6
6
|
import { agents, agentsFiles, agentsKnowledgeBases } from './agent';
|
|
@@ -28,9 +28,11 @@ export const agentsToSessions = pgTable(
|
|
|
28
28
|
.references(() => users.id, { onDelete: 'cascade' })
|
|
29
29
|
.notNull(),
|
|
30
30
|
},
|
|
31
|
-
(t) =>
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
(t) => [
|
|
32
|
+
primaryKey({ columns: [t.agentId, t.sessionId] }),
|
|
33
|
+
index('agents_to_sessions_session_id_idx').on(t.sessionId),
|
|
34
|
+
index('agents_to_sessions_agent_id_idx').on(t.agentId),
|
|
35
|
+
],
|
|
34
36
|
);
|
|
35
37
|
|
|
36
38
|
export const filesToSessions = pgTable(
|
|
@@ -70,6 +70,8 @@ export const sessions = pgTable(
|
|
|
70
70
|
|
|
71
71
|
index('sessions_user_id_idx').on(t.userId),
|
|
72
72
|
index('sessions_id_user_id_idx').on(t.id, t.userId),
|
|
73
|
+
index('sessions_user_id_updated_at_idx').on(t.userId, t.updatedAt),
|
|
74
|
+
index('sessions_group_id_idx').on(t.groupId),
|
|
73
75
|
],
|
|
74
76
|
);
|
|
75
77
|
|
|
@@ -33,6 +33,8 @@ export const topics = pgTable(
|
|
|
33
33
|
uniqueIndex('topics_client_id_user_id_unique').on(t.clientId, t.userId),
|
|
34
34
|
index('topics_user_id_idx').on(t.userId),
|
|
35
35
|
index('topics_id_user_id_idx').on(t.id, t.userId),
|
|
36
|
+
index('topics_session_id_idx').on(t.sessionId),
|
|
37
|
+
index('topics_group_id_idx').on(t.groupId),
|
|
36
38
|
],
|
|
37
39
|
);
|
|
38
40
|
|
|
@@ -65,7 +67,10 @@ export const threads = pgTable(
|
|
|
65
67
|
lastActiveAt: timestamptz('last_active_at').defaultNow(),
|
|
66
68
|
...timestamps,
|
|
67
69
|
},
|
|
68
|
-
(t) => [
|
|
70
|
+
(t) => [
|
|
71
|
+
uniqueIndex('threads_client_id_user_id_unique').on(t.clientId, t.userId),
|
|
72
|
+
index('threads_topic_id_idx').on(t.topicId),
|
|
73
|
+
],
|
|
69
74
|
);
|
|
70
75
|
|
|
71
76
|
export type NewThread = typeof threads.$inferInsert;
|
|
@@ -54,6 +54,7 @@ describe('groupAssistantMessages', () => {
|
|
|
54
54
|
content: 'Beijing: Sunny, 25°C',
|
|
55
55
|
state: { cached: true },
|
|
56
56
|
},
|
|
57
|
+
result_msg_id: 'msg-2',
|
|
57
58
|
});
|
|
58
59
|
});
|
|
59
60
|
|
|
@@ -112,7 +113,9 @@ describe('groupAssistantMessages', () => {
|
|
|
112
113
|
const block = result[0].children![0];
|
|
113
114
|
expect(block.tools).toHaveLength(2);
|
|
114
115
|
expect(block.tools![0].result?.content).toBe('Beijing: Sunny, 25°C');
|
|
116
|
+
expect(block.tools![0].result_msg_id).toBe('msg-2');
|
|
115
117
|
expect(block.tools![1].result?.content).toBe('Latest tech news: AI breakthrough');
|
|
118
|
+
expect(block.tools![1].result_msg_id).toBe('msg-3');
|
|
116
119
|
});
|
|
117
120
|
|
|
118
121
|
it('should handle assistant message without tools', () => {
|
|
@@ -165,6 +168,7 @@ describe('groupAssistantMessages', () => {
|
|
|
165
168
|
const block = result[0].children![0];
|
|
166
169
|
expect(block.tools).toHaveLength(1);
|
|
167
170
|
expect(block.tools![0].result).toBeUndefined();
|
|
171
|
+
expect(block.tools![0].result_msg_id).toBeUndefined();
|
|
168
172
|
});
|
|
169
173
|
});
|
|
170
174
|
|
|
@@ -366,11 +370,13 @@ describe('groupAssistantMessages', () => {
|
|
|
366
370
|
// First child: original assistant with tool result
|
|
367
371
|
expect(result[0].children![0].id).toBe('msg-1');
|
|
368
372
|
expect(result[0].children![0].tools![0].result?.content).toBe('Sunny, 25°C');
|
|
373
|
+
expect(result[0].children![0].tools![0].result_msg_id).toBe('msg-2');
|
|
369
374
|
|
|
370
375
|
// Second child: follow-up assistant with its own tool result
|
|
371
376
|
expect(result[0].children![1].id).toBe('msg-3');
|
|
372
377
|
expect(result[0].children![1].tools).toHaveLength(1);
|
|
373
378
|
expect(result[0].children![1].tools![0].result?.content).toBe('Breaking news');
|
|
379
|
+
expect(result[0].children![1].tools![0].result_msg_id).toBe('msg-4');
|
|
374
380
|
});
|
|
375
381
|
|
|
376
382
|
it('should group multiple follow-up assistants in chain (3+ assistants)', () => {
|
|
@@ -448,9 +454,11 @@ describe('groupAssistantMessages', () => {
|
|
|
448
454
|
|
|
449
455
|
expect(result[0].children![0].id).toBe('msg-1');
|
|
450
456
|
expect(result[0].children![0].tools![0].result?.content).toBe('Result 1');
|
|
457
|
+
expect(result[0].children![0].tools![0].result_msg_id).toBe('msg-2');
|
|
451
458
|
|
|
452
459
|
expect(result[0].children![1].id).toBe('msg-3');
|
|
453
460
|
expect(result[0].children![1].tools![0].result?.content).toBe('Result 2');
|
|
461
|
+
expect(result[0].children![1].tools![0].result_msg_id).toBe('msg-4');
|
|
454
462
|
|
|
455
463
|
expect(result[0].children![2].id).toBe('msg-5');
|
|
456
464
|
expect(result[0].children![2].content).toBe('Step 3 final');
|
|
@@ -677,7 +685,6 @@ describe('groupAssistantMessages', () => {
|
|
|
677
685
|
expect(block.content).toBe('Test');
|
|
678
686
|
expect(block.tools).toHaveLength(1);
|
|
679
687
|
expect(block.imageList).toHaveLength(1);
|
|
680
|
-
expect(block.fileList).toHaveLength(1);
|
|
681
688
|
});
|
|
682
689
|
|
|
683
690
|
it('should preserve all tool result fields', () => {
|
|
@@ -720,6 +727,7 @@ describe('groupAssistantMessages', () => {
|
|
|
720
727
|
state: { step: 1 },
|
|
721
728
|
error: null,
|
|
722
729
|
});
|
|
730
|
+
expect(block.tools![0].result_msg_id).toBe('msg-2');
|
|
723
731
|
});
|
|
724
732
|
});
|
|
725
733
|
|
|
@@ -928,6 +936,142 @@ describe('groupAssistantMessages', () => {
|
|
|
928
936
|
expect(result[0].performance).toBeUndefined();
|
|
929
937
|
expect(result[0].metadata).toBeUndefined();
|
|
930
938
|
});
|
|
939
|
+
|
|
940
|
+
it('should map reasoning field to reasoning in children blocks', () => {
|
|
941
|
+
const input: UIChatMessage[] = [
|
|
942
|
+
{
|
|
943
|
+
id: 'msg-1',
|
|
944
|
+
role: 'assistant',
|
|
945
|
+
content: 'Test response',
|
|
946
|
+
reasoning: {
|
|
947
|
+
content: 'This is my reasoning process',
|
|
948
|
+
duration: 1500,
|
|
949
|
+
},
|
|
950
|
+
tools: [
|
|
951
|
+
{
|
|
952
|
+
id: 'tool-1',
|
|
953
|
+
identifier: 'test',
|
|
954
|
+
apiName: 'test',
|
|
955
|
+
arguments: '{}',
|
|
956
|
+
type: 'default',
|
|
957
|
+
},
|
|
958
|
+
],
|
|
959
|
+
createdAt: Date.now(),
|
|
960
|
+
updatedAt: Date.now(),
|
|
961
|
+
meta: {},
|
|
962
|
+
} as UIChatMessage,
|
|
963
|
+
{
|
|
964
|
+
id: 'msg-2',
|
|
965
|
+
role: 'tool',
|
|
966
|
+
tool_call_id: 'tool-1',
|
|
967
|
+
content: 'Tool result',
|
|
968
|
+
createdAt: Date.now(),
|
|
969
|
+
updatedAt: Date.now(),
|
|
970
|
+
meta: {},
|
|
971
|
+
} as UIChatMessage,
|
|
972
|
+
{
|
|
973
|
+
id: 'msg-3',
|
|
974
|
+
role: 'assistant',
|
|
975
|
+
content: 'Follow-up response',
|
|
976
|
+
parentId: 'msg-2',
|
|
977
|
+
reasoning: {
|
|
978
|
+
content: 'Follow-up reasoning',
|
|
979
|
+
duration: 2000,
|
|
980
|
+
},
|
|
981
|
+
createdAt: Date.now(),
|
|
982
|
+
updatedAt: Date.now(),
|
|
983
|
+
meta: {},
|
|
984
|
+
} as UIChatMessage,
|
|
985
|
+
];
|
|
986
|
+
|
|
987
|
+
const result = groupAssistantMessages(input);
|
|
988
|
+
|
|
989
|
+
// First block should have reasoning
|
|
990
|
+
expect(result[0].children![0].reasoning).toEqual({
|
|
991
|
+
content: 'This is my reasoning process',
|
|
992
|
+
duration: 1500,
|
|
993
|
+
});
|
|
994
|
+
|
|
995
|
+
// Second block (follow-up) should also have reasoning
|
|
996
|
+
expect(result[0].children![1].reasoning).toEqual({
|
|
997
|
+
content: 'Follow-up reasoning',
|
|
998
|
+
duration: 2000,
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
// Group message should not have reasoning (moved to children)
|
|
1002
|
+
expect(result[0].reasoning).toBeUndefined();
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
it('should preserve error field in children blocks', () => {
|
|
1006
|
+
const input = [
|
|
1007
|
+
{
|
|
1008
|
+
id: 'msg-1',
|
|
1009
|
+
role: 'assistant',
|
|
1010
|
+
content: 'Failed to process',
|
|
1011
|
+
error: {
|
|
1012
|
+
type: 'InvalidAPIKey',
|
|
1013
|
+
message: 'API key is invalid',
|
|
1014
|
+
},
|
|
1015
|
+
tools: [
|
|
1016
|
+
{
|
|
1017
|
+
id: 'tool-1',
|
|
1018
|
+
identifier: 'test',
|
|
1019
|
+
apiName: 'test',
|
|
1020
|
+
arguments: '{}',
|
|
1021
|
+
type: 'default',
|
|
1022
|
+
},
|
|
1023
|
+
],
|
|
1024
|
+
createdAt: Date.now(),
|
|
1025
|
+
updatedAt: Date.now(),
|
|
1026
|
+
meta: {},
|
|
1027
|
+
} as unknown as UIChatMessage,
|
|
1028
|
+
] as UIChatMessage[];
|
|
1029
|
+
|
|
1030
|
+
const result = groupAssistantMessages(input);
|
|
1031
|
+
|
|
1032
|
+
// Child block should have error
|
|
1033
|
+
expect(result[0].children![0].error).toEqual({
|
|
1034
|
+
type: 'InvalidAPIKey',
|
|
1035
|
+
message: 'API key is invalid',
|
|
1036
|
+
});
|
|
1037
|
+
});
|
|
1038
|
+
|
|
1039
|
+
it('should preserve imageList in children blocks', () => {
|
|
1040
|
+
const input: UIChatMessage[] = [
|
|
1041
|
+
{
|
|
1042
|
+
id: 'msg-1',
|
|
1043
|
+
role: 'assistant',
|
|
1044
|
+
content: 'Here are the images',
|
|
1045
|
+
imageList: [
|
|
1046
|
+
{ id: 'img-1', url: 'https://example.com/img1.jpg', alt: 'Image 1' },
|
|
1047
|
+
{ id: 'img-2', url: 'https://example.com/img2.jpg', alt: 'Image 2' },
|
|
1048
|
+
],
|
|
1049
|
+
tools: [
|
|
1050
|
+
{
|
|
1051
|
+
id: 'tool-1',
|
|
1052
|
+
identifier: 'test',
|
|
1053
|
+
apiName: 'test',
|
|
1054
|
+
arguments: '{}',
|
|
1055
|
+
type: 'default',
|
|
1056
|
+
},
|
|
1057
|
+
],
|
|
1058
|
+
createdAt: Date.now(),
|
|
1059
|
+
updatedAt: Date.now(),
|
|
1060
|
+
meta: {},
|
|
1061
|
+
} as UIChatMessage,
|
|
1062
|
+
];
|
|
1063
|
+
|
|
1064
|
+
const result = groupAssistantMessages(input);
|
|
1065
|
+
|
|
1066
|
+
// Child block should have imageList
|
|
1067
|
+
expect(result[0].children![0].imageList).toEqual([
|
|
1068
|
+
{ id: 'img-1', url: 'https://example.com/img1.jpg', alt: 'Image 1' },
|
|
1069
|
+
{ id: 'img-2', url: 'https://example.com/img2.jpg', alt: 'Image 2' },
|
|
1070
|
+
]);
|
|
1071
|
+
|
|
1072
|
+
// Parent should not have imageList (moved to children)
|
|
1073
|
+
expect(result[0].imageList).toBeUndefined();
|
|
1074
|
+
});
|
|
931
1075
|
});
|
|
932
1076
|
|
|
933
1077
|
describe('Empty and Null Cases', () => {
|
|
@@ -958,7 +1102,6 @@ describe('groupAssistantMessages', () => {
|
|
|
958
1102
|
|
|
959
1103
|
// Empty arrays should become undefined
|
|
960
1104
|
expect(result[0].children![0].imageList).toBeUndefined();
|
|
961
|
-
expect(result[0].children![0].fileList).toBeUndefined();
|
|
962
1105
|
});
|
|
963
1106
|
|
|
964
1107
|
it('should handle empty message list', () => {
|
|
@@ -243,6 +243,7 @@ export function groupAssistantMessages(messages: UIChatMessage[]): UIChatMessage
|
|
|
243
243
|
id: toolMsg.id,
|
|
244
244
|
state: toolMsg.pluginState,
|
|
245
245
|
},
|
|
246
|
+
result_msg_id: toolMsg.id,
|
|
246
247
|
};
|
|
247
248
|
}
|
|
248
249
|
|
|
@@ -253,10 +254,11 @@ export function groupAssistantMessages(messages: UIChatMessage[]): UIChatMessage
|
|
|
253
254
|
const { usage: msgUsage, performance: msgPerformance } = splitMetadata(msg.metadata);
|
|
254
255
|
children.push({
|
|
255
256
|
content: msg.content || '',
|
|
256
|
-
|
|
257
|
+
error: msg.error,
|
|
257
258
|
id: msg.id,
|
|
258
259
|
imageList: msg.imageList && msg.imageList.length > 0 ? msg.imageList : undefined,
|
|
259
260
|
performance: msgPerformance,
|
|
261
|
+
reasoning: msg.reasoning || undefined,
|
|
260
262
|
tools: toolsWithResults,
|
|
261
263
|
usage: msgUsage,
|
|
262
264
|
});
|
|
@@ -299,6 +301,7 @@ export function groupAssistantMessages(messages: UIChatMessage[]): UIChatMessage
|
|
|
299
301
|
id: followUpToolMsg.id,
|
|
300
302
|
state: followUpToolMsg.pluginState,
|
|
301
303
|
},
|
|
304
|
+
result_msg_id: followUpToolMsg.id,
|
|
302
305
|
};
|
|
303
306
|
}
|
|
304
307
|
|
|
@@ -311,16 +314,14 @@ export function groupAssistantMessages(messages: UIChatMessage[]): UIChatMessage
|
|
|
311
314
|
);
|
|
312
315
|
children.push({
|
|
313
316
|
content: followUpMsg.content || '',
|
|
314
|
-
|
|
315
|
-
followUpMsg.fileList && followUpMsg.fileList.length > 0
|
|
316
|
-
? followUpMsg.fileList
|
|
317
|
-
: undefined,
|
|
317
|
+
error: followUpMsg.error,
|
|
318
318
|
id: followUpMsg.id,
|
|
319
319
|
imageList:
|
|
320
320
|
followUpMsg.imageList && followUpMsg.imageList.length > 0
|
|
321
321
|
? followUpMsg.imageList
|
|
322
322
|
: undefined,
|
|
323
323
|
performance: followUpPerformance,
|
|
324
|
+
reasoning: followUpMsg.reasoning || undefined,
|
|
324
325
|
tools: followUpToolsWithResults,
|
|
325
326
|
usage: followUpUsage,
|
|
326
327
|
});
|
|
@@ -347,6 +348,7 @@ export function groupAssistantMessages(messages: UIChatMessage[]): UIChatMessage
|
|
|
347
348
|
assistantMsg.performance = aggregated.performance;
|
|
348
349
|
}
|
|
349
350
|
delete assistantMsg.metadata; // Clear individual metadata
|
|
351
|
+
delete assistantMsg.reasoning; // Reasoning moved to children blocks
|
|
350
352
|
delete assistantMsg.tools;
|
|
351
353
|
delete assistantMsg.imageList;
|
|
352
354
|
delete assistantMsg.fileList;
|