@lobehub/lobehub 2.0.0-next.4 → 2.0.0-next.40
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/.env.desktop +1 -2
- package/.env.example +0 -3
- package/.env.example.development +0 -2
- package/.github/workflows/claude-auto-testing.yml +73 -0
- package/.github/workflows/claude-translate-comments.yml +67 -0
- package/.github/workflows/desktop-pr-build.yml +18 -16
- package/.github/workflows/docker.yml +25 -20
- package/.github/workflows/e2e.yml +17 -3
- package/.github/workflows/release-desktop-beta.yml +12 -12
- package/.github/workflows/release.yml +3 -5
- package/.github/workflows/test.yml +48 -12
- package/.nvmrc +1 -1
- package/CHANGELOG.md +884 -0
- package/Dockerfile +1 -3
- package/README.md +2 -45
- package/README.zh-CN.md +2 -45
- package/apps/desktop/package.json +1 -1
- package/apps/desktop/src/main/controllers/AuthCtr.ts +53 -39
- package/apps/desktop/src/main/controllers/MenuCtr.ts +5 -5
- package/apps/desktop/src/main/controllers/NotificationCtr.ts +29 -29
- package/apps/desktop/src/main/controllers/RemoteServerConfigCtr.ts +16 -16
- package/apps/desktop/src/main/controllers/ShortcutCtr.ts +2 -2
- package/apps/desktop/src/main/controllers/TrayMenuCtr.ts +18 -18
- package/apps/desktop/src/main/controllers/UpdaterCtr.ts +4 -4
- package/apps/desktop/src/main/controllers/__tests__/AuthCtr.test.ts +706 -0
- package/apps/desktop/src/main/controllers/__tests__/TrayMenuCtr.test.ts +5 -5
- package/apps/desktop/src/main/controllers/index.ts +4 -4
- package/apps/desktop/src/main/core/infrastructure/UpdaterManager.ts +23 -2
- package/apps/desktop/src/main/modules/networkProxy/__tests__/dispatcher.test.ts +401 -0
- package/apps/desktop/src/main/modules/networkProxy/__tests__/tester.test.ts +531 -0
- package/apps/desktop/src/main/modules/networkProxy/__tests__/urlBuilder.test.ts +349 -0
- package/apps/desktop/src/main/modules/networkProxy/__tests__/validator.test.ts +492 -0
- package/apps/desktop/src/main/utils/next-electron-rsc.ts +7 -5
- package/apps/desktop/tsconfig.json +0 -1
- package/changelog/v1.json +299 -0
- package/docker-compose/local/.env.example +3 -0
- package/docs/development/database-schema.dbml +12 -0
- 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/feature-flags.mdx +0 -1
- package/docs/self-hosting/advanced/feature-flags.zh-CN.mdx +0 -1
- package/docs/self-hosting/advanced/online-search.mdx +30 -25
- package/docs/self-hosting/advanced/online-search.zh-CN.mdx +25 -23
- package/docs/self-hosting/server-database/docker-compose.mdx +29 -0
- package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +29 -0
- package/e2e/src/features/discover/detail-pages.feature +95 -0
- package/e2e/src/features/discover/interactions.feature +113 -0
- package/e2e/src/features/discover/smoke.feature +34 -1
- package/e2e/src/steps/discover/detail-pages.steps.ts +295 -0
- package/e2e/src/steps/discover/interactions.steps.ts +451 -0
- package/e2e/src/steps/discover/smoke.steps.ts +116 -4
- package/e2e/tsconfig.json +0 -1
- package/locales/ar/auth.json +45 -1
- package/locales/ar/labs.json +4 -0
- package/locales/ar/modelProvider.json +13 -1
- package/locales/ar/models.json +6 -6
- package/locales/ar/oauth.json +1 -0
- package/locales/bg-BG/auth.json +45 -1
- package/locales/bg-BG/labs.json +4 -0
- package/locales/bg-BG/modelProvider.json +13 -1
- package/locales/bg-BG/models.json +6 -6
- package/locales/bg-BG/oauth.json +1 -0
- package/locales/de-DE/auth.json +45 -1
- package/locales/de-DE/labs.json +4 -0
- package/locales/de-DE/modelProvider.json +13 -1
- package/locales/de-DE/models.json +6 -6
- package/locales/de-DE/oauth.json +1 -0
- package/locales/en-US/auth.json +45 -1
- package/locales/en-US/labs.json +4 -0
- package/locales/en-US/modelProvider.json +13 -1
- package/locales/en-US/models.json +6 -6
- package/locales/en-US/oauth.json +1 -0
- package/locales/es-ES/auth.json +45 -1
- package/locales/es-ES/labs.json +4 -0
- package/locales/es-ES/modelProvider.json +13 -1
- package/locales/es-ES/models.json +6 -6
- package/locales/es-ES/oauth.json +1 -0
- package/locales/fa-IR/auth.json +45 -1
- package/locales/fa-IR/labs.json +4 -0
- package/locales/fa-IR/modelProvider.json +13 -1
- package/locales/fa-IR/models.json +6 -6
- package/locales/fa-IR/oauth.json +1 -0
- package/locales/fr-FR/auth.json +45 -1
- package/locales/fr-FR/labs.json +4 -0
- package/locales/fr-FR/modelProvider.json +13 -1
- package/locales/fr-FR/models.json +6 -6
- package/locales/fr-FR/oauth.json +1 -0
- package/locales/it-IT/auth.json +45 -1
- package/locales/it-IT/labs.json +4 -0
- package/locales/it-IT/modelProvider.json +13 -1
- package/locales/it-IT/models.json +6 -6
- package/locales/it-IT/oauth.json +1 -0
- package/locales/ja-JP/auth.json +45 -1
- package/locales/ja-JP/labs.json +4 -0
- package/locales/ja-JP/modelProvider.json +13 -1
- package/locales/ja-JP/models.json +6 -6
- package/locales/ja-JP/oauth.json +1 -0
- package/locales/ko-KR/auth.json +45 -1
- package/locales/ko-KR/labs.json +4 -0
- package/locales/ko-KR/modelProvider.json +13 -1
- package/locales/ko-KR/models.json +12 -12
- package/locales/ko-KR/oauth.json +1 -0
- package/locales/nl-NL/auth.json +45 -1
- package/locales/nl-NL/labs.json +4 -0
- package/locales/nl-NL/modelProvider.json +13 -1
- package/locales/nl-NL/models.json +6 -6
- package/locales/nl-NL/oauth.json +1 -0
- package/locales/pl-PL/auth.json +45 -1
- package/locales/pl-PL/labs.json +4 -0
- package/locales/pl-PL/modelProvider.json +13 -1
- package/locales/pl-PL/models.json +6 -6
- package/locales/pl-PL/oauth.json +1 -0
- package/locales/pt-BR/auth.json +45 -1
- package/locales/pt-BR/labs.json +4 -0
- package/locales/pt-BR/modelProvider.json +13 -1
- package/locales/pt-BR/models.json +6 -6
- package/locales/pt-BR/oauth.json +1 -0
- package/locales/ru-RU/auth.json +45 -1
- package/locales/ru-RU/labs.json +4 -0
- package/locales/ru-RU/modelProvider.json +13 -1
- package/locales/ru-RU/models.json +6 -6
- package/locales/ru-RU/oauth.json +1 -0
- package/locales/tr-TR/auth.json +45 -1
- package/locales/tr-TR/labs.json +4 -0
- package/locales/tr-TR/modelProvider.json +13 -1
- package/locales/tr-TR/models.json +6 -6
- package/locales/tr-TR/oauth.json +1 -0
- package/locales/vi-VN/auth.json +45 -1
- package/locales/vi-VN/labs.json +4 -0
- package/locales/vi-VN/modelProvider.json +13 -1
- package/locales/vi-VN/models.json +6 -6
- package/locales/vi-VN/oauth.json +1 -0
- package/locales/zh-CN/auth.json +45 -1
- package/locales/zh-CN/labs.json +4 -0
- package/locales/zh-CN/modelProvider.json +13 -1
- package/locales/zh-CN/models.json +6 -6
- package/locales/zh-CN/oauth.json +1 -0
- package/locales/zh-TW/auth.json +45 -1
- package/locales/zh-TW/labs.json +4 -0
- package/locales/zh-TW/modelProvider.json +13 -1
- package/locales/zh-TW/models.json +6 -6
- package/locales/zh-TW/oauth.json +1 -0
- package/next.config.ts +7 -9
- package/package.json +77 -83
- 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/hotkeys.ts +3 -3
- package/packages/const/src/index.ts +0 -1
- package/packages/const/src/models.ts +2 -2
- package/packages/const/src/url.ts +1 -4
- package/packages/const/src/user.ts +4 -2
- package/packages/const/src/utils/merge.ts +3 -3
- package/packages/const/src/version.ts +3 -3
- package/packages/context-engine/src/index.ts +1 -6
- package/packages/context-engine/src/processors/GroupMessageFlatten.ts +20 -8
- package/packages/context-engine/src/processors/MessageCleanup.ts +1 -0
- package/packages/context-engine/src/processors/__tests__/GroupMessageFlatten.test.ts +83 -19
- package/packages/context-engine/src/processors/__tests__/MessageCleanup.test.ts +28 -0
- package/packages/context-engine/src/providers/index.ts +0 -2
- package/packages/conversation-flow/package.json +13 -0
- package/packages/conversation-flow/src/__tests__/fixtures/index.ts +48 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/assistant-chain-with-followup.json +56 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/assistant-with-tools.json +144 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/active-index-1.json +131 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/assistant-branch.json +96 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/assistant-group-branches.json +249 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/assistant-user-branch.json +123 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/conversation.json +128 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/index.ts +18 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/multi-assistant-group.json +260 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/nested.json +179 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/compare/index.ts +8 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/compare/simple.json +85 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/compare/with-tools.json +169 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/complex-scenario.json +107 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/index.ts +14 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/linear-conversation.json +59 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/assistant-chain-with-followup.json +135 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/assistant-with-tools.json +340 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/active-index-1.json +246 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/assistant-branch.json +208 -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/assistant-user-branch.json +254 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/conversation.json +264 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/index.ts +18 -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 +405 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/compare/index.ts +8 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/compare/simple.json +224 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/compare/with-tools.json +418 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/complex-scenario.json +261 -0
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/linear-conversation.json +138 -0
- package/packages/conversation-flow/src/__tests__/parse.test.ts +109 -0
- package/packages/conversation-flow/src/index.ts +17 -0
- package/packages/conversation-flow/src/indexing.ts +58 -0
- package/packages/conversation-flow/src/parse.ts +53 -0
- package/packages/conversation-flow/src/structuring.ts +38 -0
- package/packages/conversation-flow/src/transformation/BranchResolver.ts +66 -0
- package/packages/conversation-flow/src/transformation/ContextTreeBuilder.ts +292 -0
- package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +499 -0
- package/packages/conversation-flow/src/transformation/MessageCollector.ts +166 -0
- package/packages/conversation-flow/src/transformation/MessageTransformer.ts +177 -0
- package/packages/conversation-flow/src/transformation/__tests__/BranchResolver.test.ts +151 -0
- package/packages/conversation-flow/src/transformation/__tests__/ContextTreeBuilder.test.ts +385 -0
- package/packages/conversation-flow/src/transformation/__tests__/FlatListBuilder.test.ts +511 -0
- package/packages/conversation-flow/src/transformation/__tests__/MessageCollector.test.ts +220 -0
- package/packages/conversation-flow/src/transformation/__tests__/MessageTransformer.test.ts +287 -0
- package/packages/conversation-flow/src/transformation/index.ts +78 -0
- package/packages/conversation-flow/src/types/contextTree.ts +65 -0
- package/packages/conversation-flow/src/types/flatMessageList.ts +54 -0
- package/packages/conversation-flow/src/types/index.ts +25 -0
- package/packages/conversation-flow/src/types/shared.ts +63 -0
- package/packages/conversation-flow/vitest.config.mts +10 -0
- package/packages/database/migrations/0041_improve_index.sql +10 -0
- package/packages/database/migrations/0042_improve_agent_index.sql +1 -0
- package/packages/database/migrations/0043_add_ai_model_settings.sql +1 -0
- package/packages/database/migrations/meta/0041_snapshot.json +7784 -0
- package/packages/database/migrations/meta/0042_snapshot.json +7800 -0
- package/packages/database/migrations/meta/0043_snapshot.json +8419 -0
- package/packages/database/migrations/meta/_journal.json +21 -0
- package/packages/database/package.json +2 -2
- package/packages/database/src/core/migrations.json +33 -0
- package/packages/database/src/core/web-server.ts +2 -1
- package/packages/database/src/models/__tests__/apiKey.test.ts +444 -0
- package/packages/database/src/models/__tests__/message.test.ts +313 -233
- package/packages/database/src/models/agent.ts +16 -13
- package/packages/database/src/models/message.ts +91 -78
- package/packages/database/src/models/session.ts +80 -28
- package/packages/database/src/models/user.ts +2 -1
- package/packages/database/src/repositories/aiInfra/index.test.ts +198 -0
- package/packages/database/src/repositories/aiInfra/index.ts +2 -1
- package/packages/database/src/repositories/dataImporter/deprecated/__tests__/index.test.ts +2 -1
- package/packages/database/src/repositories/dataImporter/deprecated/index.ts +7 -1
- package/packages/database/src/schemas/agent.ts +13 -11
- package/packages/database/src/schemas/aiInfra.ts +2 -0
- 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/electron-client-ipc/package.json +4 -1
- package/packages/file-loaders/package.json +1 -0
- package/packages/memory-extract/package.json +2 -2
- package/packages/model-bank/src/aiModels/anthropic.ts +0 -63
- package/packages/model-bank/src/aiModels/google.ts +1 -1
- 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/streams/openai/__snapshots__/responsesStream.test.ts.snap +0 -38
- 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/model-runtime/src/utils/googleErrorParser.test.ts +125 -0
- package/packages/model-runtime/src/utils/googleErrorParser.ts +103 -77
- package/packages/obervability-otel/package.json +4 -4
- package/packages/obervability-otel/src/api.ts +2 -0
- package/packages/obervability-otel/src/node.ts +3 -7
- package/packages/obervability-otel/src/trpc/convention.ts +16 -0
- package/packages/obervability-otel/src/trpc/index.test.ts +38 -0
- package/packages/obervability-otel/src/trpc/index.ts +62 -0
- package/packages/obervability-otel/src/trpc/metrics.ts +31 -0
- package/packages/types/src/aiChat.ts +2 -0
- package/packages/types/src/discover/mcp.ts +6 -0
- package/packages/types/src/importer.ts +2 -2
- package/packages/types/src/index.ts +0 -1
- 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 +44 -1
- 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 +21 -2
- package/packages/types/src/message/ui/extra.ts +2 -2
- package/packages/types/src/message/ui/params.ts +51 -6
- package/packages/types/src/plugins/mcp.ts +4 -1
- package/packages/types/src/search.ts +16 -0
- package/packages/types/src/serverConfig.ts +2 -6
- package/packages/types/src/topic/topic.ts +14 -0
- package/packages/types/src/usage/usageRecord.ts +54 -0
- package/packages/types/src/user/index.ts +2 -76
- package/packages/types/src/user/preference.ts +101 -0
- package/packages/types/src/user/settings/index.ts +22 -0
- package/packages/utils/src/apiKey.test.ts +139 -0
- package/packages/utils/src/client/clipboard.ts +2 -2
- package/packages/utils/src/client/exportFile.ts +10 -10
- package/packages/utils/src/client/parserPlaceholder.ts +18 -18
- package/packages/utils/src/client/topic.ts +10 -10
- package/packages/utils/src/client/xor-obfuscation.ts +11 -11
- package/packages/utils/src/server/auth.ts +6 -6
- package/packages/utils/src/server/geo.ts +9 -9
- package/packages/utils/src/server/xor.ts +7 -7
- package/packages/utils/src/tokenizer/index.ts +3 -11
- package/packages/web-crawler/src/crawImpl/browserless.ts +1 -1
- package/packages/web-crawler/src/crawImpl/firecrawl.ts +39 -12
- package/packages/web-crawler/src/crawImpl/naive.ts +9 -9
- package/packages/web-crawler/src/crawler.ts +5 -5
- package/packages/web-crawler/src/urlRules.ts +13 -13
- package/packages/web-crawler/src/utils/appUrlRules.ts +5 -5
- package/packages/web-crawler/tsconfig.json +0 -1
- package/renovate.json +23 -1
- package/scripts/migrateServerDB/errorHint.js +1 -7
- package/scripts/migrateServerDB/index.ts +2 -1
- package/src/app/(backend)/webapi/revalidate/route.ts +1 -1
- package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -8
- package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +9 -0
- package/src/app/[variants]/(main)/(mobile)/me/(home)/features/UserBanner.tsx +3 -6
- package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +0 -2
- package/src/app/[variants]/(main)/_layout/Desktop/SideBar/TopActions.tsx +1 -4
- package/src/app/[variants]/(main)/chat/ChatRouter.tsx +83 -0
- package/src/app/[variants]/(main)/chat/_layout/ChatLayout.tsx +22 -0
- package/src/app/[variants]/(main)/chat/_layout/Desktop/SessionPanel.tsx +12 -7
- package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +2 -4
- package/src/app/[variants]/(main)/chat/_layout/FeatureFlagsProvider.tsx +24 -0
- package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +4 -7
- package/src/app/[variants]/(main)/chat/_layout/type.ts +0 -1
- package/src/app/[variants]/(main)/chat/components/ConversationArea.tsx +29 -0
- package/src/app/[variants]/(main)/chat/components/MainChatPage.tsx +25 -0
- package/src/app/[variants]/(main)/chat/components/PortalPanel.tsx +28 -0
- package/src/app/[variants]/(main)/chat/components/SessionPanel.tsx +33 -0
- package/src/app/[variants]/(main)/chat/{settings/page.tsx → components/SettingsPage.tsx} +35 -3
- package/src/app/[variants]/(main)/chat/components/TopicSidebar.tsx +30 -0
- package/src/app/[variants]/(main)/chat/components/WorkspaceLayout.tsx +73 -0
- package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/MessageFromUrl.tsx +3 -3
- package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/index.tsx +3 -3
- package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/useSend.ts +9 -7
- package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/useSend.ts +21 -16
- package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/index.tsx +1 -1
- package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/Content.tsx +5 -3
- package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/OpeningQuestions.tsx +2 -2
- package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/GroupUsageSuggest.tsx +2 -2
- package/src/app/[variants]/(main)/chat/{layout.ts → layout.tsx} +0 -1
- package/src/app/[variants]/(main)/chat/page.tsx +12 -0
- package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/Item/Actions.tsx +3 -28
- package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/Item/index.tsx +7 -6
- package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -62
- package/src/app/[variants]/(main)/discover/(list)/features/Pagination.tsx +1 -0
- package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +1 -1
- package/src/app/[variants]/(main)/discover/(list)/mcp/features/List/Item.tsx +1 -0
- package/src/app/[variants]/(main)/discover/(list)/model/features/List/Item.tsx +1 -0
- package/src/app/[variants]/(main)/discover/(list)/provider/features/List/Item.tsx +1 -0
- package/src/app/[variants]/(main)/discover/components/CategoryMenu.tsx +9 -1
- package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicList.tsx +1 -0
- package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +1 -1
- package/src/app/[variants]/(main)/image/page.tsx +0 -2
- package/src/app/[variants]/(main)/labs/components/LabCard.tsx +8 -6
- package/src/app/[variants]/(main)/labs/page.tsx +10 -22
- package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +23 -24
- package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +5 -9
- package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +10 -1
- package/src/app/[variants]/(main)/profile/usage/Client.tsx +114 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/ModelTable.tsx +175 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/index.tsx +126 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/MonthSpend.tsx +53 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/TodaySpend.tsx +67 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageCards/index.tsx +19 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageTable.tsx +145 -0
- package/src/app/[variants]/(main)/profile/usage/features/UsageTrends.tsx +107 -0
- package/src/app/[variants]/(main)/profile/usage/features/components/UsageBarChart.tsx +48 -0
- package/src/app/[variants]/(main)/{(mobile)/me/data → profile/usage}/page.tsx +6 -12
- package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +0 -2
- package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +0 -2
- package/src/app/[variants]/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/ProviderMenu/List.tsx +97 -7
- package/src/app/[variants]/(main)/settings/provider/detail/azure/index.tsx +6 -8
- package/src/app/[variants]/(main)/settings/provider/detail/azureai/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/detail/bedrock/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/detail/cloudflare/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/detail/comfyui/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/detail/github/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/detail/vertexai/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/DisabledModels.tsx +144 -8
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +2 -4
- package/src/app/[variants]/layout.tsx +1 -0
- package/src/app/[variants]/loading/index.tsx +1 -10
- package/src/app/[variants]/oauth/ResultLayout.tsx +47 -0
- package/src/app/[variants]/oauth/callback/error/page.tsx +20 -33
- package/src/app/[variants]/oauth/callback/layout.tsx +1 -0
- package/src/app/[variants]/oauth/callback/success/page.tsx +8 -22
- package/src/app/[variants]/oauth/consent/[uid]/Consent/BuiltinConsent.tsx +47 -0
- package/src/app/[variants]/oauth/consent/[uid]/{Consent.tsx → Consent/index.tsx} +12 -1
- package/src/app/[variants]/oauth/consent/[uid]/Login.tsx +19 -2
- package/src/app/sitemap.tsx +7 -1
- package/src/components/InvalidAPIKey/APIKeyForm/Bedrock.tsx +8 -13
- package/src/components/Link.tsx +12 -0
- package/src/components/Skeleton/SkeletonSwitch.tsx +13 -0
- package/src/components/Skeleton/index.ts +2 -0
- package/src/components/Thinking/index.tsx +4 -3
- package/src/config/db.ts +0 -5
- package/src/config/featureFlags/schema.test.ts +0 -2
- package/src/config/featureFlags/schema.ts +0 -6
- package/src/config/modelProviders/ai21.ts +1 -16
- package/src/config/modelProviders/ai302.ts +1 -128
- package/src/config/modelProviders/ai360.ts +1 -32
- package/src/config/modelProviders/anthropic.ts +1 -94
- package/src/config/modelProviders/azure.ts +1 -51
- package/src/config/modelProviders/baichuan.ts +1 -57
- package/src/config/modelProviders/bedrock.ts +1 -276
- package/src/config/modelProviders/cloudflare.ts +1 -64
- package/src/config/modelProviders/deepseek.ts +1 -19
- package/src/config/modelProviders/fireworksai.ts +1 -174
- package/src/config/modelProviders/giteeai.ts +1 -135
- package/src/config/modelProviders/github.ts +1 -254
- package/src/config/modelProviders/google.ts +1 -130
- package/src/config/modelProviders/groq.ts +1 -119
- package/src/config/modelProviders/higress.ts +1 -1736
- package/src/config/modelProviders/huggingface.ts +1 -54
- package/src/config/modelProviders/hunyuan.ts +1 -83
- package/src/config/modelProviders/infiniai.ts +1 -74
- package/src/config/modelProviders/internlm.ts +1 -20
- package/src/config/modelProviders/minimax.ts +1 -1
- package/src/config/modelProviders/mistral.ts +1 -95
- package/src/config/modelProviders/modelscope.ts +1 -27
- package/src/config/modelProviders/moonshot.ts +1 -29
- package/src/config/modelProviders/novita.ts +1 -105
- package/src/config/modelProviders/ollama.ts +1 -325
- package/src/config/modelProviders/openai.ts +1 -242
- package/src/config/modelProviders/openrouter.ts +1 -240
- package/src/config/modelProviders/perplexity.ts +1 -45
- package/src/config/modelProviders/ppio.ts +1 -152
- package/src/config/modelProviders/qiniu.ts +2 -19
- package/src/config/modelProviders/qwen.ts +1 -245
- package/src/config/modelProviders/search1api.ts +1 -34
- package/src/config/modelProviders/sensenova.ts +1 -69
- package/src/config/modelProviders/siliconcloud.ts +1 -417
- package/src/config/modelProviders/spark.ts +1 -59
- package/src/config/modelProviders/stepfun.ts +1 -98
- package/src/config/modelProviders/taichu.ts +1 -18
- package/src/config/modelProviders/togetherai.ts +1 -274
- package/src/config/modelProviders/upstage.ts +1 -28
- package/src/config/modelProviders/wenxin.ts +1 -140
- package/src/config/modelProviders/xai.ts +1 -38
- package/src/config/modelProviders/zeroone.ts +1 -81
- package/src/config/modelProviders/zhipu.ts +1 -108
- package/src/envs/__tests__/app.test.ts +47 -13
- package/src/envs/app.ts +10 -7
- package/src/envs/auth.ts +0 -179
- package/src/features/AgentSetting/AgentPlugin/index.tsx +2 -2
- package/src/features/ChatInput/ActionBar/STT/browser.tsx +5 -5
- package/src/features/ChatInput/ActionBar/STT/openai.tsx +5 -5
- package/src/features/ChatInput/ActionBar/Tools/useControls.tsx +1 -3
- package/src/features/ChatInput/ActionBar/index.tsx +2 -2
- package/src/features/ChatInput/InputEditor/index.tsx +2 -2
- 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/ErrorJsonViewer.tsx +4 -3
- package/src/features/Conversation/Error/OAuthForm.tsx +1 -1
- package/src/features/Conversation/Error/OllamaBizError/index.tsx +7 -2
- package/src/features/Conversation/Error/index.tsx +15 -10
- package/src/features/Conversation/MarkdownElements/LobeArtifact/Render/index.tsx +2 -2
- 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 +4 -8
- package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +12 -12
- package/src/features/Conversation/Messages/Assistant/Tool/Inspector/BuiltinPluginTitle.tsx +2 -2
- 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/Inspector/ToolTitle.tsx +4 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +5 -5
- package/src/features/Conversation/Messages/Assistant/Tool/Render/PluginSettings.tsx +4 -1
- package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +3 -4
- package/src/features/Conversation/Messages/Assistant/Tool/index.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/index.tsx +61 -64
- package/src/features/Conversation/Messages/Default.tsx +3 -2
- package/src/features/Conversation/Messages/Group/Actions/WithContentId.tsx +180 -0
- package/src/features/Conversation/Messages/Group/Actions/WithoutContentId.tsx +93 -0
- package/src/features/Conversation/Messages/Group/Actions/index.tsx +21 -0
- package/src/features/Conversation/Messages/Group/ContentBlock.tsx +89 -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 +51 -0
- package/src/features/Conversation/Messages/Group/GroupItem.tsx +43 -0
- package/src/features/Conversation/Messages/Group/MessageContent.tsx +45 -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 +175 -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 +73 -0
- package/src/features/Conversation/Messages/Group/Tools.tsx +46 -0
- package/src/features/Conversation/Messages/Group/index.tsx +146 -0
- 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/Extra.tsx +2 -2
- package/src/features/Conversation/Messages/User/index.tsx +47 -48
- package/src/features/Conversation/Messages/index.tsx +16 -4
- package/src/features/Conversation/components/AutoScroll.tsx +4 -4
- package/src/features/Conversation/components/Extras/Usage/UsageDetail/AnimatedNumber.tsx +55 -0
- package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +15 -6
- package/src/features/Conversation/components/ShareMessageModal/ShareImage/Preview.tsx +2 -2
- package/src/features/Conversation/components/VirtualizedList/index.tsx +29 -20
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +26 -14
- package/src/features/DataImporter/index.tsx +15 -60
- package/src/features/DevPanel/PostgresViewer/usePgTable.ts +3 -2
- package/src/features/MCP/utils.test.ts +91 -0
- package/src/features/MCP/utils.ts +20 -2
- package/src/features/PluginStore/Content.tsx +2 -3
- package/src/features/PluginStore/McpList/index.tsx +6 -2
- package/src/features/PluginTag/index.tsx +1 -3
- package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +37 -28
- package/src/features/PluginsUI/Render/BuiltinType/index.tsx +1 -1
- package/src/features/PluginsUI/Render/MCPType/index.tsx +52 -0
- package/src/features/PluginsUI/Render/StandaloneType/Iframe.tsx +2 -2
- package/src/features/PluginsUI/Render/index.tsx +17 -0
- package/src/features/Portal/Artifacts/Body/index.tsx +2 -2
- package/src/features/Portal/GroupThread/Body/index.tsx +1 -1
- package/src/features/Portal/Thread/Chat/ChatInput/useSend.ts +3 -3
- package/src/helpers/isCanUseFC.ts +0 -8
- package/src/hooks/useEnabledChatModels.ts +0 -8
- package/src/hooks/useHotkeys/chatScope.ts +16 -8
- package/src/hooks/useInterceptingRoutes.test.ts +21 -3
- package/src/hooks/useModelContextWindowTokens.ts +0 -8
- package/src/hooks/useModelHasContextWindowToken.ts +1 -10
- package/src/hooks/useModelSupportFiles.ts +1 -11
- package/src/hooks/useModelSupportReasoning.ts +1 -11
- package/src/hooks/useModelSupportToolUse.ts +1 -11
- package/src/hooks/useModelSupportVision.ts +1 -11
- package/src/layout/AuthProvider/Clerk/index.tsx +2 -16
- package/src/libs/mcp/client.ts +3 -2
- package/src/libs/mcp/types.ts +71 -0
- package/src/libs/next-auth/auth.config.ts +3 -6
- 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/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/trpc/client/index.ts +0 -1
- package/src/libs/trpc/client/lambda.ts +12 -8
- package/src/libs/trpc/lambda/context.ts +4 -1
- package/src/libs/trpc/lambda/index.ts +5 -2
- package/src/libs/trpc/middleware/openTelemetry.ts +141 -0
- package/src/locales/default/auth.ts +44 -0
- package/src/locales/default/chat.ts +1 -0
- package/src/locales/default/labs.ts +4 -0
- package/src/locales/default/modelProvider.ts +15 -1
- package/src/locales/default/oauth.ts +1 -0
- package/src/server/globalConfig/index.ts +0 -23
- package/src/server/modules/AssistantStore/index.ts +1 -1
- package/src/server/modules/ModelRuntime/trace.ts +11 -4
- package/src/server/modules/S3/index.test.ts +379 -0
- package/src/server/routers/async/__tests__/caller.test.ts +333 -0
- package/src/server/routers/async/caller.ts +2 -1
- package/src/server/routers/desktop/mcp.ts +2 -6
- package/src/server/routers/lambda/__tests__/aiChat.test.ts +1 -1
- package/src/server/routers/lambda/__tests__/integration/message.integration.test.ts +771 -57
- package/src/server/routers/lambda/aiChat.ts +3 -2
- package/src/server/routers/lambda/config/__snapshots__/index.test.ts.snap +175 -12
- package/src/server/routers/lambda/config/index.test.ts +38 -30
- package/src/server/routers/lambda/index.ts +2 -0
- package/src/server/routers/lambda/market/index.ts +4 -2
- package/src/server/routers/lambda/message.ts +53 -53
- package/src/server/routers/lambda/session.ts +8 -5
- package/src/server/routers/lambda/topic.ts +7 -1
- package/src/server/routers/lambda/usage.ts +36 -0
- package/src/server/routers/lambda/user.ts +32 -31
- package/src/server/routers/tools/mcp.ts +3 -6
- package/src/server/routers/tools/search.test.ts +1 -7
- package/src/server/routers/tools/search.ts +1 -4
- package/src/server/services/mcp/deps/MCPSystemDepsCheckService.test.ts +541 -0
- package/src/server/services/mcp/deps/checkers/ManualInstallationChecker.test.ts +162 -0
- package/src/server/services/mcp/deps/checkers/NpmInstallationChecker.test.ts +374 -0
- package/src/server/services/mcp/deps/checkers/PythonInstallationChecker.test.ts +368 -0
- package/src/server/services/mcp/index.test.ts +28 -15
- package/src/server/services/mcp/index.ts +29 -18
- package/src/server/services/message/__tests__/index.test.ts +338 -0
- package/src/server/services/message/index.ts +164 -0
- package/src/server/services/search/impls/firecrawl/index.ts +51 -11
- package/src/server/services/search/impls/firecrawl/type.ts +60 -9
- package/src/server/services/usage/index.test.ts +310 -0
- package/src/server/services/usage/index.ts +164 -0
- package/src/services/__tests__/tool.test.ts +0 -3
- package/src/services/aiModel/index.test.ts +3 -6
- package/src/services/aiModel/index.ts +55 -7
- package/src/services/aiProvider/index.test.ts +2 -5
- package/src/services/aiProvider/index.ts +47 -7
- package/src/services/chat/chat.test.ts +13 -40
- package/src/services/chat/contextEngineering.test.ts +4 -30
- package/src/services/chat/contextEngineering.ts +7 -17
- package/src/services/chat/helper.ts +7 -31
- package/src/services/chat/index.ts +5 -10
- package/src/services/chat/types.ts +1 -1
- package/src/services/chatGroup/index.ts +64 -9
- package/src/services/config.ts +1 -65
- package/src/services/electron/desktopNotification.ts +6 -6
- package/src/services/electron/file.ts +6 -6
- package/src/services/export/index.ts +9 -4
- package/src/services/file/ClientS3/index.ts +8 -8
- package/src/services/file/index.ts +59 -10
- package/src/services/import/index.ts +132 -7
- package/src/services/mcp.test.ts +783 -0
- package/src/services/mcp.ts +39 -4
- package/src/services/message/__tests__/metadata-race-condition.test.ts +157 -0
- package/src/services/message/index.ts +208 -10
- package/src/services/message/{__tests__/server.test.ts → server.test.ts} +3 -3
- package/src/services/models.ts +2 -11
- package/src/services/plugin/index.test.ts +8 -0
- package/src/services/plugin/index.ts +51 -10
- package/src/services/session/index.test.ts +8 -0
- package/src/services/session/index.ts +143 -10
- package/src/services/tableViewer/client.ts +12 -15
- package/src/services/thread/index.test.ts +8 -0
- package/src/services/thread/index.ts +37 -7
- package/src/services/topic/index.test.ts +8 -0
- package/src/services/topic/index.ts +74 -10
- package/src/services/upload.ts +11 -11
- package/src/services/usage.ts +13 -0
- package/src/services/user/index.test.ts +8 -0
- package/src/services/user/index.ts +50 -11
- package/src/services/utils/abortableRequest.test.ts +161 -0
- package/src/services/utils/abortableRequest.ts +67 -0
- package/src/store/aiInfra/slices/aiModel/action.test.ts +17 -9
- package/src/store/chat/agents/GeneralChatAgent.ts +137 -0
- package/src/store/chat/agents/createAgentExecutors.ts +394 -0
- package/src/store/chat/helpers.ts +10 -2
- package/src/store/chat/selectors.ts +1 -1
- 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 +19 -6
- 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 +368 -0
- package/src/store/chat/slices/aiChat/actions/generateAIGroupChat.ts +19 -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 +612 -0
- package/src/store/chat/slices/aiChat/actions/streamingStates.ts +84 -0
- package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +7 -7
- package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +17 -17
- package/src/store/chat/slices/builtinTool/actions/index.ts +1 -4
- package/src/store/chat/slices/builtinTool/actions/interpreter.ts +10 -10
- package/src/store/chat/slices/builtinTool/actions/localSystem.ts +4 -4
- package/src/store/chat/slices/builtinTool/actions/search.ts +16 -16
- package/src/store/chat/slices/message/action.test.ts +199 -47
- 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 +242 -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 +18 -0
- package/src/store/chat/slices/message/reducer.test.ts +48 -12
- package/src/store/chat/slices/message/reducer.ts +23 -3
- package/src/store/chat/slices/message/selectors/chat.test.ts +92 -0
- package/src/store/chat/slices/message/selectors/chat.ts +106 -0
- package/src/store/chat/slices/message/selectors/dbMessage.test.ts +51 -0
- package/src/store/chat/slices/message/selectors/dbMessage.ts +140 -0
- package/src/store/chat/slices/message/selectors/displayMessage.test.ts +818 -0
- package/src/store/chat/slices/message/selectors/displayMessage.ts +352 -0
- 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 +85 -0
- package/src/store/chat/slices/plugin/action.test.ts +169 -210
- package/src/store/chat/slices/plugin/actions/index.ts +39 -0
- package/src/store/chat/slices/plugin/actions/internals.ts +83 -0
- package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +188 -0
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +213 -0
- package/src/store/chat/slices/plugin/actions/publicApi.ts +115 -0
- package/src/store/chat/slices/plugin/actions/workflow.ts +121 -0
- package/src/store/chat/slices/thread/action.test.ts +38 -32
- package/src/store/chat/slices/thread/action.ts +15 -10
- package/src/store/chat/slices/thread/selectors/index.ts +8 -6
- package/src/store/chat/slices/topic/action.test.ts +1 -1
- package/src/store/chat/slices/topic/action.ts +1 -2
- package/src/store/chat/slices/topic/reducer.ts +12 -5
- package/src/store/chat/store.ts +2 -2
- package/src/store/file/slices/chat/action.ts +1 -4
- package/src/store/file/slices/fileManager/action.ts +2 -3
- package/src/store/global/initialState.ts +5 -0
- package/src/store/global/selectors/systemStatus.ts +6 -0
- package/src/store/global/store.ts +1 -7
- package/src/store/session/slices/sessionGroup/action.test.ts +5 -5
- 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/store/tool/slices/mcpStore/action.test.ts +95 -3
- package/src/store/tool/slices/mcpStore/action.ts +177 -53
- package/src/store/tool/slices/oldStore/initialState.ts +1 -2
- package/src/store/user/initialState.ts +1 -7
- package/src/store/user/selectors.ts +1 -5
- package/src/store/user/slices/common/action.test.ts +1 -4
- package/src/store/user/slices/common/action.ts +5 -4
- package/src/store/user/slices/preference/action.ts +8 -1
- package/src/store/user/slices/preference/selectors/index.ts +2 -0
- package/src/store/user/slices/preference/selectors/labPrefer.ts +10 -0
- package/src/store/user/slices/preference/{selectors.ts → selectors/preference.ts} +0 -2
- package/src/store/user/slices/settings/selectors/index.ts +1 -0
- package/src/store/user/slices/settings/selectors/keyVaults.ts +21 -0
- package/src/store/user/store.ts +0 -3
- 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/src/tools/web-browsing/Render/Search/ConfigForm/Form.tsx +1 -1
- package/tsconfig.json +9 -3
- package/packages/const/src/guide.ts +0 -89
- package/packages/context-engine/ARCHITECTURE.md +0 -425
- package/packages/context-engine/src/providers/InboxGuide.ts +0 -102
- package/packages/context-engine/src/providers/__tests__/InboxGuideProvider.test.ts +0 -121
- package/packages/database/src/utils/__tests__/groupMessages.test.ts +0 -989
- package/packages/database/src/utils/groupMessages.ts +0 -359
- package/packages/utils/src/_deprecated/__snapshots__/parseModels.test.ts.snap +0 -104
- package/packages/utils/src/_deprecated/parseModels.test.ts +0 -287
- package/packages/utils/src/_deprecated/parseModels.ts +0 -165
- 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)/trpc/edge/[trpc]/route.ts +0 -26
- package/src/app/(backend)/webapi/tokenizer/index.test.ts +0 -32
- package/src/app/(backend)/webapi/tokenizer/route.ts +0 -8
- package/src/app/[variants]/(main)/(mobile)/me/data/features/Category.tsx +0 -48
- package/src/app/[variants]/(main)/(mobile)/me/data/features/Header.tsx +0 -33
- package/src/app/[variants]/(main)/(mobile)/me/data/layout.tsx +0 -13
- package/src/app/[variants]/(main)/(mobile)/me/data/loading.tsx +0 -5
- package/src/app/[variants]/(main)/chat/(workspace)/layout.ts +0 -11
- package/src/app/[variants]/(main)/chat/(workspace)/page.tsx +0 -53
- package/src/app/[variants]/(main)/chat/@session/default.tsx +0 -31
- package/src/app/[variants]/(main)/chat/features/Migration/DBReader.ts +0 -290
- package/src/app/[variants]/(main)/chat/features/Migration/ExportConfigButton.tsx +0 -35
- package/src/app/[variants]/(main)/chat/features/Migration/Failed.tsx +0 -120
- package/src/app/[variants]/(main)/chat/features/Migration/Modal.tsx +0 -81
- package/src/app/[variants]/(main)/chat/features/Migration/Start.tsx +0 -108
- package/src/app/[variants]/(main)/chat/features/Migration/UpgradeButton.tsx +0 -71
- package/src/app/[variants]/(main)/chat/features/Migration/const.ts +0 -15
- package/src/app/[variants]/(main)/chat/features/Migration/index.tsx +0 -50
- package/src/app/[variants]/(main)/chat/settings/layout.tsx +0 -21
- package/src/app/[variants]/loading/Client/Content.tsx +0 -48
- package/src/app/[variants]/loading/Client/Error.tsx +0 -27
- package/src/app/[variants]/loading/Client/Redirect.tsx +0 -47
- package/src/app/[variants]/loading/Client/index.tsx +0 -22
- package/src/components/InnerLink.tsx +0 -20
- package/src/database/_deprecated/core/__tests__/db-upgrade.test.ts +0 -42
- package/src/database/_deprecated/core/__tests__/db.test.ts +0 -79
- package/src/database/_deprecated/core/__tests__/model.test.ts +0 -55
- package/src/database/_deprecated/core/db.ts +0 -246
- package/src/database/_deprecated/core/index.ts +0 -2
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/input.json +0 -55
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/output.json +0 -60
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.test.ts +0 -14
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.ts +0 -22
- package/src/database/_deprecated/core/migrations/migrateSettingsToUser/type.ts +0 -105
- package/src/database/_deprecated/core/model.ts +0 -218
- package/src/database/_deprecated/core/schemas.ts +0 -88
- package/src/database/_deprecated/core/types/db.ts +0 -15
- package/src/database/_deprecated/models/__DEBUG.ts +0 -124
- package/src/database/_deprecated/models/__tests__/file.test.ts +0 -83
- package/src/database/_deprecated/models/__tests__/message.test.ts +0 -426
- package/src/database/_deprecated/models/__tests__/plugin.test.ts +0 -81
- package/src/database/_deprecated/models/__tests__/session.test.ts +0 -253
- package/src/database/_deprecated/models/__tests__/sessionGroup.test.ts +0 -220
- package/src/database/_deprecated/models/__tests__/topic.test.ts +0 -523
- package/src/database/_deprecated/models/__tests__/user.test.ts +0 -82
- package/src/database/_deprecated/models/file.ts +0 -51
- package/src/database/_deprecated/models/message.ts +0 -277
- package/src/database/_deprecated/models/plugin.ts +0 -62
- package/src/database/_deprecated/models/session.ts +0 -271
- package/src/database/_deprecated/models/sessionGroup.ts +0 -93
- package/src/database/_deprecated/models/topic.ts +0 -250
- package/src/database/_deprecated/models/user.ts +0 -69
- package/src/database/_deprecated/schemas/files.ts +0 -39
- package/src/database/_deprecated/schemas/message.ts +0 -50
- package/src/database/_deprecated/schemas/plugin.ts +0 -12
- package/src/database/_deprecated/schemas/session.ts +0 -54
- package/src/database/_deprecated/schemas/sessionGroup.ts +0 -8
- package/src/database/_deprecated/schemas/topic.ts +0 -12
- package/src/database/_deprecated/schemas/user.ts +0 -40
- package/src/envs/__tests__/auth.test.ts +0 -200
- package/src/features/Conversation/Error/InvalidAccessCode.tsx +0 -79
- package/src/features/DataImporter/_deprecated.ts +0 -43
- package/src/features/InitClientDB/EnableModal.tsx +0 -118
- package/src/features/InitClientDB/ErrorResult.tsx +0 -143
- package/src/features/InitClientDB/InitIndicator.tsx +0 -124
- package/src/features/InitClientDB/PGliteIcon.tsx +0 -28
- package/src/features/InitClientDB/features/DatabaseRepair/Backup.tsx +0 -75
- package/src/features/InitClientDB/features/DatabaseRepair/Diagnosis.tsx +0 -98
- package/src/features/InitClientDB/features/DatabaseRepair/Repair.tsx +0 -218
- package/src/features/InitClientDB/features/DatabaseRepair/index.tsx +0 -91
- package/src/features/InitClientDB/index.tsx +0 -37
- package/src/hooks/_header.ts +0 -23
- package/src/libs/trpc/client/edge.ts +0 -26
- package/src/libs/trpc/edge/context.ts +0 -71
- package/src/libs/trpc/edge/index.ts +0 -45
- package/src/libs/trpc/edge/init.ts +0 -26
- package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +0 -75
- package/src/libs/trpc/edge/middleware/jwtPayload.ts +0 -14
- package/src/migrations/FromV0ToV1.ts +0 -10
- package/src/migrations/FromV1ToV2/fixtures/input-v1-session.json +0 -191
- package/src/migrations/FromV1ToV2/fixtures/output-v2.json +0 -202
- package/src/migrations/FromV1ToV2/index.ts +0 -82
- package/src/migrations/FromV1ToV2/migrations.test.ts +0 -224
- package/src/migrations/FromV1ToV2/types/v1.ts +0 -78
- package/src/migrations/FromV1ToV2/types/v2.ts +0 -52
- package/src/migrations/FromV2ToV3/fixtures/input-v2-session.json +0 -72
- package/src/migrations/FromV2ToV3/fixtures/output-v3-from-v1.json +0 -203
- package/src/migrations/FromV2ToV3/fixtures/output-v3.json +0 -74
- package/src/migrations/FromV2ToV3/index.ts +0 -30
- package/src/migrations/FromV2ToV3/migrations.test.ts +0 -42
- package/src/migrations/FromV2ToV3/types/v3.ts +0 -27
- package/src/migrations/FromV3ToV4/fixtures/azure-input-v3.json +0 -79
- package/src/migrations/FromV3ToV4/fixtures/azure-output-v4.json +0 -75
- package/src/migrations/FromV3ToV4/fixtures/ollama-input-v3.json +0 -85
- package/src/migrations/FromV3ToV4/fixtures/ollama-output-v4.json +0 -86
- package/src/migrations/FromV3ToV4/fixtures/openai-input-v3.json +0 -77
- package/src/migrations/FromV3ToV4/fixtures/openai-output-v4.json +0 -77
- package/src/migrations/FromV3ToV4/fixtures/openrouter-input-v3.json +0 -82
- package/src/migrations/FromV3ToV4/fixtures/openrouter-output-v4.json +0 -85
- package/src/migrations/FromV3ToV4/fixtures/output-v4-from-v1.json +0 -203
- package/src/migrations/FromV3ToV4/index.ts +0 -102
- package/src/migrations/FromV3ToV4/migrations.test.ts +0 -195
- package/src/migrations/FromV3ToV4/types/v3.ts +0 -52
- package/src/migrations/FromV3ToV4/types/v4.ts +0 -37
- package/src/migrations/FromV4ToV5/fixtures/from-v1-to-v5-output.json +0 -245
- package/src/migrations/FromV4ToV5/fixtures/function-input-v4.json +0 -96
- package/src/migrations/FromV4ToV5/fixtures/function-output-v5.json +0 -120
- package/src/migrations/FromV4ToV5/index.ts +0 -58
- package/src/migrations/FromV4ToV5/migrations.test.ts +0 -49
- package/src/migrations/FromV4ToV5/types/v4.ts +0 -21
- package/src/migrations/FromV4ToV5/types/v5.ts +0 -27
- package/src/migrations/FromV5ToV6/fixtures/from-v1-to-v6-output.json +0 -247
- package/src/migrations/FromV5ToV6/fixtures/session-input-v5.json +0 -81
- package/src/migrations/FromV5ToV6/fixtures/session-output-v6.json +0 -85
- package/src/migrations/FromV5ToV6/index.ts +0 -61
- package/src/migrations/FromV5ToV6/migrations.test.ts +0 -50
- package/src/migrations/FromV5ToV6/types/v5.ts +0 -48
- package/src/migrations/FromV5ToV6/types/v6.ts +0 -63
- package/src/migrations/FromV6ToV7/fixtures/output-v7-from-v1.json +0 -203
- package/src/migrations/FromV6ToV7/fixtures/provider-input-v6.json +0 -103
- package/src/migrations/FromV6ToV7/fixtures/provider-output-v7.json +0 -118
- package/src/migrations/FromV6ToV7/index.ts +0 -101
- package/src/migrations/FromV6ToV7/migrations.test.ts +0 -64
- package/src/migrations/FromV6ToV7/types/v6.ts +0 -61
- package/src/migrations/FromV6ToV7/types/v7.ts +0 -69
- package/src/migrations/VersionController.test.ts +0 -88
- package/src/migrations/VersionController.ts +0 -67
- package/src/migrations/index.ts +0 -61
- package/src/server/globalConfig/_deprecated.test.ts +0 -92
- package/src/server/globalConfig/_deprecated.ts +0 -41
- package/src/server/routers/edge/appStatus.ts +0 -3
- package/src/server/routers/edge/index.ts +0 -14
- package/src/server/routers/edge/upload.ts +0 -16
- package/src/services/aiModel/client.ts +0 -70
- package/src/services/aiModel/server.test.ts +0 -122
- package/src/services/aiModel/server.ts +0 -51
- package/src/services/aiModel/type.ts +0 -32
- package/src/services/aiProvider/client.ts +0 -58
- package/src/services/aiProvider/server.ts +0 -43
- package/src/services/aiProvider/type.ts +0 -27
- package/src/services/baseClientService/index.ts +0 -9
- package/src/services/chat/__snapshots__/chat.test.ts.snap +0 -110
- package/src/services/chatGroup/client.ts +0 -63
- package/src/services/chatGroup/server.ts +0 -67
- package/src/services/chatGroup/type.ts +0 -22
- package/src/services/export/_deprecated.ts +0 -155
- package/src/services/export/client.ts +0 -15
- package/src/services/export/server.ts +0 -9
- package/src/services/export/type.ts +0 -5
- package/src/services/file/_deprecated.test.ts +0 -119
- package/src/services/file/_deprecated.ts +0 -80
- package/src/services/file/client.test.ts +0 -199
- package/src/services/file/client.ts +0 -85
- package/src/services/file/server.ts +0 -53
- package/src/services/file/type.ts +0 -13
- package/src/services/import/_deprecated.ts +0 -115
- package/src/services/import/client.test.ts +0 -1015
- package/src/services/import/client.ts +0 -64
- package/src/services/import/server.ts +0 -133
- package/src/services/import/type.ts +0 -17
- package/src/services/message/_deprecated.test.ts +0 -398
- package/src/services/message/_deprecated.ts +0 -168
- package/src/services/message/client.test.ts +0 -410
- package/src/services/message/client.ts +0 -186
- package/src/services/message/server.ts +0 -150
- package/src/services/message/type.ts +0 -54
- package/src/services/plugin/_deprecated.test.ts +0 -162
- package/src/services/plugin/_deprecated.ts +0 -42
- package/src/services/plugin/client.test.ts +0 -177
- package/src/services/plugin/client.ts +0 -46
- package/src/services/plugin/server.ts +0 -42
- package/src/services/plugin/type.ts +0 -23
- package/src/services/session/_deprecated.test.ts +0 -440
- package/src/services/session/_deprecated.ts +0 -190
- package/src/services/session/client.test.ts +0 -413
- package/src/services/session/client.ts +0 -193
- package/src/services/session/server.test.ts +0 -260
- package/src/services/session/server.ts +0 -125
- package/src/services/session/type.ts +0 -82
- package/src/services/thread/client.ts +0 -51
- package/src/services/thread/server.ts +0 -32
- package/src/services/thread/type.ts +0 -21
- package/src/services/topic/_deprecated.test.ts +0 -245
- package/src/services/topic/_deprecated.ts +0 -75
- package/src/services/topic/client.ts +0 -89
- package/src/services/topic/pglite.test.ts +0 -212
- package/src/services/topic/server.ts +0 -57
- package/src/services/topic/type.ts +0 -40
- package/src/services/user/_deprecated.test.ts +0 -101
- package/src/services/user/_deprecated.ts +0 -70
- package/src/services/user/client.test.ts +0 -108
- package/src/services/user/client.ts +0 -104
- package/src/services/user/server.test.ts +0 -149
- package/src/services/user/server.ts +0 -47
- package/src/services/user/type.ts +0 -21
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -1209
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +0 -718
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +0 -849
- package/src/store/chat/slices/aiChat/actions/generateAIChatV2.ts +0 -591
- 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/store/chat/slices/message/action.ts +0 -553
- package/src/store/chat/slices/message/selectors.test.ts +0 -473
- package/src/store/chat/slices/message/selectors.ts +0 -322
- package/src/store/chat/slices/plugin/action.ts +0 -548
- package/src/store/global/actions/clientDb.ts +0 -67
- package/src/store/user/slices/modelList/__snapshots__/action.test.ts.snap +0 -12
- package/src/store/user/slices/modelList/action.test.ts +0 -359
- package/src/store/user/slices/modelList/action.ts +0 -223
- package/src/store/user/slices/modelList/initialState.ts +0 -15
- package/src/store/user/slices/modelList/reducers/customModelCard.test.ts +0 -204
- package/src/store/user/slices/modelList/reducers/customModelCard.ts +0 -64
- package/src/store/user/slices/modelList/selectors/index.ts +0 -3
- package/src/store/user/slices/modelList/selectors/keyVaults.test.ts +0 -201
- package/src/store/user/slices/modelList/selectors/keyVaults.ts +0 -50
- package/src/store/user/slices/modelList/selectors/modelConfig.test.ts +0 -219
- package/src/store/user/slices/modelList/selectors/modelConfig.ts +0 -95
- package/src/store/user/slices/modelList/selectors/modelProvider.test.ts +0 -138
- package/src/store/user/slices/modelList/selectors/modelProvider.ts +0 -170
- 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/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/default.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatHydration/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/ClassicChat.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/GroupChat.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/useSendMenuItems.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/MentionedUsers/MentionedUserItem.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/MentionedUsers/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/ActionBar.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/Files/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/InputArea/Container.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/InputArea/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/Send.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/OrchestratorThinking.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/Thread.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/ThreadItem.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/AddButton.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/useTemplateMatching.ts +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatMinimap/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ThreadHydration.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ZenModeToast/Toast.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ZenModeToast/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/AgentSettings/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/AgentTeamSettings/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/ChangelogModal.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/SettingButton.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/ShareButton/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/TelemetryNotification.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/HeaderAction.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Main.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/HistoryLimitTags.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/KnowledgeTag.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/MemberCountTag.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/SearchTags.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/Portal.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/TopicPanel.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/ChatHeader/ChatHeaderTitle.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/ChatHeader/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/TopicModal.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/type.ts +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/_layout/Desktop.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/_layout/Mobile.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/default.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/error.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/features/Body.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/loading.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/_layout/Desktop.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/_layout/Mobile.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/default.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/AgentConfig/SystemRole.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/AgentConfig/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/ConfigLayout.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/ConfigSwitcher.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupMember.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupMemberItem.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupRole.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/style.ts +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/SkeletonList.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/Header.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ByTimeMode/GroupItem.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ByTimeMode/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/FlatMode/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/SearchResult/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadItem/Content.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadItem/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadList/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/DefaultContent.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/TopicContent.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicSearchBar/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionHydration.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/CollapseGroup/Actions.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/CollapseGroup/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/DefaultMode.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Inbox/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/AddButton.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/ListItem/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/ConfigGroupModal/GroupItem.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/ConfigGroupModal/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/CreateGroupModal.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/RenameGroupModal.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/SearchMode.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionSearchBar.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session → session}/features/SkeletonList.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/PanelBody.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/SessionHeader.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/index.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Mobile/SessionHeader.tsx +0 -0
- /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Mobile/index.tsx +0 -0
- /package/src/{app/[variants]/(main)/settings/provider/features/ProviderConfig → components/Skeleton}/SkeletonInput.tsx +0 -0
- /package/src/{middleware.ts → proxy.ts} +0 -0
|
@@ -35,7 +35,7 @@ const messageModel = new MessageModel(serverDB, userId);
|
|
|
35
35
|
const embeddingsId = uuid();
|
|
36
36
|
|
|
37
37
|
beforeEach(async () => {
|
|
38
|
-
//
|
|
38
|
+
// Clear tables before each test case
|
|
39
39
|
await serverDB.transaction(async (trx) => {
|
|
40
40
|
await trx.delete(users);
|
|
41
41
|
await trx.insert(users).values([{ id: userId }, { id: '456' }]);
|
|
@@ -63,14 +63,14 @@ beforeEach(async () => {
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
afterEach(async () => {
|
|
66
|
-
//
|
|
66
|
+
// Clear tables after each test case
|
|
67
67
|
await serverDB.delete(users);
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
describe('MessageModel', () => {
|
|
71
71
|
describe('query', () => {
|
|
72
72
|
it('should query messages by user ID', async () => {
|
|
73
|
-
//
|
|
73
|
+
// Create test data
|
|
74
74
|
await serverDB.insert(messages).values([
|
|
75
75
|
{ id: '1', userId, role: 'user', content: 'message 1', createdAt: new Date('2023-01-01') },
|
|
76
76
|
{ id: '2', userId, role: 'user', content: 'message 2', createdAt: new Date('2023-02-01') },
|
|
@@ -83,39 +83,39 @@ describe('MessageModel', () => {
|
|
|
83
83
|
},
|
|
84
84
|
]);
|
|
85
85
|
|
|
86
|
-
//
|
|
86
|
+
// Call query method
|
|
87
87
|
const result = await messageModel.query();
|
|
88
88
|
|
|
89
|
-
//
|
|
89
|
+
// Assert result
|
|
90
90
|
expect(result).toHaveLength(2);
|
|
91
91
|
expect(result[0].id).toBe('1');
|
|
92
92
|
expect(result[1].id).toBe('2');
|
|
93
93
|
});
|
|
94
94
|
|
|
95
95
|
it('should return empty messages if not match the user ID', async () => {
|
|
96
|
-
//
|
|
96
|
+
// Create test data
|
|
97
97
|
await serverDB.insert(messages).values([
|
|
98
98
|
{ id: '1', userId: '456', role: 'user', content: '1', createdAt: new Date('2023-01-01') },
|
|
99
99
|
{ id: '2', userId: '456', role: 'user', content: '2', createdAt: new Date('2023-02-01') },
|
|
100
100
|
{ id: '3', userId: '456', role: 'user', content: '3', createdAt: new Date('2023-03-01') },
|
|
101
101
|
]);
|
|
102
102
|
|
|
103
|
-
//
|
|
103
|
+
// Call query method
|
|
104
104
|
const result = await messageModel.query();
|
|
105
105
|
|
|
106
|
-
//
|
|
106
|
+
// Assert result
|
|
107
107
|
expect(result).toHaveLength(0);
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
it('should query messages with pagination', async () => {
|
|
111
|
-
//
|
|
111
|
+
// Create test data
|
|
112
112
|
await serverDB.insert(messages).values([
|
|
113
113
|
{ id: '1', userId, role: 'user', content: 'message 1', createdAt: new Date('2023-01-01') },
|
|
114
114
|
{ id: '2', userId, role: 'user', content: 'message 2', createdAt: new Date('2023-02-01') },
|
|
115
115
|
{ id: '3', userId, role: 'user', content: 'message 3', createdAt: new Date('2023-03-01') },
|
|
116
116
|
]);
|
|
117
117
|
|
|
118
|
-
//
|
|
118
|
+
// Test pagination
|
|
119
119
|
const result1 = await messageModel.query({ current: 0, pageSize: 2 });
|
|
120
120
|
expect(result1).toHaveLength(2);
|
|
121
121
|
|
|
@@ -125,7 +125,7 @@ describe('MessageModel', () => {
|
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
it('should filter messages by sessionId', async () => {
|
|
128
|
-
//
|
|
128
|
+
// Create test data
|
|
129
129
|
await serverDB.insert(sessions).values([
|
|
130
130
|
{ id: 'session1', userId },
|
|
131
131
|
{ id: 'session2', userId },
|
|
@@ -150,7 +150,7 @@ describe('MessageModel', () => {
|
|
|
150
150
|
{ id: '3', userId, role: 'user', sessionId: 'session2', content: 'message 3' },
|
|
151
151
|
]);
|
|
152
152
|
|
|
153
|
-
//
|
|
153
|
+
// Test filtering by sessionId
|
|
154
154
|
const result = await messageModel.query({ sessionId: 'session1' });
|
|
155
155
|
expect(result).toHaveLength(2);
|
|
156
156
|
expect(result[0].id).toBe('1');
|
|
@@ -158,7 +158,7 @@ describe('MessageModel', () => {
|
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
it('should filter messages by topicId', async () => {
|
|
161
|
-
//
|
|
161
|
+
// Create test data
|
|
162
162
|
const sessionId = 'session1';
|
|
163
163
|
await serverDB.insert(sessions).values([{ id: sessionId, userId }]);
|
|
164
164
|
const topicId = 'topic1';
|
|
@@ -173,7 +173,7 @@ describe('MessageModel', () => {
|
|
|
173
173
|
{ id: '3', userId, role: 'user', topicId: 'topic2', content: 'message 3' },
|
|
174
174
|
]);
|
|
175
175
|
|
|
176
|
-
//
|
|
176
|
+
// Test filtering by topicId
|
|
177
177
|
const result = await messageModel.query({ topicId });
|
|
178
178
|
expect(result).toHaveLength(2);
|
|
179
179
|
expect(result[0].id).toBe('1');
|
|
@@ -226,7 +226,7 @@ describe('MessageModel', () => {
|
|
|
226
226
|
});
|
|
227
227
|
|
|
228
228
|
it('should query messages with join', async () => {
|
|
229
|
-
//
|
|
229
|
+
// Create test data
|
|
230
230
|
await serverDB.transaction(async (trx) => {
|
|
231
231
|
await trx.insert(messages).values([
|
|
232
232
|
{
|
|
@@ -268,13 +268,13 @@ describe('MessageModel', () => {
|
|
|
268
268
|
});
|
|
269
269
|
|
|
270
270
|
const domain = 'http://abc.com';
|
|
271
|
-
//
|
|
271
|
+
// Call query method
|
|
272
272
|
const result = await messageModel.query(
|
|
273
273
|
{},
|
|
274
274
|
{ postProcessUrl: async (path) => `${domain}/${path}` },
|
|
275
275
|
);
|
|
276
276
|
|
|
277
|
-
//
|
|
277
|
+
// Assert result
|
|
278
278
|
expect(result).toHaveLength(2);
|
|
279
279
|
expect(result[0].id).toBe('1');
|
|
280
280
|
expect(result[0].imageList).toEqual([
|
|
@@ -287,7 +287,7 @@ describe('MessageModel', () => {
|
|
|
287
287
|
});
|
|
288
288
|
|
|
289
289
|
it('should include translate, tts and other extra fields in query result', async () => {
|
|
290
|
-
//
|
|
290
|
+
// Create test data
|
|
291
291
|
await serverDB.transaction(async (trx) => {
|
|
292
292
|
await trx.insert(messages).values([
|
|
293
293
|
{
|
|
@@ -306,10 +306,10 @@ describe('MessageModel', () => {
|
|
|
306
306
|
.values([{ id: '1', voice: 'voice1', fileId: 'f1', contentMd5: 'md5', userId }]);
|
|
307
307
|
});
|
|
308
308
|
|
|
309
|
-
//
|
|
309
|
+
// Call query method
|
|
310
310
|
const result = await messageModel.query();
|
|
311
311
|
|
|
312
|
-
//
|
|
312
|
+
// Assert result
|
|
313
313
|
expect(result[0].extra!.translate).toEqual({ content: 'translated', from: 'en', to: 'zh' });
|
|
314
314
|
expect(result[0].extra!.tts).toEqual({
|
|
315
315
|
contentMd5: 'md5',
|
|
@@ -319,7 +319,7 @@ describe('MessageModel', () => {
|
|
|
319
319
|
});
|
|
320
320
|
|
|
321
321
|
it('should handle edge cases of pagination parameters', async () => {
|
|
322
|
-
//
|
|
322
|
+
// Create test data
|
|
323
323
|
await serverDB.insert(messages).values([
|
|
324
324
|
{ id: '1', userId, role: 'user', content: 'message 1' },
|
|
325
325
|
{ id: '2', userId, role: 'user', content: 'message 2' },
|
|
@@ -339,7 +339,7 @@ describe('MessageModel', () => {
|
|
|
339
339
|
|
|
340
340
|
describe('query with messageQueries', () => {
|
|
341
341
|
it('should include ragQuery, ragQueryId and ragRawQuery in query results', async () => {
|
|
342
|
-
//
|
|
342
|
+
// Create test data
|
|
343
343
|
const messageId = 'msg-with-query';
|
|
344
344
|
const queryId = uuid();
|
|
345
345
|
|
|
@@ -358,10 +358,10 @@ describe('MessageModel', () => {
|
|
|
358
358
|
userId,
|
|
359
359
|
});
|
|
360
360
|
|
|
361
|
-
//
|
|
361
|
+
// Call query method
|
|
362
362
|
const result = await messageModel.query();
|
|
363
363
|
|
|
364
|
-
//
|
|
364
|
+
// Assert result
|
|
365
365
|
expect(result).toHaveLength(1);
|
|
366
366
|
expect(result[0].id).toBe(messageId);
|
|
367
367
|
expect(result[0].ragQueryId).toBe(queryId);
|
|
@@ -370,7 +370,7 @@ describe('MessageModel', () => {
|
|
|
370
370
|
});
|
|
371
371
|
|
|
372
372
|
it.skip('should handle multiple message queries for the same message', async () => {
|
|
373
|
-
//
|
|
373
|
+
// Create test data
|
|
374
374
|
const messageId = 'msg-multi-query';
|
|
375
375
|
const queryId1 = uuid();
|
|
376
376
|
const queryId2 = uuid();
|
|
@@ -400,10 +400,10 @@ describe('MessageModel', () => {
|
|
|
400
400
|
},
|
|
401
401
|
]);
|
|
402
402
|
|
|
403
|
-
//
|
|
403
|
+
// Call query method
|
|
404
404
|
const result = await messageModel.query();
|
|
405
405
|
|
|
406
|
-
//
|
|
406
|
+
// Assert result - 应该只包含最新的查询
|
|
407
407
|
expect(result).toHaveLength(1);
|
|
408
408
|
expect(result[0].id).toBe(messageId);
|
|
409
409
|
expect(result[0].ragQueryId).toBe(queryId2);
|
|
@@ -505,7 +505,7 @@ describe('MessageModel', () => {
|
|
|
505
505
|
|
|
506
506
|
describe('queryAll', () => {
|
|
507
507
|
it('should return all messages belonging to the user in ascending order', async () => {
|
|
508
|
-
//
|
|
508
|
+
// Create test data
|
|
509
509
|
await serverDB.insert(messages).values([
|
|
510
510
|
{
|
|
511
511
|
id: '1',
|
|
@@ -530,10 +530,10 @@ describe('MessageModel', () => {
|
|
|
530
530
|
},
|
|
531
531
|
]);
|
|
532
532
|
|
|
533
|
-
//
|
|
533
|
+
// Call queryAll method
|
|
534
534
|
const result = await messageModel.queryAll();
|
|
535
535
|
|
|
536
|
-
//
|
|
536
|
+
// Assert result
|
|
537
537
|
expect(result).toHaveLength(2);
|
|
538
538
|
expect(result[0].id).toBe('1');
|
|
539
539
|
expect(result[1].id).toBe('2');
|
|
@@ -542,37 +542,37 @@ describe('MessageModel', () => {
|
|
|
542
542
|
|
|
543
543
|
describe('findById', () => {
|
|
544
544
|
it('should find message by ID', async () => {
|
|
545
|
-
//
|
|
545
|
+
// Create test data
|
|
546
546
|
await serverDB.insert(messages).values([
|
|
547
547
|
{ id: '1', userId, role: 'user', content: 'message 1' },
|
|
548
548
|
{ id: '2', userId: '456', role: 'user', content: 'message 2' },
|
|
549
549
|
]);
|
|
550
550
|
|
|
551
|
-
//
|
|
551
|
+
// Call findById method
|
|
552
552
|
const result = await messageModel.findById('1');
|
|
553
553
|
|
|
554
|
-
//
|
|
554
|
+
// Assert result
|
|
555
555
|
expect(result?.id).toBe('1');
|
|
556
556
|
expect(result?.content).toBe('message 1');
|
|
557
557
|
});
|
|
558
558
|
|
|
559
559
|
it('should return undefined if message does not belong to user', async () => {
|
|
560
|
-
//
|
|
560
|
+
// Create test data
|
|
561
561
|
await serverDB
|
|
562
562
|
.insert(messages)
|
|
563
563
|
.values([{ id: '1', userId: '456', role: 'user', content: 'message 1' }]);
|
|
564
564
|
|
|
565
|
-
//
|
|
565
|
+
// Call findById method
|
|
566
566
|
const result = await messageModel.findById('1');
|
|
567
567
|
|
|
568
|
-
//
|
|
568
|
+
// Assert result
|
|
569
569
|
expect(result).toBeUndefined();
|
|
570
570
|
});
|
|
571
571
|
});
|
|
572
572
|
|
|
573
573
|
describe('queryBySessionId', () => {
|
|
574
574
|
it('should query messages by sessionId', async () => {
|
|
575
|
-
//
|
|
575
|
+
// Create test data
|
|
576
576
|
const sessionId = 'session1';
|
|
577
577
|
await serverDB.insert(sessions).values([
|
|
578
578
|
{ id: 'session1', userId },
|
|
@@ -598,10 +598,10 @@ describe('MessageModel', () => {
|
|
|
598
598
|
{ id: '3', userId, role: 'user', sessionId: 'session2', content: 'message 3' },
|
|
599
599
|
]);
|
|
600
600
|
|
|
601
|
-
//
|
|
601
|
+
// Call queryBySessionId method
|
|
602
602
|
const result = await messageModel.queryBySessionId(sessionId);
|
|
603
603
|
|
|
604
|
-
//
|
|
604
|
+
// Assert result
|
|
605
605
|
expect(result).toHaveLength(2);
|
|
606
606
|
expect(result[0].id).toBe('1');
|
|
607
607
|
expect(result[1].id).toBe('2');
|
|
@@ -610,7 +610,7 @@ describe('MessageModel', () => {
|
|
|
610
610
|
|
|
611
611
|
describe('queryByKeyWord', () => {
|
|
612
612
|
it('should query messages by keyword', async () => {
|
|
613
|
-
//
|
|
613
|
+
// Create test data
|
|
614
614
|
await serverDB.insert(messages).values([
|
|
615
615
|
{ id: '1', userId, role: 'user', content: 'apple', createdAt: new Date('2022-02-01') },
|
|
616
616
|
{ id: '2', userId, role: 'user', content: 'banana' },
|
|
@@ -618,17 +618,17 @@ describe('MessageModel', () => {
|
|
|
618
618
|
{ id: '4', userId, role: 'user', content: 'apple pie', createdAt: new Date('2024-02-01') },
|
|
619
619
|
]);
|
|
620
620
|
|
|
621
|
-
//
|
|
621
|
+
// Test querying messages with specific keyword
|
|
622
622
|
const result = await messageModel.queryByKeyword('apple');
|
|
623
623
|
|
|
624
|
-
//
|
|
624
|
+
// Assert result
|
|
625
625
|
expect(result).toHaveLength(2);
|
|
626
626
|
expect(result[0].id).toBe('4');
|
|
627
627
|
expect(result[1].id).toBe('1');
|
|
628
628
|
});
|
|
629
629
|
|
|
630
630
|
it('should return empty array when keyword is empty', async () => {
|
|
631
|
-
//
|
|
631
|
+
// Create test data
|
|
632
632
|
await serverDB.insert(messages).values([
|
|
633
633
|
{ id: '1', userId, role: 'user', content: 'apple' },
|
|
634
634
|
{ id: '2', userId, role: 'user', content: 'banana' },
|
|
@@ -636,20 +636,20 @@ describe('MessageModel', () => {
|
|
|
636
636
|
{ id: '4', userId, role: 'user', content: 'apple pie' },
|
|
637
637
|
]);
|
|
638
638
|
|
|
639
|
-
//
|
|
639
|
+
// Test returning empty array when keyword is empty
|
|
640
640
|
const result = await messageModel.queryByKeyword('');
|
|
641
641
|
|
|
642
|
-
//
|
|
642
|
+
// Assert result
|
|
643
643
|
expect(result).toHaveLength(0);
|
|
644
644
|
});
|
|
645
645
|
});
|
|
646
646
|
|
|
647
647
|
describe('createMessage', () => {
|
|
648
648
|
it('should create a new message', async () => {
|
|
649
|
-
//
|
|
649
|
+
// Call createMessage method
|
|
650
650
|
await messageModel.create({ role: 'user', content: 'new message', sessionId: '1' });
|
|
651
651
|
|
|
652
|
-
//
|
|
652
|
+
// Assert result
|
|
653
653
|
const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
|
|
654
654
|
expect(result).toHaveLength(1);
|
|
655
655
|
expect(result[0].content).toBe('new message');
|
|
@@ -673,21 +673,21 @@ describe('MessageModel', () => {
|
|
|
673
673
|
});
|
|
674
674
|
|
|
675
675
|
it('should generate message ID automatically', async () => {
|
|
676
|
-
//
|
|
676
|
+
// Call createMessage method
|
|
677
677
|
await messageModel.create({
|
|
678
678
|
role: 'user',
|
|
679
679
|
content: 'new message',
|
|
680
680
|
sessionId: '1',
|
|
681
681
|
});
|
|
682
682
|
|
|
683
|
-
//
|
|
683
|
+
// Assert result
|
|
684
684
|
const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
|
|
685
685
|
expect(result[0].id).toBeDefined();
|
|
686
686
|
expect(result[0].id).toHaveLength(18);
|
|
687
687
|
});
|
|
688
688
|
|
|
689
689
|
it('should create a tool message and insert into messagePlugins table', async () => {
|
|
690
|
-
//
|
|
690
|
+
// Call create method
|
|
691
691
|
const result = await messageModel.create({
|
|
692
692
|
content: 'message 1',
|
|
693
693
|
role: 'tool',
|
|
@@ -701,7 +701,7 @@ describe('MessageModel', () => {
|
|
|
701
701
|
},
|
|
702
702
|
});
|
|
703
703
|
|
|
704
|
-
//
|
|
704
|
+
// Assert result
|
|
705
705
|
expect(result.id).toBeDefined();
|
|
706
706
|
expect(result.content).toBe('message 1');
|
|
707
707
|
expect(result.role).toBe('tool');
|
|
@@ -716,7 +716,7 @@ describe('MessageModel', () => {
|
|
|
716
716
|
});
|
|
717
717
|
|
|
718
718
|
it('should create tool message ', async () => {
|
|
719
|
-
//
|
|
719
|
+
// Call create method
|
|
720
720
|
const state = {
|
|
721
721
|
query: 'Composio',
|
|
722
722
|
answers: [],
|
|
@@ -768,7 +768,7 @@ describe('MessageModel', () => {
|
|
|
768
768
|
sessionId: '1',
|
|
769
769
|
});
|
|
770
770
|
|
|
771
|
-
//
|
|
771
|
+
// Assert result
|
|
772
772
|
expect(result.id).toBeDefined();
|
|
773
773
|
expect(result.content).toBe('[{}]');
|
|
774
774
|
expect(result.role).toBe('tool');
|
|
@@ -798,14 +798,14 @@ describe('MessageModel', () => {
|
|
|
798
798
|
|
|
799
799
|
expect(result.id).toBe(customId);
|
|
800
800
|
|
|
801
|
-
//
|
|
801
|
+
// Verify database records
|
|
802
802
|
const dbResult = await serverDB.select().from(messages).where(eq(messages.id, customId));
|
|
803
803
|
expect(dbResult).toHaveLength(1);
|
|
804
804
|
expect(dbResult[0].id).toBe(customId);
|
|
805
805
|
});
|
|
806
806
|
|
|
807
807
|
it.skip('should create a message with file chunks and RAG query ID', async () => {
|
|
808
|
-
//
|
|
808
|
+
// Create test data
|
|
809
809
|
const chunkId1 = uuid();
|
|
810
810
|
const chunkId2 = uuid();
|
|
811
811
|
const ragQueryId = uuid();
|
|
@@ -815,7 +815,7 @@ describe('MessageModel', () => {
|
|
|
815
815
|
{ id: chunkId2, text: 'chunk text 2' },
|
|
816
816
|
]);
|
|
817
817
|
|
|
818
|
-
//
|
|
818
|
+
// Call create method
|
|
819
819
|
const result = await messageModel.create({
|
|
820
820
|
role: 'assistant',
|
|
821
821
|
content: 'message with file chunks',
|
|
@@ -827,10 +827,10 @@ describe('MessageModel', () => {
|
|
|
827
827
|
sessionId: '1',
|
|
828
828
|
});
|
|
829
829
|
|
|
830
|
-
//
|
|
830
|
+
// Verify message created successfully
|
|
831
831
|
expect(result.id).toBeDefined();
|
|
832
832
|
|
|
833
|
-
//
|
|
833
|
+
// Verify message query chunk associations created successfully
|
|
834
834
|
const queryChunks = await serverDB
|
|
835
835
|
.select()
|
|
836
836
|
.from(messageQueryChunks)
|
|
@@ -845,7 +845,7 @@ describe('MessageModel', () => {
|
|
|
845
845
|
});
|
|
846
846
|
|
|
847
847
|
it('should create a message with files', async () => {
|
|
848
|
-
//
|
|
848
|
+
// Create test data
|
|
849
849
|
await serverDB.insert(files).values([
|
|
850
850
|
{
|
|
851
851
|
id: 'file1',
|
|
@@ -865,7 +865,7 @@ describe('MessageModel', () => {
|
|
|
865
865
|
},
|
|
866
866
|
]);
|
|
867
867
|
|
|
868
|
-
//
|
|
868
|
+
// Call create method
|
|
869
869
|
const result = await messageModel.create({
|
|
870
870
|
role: 'user',
|
|
871
871
|
content: 'message with files',
|
|
@@ -873,10 +873,10 @@ describe('MessageModel', () => {
|
|
|
873
873
|
sessionId: '1',
|
|
874
874
|
});
|
|
875
875
|
|
|
876
|
-
//
|
|
876
|
+
// Verify message created successfully
|
|
877
877
|
expect(result.id).toBeDefined();
|
|
878
878
|
|
|
879
|
-
//
|
|
879
|
+
// Verify message file associations created successfully
|
|
880
880
|
const messageFiles = await serverDB
|
|
881
881
|
.select()
|
|
882
882
|
.from(messagesFiles)
|
|
@@ -899,10 +899,10 @@ describe('MessageModel', () => {
|
|
|
899
899
|
sessionId: '1',
|
|
900
900
|
});
|
|
901
901
|
|
|
902
|
-
//
|
|
902
|
+
// Verify database records
|
|
903
903
|
const dbResult = await serverDB.select().from(messages).where(eq(messages.id, result.id));
|
|
904
904
|
|
|
905
|
-
//
|
|
905
|
+
// Date comparison needs to consider timezone and formatting, so use toISOString for comparison
|
|
906
906
|
expect(new Date(dbResult[0].createdAt!).toISOString()).toBe(
|
|
907
907
|
new Date(customCreatedAt).toISOString(),
|
|
908
908
|
);
|
|
@@ -915,16 +915,16 @@ describe('MessageModel', () => {
|
|
|
915
915
|
|
|
916
916
|
describe('batchCreateMessages', () => {
|
|
917
917
|
it('should batch create messages', async () => {
|
|
918
|
-
//
|
|
918
|
+
// Prepare test data
|
|
919
919
|
const newMessages = [
|
|
920
920
|
{ id: '1', role: 'user', content: 'message 1' },
|
|
921
921
|
{ id: '2', role: 'assistant', content: 'message 2' },
|
|
922
922
|
] as DBMessageItem[];
|
|
923
923
|
|
|
924
|
-
//
|
|
924
|
+
// Call batchCreateMessages method
|
|
925
925
|
await messageModel.batchCreate(newMessages);
|
|
926
926
|
|
|
927
|
-
//
|
|
927
|
+
// Assert result
|
|
928
928
|
const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
|
|
929
929
|
expect(result).toHaveLength(2);
|
|
930
930
|
expect(result[0].content).toBe('message 1');
|
|
@@ -932,109 +932,37 @@ describe('MessageModel', () => {
|
|
|
932
932
|
});
|
|
933
933
|
});
|
|
934
934
|
|
|
935
|
-
describe('createNewMessage', () => {
|
|
936
|
-
it('should create message and return id with messages list', async () => {
|
|
937
|
-
// 调用 createNewMessage 方法
|
|
938
|
-
const result = await messageModel.createNewMessage({
|
|
939
|
-
role: 'user',
|
|
940
|
-
content: 'test message',
|
|
941
|
-
sessionId: '1',
|
|
942
|
-
});
|
|
943
|
-
|
|
944
|
-
// 断言返回结构
|
|
945
|
-
expect(result).toHaveProperty('id');
|
|
946
|
-
expect(result).toHaveProperty('messages');
|
|
947
|
-
expect(result.id).toBeDefined();
|
|
948
|
-
expect(result.messages).toBeInstanceOf(Array);
|
|
949
|
-
});
|
|
950
|
-
|
|
951
|
-
it('should return newly created message in messages list', async () => {
|
|
952
|
-
const content = 'new test message ' + Date.now();
|
|
953
|
-
|
|
954
|
-
const result = await messageModel.createNewMessage({
|
|
955
|
-
role: 'user',
|
|
956
|
-
content,
|
|
957
|
-
sessionId: '1',
|
|
958
|
-
});
|
|
959
|
-
|
|
960
|
-
// 验证新创建的消息在列表中
|
|
961
|
-
const createdMessage = result.messages.find((m) => m.id === result.id);
|
|
962
|
-
expect(createdMessage).toBeDefined();
|
|
963
|
-
expect(createdMessage?.content).toBe(content);
|
|
964
|
-
expect(createdMessage?.role).toBe('user');
|
|
965
|
-
});
|
|
966
|
-
|
|
967
|
-
it('should return all messages for the session', async () => {
|
|
968
|
-
// 创建多条消息
|
|
969
|
-
await messageModel.create({ role: 'user', content: 'message 1', sessionId: '1' });
|
|
970
|
-
await messageModel.create({ role: 'assistant', content: 'message 2', sessionId: '1' });
|
|
971
|
-
|
|
972
|
-
// 创建第三条消息并获取完整列表
|
|
973
|
-
const result = await messageModel.createNewMessage({
|
|
974
|
-
role: 'user',
|
|
975
|
-
content: 'message 3',
|
|
976
|
-
sessionId: '1',
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
// 验证返回了所有消息
|
|
980
|
-
expect(result.messages.length).toBeGreaterThanOrEqual(3);
|
|
981
|
-
});
|
|
982
|
-
|
|
983
|
-
it('should filter messages by topicId if provided', async () => {
|
|
984
|
-
const topicId = 'topic-1';
|
|
985
|
-
await serverDB.insert(topics).values({ id: topicId, sessionId: '1', userId });
|
|
986
|
-
|
|
987
|
-
// 创建不同 topic 的消息
|
|
988
|
-
await messageModel.create({ role: 'user', content: 'topic 1 msg', sessionId: '1', topicId });
|
|
989
|
-
await messageModel.create({ role: 'user', content: 'no topic msg', sessionId: '1' });
|
|
990
|
-
|
|
991
|
-
// 创建新消息并指定 topicId
|
|
992
|
-
const result = await messageModel.createNewMessage({
|
|
993
|
-
role: 'user',
|
|
994
|
-
content: 'new topic msg',
|
|
995
|
-
sessionId: '1',
|
|
996
|
-
topicId,
|
|
997
|
-
});
|
|
998
|
-
|
|
999
|
-
// 验证只返回该 topic 的消息
|
|
1000
|
-
expect(result.messages.every((m) => m.topicId === topicId || m.topicId === undefined)).toBe(
|
|
1001
|
-
true,
|
|
1002
|
-
);
|
|
1003
|
-
expect(result.messages.find((m) => m.content === 'no topic msg')).toBeUndefined();
|
|
1004
|
-
});
|
|
1005
|
-
});
|
|
1006
|
-
|
|
1007
935
|
describe('updateMessage', () => {
|
|
1008
936
|
it('should update message content', async () => {
|
|
1009
|
-
//
|
|
937
|
+
// Create test data
|
|
1010
938
|
await serverDB
|
|
1011
939
|
.insert(messages)
|
|
1012
940
|
.values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
|
|
1013
941
|
|
|
1014
|
-
//
|
|
942
|
+
// Call updateMessage method
|
|
1015
943
|
await messageModel.update('1', { content: 'updated message' });
|
|
1016
944
|
|
|
1017
|
-
//
|
|
945
|
+
// Assert result
|
|
1018
946
|
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
|
1019
947
|
expect(result[0].content).toBe('updated message');
|
|
1020
948
|
});
|
|
1021
949
|
|
|
1022
950
|
it('should only update messages belonging to the user', async () => {
|
|
1023
|
-
//
|
|
951
|
+
// Create test data
|
|
1024
952
|
await serverDB
|
|
1025
953
|
.insert(messages)
|
|
1026
954
|
.values([{ id: '1', userId: '456', role: 'user', content: 'message 1' }]);
|
|
1027
955
|
|
|
1028
|
-
//
|
|
956
|
+
// Call updateMessage method
|
|
1029
957
|
await messageModel.update('1', { content: 'updated message' });
|
|
1030
958
|
|
|
1031
|
-
//
|
|
959
|
+
// Assert result
|
|
1032
960
|
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
|
1033
961
|
expect(result[0].content).toBe('message 1');
|
|
1034
962
|
});
|
|
1035
963
|
|
|
1036
964
|
it('should update message tools', async () => {
|
|
1037
|
-
//
|
|
965
|
+
// Create test data
|
|
1038
966
|
await serverDB.insert(messages).values([
|
|
1039
967
|
{
|
|
1040
968
|
id: '1',
|
|
@@ -1054,7 +982,7 @@ describe('MessageModel', () => {
|
|
|
1054
982
|
},
|
|
1055
983
|
]);
|
|
1056
984
|
|
|
1057
|
-
//
|
|
985
|
+
// Call updateMessage method
|
|
1058
986
|
await messageModel.update('1', {
|
|
1059
987
|
tools: [
|
|
1060
988
|
{
|
|
@@ -1067,7 +995,7 @@ describe('MessageModel', () => {
|
|
|
1067
995
|
],
|
|
1068
996
|
});
|
|
1069
997
|
|
|
1070
|
-
//
|
|
998
|
+
// Assert result
|
|
1071
999
|
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
|
1072
1000
|
expect((result[0].tools as any)[0].arguments).toBe(
|
|
1073
1001
|
'{"query":"2024 杭州暴雨","searchEngines":["duckduckgo","google","brave"]}',
|
|
@@ -1076,7 +1004,7 @@ describe('MessageModel', () => {
|
|
|
1076
1004
|
|
|
1077
1005
|
describe('update with imageList', () => {
|
|
1078
1006
|
it('should update a message and add image files', async () => {
|
|
1079
|
-
//
|
|
1007
|
+
// Create test data
|
|
1080
1008
|
await serverDB.insert(messages).values({
|
|
1081
1009
|
id: 'msg-to-update',
|
|
1082
1010
|
userId,
|
|
@@ -1096,7 +1024,7 @@ describe('MessageModel', () => {
|
|
|
1096
1024
|
{ id: 'img2', name: 'image2.png', fileType: 'image/png', size: 200, url: 'url2', userId },
|
|
1097
1025
|
]);
|
|
1098
1026
|
|
|
1099
|
-
//
|
|
1027
|
+
// Call update method
|
|
1100
1028
|
await messageModel.update('msg-to-update', {
|
|
1101
1029
|
content: 'updated content',
|
|
1102
1030
|
imageList: [
|
|
@@ -1105,7 +1033,7 @@ describe('MessageModel', () => {
|
|
|
1105
1033
|
],
|
|
1106
1034
|
});
|
|
1107
1035
|
|
|
1108
|
-
//
|
|
1036
|
+
// Verify message updated successfully
|
|
1109
1037
|
const updatedMessage = await serverDB
|
|
1110
1038
|
.select()
|
|
1111
1039
|
.from(messages)
|
|
@@ -1113,7 +1041,7 @@ describe('MessageModel', () => {
|
|
|
1113
1041
|
|
|
1114
1042
|
expect(updatedMessage[0].content).toBe('updated content');
|
|
1115
1043
|
|
|
1116
|
-
//
|
|
1044
|
+
// Verify message file associations created successfully
|
|
1117
1045
|
const messageFiles = await serverDB
|
|
1118
1046
|
.select()
|
|
1119
1047
|
.from(messagesFiles)
|
|
@@ -1125,7 +1053,7 @@ describe('MessageModel', () => {
|
|
|
1125
1053
|
});
|
|
1126
1054
|
|
|
1127
1055
|
it('should handle empty imageList', async () => {
|
|
1128
|
-
//
|
|
1056
|
+
// Create test data
|
|
1129
1057
|
await serverDB.insert(messages).values({
|
|
1130
1058
|
id: 'msg-no-images',
|
|
1131
1059
|
userId,
|
|
@@ -1133,12 +1061,12 @@ describe('MessageModel', () => {
|
|
|
1133
1061
|
content: 'original content',
|
|
1134
1062
|
});
|
|
1135
1063
|
|
|
1136
|
-
//
|
|
1064
|
+
// Call update method without providing imageList
|
|
1137
1065
|
await messageModel.update('msg-no-images', {
|
|
1138
1066
|
content: 'updated content',
|
|
1139
1067
|
});
|
|
1140
1068
|
|
|
1141
|
-
//
|
|
1069
|
+
// Verify message updated successfully
|
|
1142
1070
|
const updatedMessage = await serverDB
|
|
1143
1071
|
.select()
|
|
1144
1072
|
.from(messages)
|
|
@@ -1146,7 +1074,7 @@ describe('MessageModel', () => {
|
|
|
1146
1074
|
|
|
1147
1075
|
expect(updatedMessage[0].content).toBe('updated content');
|
|
1148
1076
|
|
|
1149
|
-
//
|
|
1077
|
+
// Verify no message file associations created
|
|
1150
1078
|
const messageFiles = await serverDB
|
|
1151
1079
|
.select()
|
|
1152
1080
|
.from(messagesFiles)
|
|
@@ -1156,7 +1084,7 @@ describe('MessageModel', () => {
|
|
|
1156
1084
|
});
|
|
1157
1085
|
|
|
1158
1086
|
it('should update multiple fields at once', async () => {
|
|
1159
|
-
//
|
|
1087
|
+
// Create test data
|
|
1160
1088
|
await serverDB.insert(messages).values({
|
|
1161
1089
|
id: 'msg-multi-update',
|
|
1162
1090
|
userId,
|
|
@@ -1165,7 +1093,7 @@ describe('MessageModel', () => {
|
|
|
1165
1093
|
model: 'gpt-3.5',
|
|
1166
1094
|
});
|
|
1167
1095
|
|
|
1168
|
-
//
|
|
1096
|
+
// Call update method to update multiple fields
|
|
1169
1097
|
await messageModel.update('msg-multi-update', {
|
|
1170
1098
|
content: 'updated content',
|
|
1171
1099
|
role: 'assistant',
|
|
@@ -1173,7 +1101,7 @@ describe('MessageModel', () => {
|
|
|
1173
1101
|
metadata: { tps: 1 },
|
|
1174
1102
|
});
|
|
1175
1103
|
|
|
1176
|
-
//
|
|
1104
|
+
// Verify message updated successfully
|
|
1177
1105
|
const updatedMessage = await serverDB
|
|
1178
1106
|
.select()
|
|
1179
1107
|
.from(messages)
|
|
@@ -1185,11 +1113,106 @@ describe('MessageModel', () => {
|
|
|
1185
1113
|
expect(updatedMessage[0].metadata).toEqual({ tps: 1 });
|
|
1186
1114
|
});
|
|
1187
1115
|
});
|
|
1116
|
+
|
|
1117
|
+
describe('update with returnQuery option', () => {
|
|
1118
|
+
it('should return updated message list when sessionId is provided', async () => {
|
|
1119
|
+
// Create test data
|
|
1120
|
+
const sessionId = '1';
|
|
1121
|
+
await serverDB.insert(messages).values([
|
|
1122
|
+
{
|
|
1123
|
+
id: 'msg1',
|
|
1124
|
+
userId,
|
|
1125
|
+
sessionId,
|
|
1126
|
+
role: 'user',
|
|
1127
|
+
content: 'message 1',
|
|
1128
|
+
},
|
|
1129
|
+
{
|
|
1130
|
+
id: 'msg2',
|
|
1131
|
+
userId,
|
|
1132
|
+
sessionId,
|
|
1133
|
+
role: 'assistant',
|
|
1134
|
+
content: 'message 2',
|
|
1135
|
+
},
|
|
1136
|
+
]);
|
|
1137
|
+
|
|
1138
|
+
// Call update method with sessionId option
|
|
1139
|
+
const result = await messageModel.update(
|
|
1140
|
+
'msg1',
|
|
1141
|
+
{ content: 'updated message 1' },
|
|
1142
|
+
{ sessionId },
|
|
1143
|
+
);
|
|
1144
|
+
|
|
1145
|
+
// Verify return result contains message list
|
|
1146
|
+
expect(result.success).toBe(true);
|
|
1147
|
+
expect(result.messages).toBeDefined();
|
|
1148
|
+
expect(result.messages).toHaveLength(2);
|
|
1149
|
+
expect(result.messages![0].content).toBe('updated message 1');
|
|
1150
|
+
expect(result.messages![1].content).toBe('message 2');
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
it('should return updated message list when topicId is provided', async () => {
|
|
1154
|
+
// Create test data
|
|
1155
|
+
const sessionId = '1';
|
|
1156
|
+
const topicId = 'topic-1';
|
|
1157
|
+
await serverDB.insert(topics).values({ id: topicId, sessionId, userId });
|
|
1158
|
+
await serverDB.insert(messages).values([
|
|
1159
|
+
{
|
|
1160
|
+
id: 'msg-topic1',
|
|
1161
|
+
userId,
|
|
1162
|
+
sessionId,
|
|
1163
|
+
topicId,
|
|
1164
|
+
role: 'user',
|
|
1165
|
+
content: 'topic message 1',
|
|
1166
|
+
},
|
|
1167
|
+
{
|
|
1168
|
+
id: 'msg-topic2',
|
|
1169
|
+
userId,
|
|
1170
|
+
sessionId,
|
|
1171
|
+
topicId,
|
|
1172
|
+
role: 'assistant',
|
|
1173
|
+
content: 'topic message 2',
|
|
1174
|
+
},
|
|
1175
|
+
]);
|
|
1176
|
+
|
|
1177
|
+
// Call update method with topicId option
|
|
1178
|
+
const result = await messageModel.update(
|
|
1179
|
+
'msg-topic1',
|
|
1180
|
+
{ content: 'updated topic message 1' },
|
|
1181
|
+
{ topicId, sessionId },
|
|
1182
|
+
);
|
|
1183
|
+
|
|
1184
|
+
// Verify return result contains message list
|
|
1185
|
+
expect(result.success).toBe(true);
|
|
1186
|
+
expect(result.messages).toBeDefined();
|
|
1187
|
+
expect(result.messages).toHaveLength(2);
|
|
1188
|
+
expect(result.messages![0].content).toBe('updated topic message 1');
|
|
1189
|
+
expect(result.messages![1].content).toBe('topic message 2');
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
it('should return success without messages when options not provided', async () => {
|
|
1193
|
+
// Create test data
|
|
1194
|
+
await serverDB.insert(messages).values({
|
|
1195
|
+
id: 'msg-no-options',
|
|
1196
|
+
userId,
|
|
1197
|
+
role: 'user',
|
|
1198
|
+
content: 'original content',
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
// Call update method,不提供选项
|
|
1202
|
+
const result = await messageModel.update('msg-no-options', {
|
|
1203
|
+
content: 'updated content',
|
|
1204
|
+
});
|
|
1205
|
+
|
|
1206
|
+
// 验证返回结果不包含消息列表
|
|
1207
|
+
expect(result.success).toBe(true);
|
|
1208
|
+
expect(result.messages).toBeUndefined();
|
|
1209
|
+
});
|
|
1210
|
+
});
|
|
1188
1211
|
});
|
|
1189
1212
|
|
|
1190
1213
|
describe('deleteMessage', () => {
|
|
1191
1214
|
it('should delete a message', async () => {
|
|
1192
|
-
//
|
|
1215
|
+
// Create test data
|
|
1193
1216
|
await serverDB
|
|
1194
1217
|
.insert(messages)
|
|
1195
1218
|
.values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
|
|
@@ -1197,13 +1220,13 @@ describe('MessageModel', () => {
|
|
|
1197
1220
|
// 调用 deleteMessage 方法
|
|
1198
1221
|
await messageModel.deleteMessage('1');
|
|
1199
1222
|
|
|
1200
|
-
//
|
|
1223
|
+
// Assert result
|
|
1201
1224
|
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
|
1202
1225
|
expect(result).toHaveLength(0);
|
|
1203
1226
|
});
|
|
1204
1227
|
|
|
1205
1228
|
it('should delete a message with tool calls', async () => {
|
|
1206
|
-
//
|
|
1229
|
+
// Create test data
|
|
1207
1230
|
await serverDB.transaction(async (trx) => {
|
|
1208
1231
|
await trx.insert(messages).values([
|
|
1209
1232
|
{ id: '1', userId, role: 'user', content: 'message 1', tools: [{ id: 'tool1' }] },
|
|
@@ -1217,7 +1240,7 @@ describe('MessageModel', () => {
|
|
|
1217
1240
|
// 调用 deleteMessage 方法
|
|
1218
1241
|
await messageModel.deleteMessage('1');
|
|
1219
1242
|
|
|
1220
|
-
//
|
|
1243
|
+
// Assert result
|
|
1221
1244
|
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
|
1222
1245
|
expect(result).toHaveLength(0);
|
|
1223
1246
|
|
|
@@ -1230,7 +1253,7 @@ describe('MessageModel', () => {
|
|
|
1230
1253
|
});
|
|
1231
1254
|
|
|
1232
1255
|
it('should only delete messages belonging to the user', async () => {
|
|
1233
|
-
//
|
|
1256
|
+
// Create test data
|
|
1234
1257
|
await serverDB
|
|
1235
1258
|
.insert(messages)
|
|
1236
1259
|
.values([{ id: '1', userId: '456', role: 'user', content: 'message 1' }]);
|
|
@@ -1238,7 +1261,7 @@ describe('MessageModel', () => {
|
|
|
1238
1261
|
// 调用 deleteMessage 方法
|
|
1239
1262
|
await messageModel.deleteMessage('1');
|
|
1240
1263
|
|
|
1241
|
-
//
|
|
1264
|
+
// Assert result
|
|
1242
1265
|
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
|
1243
1266
|
expect(result).toHaveLength(1);
|
|
1244
1267
|
});
|
|
@@ -1246,7 +1269,7 @@ describe('MessageModel', () => {
|
|
|
1246
1269
|
|
|
1247
1270
|
describe('deleteMessages', () => {
|
|
1248
1271
|
it('should delete 2 messages', async () => {
|
|
1249
|
-
//
|
|
1272
|
+
// Create test data
|
|
1250
1273
|
await serverDB.insert(messages).values([
|
|
1251
1274
|
{ id: '1', userId, role: 'user', content: 'message 1' },
|
|
1252
1275
|
{ id: '2', userId, role: 'user', content: 'message 2' },
|
|
@@ -1255,7 +1278,7 @@ describe('MessageModel', () => {
|
|
|
1255
1278
|
// 调用 deleteMessage 方法
|
|
1256
1279
|
await messageModel.deleteMessages(['1', '2']);
|
|
1257
1280
|
|
|
1258
|
-
//
|
|
1281
|
+
// Assert result
|
|
1259
1282
|
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
|
1260
1283
|
expect(result).toHaveLength(0);
|
|
1261
1284
|
const result2 = await serverDB.select().from(messages).where(eq(messages.id, '2'));
|
|
@@ -1263,7 +1286,7 @@ describe('MessageModel', () => {
|
|
|
1263
1286
|
});
|
|
1264
1287
|
|
|
1265
1288
|
it('should only delete messages belonging to the user', async () => {
|
|
1266
|
-
//
|
|
1289
|
+
// Create test data
|
|
1267
1290
|
await serverDB.insert(messages).values([
|
|
1268
1291
|
{ id: '1', userId: '456', role: 'user', content: 'message 1' },
|
|
1269
1292
|
{ id: '2', userId: '456', role: 'user', content: 'message 1' },
|
|
@@ -1272,7 +1295,7 @@ describe('MessageModel', () => {
|
|
|
1272
1295
|
// 调用 deleteMessage 方法
|
|
1273
1296
|
await messageModel.deleteMessages(['1', '2']);
|
|
1274
1297
|
|
|
1275
|
-
//
|
|
1298
|
+
// Assert result
|
|
1276
1299
|
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
|
1277
1300
|
expect(result).toHaveLength(1);
|
|
1278
1301
|
});
|
|
@@ -1280,7 +1303,7 @@ describe('MessageModel', () => {
|
|
|
1280
1303
|
|
|
1281
1304
|
describe('deleteAllMessages', () => {
|
|
1282
1305
|
it('should delete all messages belonging to the user', async () => {
|
|
1283
|
-
//
|
|
1306
|
+
// Create test data
|
|
1284
1307
|
await serverDB.insert(messages).values([
|
|
1285
1308
|
{ id: '1', userId, role: 'user', content: 'message 1' },
|
|
1286
1309
|
{ id: '2', userId, role: 'user', content: 'message 2' },
|
|
@@ -1290,7 +1313,7 @@ describe('MessageModel', () => {
|
|
|
1290
1313
|
// 调用 deleteAllMessages 方法
|
|
1291
1314
|
await messageModel.deleteAllMessages();
|
|
1292
1315
|
|
|
1293
|
-
//
|
|
1316
|
+
// Assert result
|
|
1294
1317
|
const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
|
|
1295
1318
|
|
|
1296
1319
|
expect(result).toHaveLength(0);
|
|
@@ -1303,7 +1326,7 @@ describe('MessageModel', () => {
|
|
|
1303
1326
|
|
|
1304
1327
|
describe('updatePluginState', () => {
|
|
1305
1328
|
it('should update the state field in messagePlugins table', async () => {
|
|
1306
|
-
//
|
|
1329
|
+
// Create test data
|
|
1307
1330
|
await serverDB.insert(messages).values({ id: '1', content: 'abc', role: 'user', userId });
|
|
1308
1331
|
await serverDB.insert(messagePlugins).values([
|
|
1309
1332
|
{
|
|
@@ -1318,7 +1341,7 @@ describe('MessageModel', () => {
|
|
|
1318
1341
|
// 调用 updatePluginState 方法
|
|
1319
1342
|
await messageModel.updatePluginState('1', { key2: 'value2' });
|
|
1320
1343
|
|
|
1321
|
-
//
|
|
1344
|
+
// Assert result
|
|
1322
1345
|
const result = await serverDB.select().from(messagePlugins).where(eq(messagePlugins.id, '1'));
|
|
1323
1346
|
|
|
1324
1347
|
expect(result[0].state).toEqual({ key1: 'value1', key2: 'value2' });
|
|
@@ -1333,7 +1356,7 @@ describe('MessageModel', () => {
|
|
|
1333
1356
|
});
|
|
1334
1357
|
describe('updateMessagePlugin', () => {
|
|
1335
1358
|
it('should update the state field in messagePlugins table', async () => {
|
|
1336
|
-
//
|
|
1359
|
+
// Create test data
|
|
1337
1360
|
await serverDB.insert(messages).values({ id: '1', content: 'abc', role: 'user', userId });
|
|
1338
1361
|
await serverDB.insert(messagePlugins).values([
|
|
1339
1362
|
{
|
|
@@ -1348,7 +1371,7 @@ describe('MessageModel', () => {
|
|
|
1348
1371
|
// 调用 updatePluginState 方法
|
|
1349
1372
|
await messageModel.updateMessagePlugin('1', { identifier: 'plugin2' });
|
|
1350
1373
|
|
|
1351
|
-
//
|
|
1374
|
+
// Assert result
|
|
1352
1375
|
const result = await serverDB.select().from(messagePlugins).where(eq(messagePlugins.id, '1'));
|
|
1353
1376
|
|
|
1354
1377
|
expect(result[0].identifier).toEqual('plugin2');
|
|
@@ -1364,7 +1387,7 @@ describe('MessageModel', () => {
|
|
|
1364
1387
|
|
|
1365
1388
|
describe('updateMetadata', () => {
|
|
1366
1389
|
it('should update metadata for an existing message', async () => {
|
|
1367
|
-
//
|
|
1390
|
+
// Create test data
|
|
1368
1391
|
await serverDB.insert(messages).values({
|
|
1369
1392
|
id: 'msg-with-metadata',
|
|
1370
1393
|
userId,
|
|
@@ -1376,7 +1399,7 @@ describe('MessageModel', () => {
|
|
|
1376
1399
|
// 调用 updateMetadata 方法
|
|
1377
1400
|
await messageModel.updateMetadata('msg-with-metadata', { newKey: 'newValue' });
|
|
1378
1401
|
|
|
1379
|
-
//
|
|
1402
|
+
// Assert result
|
|
1380
1403
|
const result = await serverDB
|
|
1381
1404
|
.select()
|
|
1382
1405
|
.from(messages)
|
|
@@ -1389,7 +1412,7 @@ describe('MessageModel', () => {
|
|
|
1389
1412
|
});
|
|
1390
1413
|
|
|
1391
1414
|
it('should merge new metadata with existing metadata using lodash merge behavior', async () => {
|
|
1392
|
-
//
|
|
1415
|
+
// Create test data
|
|
1393
1416
|
await serverDB.insert(messages).values({
|
|
1394
1417
|
id: 'msg-merge-metadata',
|
|
1395
1418
|
userId,
|
|
@@ -1413,7 +1436,7 @@ describe('MessageModel', () => {
|
|
|
1413
1436
|
newTopLevel: 'value',
|
|
1414
1437
|
});
|
|
1415
1438
|
|
|
1416
|
-
//
|
|
1439
|
+
// Assert result - 应该使用 lodash merge 行为
|
|
1417
1440
|
const result = await serverDB
|
|
1418
1441
|
.select()
|
|
1419
1442
|
.from(messages)
|
|
@@ -1434,12 +1457,12 @@ describe('MessageModel', () => {
|
|
|
1434
1457
|
// 调用 updateMetadata 方法,尝试更新不存在的消息
|
|
1435
1458
|
const result = await messageModel.updateMetadata('non-existent-id', { key: 'value' });
|
|
1436
1459
|
|
|
1437
|
-
//
|
|
1460
|
+
// Assert result - 应该返回 undefined
|
|
1438
1461
|
expect(result).toBeUndefined();
|
|
1439
1462
|
});
|
|
1440
1463
|
|
|
1441
1464
|
it('should handle empty metadata updates', async () => {
|
|
1442
|
-
//
|
|
1465
|
+
// Create test data
|
|
1443
1466
|
await serverDB.insert(messages).values({
|
|
1444
1467
|
id: 'msg-empty-metadata',
|
|
1445
1468
|
userId,
|
|
@@ -1451,7 +1474,7 @@ describe('MessageModel', () => {
|
|
|
1451
1474
|
// 调用 updateMetadata 方法,传递空对象
|
|
1452
1475
|
await messageModel.updateMetadata('msg-empty-metadata', {});
|
|
1453
1476
|
|
|
1454
|
-
//
|
|
1477
|
+
// Assert result - 原始 metadata 应该保持不变
|
|
1455
1478
|
const result = await serverDB
|
|
1456
1479
|
.select()
|
|
1457
1480
|
.from(messages)
|
|
@@ -1461,7 +1484,7 @@ describe('MessageModel', () => {
|
|
|
1461
1484
|
});
|
|
1462
1485
|
|
|
1463
1486
|
it('should handle message with null metadata', async () => {
|
|
1464
|
-
//
|
|
1487
|
+
// Create test data
|
|
1465
1488
|
await serverDB.insert(messages).values({
|
|
1466
1489
|
id: 'msg-null-metadata',
|
|
1467
1490
|
userId,
|
|
@@ -1473,7 +1496,7 @@ describe('MessageModel', () => {
|
|
|
1473
1496
|
// 调用 updateMetadata 方法
|
|
1474
1497
|
await messageModel.updateMetadata('msg-null-metadata', { key: 'value' });
|
|
1475
1498
|
|
|
1476
|
-
//
|
|
1499
|
+
// Assert result - 应该创建新的 metadata
|
|
1477
1500
|
const result = await serverDB
|
|
1478
1501
|
.select()
|
|
1479
1502
|
.from(messages)
|
|
@@ -1483,7 +1506,7 @@ describe('MessageModel', () => {
|
|
|
1483
1506
|
});
|
|
1484
1507
|
|
|
1485
1508
|
it('should only update messages belonging to the current user', async () => {
|
|
1486
|
-
//
|
|
1509
|
+
// Create test data - 其他用户的消息
|
|
1487
1510
|
await serverDB.insert(messages).values({
|
|
1488
1511
|
id: 'msg-other-user',
|
|
1489
1512
|
userId: '456',
|
|
@@ -1497,7 +1520,7 @@ describe('MessageModel', () => {
|
|
|
1497
1520
|
hackedKey: 'hackedValue',
|
|
1498
1521
|
});
|
|
1499
1522
|
|
|
1500
|
-
//
|
|
1523
|
+
// Assert result - 应该返回 undefined
|
|
1501
1524
|
expect(result).toBeUndefined();
|
|
1502
1525
|
|
|
1503
1526
|
// 验证原始 metadata 未被修改
|
|
@@ -1510,7 +1533,7 @@ describe('MessageModel', () => {
|
|
|
1510
1533
|
});
|
|
1511
1534
|
|
|
1512
1535
|
it('should handle complex nested metadata updates', async () => {
|
|
1513
|
-
//
|
|
1536
|
+
// Create test data
|
|
1514
1537
|
await serverDB.insert(messages).values({
|
|
1515
1538
|
id: 'msg-complex-metadata',
|
|
1516
1539
|
userId,
|
|
@@ -1539,7 +1562,7 @@ describe('MessageModel', () => {
|
|
|
1539
1562
|
stats: { count: 10 },
|
|
1540
1563
|
});
|
|
1541
1564
|
|
|
1542
|
-
//
|
|
1565
|
+
// Assert result
|
|
1543
1566
|
const result = await serverDB
|
|
1544
1567
|
.select()
|
|
1545
1568
|
.from(messages)
|
|
@@ -1562,7 +1585,7 @@ describe('MessageModel', () => {
|
|
|
1562
1585
|
|
|
1563
1586
|
describe('updateTranslate', () => {
|
|
1564
1587
|
it('should insert a new record if message does not exist in messageTranslates table', async () => {
|
|
1565
|
-
//
|
|
1588
|
+
// Create test data
|
|
1566
1589
|
await serverDB
|
|
1567
1590
|
.insert(messages)
|
|
1568
1591
|
.values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
|
|
@@ -1574,7 +1597,7 @@ describe('MessageModel', () => {
|
|
|
1574
1597
|
to: 'zh',
|
|
1575
1598
|
});
|
|
1576
1599
|
|
|
1577
|
-
//
|
|
1600
|
+
// Assert result
|
|
1578
1601
|
const result = await serverDB
|
|
1579
1602
|
.select()
|
|
1580
1603
|
.from(messageTranslates)
|
|
@@ -1585,7 +1608,7 @@ describe('MessageModel', () => {
|
|
|
1585
1608
|
});
|
|
1586
1609
|
|
|
1587
1610
|
it('should update the corresponding fields if message exists in messageTranslates table', async () => {
|
|
1588
|
-
//
|
|
1611
|
+
// Create test data
|
|
1589
1612
|
await serverDB.transaction(async (trx) => {
|
|
1590
1613
|
await trx
|
|
1591
1614
|
.insert(messages)
|
|
@@ -1598,7 +1621,7 @@ describe('MessageModel', () => {
|
|
|
1598
1621
|
// 调用 updateTranslate 方法
|
|
1599
1622
|
await messageModel.updateTranslate('1', { content: 'updated translated message 1' });
|
|
1600
1623
|
|
|
1601
|
-
//
|
|
1624
|
+
// Assert result
|
|
1602
1625
|
const result = await serverDB
|
|
1603
1626
|
.select()
|
|
1604
1627
|
.from(messageTranslates)
|
|
@@ -1610,7 +1633,7 @@ describe('MessageModel', () => {
|
|
|
1610
1633
|
|
|
1611
1634
|
describe('updateTTS', () => {
|
|
1612
1635
|
it('should insert a new record if message does not exist in messageTTS table', async () => {
|
|
1613
|
-
//
|
|
1636
|
+
// Create test data
|
|
1614
1637
|
await serverDB
|
|
1615
1638
|
.insert(messages)
|
|
1616
1639
|
.values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
|
|
@@ -1618,7 +1641,7 @@ describe('MessageModel', () => {
|
|
|
1618
1641
|
// 调用 updateTTS 方法
|
|
1619
1642
|
await messageModel.updateTTS('1', { contentMd5: 'md5', file: 'f1', voice: 'voice1' });
|
|
1620
1643
|
|
|
1621
|
-
//
|
|
1644
|
+
// Assert result
|
|
1622
1645
|
const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
|
|
1623
1646
|
|
|
1624
1647
|
expect(result).toHaveLength(1);
|
|
@@ -1626,7 +1649,7 @@ describe('MessageModel', () => {
|
|
|
1626
1649
|
});
|
|
1627
1650
|
|
|
1628
1651
|
it('should update the corresponding fields if message exists in messageTTS table', async () => {
|
|
1629
|
-
//
|
|
1652
|
+
// Create test data
|
|
1630
1653
|
await serverDB.transaction(async (trx) => {
|
|
1631
1654
|
await trx
|
|
1632
1655
|
.insert(messages)
|
|
@@ -1639,7 +1662,7 @@ describe('MessageModel', () => {
|
|
|
1639
1662
|
// 调用 updateTTS 方法
|
|
1640
1663
|
await messageModel.updateTTS('1', { voice: 'updated voice1' });
|
|
1641
1664
|
|
|
1642
|
-
//
|
|
1665
|
+
// Assert result
|
|
1643
1666
|
const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
|
|
1644
1667
|
|
|
1645
1668
|
expect(result[0].voice).toBe('updated voice1');
|
|
@@ -1648,14 +1671,14 @@ describe('MessageModel', () => {
|
|
|
1648
1671
|
|
|
1649
1672
|
describe('deleteMessageTranslate', () => {
|
|
1650
1673
|
it('should delete the message translate record', async () => {
|
|
1651
|
-
//
|
|
1674
|
+
// Create test data
|
|
1652
1675
|
await serverDB.insert(messages).values([{ id: '1', role: 'abc', userId }]);
|
|
1653
1676
|
await serverDB.insert(messageTranslates).values([{ id: '1', userId }]);
|
|
1654
1677
|
|
|
1655
1678
|
// 调用 deleteMessageTranslate 方法
|
|
1656
1679
|
await messageModel.deleteMessageTranslate('1');
|
|
1657
1680
|
|
|
1658
|
-
//
|
|
1681
|
+
// Assert result
|
|
1659
1682
|
const result = await serverDB
|
|
1660
1683
|
.select()
|
|
1661
1684
|
.from(messageTranslates)
|
|
@@ -1667,14 +1690,14 @@ describe('MessageModel', () => {
|
|
|
1667
1690
|
|
|
1668
1691
|
describe('deleteMessageTTS', () => {
|
|
1669
1692
|
it('should delete the message TTS record', async () => {
|
|
1670
|
-
//
|
|
1693
|
+
// Create test data
|
|
1671
1694
|
await serverDB.insert(messages).values([{ id: '1', role: 'abc', userId }]);
|
|
1672
1695
|
await serverDB.insert(messageTTS).values([{ userId, id: '1' }]);
|
|
1673
1696
|
|
|
1674
1697
|
// 调用 deleteMessageTTS 方法
|
|
1675
1698
|
await messageModel.deleteMessageTTS('1');
|
|
1676
1699
|
|
|
1677
|
-
//
|
|
1700
|
+
// Assert result
|
|
1678
1701
|
const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
|
|
1679
1702
|
expect(result).toHaveLength(0);
|
|
1680
1703
|
});
|
|
@@ -1682,7 +1705,7 @@ describe('MessageModel', () => {
|
|
|
1682
1705
|
|
|
1683
1706
|
describe('count', () => {
|
|
1684
1707
|
it('should return the count of messages belonging to the user', async () => {
|
|
1685
|
-
//
|
|
1708
|
+
// Create test data
|
|
1686
1709
|
await serverDB.insert(messages).values([
|
|
1687
1710
|
{ id: '1', userId, role: 'user', content: 'message 1' },
|
|
1688
1711
|
{ id: '2', userId, role: 'user', content: 'message 2' },
|
|
@@ -1692,13 +1715,13 @@ describe('MessageModel', () => {
|
|
|
1692
1715
|
// 调用 count 方法
|
|
1693
1716
|
const result = await messageModel.count();
|
|
1694
1717
|
|
|
1695
|
-
//
|
|
1718
|
+
// Assert result
|
|
1696
1719
|
expect(result).toBe(2);
|
|
1697
1720
|
});
|
|
1698
1721
|
|
|
1699
1722
|
describe('count with date filters', () => {
|
|
1700
1723
|
beforeEach(async () => {
|
|
1701
|
-
//
|
|
1724
|
+
// Create test data,包含不同日期的消息
|
|
1702
1725
|
await serverDB.insert(messages).values([
|
|
1703
1726
|
{
|
|
1704
1727
|
id: 'date1',
|
|
@@ -1899,6 +1922,63 @@ describe('MessageModel', () => {
|
|
|
1899
1922
|
expect(remainingMessages).toHaveLength(1);
|
|
1900
1923
|
expect(remainingMessages[0].id).toBe('2');
|
|
1901
1924
|
});
|
|
1925
|
+
|
|
1926
|
+
it('should delete only non-topic messages when topicId is null', async () => {
|
|
1927
|
+
await serverDB.insert(sessions).values([{ id: 'session1', userId }]);
|
|
1928
|
+
await serverDB.insert(topics).values([
|
|
1929
|
+
{ id: 'topic1', sessionId: 'session1', userId },
|
|
1930
|
+
{ id: 'topic2', sessionId: 'session1', userId },
|
|
1931
|
+
]);
|
|
1932
|
+
|
|
1933
|
+
await serverDB.insert(messages).values([
|
|
1934
|
+
{
|
|
1935
|
+
id: '1',
|
|
1936
|
+
userId,
|
|
1937
|
+
sessionId: 'session1',
|
|
1938
|
+
topicId: null,
|
|
1939
|
+
role: 'user',
|
|
1940
|
+
content: 'message without topic 1',
|
|
1941
|
+
},
|
|
1942
|
+
{
|
|
1943
|
+
id: '2',
|
|
1944
|
+
userId,
|
|
1945
|
+
sessionId: 'session1',
|
|
1946
|
+
topicId: null,
|
|
1947
|
+
role: 'assistant',
|
|
1948
|
+
content: 'message without topic 2',
|
|
1949
|
+
},
|
|
1950
|
+
{
|
|
1951
|
+
id: '3',
|
|
1952
|
+
userId,
|
|
1953
|
+
sessionId: 'session1',
|
|
1954
|
+
topicId: 'topic1',
|
|
1955
|
+
role: 'user',
|
|
1956
|
+
content: 'message in topic1',
|
|
1957
|
+
},
|
|
1958
|
+
{
|
|
1959
|
+
id: '4',
|
|
1960
|
+
userId,
|
|
1961
|
+
sessionId: 'session1',
|
|
1962
|
+
topicId: 'topic2',
|
|
1963
|
+
role: 'assistant',
|
|
1964
|
+
content: 'message in topic2',
|
|
1965
|
+
},
|
|
1966
|
+
]);
|
|
1967
|
+
|
|
1968
|
+
// Delete messages in session1 with null topicId
|
|
1969
|
+
await messageModel.deleteMessagesBySession('session1', null);
|
|
1970
|
+
|
|
1971
|
+
const remainingMessages = await serverDB
|
|
1972
|
+
.select()
|
|
1973
|
+
.from(messages)
|
|
1974
|
+
.where(eq(messages.userId, userId))
|
|
1975
|
+
.orderBy(messages.id);
|
|
1976
|
+
|
|
1977
|
+
// Should only keep messages with topics
|
|
1978
|
+
expect(remainingMessages).toHaveLength(2);
|
|
1979
|
+
expect(remainingMessages[0].id).toBe('3');
|
|
1980
|
+
expect(remainingMessages[1].id).toBe('4');
|
|
1981
|
+
});
|
|
1902
1982
|
});
|
|
1903
1983
|
|
|
1904
1984
|
describe('genId', () => {
|
|
@@ -1919,7 +1999,7 @@ describe('MessageModel', () => {
|
|
|
1919
1999
|
|
|
1920
2000
|
describe('countWords', () => {
|
|
1921
2001
|
it('should count total words of messages belonging to the user', async () => {
|
|
1922
|
-
//
|
|
2002
|
+
// Create test data
|
|
1923
2003
|
await serverDB.insert(messages).values([
|
|
1924
2004
|
{ id: '1', userId, role: 'user', content: 'hello world' },
|
|
1925
2005
|
{ id: '2', userId, role: 'user', content: 'test message' },
|
|
@@ -1929,12 +2009,12 @@ describe('MessageModel', () => {
|
|
|
1929
2009
|
// 调用 countWords 方法
|
|
1930
2010
|
const result = await messageModel.countWords();
|
|
1931
2011
|
|
|
1932
|
-
//
|
|
2012
|
+
// Assert result - 'hello world' + 'test message' = 23 characters
|
|
1933
2013
|
expect(result).toEqual(23);
|
|
1934
2014
|
});
|
|
1935
2015
|
|
|
1936
2016
|
it('should count words within date range', async () => {
|
|
1937
|
-
//
|
|
2017
|
+
// Create test data
|
|
1938
2018
|
await serverDB.insert(messages).values([
|
|
1939
2019
|
{
|
|
1940
2020
|
id: '1',
|
|
@@ -1957,12 +2037,12 @@ describe('MessageModel', () => {
|
|
|
1957
2037
|
range: ['2023-05-01', '2023-07-01'],
|
|
1958
2038
|
});
|
|
1959
2039
|
|
|
1960
|
-
//
|
|
2040
|
+
// Assert result - 只计算 'new message' = 11 characters
|
|
1961
2041
|
expect(result).toEqual(11);
|
|
1962
2042
|
});
|
|
1963
2043
|
|
|
1964
2044
|
it('should handle empty content', async () => {
|
|
1965
|
-
//
|
|
2045
|
+
// Create test data
|
|
1966
2046
|
await serverDB.insert(messages).values([
|
|
1967
2047
|
{ id: '1', userId, role: 'user', content: '' },
|
|
1968
2048
|
{ id: '2', userId, role: 'user', content: null },
|
|
@@ -1971,7 +2051,7 @@ describe('MessageModel', () => {
|
|
|
1971
2051
|
// 调用 countWords 方法
|
|
1972
2052
|
const result = await messageModel.countWords();
|
|
1973
2053
|
|
|
1974
|
-
//
|
|
2054
|
+
// Assert result
|
|
1975
2055
|
expect(result).toEqual(0);
|
|
1976
2056
|
});
|
|
1977
2057
|
});
|
|
@@ -1988,7 +2068,7 @@ describe('MessageModel', () => {
|
|
|
1988
2068
|
const oneDayAgoDate = today.subtract(1, 'day').format('YYYY-MM-DD');
|
|
1989
2069
|
const todayDate = today.format('YYYY-MM-DD');
|
|
1990
2070
|
|
|
1991
|
-
//
|
|
2071
|
+
// Create test data
|
|
1992
2072
|
await serverDB.insert(messages).values([
|
|
1993
2073
|
{
|
|
1994
2074
|
id: '1',
|
|
@@ -2016,7 +2096,7 @@ describe('MessageModel', () => {
|
|
|
2016
2096
|
// 调用 getHeatmaps 方法
|
|
2017
2097
|
const result = await messageModel.getHeatmaps();
|
|
2018
2098
|
|
|
2019
|
-
//
|
|
2099
|
+
// Assert result
|
|
2020
2100
|
expect(result.length).toBeGreaterThanOrEqual(366);
|
|
2021
2101
|
expect(result.length).toBeLessThan(368);
|
|
2022
2102
|
|
|
@@ -2051,7 +2131,7 @@ describe('MessageModel', () => {
|
|
|
2051
2131
|
const oneDayAgoDate = today.subtract(1, 'day').format('YYYY-MM-DD');
|
|
2052
2132
|
const todayDate = today.format('YYYY-MM-DD');
|
|
2053
2133
|
|
|
2054
|
-
//
|
|
2134
|
+
// Create test data - 不同数量的消息以测试不同的等级
|
|
2055
2135
|
await serverDB.insert(messages).values([
|
|
2056
2136
|
// 1 message - level 1
|
|
2057
2137
|
{
|
|
@@ -2141,7 +2221,7 @@ describe('MessageModel', () => {
|
|
|
2141
2221
|
const oneDayAgoDate = today.subtract(1, 'day').format('YYYY-MM-DD');
|
|
2142
2222
|
const todayDate = today.format('YYYY-MM-DD');
|
|
2143
2223
|
|
|
2144
|
-
//
|
|
2224
|
+
// Create test data
|
|
2145
2225
|
await serverDB.insert(messages).values([
|
|
2146
2226
|
{
|
|
2147
2227
|
id: '1',
|
|
@@ -2169,7 +2249,7 @@ describe('MessageModel', () => {
|
|
|
2169
2249
|
// 调用 getHeatmaps 方法
|
|
2170
2250
|
const result = await messageModel.getHeatmaps();
|
|
2171
2251
|
|
|
2172
|
-
//
|
|
2252
|
+
// Assert result
|
|
2173
2253
|
expect(result.length).toBeGreaterThanOrEqual(366);
|
|
2174
2254
|
expect(result.length).toBeLessThan(368);
|
|
2175
2255
|
|
|
@@ -2197,7 +2277,7 @@ describe('MessageModel', () => {
|
|
|
2197
2277
|
// 调用 getHeatmaps 方法
|
|
2198
2278
|
const result = await messageModel.getHeatmaps();
|
|
2199
2279
|
|
|
2200
|
-
//
|
|
2280
|
+
// Assert result
|
|
2201
2281
|
expect(result.length).toBeGreaterThanOrEqual(366);
|
|
2202
2282
|
expect(result.length).toBeLessThan(368);
|
|
2203
2283
|
|
|
@@ -2211,7 +2291,7 @@ describe('MessageModel', () => {
|
|
|
2211
2291
|
|
|
2212
2292
|
describe('rankModels', () => {
|
|
2213
2293
|
it('should rank models by usage count', async () => {
|
|
2214
|
-
//
|
|
2294
|
+
// Create test data
|
|
2215
2295
|
await serverDB.insert(messages).values([
|
|
2216
2296
|
{ id: '1', userId, role: 'assistant', content: 'message 1', model: 'gpt-3.5' },
|
|
2217
2297
|
{ id: '2', userId, role: 'assistant', content: 'message 2', model: 'gpt-3.5' },
|
|
@@ -2222,14 +2302,14 @@ describe('MessageModel', () => {
|
|
|
2222
2302
|
// 调用 rankModels 方法
|
|
2223
2303
|
const result = await messageModel.rankModels();
|
|
2224
2304
|
|
|
2225
|
-
//
|
|
2305
|
+
// Assert result
|
|
2226
2306
|
expect(result).toHaveLength(2);
|
|
2227
2307
|
expect(result[0]).toEqual({ id: 'gpt-3.5', count: 2 }); // 当前用户使用 gpt-3.5 两次
|
|
2228
2308
|
expect(result[1]).toEqual({ id: 'gpt-4', count: 1 }); // 当前用户使用 gpt-4 一次
|
|
2229
2309
|
});
|
|
2230
2310
|
|
|
2231
2311
|
it('should only count messages with model field', async () => {
|
|
2232
|
-
//
|
|
2312
|
+
// Create test data,包括没有 model 字段的消息
|
|
2233
2313
|
await serverDB.insert(messages).values([
|
|
2234
2314
|
{ id: '1', userId, role: 'assistant', content: 'message 1', model: 'gpt-3.5' },
|
|
2235
2315
|
{ id: '2', userId, role: 'assistant', content: 'message 2', model: null },
|
|
@@ -2239,13 +2319,13 @@ describe('MessageModel', () => {
|
|
|
2239
2319
|
// 调用 rankModels 方法
|
|
2240
2320
|
const result = await messageModel.rankModels();
|
|
2241
2321
|
|
|
2242
|
-
//
|
|
2322
|
+
// Assert result
|
|
2243
2323
|
expect(result).toHaveLength(1);
|
|
2244
2324
|
expect(result[0]).toEqual({ id: 'gpt-3.5', count: 1 });
|
|
2245
2325
|
});
|
|
2246
2326
|
|
|
2247
2327
|
it('should return empty array when no models are used', async () => {
|
|
2248
|
-
//
|
|
2328
|
+
// Create test data,所有消息都没有 model
|
|
2249
2329
|
await serverDB.insert(messages).values([
|
|
2250
2330
|
{ id: '1', userId, role: 'user', content: 'message 1' },
|
|
2251
2331
|
{ id: '2', userId, role: 'assistant', content: 'message 2' },
|
|
@@ -2254,12 +2334,12 @@ describe('MessageModel', () => {
|
|
|
2254
2334
|
// 调用 rankModels 方法
|
|
2255
2335
|
const result = await messageModel.rankModels();
|
|
2256
2336
|
|
|
2257
|
-
//
|
|
2337
|
+
// Assert result
|
|
2258
2338
|
expect(result).toHaveLength(0);
|
|
2259
2339
|
});
|
|
2260
2340
|
|
|
2261
2341
|
it('should order models by count in descending order', async () => {
|
|
2262
|
-
//
|
|
2342
|
+
// Create test data,使用不同次数的模型
|
|
2263
2343
|
await serverDB.insert(messages).values([
|
|
2264
2344
|
{ id: '1', userId, role: 'assistant', content: 'message 1', model: 'gpt-4' },
|
|
2265
2345
|
{ id: '2', userId, role: 'assistant', content: 'message 2', model: 'gpt-3.5' },
|
|
@@ -2271,7 +2351,7 @@ describe('MessageModel', () => {
|
|
|
2271
2351
|
// 调用 rankModels 方法
|
|
2272
2352
|
const result = await messageModel.rankModels();
|
|
2273
2353
|
|
|
2274
|
-
//
|
|
2354
|
+
// Assert result
|
|
2275
2355
|
expect(result).toHaveLength(3);
|
|
2276
2356
|
expect(result[0]).toEqual({ id: 'gpt-3.5', count: 3 }); // 最多使用
|
|
2277
2357
|
expect(result[1]).toEqual({ id: 'claude', count: 1 });
|
|
@@ -2281,7 +2361,7 @@ describe('MessageModel', () => {
|
|
|
2281
2361
|
|
|
2282
2362
|
describe('hasMoreThanN', () => {
|
|
2283
2363
|
it('should return true when message count is greater than N', async () => {
|
|
2284
|
-
//
|
|
2364
|
+
// Create test data
|
|
2285
2365
|
await serverDB.insert(messages).values([
|
|
2286
2366
|
{ id: '1', userId, role: 'user', content: 'message 1' },
|
|
2287
2367
|
{ id: '2', userId, role: 'user', content: 'message 2' },
|
|
@@ -2299,7 +2379,7 @@ describe('MessageModel', () => {
|
|
|
2299
2379
|
});
|
|
2300
2380
|
|
|
2301
2381
|
it('should only count messages belonging to the user', async () => {
|
|
2302
|
-
//
|
|
2382
|
+
// Create test data,包括其他用户的消息
|
|
2303
2383
|
await serverDB.insert(messages).values([
|
|
2304
2384
|
{ id: '1', userId, role: 'user', content: 'message 1' },
|
|
2305
2385
|
{ id: '2', userId, role: 'user', content: 'message 2' },
|
|
@@ -2335,7 +2415,7 @@ describe('MessageModel', () => {
|
|
|
2335
2415
|
|
|
2336
2416
|
describe('createMessageQuery', () => {
|
|
2337
2417
|
it('should create a new message query', async () => {
|
|
2338
|
-
//
|
|
2418
|
+
// Create test data
|
|
2339
2419
|
await serverDB.insert(messages).values({
|
|
2340
2420
|
id: 'msg1',
|
|
2341
2421
|
userId,
|
|
@@ -2351,7 +2431,7 @@ describe('MessageModel', () => {
|
|
|
2351
2431
|
embeddingsId,
|
|
2352
2432
|
});
|
|
2353
2433
|
|
|
2354
|
-
//
|
|
2434
|
+
// Assert result
|
|
2355
2435
|
expect(result).toBeDefined();
|
|
2356
2436
|
expect(result.id).toBeDefined();
|
|
2357
2437
|
expect(result.messageId).toBe('msg1');
|
|
@@ -2372,7 +2452,7 @@ describe('MessageModel', () => {
|
|
|
2372
2452
|
});
|
|
2373
2453
|
|
|
2374
2454
|
it('should create a message query with embeddings ID', async () => {
|
|
2375
|
-
//
|
|
2455
|
+
// Create test data
|
|
2376
2456
|
await serverDB.insert(messages).values({
|
|
2377
2457
|
id: 'msg2',
|
|
2378
2458
|
userId,
|
|
@@ -2388,7 +2468,7 @@ describe('MessageModel', () => {
|
|
|
2388
2468
|
embeddingsId,
|
|
2389
2469
|
});
|
|
2390
2470
|
|
|
2391
|
-
//
|
|
2471
|
+
// Assert result
|
|
2392
2472
|
expect(result).toBeDefined();
|
|
2393
2473
|
expect(result.embeddingsId).toBe(embeddingsId);
|
|
2394
2474
|
|
|
@@ -2402,7 +2482,7 @@ describe('MessageModel', () => {
|
|
|
2402
2482
|
});
|
|
2403
2483
|
|
|
2404
2484
|
it('should generate a unique ID for each message query', async () => {
|
|
2405
|
-
//
|
|
2485
|
+
// Create test data
|
|
2406
2486
|
await serverDB.insert(messages).values({
|
|
2407
2487
|
id: 'msg3',
|
|
2408
2488
|
userId,
|
|
@@ -2425,7 +2505,7 @@ describe('MessageModel', () => {
|
|
|
2425
2505
|
embeddingsId,
|
|
2426
2506
|
});
|
|
2427
2507
|
|
|
2428
|
-
//
|
|
2508
|
+
// Assert result
|
|
2429
2509
|
expect(result1.id).not.toBe(result2.id);
|
|
2430
2510
|
});
|
|
2431
2511
|
});
|
|
@@ -2473,7 +2553,7 @@ describe('MessageModel', () => {
|
|
|
2473
2553
|
|
|
2474
2554
|
describe('deleteMessageQuery', () => {
|
|
2475
2555
|
it('should delete a message query by ID', async () => {
|
|
2476
|
-
//
|
|
2556
|
+
// Create test data
|
|
2477
2557
|
const queryId = uuid();
|
|
2478
2558
|
await serverDB.insert(messages).values({
|
|
2479
2559
|
id: 'msg4',
|
|
@@ -2511,7 +2591,7 @@ describe('MessageModel', () => {
|
|
|
2511
2591
|
});
|
|
2512
2592
|
|
|
2513
2593
|
it('should only delete message queries belonging to the user', async () => {
|
|
2514
|
-
//
|
|
2594
|
+
// Create test data - 其他用户的查询
|
|
2515
2595
|
const queryId = uuid();
|
|
2516
2596
|
await serverDB.insert(messages).values({
|
|
2517
2597
|
id: 'msg5',
|