@lobehub/chat 1.98.1 → 1.99.0
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/.cursor/rules/backend-architecture.mdc +93 -17
- package/.cursor/rules/cursor-ux.mdc +45 -35
- package/.cursor/rules/project-introduce.mdc +72 -6
- package/.cursor/rules/rules-attach.mdc +16 -7
- package/.eslintrc.js +10 -0
- package/CHANGELOG.md +52 -0
- package/apps/desktop/README.md +7 -0
- package/apps/desktop/electron-builder.js +5 -0
- package/apps/desktop/package.json +2 -1
- package/apps/desktop/src/main/const/dir.ts +3 -0
- package/apps/desktop/src/main/controllers/UploadFileCtr.ts +13 -8
- package/apps/desktop/src/main/core/App.ts +8 -0
- package/apps/desktop/src/main/core/StaticFileServerManager.ts +221 -0
- package/apps/desktop/src/main/services/fileSrv.ts +231 -44
- package/apps/desktop/src/main/utils/next-electron-rsc.ts +36 -5
- package/changelog/v1.json +18 -0
- package/docs/development/database-schema.dbml +70 -0
- package/locales/ar/common.json +2 -0
- package/locales/ar/components.json +35 -0
- package/locales/ar/error.json +2 -0
- package/locales/ar/image.json +100 -0
- package/locales/ar/metadata.json +4 -0
- package/locales/ar/modelProvider.json +1 -0
- package/locales/ar/models.json +51 -9
- package/locales/ar/plugin.json +22 -0
- package/locales/ar/providers.json +3 -0
- package/locales/ar/setting.json +5 -0
- package/locales/bg-BG/common.json +2 -0
- package/locales/bg-BG/components.json +35 -0
- package/locales/bg-BG/error.json +2 -0
- package/locales/bg-BG/image.json +100 -0
- package/locales/bg-BG/metadata.json +4 -0
- package/locales/bg-BG/modelProvider.json +1 -0
- package/locales/bg-BG/models.json +51 -9
- package/locales/bg-BG/plugin.json +22 -0
- package/locales/bg-BG/providers.json +3 -0
- package/locales/bg-BG/setting.json +5 -0
- package/locales/de-DE/common.json +2 -0
- package/locales/de-DE/components.json +35 -0
- package/locales/de-DE/error.json +2 -0
- package/locales/de-DE/image.json +100 -0
- package/locales/de-DE/metadata.json +4 -0
- package/locales/de-DE/modelProvider.json +1 -0
- package/locales/de-DE/models.json +51 -9
- package/locales/de-DE/plugin.json +22 -0
- package/locales/de-DE/providers.json +3 -0
- package/locales/de-DE/setting.json +5 -0
- package/locales/en-US/common.json +2 -0
- package/locales/en-US/components.json +35 -0
- package/locales/en-US/error.json +2 -0
- package/locales/en-US/image.json +100 -0
- package/locales/en-US/metadata.json +4 -0
- package/locales/en-US/modelProvider.json +1 -0
- package/locales/en-US/models.json +51 -9
- package/locales/en-US/plugin.json +22 -0
- package/locales/en-US/providers.json +3 -0
- package/locales/en-US/setting.json +5 -0
- package/locales/es-ES/common.json +2 -0
- package/locales/es-ES/components.json +35 -0
- package/locales/es-ES/error.json +2 -0
- package/locales/es-ES/image.json +100 -0
- package/locales/es-ES/metadata.json +4 -0
- package/locales/es-ES/modelProvider.json +1 -0
- package/locales/es-ES/models.json +51 -9
- package/locales/es-ES/plugin.json +22 -0
- package/locales/es-ES/providers.json +3 -0
- package/locales/es-ES/setting.json +5 -0
- package/locales/fa-IR/common.json +2 -0
- package/locales/fa-IR/components.json +35 -0
- package/locales/fa-IR/error.json +2 -0
- package/locales/fa-IR/image.json +100 -0
- package/locales/fa-IR/metadata.json +4 -0
- package/locales/fa-IR/modelProvider.json +1 -0
- package/locales/fa-IR/models.json +51 -9
- package/locales/fa-IR/plugin.json +22 -0
- package/locales/fa-IR/providers.json +3 -0
- package/locales/fa-IR/setting.json +5 -0
- package/locales/fr-FR/common.json +2 -0
- package/locales/fr-FR/components.json +35 -0
- package/locales/fr-FR/error.json +2 -0
- package/locales/fr-FR/image.json +100 -0
- package/locales/fr-FR/metadata.json +4 -0
- package/locales/fr-FR/modelProvider.json +1 -0
- package/locales/fr-FR/models.json +51 -9
- package/locales/fr-FR/plugin.json +22 -0
- package/locales/fr-FR/providers.json +3 -0
- package/locales/fr-FR/setting.json +5 -0
- package/locales/it-IT/common.json +2 -0
- package/locales/it-IT/components.json +35 -0
- package/locales/it-IT/error.json +2 -0
- package/locales/it-IT/image.json +100 -0
- package/locales/it-IT/metadata.json +4 -0
- package/locales/it-IT/modelProvider.json +1 -0
- package/locales/it-IT/models.json +51 -9
- package/locales/it-IT/plugin.json +22 -0
- package/locales/it-IT/providers.json +3 -0
- package/locales/it-IT/setting.json +5 -0
- package/locales/ja-JP/common.json +2 -0
- package/locales/ja-JP/components.json +35 -0
- package/locales/ja-JP/error.json +2 -0
- package/locales/ja-JP/image.json +100 -0
- package/locales/ja-JP/metadata.json +4 -0
- package/locales/ja-JP/modelProvider.json +1 -0
- package/locales/ja-JP/models.json +51 -9
- package/locales/ja-JP/plugin.json +22 -0
- package/locales/ja-JP/providers.json +3 -0
- package/locales/ja-JP/setting.json +5 -0
- package/locales/ko-KR/common.json +2 -0
- package/locales/ko-KR/components.json +35 -0
- package/locales/ko-KR/error.json +2 -0
- package/locales/ko-KR/image.json +100 -0
- package/locales/ko-KR/metadata.json +4 -0
- package/locales/ko-KR/modelProvider.json +1 -0
- package/locales/ko-KR/models.json +51 -9
- package/locales/ko-KR/plugin.json +22 -0
- package/locales/ko-KR/providers.json +3 -0
- package/locales/ko-KR/setting.json +5 -0
- package/locales/nl-NL/common.json +2 -0
- package/locales/nl-NL/components.json +35 -0
- package/locales/nl-NL/error.json +2 -0
- package/locales/nl-NL/image.json +100 -0
- package/locales/nl-NL/metadata.json +4 -0
- package/locales/nl-NL/modelProvider.json +1 -0
- package/locales/nl-NL/models.json +51 -9
- package/locales/nl-NL/plugin.json +22 -0
- package/locales/nl-NL/providers.json +3 -0
- package/locales/nl-NL/setting.json +5 -0
- package/locales/pl-PL/common.json +2 -0
- package/locales/pl-PL/components.json +35 -0
- package/locales/pl-PL/error.json +2 -0
- package/locales/pl-PL/image.json +100 -0
- package/locales/pl-PL/metadata.json +4 -0
- package/locales/pl-PL/modelProvider.json +1 -0
- package/locales/pl-PL/models.json +51 -9
- package/locales/pl-PL/plugin.json +22 -0
- package/locales/pl-PL/providers.json +3 -0
- package/locales/pl-PL/setting.json +5 -0
- package/locales/pt-BR/common.json +2 -0
- package/locales/pt-BR/components.json +35 -0
- package/locales/pt-BR/error.json +2 -0
- package/locales/pt-BR/image.json +100 -0
- package/locales/pt-BR/metadata.json +4 -0
- package/locales/pt-BR/modelProvider.json +1 -0
- package/locales/pt-BR/models.json +51 -9
- package/locales/pt-BR/plugin.json +22 -0
- package/locales/pt-BR/providers.json +3 -0
- package/locales/pt-BR/setting.json +5 -0
- package/locales/ru-RU/common.json +2 -0
- package/locales/ru-RU/components.json +35 -0
- package/locales/ru-RU/error.json +2 -0
- package/locales/ru-RU/image.json +100 -0
- package/locales/ru-RU/metadata.json +4 -0
- package/locales/ru-RU/modelProvider.json +1 -0
- package/locales/ru-RU/models.json +51 -9
- package/locales/ru-RU/plugin.json +22 -0
- package/locales/ru-RU/providers.json +3 -0
- package/locales/ru-RU/setting.json +5 -0
- package/locales/tr-TR/common.json +2 -0
- package/locales/tr-TR/components.json +35 -0
- package/locales/tr-TR/error.json +2 -0
- package/locales/tr-TR/image.json +100 -0
- package/locales/tr-TR/metadata.json +4 -0
- package/locales/tr-TR/modelProvider.json +1 -0
- package/locales/tr-TR/models.json +51 -9
- package/locales/tr-TR/plugin.json +22 -0
- package/locales/tr-TR/providers.json +3 -0
- package/locales/tr-TR/setting.json +5 -0
- package/locales/vi-VN/common.json +2 -0
- package/locales/vi-VN/components.json +35 -0
- package/locales/vi-VN/error.json +2 -0
- package/locales/vi-VN/image.json +100 -0
- package/locales/vi-VN/metadata.json +4 -0
- package/locales/vi-VN/modelProvider.json +1 -0
- package/locales/vi-VN/models.json +51 -9
- package/locales/vi-VN/plugin.json +22 -0
- package/locales/vi-VN/providers.json +3 -0
- package/locales/vi-VN/setting.json +5 -0
- package/locales/zh-CN/common.json +2 -0
- package/locales/zh-CN/components.json +35 -0
- package/locales/zh-CN/error.json +2 -0
- package/locales/zh-CN/image.json +100 -0
- package/locales/zh-CN/metadata.json +4 -0
- package/locales/zh-CN/modelProvider.json +1 -0
- package/locales/zh-CN/models.json +51 -9
- package/locales/zh-CN/plugin.json +22 -0
- package/locales/zh-CN/providers.json +3 -0
- package/locales/zh-CN/setting.json +5 -0
- package/locales/zh-TW/common.json +2 -0
- package/locales/zh-TW/components.json +35 -0
- package/locales/zh-TW/error.json +2 -0
- package/locales/zh-TW/image.json +100 -0
- package/locales/zh-TW/metadata.json +4 -0
- package/locales/zh-TW/modelProvider.json +1 -0
- package/locales/zh-TW/models.json +51 -9
- package/locales/zh-TW/plugin.json +22 -0
- package/locales/zh-TW/providers.json +3 -0
- package/locales/zh-TW/setting.json +5 -0
- package/package.json +11 -4
- package/packages/electron-server-ipc/src/events/file.ts +3 -1
- package/packages/electron-server-ipc/src/types/file.ts +15 -0
- package/src/app/[variants]/(main)/_layout/Desktop/SideBar/TopActions.tsx +11 -1
- package/src/app/[variants]/(main)/image/@menu/components/AspectRatioSelect/index.tsx +73 -0
- package/src/app/[variants]/(main)/image/@menu/components/SeedNumberInput/index.tsx +39 -0
- package/src/app/[variants]/(main)/image/@menu/components/SizeSelect/index.tsx +89 -0
- package/src/app/[variants]/(main)/image/@menu/default.tsx +11 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/AspectRatioSelect.tsx +24 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/DimensionControlGroup.tsx +107 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ImageNum.tsx +290 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ImageUpload.tsx +504 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ImageUrl.tsx +18 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ImageUrlsUpload.tsx +19 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ModelSelect.tsx +155 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/MultiImagesUpload/ImageManageModal.tsx +415 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/MultiImagesUpload/index.tsx +732 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/SeedNumberInput.tsx +24 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/SizeSelect.tsx +17 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/SizeSliderInput.tsx +15 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/StepsSliderInput.tsx +11 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/constants.ts +1 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/index.tsx +93 -0
- package/src/app/[variants]/(main)/image/@topic/default.tsx +17 -0
- package/src/app/[variants]/(main)/image/@topic/features/Topics/NewTopicButton.tsx +64 -0
- package/src/app/[variants]/(main)/image/@topic/features/Topics/SkeletonList.tsx +34 -0
- package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicItem.tsx +136 -0
- package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicItemContainer.tsx +91 -0
- package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicList.tsx +57 -0
- package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicUrlSync.tsx +37 -0
- package/src/app/[variants]/(main)/image/@topic/features/Topics/index.tsx +19 -0
- package/src/app/[variants]/(main)/image/NotSupportClient.tsx +153 -0
- package/src/app/[variants]/(main)/image/_layout/Desktop/Container.tsx +35 -0
- package/src/app/[variants]/(main)/image/_layout/Desktop/RegisterHotkeys.tsx +10 -0
- package/src/app/[variants]/(main)/image/_layout/Desktop/index.tsx +30 -0
- package/src/app/[variants]/(main)/image/_layout/Mobile/index.tsx +14 -0
- package/src/app/[variants]/(main)/image/_layout/type.ts +7 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/BatchItem.tsx +196 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/ActionButtons.tsx +60 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/ElapsedTime.tsx +90 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/ErrorState.tsx +65 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/LoadingState.tsx +43 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/SuccessState.tsx +49 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/index.tsx +156 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/styles.ts +51 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/types.ts +39 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/utils.ts +11 -0
- package/src/app/[variants]/(main)/image/features/GenerationFeed/index.tsx +97 -0
- package/src/app/[variants]/(main)/image/features/ImageWorkspace/Content.tsx +48 -0
- package/src/app/[variants]/(main)/image/features/ImageWorkspace/EmptyState.tsx +37 -0
- package/src/app/[variants]/(main)/image/features/ImageWorkspace/SkeletonList.tsx +50 -0
- package/src/app/[variants]/(main)/image/features/ImageWorkspace/index.tsx +23 -0
- package/src/app/[variants]/(main)/image/features/PromptInput/Title.tsx +38 -0
- package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +114 -0
- package/src/app/[variants]/(main)/image/layout.tsx +19 -0
- package/src/app/[variants]/(main)/image/loading.tsx +3 -0
- package/src/app/[variants]/(main)/image/page.tsx +47 -0
- package/src/app/[variants]/(main)/settings/system-agent/index.tsx +2 -1
- package/src/chains/summaryGenerationTitle.ts +25 -0
- package/src/components/ImageItem/index.tsx +9 -6
- package/src/{features/Conversation/Error → components/InvalidAPIKey}/APIKeyForm/Bedrock.tsx +3 -4
- package/src/{features/Conversation/Error → components/InvalidAPIKey}/APIKeyForm/ProviderApiKeyForm.tsx +5 -4
- package/src/components/InvalidAPIKey/APIKeyForm/index.tsx +108 -0
- package/src/{features/Conversation/Error → components/InvalidAPIKey}/APIKeyForm/useApiKey.ts +2 -1
- package/src/components/InvalidAPIKey/index.tsx +30 -0
- package/src/components/KeyValueEditor/index.tsx +203 -0
- package/src/components/KeyValueEditor/utils.ts +42 -0
- package/src/config/aiModels/fal.ts +52 -0
- package/src/config/aiModels/index.ts +3 -0
- package/src/config/aiModels/openai.ts +20 -6
- package/src/config/llm.ts +6 -0
- package/src/config/modelProviders/fal.ts +21 -0
- package/src/config/modelProviders/index.ts +3 -0
- package/src/config/paramsSchemas/fal/flux-kontext-dev.ts +8 -0
- package/src/config/paramsSchemas/fal/flux-pro-kontext.ts +11 -0
- package/src/config/paramsSchemas/fal/flux-schnell.ts +9 -0
- package/src/config/paramsSchemas/fal/imagen4.ts +10 -0
- package/src/config/paramsSchemas/openai/gpt-image-1.ts +10 -0
- package/src/const/hotkeys.ts +2 -2
- package/src/const/image.ts +6 -0
- package/src/const/settings/systemAgent.ts +1 -0
- package/src/database/client/migrations.json +27 -0
- package/src/database/migrations/0026_add_autovacuum_tuning.sql +2 -0
- package/src/database/migrations/0027_ai_image.sql +47 -0
- package/src/database/migrations/meta/0027_snapshot.json +6003 -0
- package/src/database/migrations/meta/_journal.json +7 -0
- package/src/database/models/__tests__/asyncTask.test.ts +7 -5
- package/src/database/models/__tests__/file.test.ts +287 -0
- package/src/database/models/__tests__/generation.test.ts +786 -0
- package/src/database/models/__tests__/generationBatch.test.ts +614 -0
- package/src/database/models/__tests__/generationTopic.test.ts +411 -0
- package/src/database/models/aiModel.ts +2 -0
- package/src/database/models/asyncTask.ts +1 -1
- package/src/database/models/file.ts +28 -20
- package/src/database/models/generation.ts +197 -0
- package/src/database/models/generationBatch.ts +212 -0
- package/src/database/models/generationTopic.ts +131 -0
- package/src/database/repositories/aiInfra/index.test.ts +151 -1
- package/src/database/repositories/aiInfra/index.ts +28 -19
- package/src/database/repositories/tableViewer/index.test.ts +1 -1
- package/src/database/schemas/file.ts +8 -0
- package/src/database/schemas/generation.ts +127 -0
- package/src/database/schemas/index.ts +1 -0
- package/src/database/schemas/relations.ts +45 -1
- package/src/database/type.ts +2 -0
- package/src/database/utils/idGenerator.ts +3 -0
- package/src/features/Conversation/Error/ChatInvalidApiKey.tsx +39 -0
- package/src/features/Conversation/Error/InvalidAccessCode.tsx +2 -2
- package/src/features/Conversation/Error/index.tsx +3 -3
- package/src/features/ImageSidePanel/index.tsx +83 -0
- package/src/features/ImageTopicPanel/index.tsx +79 -0
- package/src/features/PluginDevModal/MCPManifestForm/CollapsibleSection.tsx +62 -0
- package/src/features/PluginDevModal/MCPManifestForm/QuickImportSection.tsx +158 -0
- package/src/features/PluginDevModal/MCPManifestForm/index.tsx +99 -155
- package/src/features/PluginStore/McpList/Detail/Settings/index.tsx +5 -2
- package/src/hooks/useDownloadImage.ts +31 -0
- package/src/hooks/useFetchGenerationTopics.ts +13 -0
- package/src/hooks/useHotkeys/imageScope.ts +48 -0
- package/src/libs/mcp/client.ts +55 -22
- package/src/libs/mcp/types.ts +42 -6
- package/src/libs/model-runtime/BaseAI.ts +3 -1
- package/src/libs/model-runtime/ModelRuntime.test.ts +80 -0
- package/src/libs/model-runtime/ModelRuntime.ts +15 -1
- package/src/libs/model-runtime/UniformRuntime/index.ts +4 -1
- package/src/libs/model-runtime/fal/index.test.ts +442 -0
- package/src/libs/model-runtime/fal/index.ts +88 -0
- package/src/libs/model-runtime/openai/index.test.ts +396 -2
- package/src/libs/model-runtime/openai/index.ts +129 -3
- package/src/libs/model-runtime/runtimeMap.ts +2 -0
- package/src/libs/model-runtime/types/image.ts +25 -0
- package/src/libs/model-runtime/types/type.ts +1 -0
- package/src/libs/model-runtime/utils/openaiCompatibleFactory/index.ts +10 -0
- package/src/libs/standard-parameters/index.ts +1 -0
- package/src/libs/standard-parameters/meta-schema.test.ts +214 -0
- package/src/libs/standard-parameters/meta-schema.ts +147 -0
- package/src/libs/swr/index.ts +1 -0
- package/src/libs/trpc/async/asyncAuth.ts +29 -8
- package/src/libs/trpc/async/context.ts +42 -4
- package/src/libs/trpc/async/index.ts +17 -4
- package/src/libs/trpc/async/init.ts +8 -0
- package/src/libs/trpc/client/lambda.ts +19 -2
- package/src/locales/default/common.ts +2 -0
- package/src/locales/default/components.ts +35 -0
- package/src/locales/default/error.ts +2 -0
- package/src/locales/default/image.ts +100 -0
- package/src/locales/default/index.ts +2 -0
- package/src/locales/default/metadata.ts +4 -0
- package/src/locales/default/modelProvider.ts +2 -0
- package/src/locales/default/plugin.ts +22 -0
- package/src/locales/default/setting.ts +5 -0
- package/src/middleware.ts +1 -0
- package/src/server/modules/ElectronIPCClient/index.ts +9 -1
- package/src/server/modules/S3/index.ts +15 -0
- package/src/server/routers/async/caller.ts +9 -1
- package/src/server/routers/async/image.ts +253 -0
- package/src/server/routers/async/index.ts +2 -0
- package/src/server/routers/lambda/aiProvider.test.ts +1 -0
- package/src/server/routers/lambda/generation.test.ts +267 -0
- package/src/server/routers/lambda/generation.ts +86 -0
- package/src/server/routers/lambda/generationBatch.test.ts +376 -0
- package/src/server/routers/lambda/generationBatch.ts +56 -0
- package/src/server/routers/lambda/generationTopic.test.ts +508 -0
- package/src/server/routers/lambda/generationTopic.ts +93 -0
- package/src/server/routers/lambda/image.ts +248 -0
- package/src/server/routers/lambda/index.ts +8 -0
- package/src/server/routers/tools/mcp.ts +15 -0
- package/src/server/services/file/__tests__/index.test.ts +135 -0
- package/src/server/services/file/impls/local.test.ts +153 -52
- package/src/server/services/file/impls/local.ts +70 -46
- package/src/server/services/file/impls/s3.test.ts +114 -0
- package/src/server/services/file/impls/s3.ts +40 -0
- package/src/server/services/file/impls/type.ts +10 -0
- package/src/server/services/file/index.ts +14 -0
- package/src/server/services/generation/index.ts +239 -0
- package/src/server/services/mcp/index.ts +20 -2
- package/src/services/__tests__/generation.test.ts +40 -0
- package/src/services/__tests__/generationBatch.test.ts +36 -0
- package/src/services/__tests__/generationTopic.test.ts +72 -0
- package/src/services/electron/file.ts +3 -1
- package/src/services/generation.ts +16 -0
- package/src/services/generationBatch.ts +25 -0
- package/src/services/generationTopic.ts +28 -0
- package/src/services/image.ts +33 -0
- package/src/services/mcp.ts +12 -7
- package/src/services/upload.ts +43 -9
- package/src/store/aiInfra/slices/aiProvider/action.ts +25 -5
- package/src/store/aiInfra/slices/aiProvider/initialState.ts +1 -0
- package/src/store/aiInfra/slices/aiProvider/selectors.ts +3 -0
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +5 -5
- package/src/store/chat/slices/message/action.ts +2 -2
- package/src/store/chat/slices/translate/action.ts +1 -1
- package/src/store/global/initialState.ts +9 -0
- package/src/store/global/selectors/systemStatus.ts +8 -0
- package/src/store/image/index.ts +2 -0
- package/src/store/image/initialState.ts +25 -0
- package/src/store/image/selectors.ts +4 -0
- package/src/store/image/slices/createImage/action.test.ts +330 -0
- package/src/store/image/slices/createImage/action.ts +134 -0
- package/src/store/image/slices/createImage/initialState.ts +9 -0
- package/src/store/image/slices/createImage/selectors.test.ts +114 -0
- package/src/store/image/slices/createImage/selectors.ts +9 -0
- package/src/store/image/slices/generationBatch/action.test.ts +495 -0
- package/src/store/image/slices/generationBatch/action.ts +303 -0
- package/src/store/image/slices/generationBatch/initialState.ts +13 -0
- package/src/store/image/slices/generationBatch/reducer.test.ts +568 -0
- package/src/store/image/slices/generationBatch/reducer.ts +101 -0
- package/src/store/image/slices/generationBatch/selectors.test.ts +307 -0
- package/src/store/image/slices/generationBatch/selectors.ts +36 -0
- package/src/store/image/slices/generationConfig/action.test.ts +351 -0
- package/src/store/image/slices/generationConfig/action.ts +295 -0
- package/src/store/image/slices/generationConfig/hooks.test.ts +304 -0
- package/src/store/image/slices/generationConfig/hooks.ts +118 -0
- package/src/store/image/slices/generationConfig/index.ts +1 -0
- package/src/store/image/slices/generationConfig/initialState.ts +37 -0
- package/src/store/image/slices/generationConfig/selectors.test.ts +204 -0
- package/src/store/image/slices/generationConfig/selectors.ts +25 -0
- package/src/store/image/slices/generationTopic/action.test.ts +687 -0
- package/src/store/image/slices/generationTopic/action.ts +319 -0
- package/src/store/image/slices/generationTopic/index.ts +2 -0
- package/src/store/image/slices/generationTopic/initialState.ts +14 -0
- package/src/store/image/slices/generationTopic/reducer.test.ts +198 -0
- package/src/store/image/slices/generationTopic/reducer.ts +66 -0
- package/src/store/image/slices/generationTopic/selectors.test.ts +103 -0
- package/src/store/image/slices/generationTopic/selectors.ts +15 -0
- package/src/store/image/store.ts +42 -0
- package/src/store/image/utils/size.ts +51 -0
- package/src/store/tool/slices/customPlugin/action.ts +10 -1
- package/src/store/tool/slices/mcpStore/action.ts +6 -4
- package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +4 -0
- package/src/store/user/slices/settings/selectors/systemAgent.ts +2 -0
- package/src/types/aiModel.ts +8 -3
- package/src/types/aiProvider.ts +1 -0
- package/src/types/asyncTask.ts +2 -0
- package/src/types/files/index.ts +5 -0
- package/src/types/generation/index.ts +80 -0
- package/src/types/hotkey.ts +2 -0
- package/src/types/plugins/mcp.ts +2 -6
- package/src/types/tool/plugin.ts +8 -0
- package/src/types/user/settings/keyVaults.ts +5 -0
- package/src/types/user/settings/systemAgent.ts +1 -0
- package/src/utils/client/downloadFile.ts +33 -4
- package/src/utils/number.test.ts +105 -0
- package/src/utils/number.ts +25 -0
- package/src/utils/server/__tests__/geo.test.ts +6 -3
- package/src/utils/storeDebug.test.ts +152 -0
- package/src/utils/storeDebug.ts +16 -7
- package/src/utils/time.test.ts +259 -0
- package/src/utils/time.ts +18 -0
- package/src/utils/units.ts +61 -0
- package/src/utils/url.test.ts +358 -9
- package/src/utils/url.ts +105 -3
- package/{vitest.server.config.ts → vitest.config.server.ts} +3 -0
- package/.cursor/rules/i18n/i18n-auto-attached.mdc +0 -6
- package/src/features/Conversation/Error/APIKeyForm/index.tsx +0 -105
- package/src/features/Conversation/Error/InvalidAPIKey.tsx +0 -16
- package/src/features/PluginDevModal/MCPManifestForm/EnvEditor.tsx +0 -227
- /package/.cursor/rules/{i18n/i18n.mdc → i18n.mdc} +0 -0
- /package/src/app/[variants]/(main)/settings/system-agent/features/{createForm.tsx → SystemAgentForm.tsx} +0 -0
- /package/src/{features/Conversation/Error → components/InvalidAPIKey}/APIKeyForm/LoadingContext.ts +0 -0
@@ -0,0 +1,203 @@
|
|
1
|
+
import { ActionIcon, Icon } from '@lobehub/ui';
|
2
|
+
import { Button } from 'antd';
|
3
|
+
import { createStyles } from 'antd-style';
|
4
|
+
import fastDeepEqual from 'fast-deep-equal';
|
5
|
+
import { LucidePlus, LucideTrash } from 'lucide-react';
|
6
|
+
import { memo, useEffect, useRef, useState } from 'react';
|
7
|
+
import { useTranslation } from 'react-i18next';
|
8
|
+
import { Flexbox } from 'react-layout-kit';
|
9
|
+
import { v4 as uuidv4 } from 'uuid';
|
10
|
+
|
11
|
+
import { FormInput } from '@/components/FormInput';
|
12
|
+
|
13
|
+
import { KeyValueItem, localListToRecord, recordToLocalList } from './utils';
|
14
|
+
|
15
|
+
const useStyles = createStyles(({ css, token }) => ({
|
16
|
+
container: css`
|
17
|
+
position: relative;
|
18
|
+
|
19
|
+
width: 100%;
|
20
|
+
padding: 12px;
|
21
|
+
border: 1px solid ${token.colorBorderSecondary};
|
22
|
+
border-radius: ${token.borderRadiusLG}px;
|
23
|
+
`,
|
24
|
+
input: css`
|
25
|
+
font-family: ${token.fontFamilyCode};
|
26
|
+
font-size: 12px;
|
27
|
+
`,
|
28
|
+
row: css`
|
29
|
+
margin-block-end: 8px;
|
30
|
+
|
31
|
+
&:last-child {
|
32
|
+
margin-block-end: 0;
|
33
|
+
}
|
34
|
+
`,
|
35
|
+
title: css`
|
36
|
+
margin-block-end: 8px;
|
37
|
+
color: ${token.colorTextTertiary};
|
38
|
+
`,
|
39
|
+
}));
|
40
|
+
|
41
|
+
export interface KeyValueEditorProps {
|
42
|
+
addButtonText?: string;
|
43
|
+
deleteTooltip?: string;
|
44
|
+
duplicateKeyErrorText?: string;
|
45
|
+
keyPlaceholder?: string;
|
46
|
+
onChange?: (value: Record<string, string>) => void;
|
47
|
+
value?: Record<string, string>;
|
48
|
+
valuePlaceholder?: string;
|
49
|
+
}
|
50
|
+
|
51
|
+
const KeyValueEditor = memo<KeyValueEditorProps>(
|
52
|
+
({
|
53
|
+
value,
|
54
|
+
onChange,
|
55
|
+
keyPlaceholder,
|
56
|
+
valuePlaceholder,
|
57
|
+
addButtonText,
|
58
|
+
duplicateKeyErrorText,
|
59
|
+
deleteTooltip,
|
60
|
+
}) => {
|
61
|
+
const { styles } = useStyles();
|
62
|
+
const { t } = useTranslation('components');
|
63
|
+
const [items, setItems] = useState<KeyValueItem[]>(() => recordToLocalList(value));
|
64
|
+
const prevValueRef = useRef<Record<string, string> | undefined>(undefined);
|
65
|
+
|
66
|
+
useEffect(() => {
|
67
|
+
const externalRecord = value || {};
|
68
|
+
if (!fastDeepEqual(externalRecord, prevValueRef.current)) {
|
69
|
+
setItems(recordToLocalList(externalRecord));
|
70
|
+
prevValueRef.current = externalRecord;
|
71
|
+
}
|
72
|
+
}, [value]);
|
73
|
+
|
74
|
+
const triggerChange = (newItems: KeyValueItem[]) => {
|
75
|
+
const keysCount: Record<string, number> = {};
|
76
|
+
newItems.forEach((item) => {
|
77
|
+
const trimmedKey = item.key.trim();
|
78
|
+
if (trimmedKey) {
|
79
|
+
keysCount[trimmedKey] = (keysCount[trimmedKey] || 0) + 1;
|
80
|
+
}
|
81
|
+
});
|
82
|
+
setItems(
|
83
|
+
newItems.map((item) => ({
|
84
|
+
...item,
|
85
|
+
})),
|
86
|
+
);
|
87
|
+
onChange?.(localListToRecord(newItems));
|
88
|
+
};
|
89
|
+
|
90
|
+
const handleAdd = () => {
|
91
|
+
const newItems = [...items, { id: uuidv4(), key: '', value: '' }];
|
92
|
+
triggerChange(newItems);
|
93
|
+
};
|
94
|
+
|
95
|
+
const handleRemove = (id: string) => {
|
96
|
+
const newItems = items.filter((item) => item.id !== id);
|
97
|
+
triggerChange(newItems);
|
98
|
+
};
|
99
|
+
|
100
|
+
const handleKeyChange = (id: string, newKey: string) => {
|
101
|
+
const newItems = items.map((item) => (item.id === id ? { ...item, key: newKey } : item));
|
102
|
+
triggerChange(newItems);
|
103
|
+
};
|
104
|
+
|
105
|
+
const handleValueChange = (id: string, newValue: string) => {
|
106
|
+
const newItems = items.map((item) => (item.id === id ? { ...item, value: newValue } : item));
|
107
|
+
triggerChange(newItems);
|
108
|
+
};
|
109
|
+
|
110
|
+
const getDuplicateKeys = (currentItems: KeyValueItem[]): Set<string> => {
|
111
|
+
const keys = new Set<string>();
|
112
|
+
const duplicates = new Set<string>();
|
113
|
+
currentItems.forEach((item) => {
|
114
|
+
const trimmedKey = item.key.trim();
|
115
|
+
if (trimmedKey) {
|
116
|
+
if (keys.has(trimmedKey)) {
|
117
|
+
duplicates.add(trimmedKey);
|
118
|
+
} else {
|
119
|
+
keys.add(trimmedKey);
|
120
|
+
}
|
121
|
+
}
|
122
|
+
});
|
123
|
+
return duplicates;
|
124
|
+
};
|
125
|
+
const duplicateKeys = getDuplicateKeys(items);
|
126
|
+
|
127
|
+
return (
|
128
|
+
<div className={styles.container}>
|
129
|
+
<Flexbox className={styles.title} gap={8} horizontal>
|
130
|
+
<Flexbox flex={1}>{keyPlaceholder || t('KeyValueEditor.keyPlaceholder')}</Flexbox>
|
131
|
+
<Flexbox flex={2}>{valuePlaceholder || t('KeyValueEditor.valuePlaceholder')}</Flexbox>
|
132
|
+
<Flexbox style={{ width: 30 }} />
|
133
|
+
</Flexbox>
|
134
|
+
<Flexbox width={'100%'}>
|
135
|
+
{items.map((item) => {
|
136
|
+
const isDuplicate = item.key.trim() && duplicateKeys.has(item.key.trim());
|
137
|
+
return (
|
138
|
+
<Flexbox
|
139
|
+
align="flex-start"
|
140
|
+
className={styles.row}
|
141
|
+
gap={8}
|
142
|
+
horizontal
|
143
|
+
key={item.id}
|
144
|
+
width={'100%'}
|
145
|
+
>
|
146
|
+
<Flexbox flex={1} style={{ position: 'relative' }}>
|
147
|
+
<FormInput
|
148
|
+
className={styles.input}
|
149
|
+
onChange={(e) => handleKeyChange(item.id, e)}
|
150
|
+
placeholder={keyPlaceholder || t('KeyValueEditor.keyPlaceholder')}
|
151
|
+
status={isDuplicate ? 'error' : undefined}
|
152
|
+
value={item.key}
|
153
|
+
variant={'filled'}
|
154
|
+
/>
|
155
|
+
{isDuplicate && (
|
156
|
+
<div
|
157
|
+
style={{
|
158
|
+
bottom: '-16px',
|
159
|
+
color: 'red',
|
160
|
+
fontSize: '12px',
|
161
|
+
position: 'absolute',
|
162
|
+
}}
|
163
|
+
>
|
164
|
+
{duplicateKeyErrorText || t('KeyValueEditor.duplicateKeyError')}
|
165
|
+
</div>
|
166
|
+
)}
|
167
|
+
</Flexbox>
|
168
|
+
<Flexbox flex={2}>
|
169
|
+
<FormInput
|
170
|
+
className={styles.input}
|
171
|
+
onChange={(value) => handleValueChange(item.id, value)}
|
172
|
+
placeholder={valuePlaceholder || t('KeyValueEditor.valuePlaceholder')}
|
173
|
+
value={item.value}
|
174
|
+
variant={'filled'}
|
175
|
+
/>
|
176
|
+
</Flexbox>
|
177
|
+
<ActionIcon
|
178
|
+
icon={LucideTrash}
|
179
|
+
onClick={() => handleRemove(item.id)}
|
180
|
+
size={'small'}
|
181
|
+
style={{ marginTop: 4 }}
|
182
|
+
title={deleteTooltip || t('KeyValueEditor.deleteTooltip')}
|
183
|
+
/>
|
184
|
+
</Flexbox>
|
185
|
+
);
|
186
|
+
})}
|
187
|
+
<Button
|
188
|
+
block
|
189
|
+
icon={<Icon icon={LucidePlus} />}
|
190
|
+
onClick={handleAdd}
|
191
|
+
size={'small'}
|
192
|
+
style={{ marginTop: items.length > 0 ? 16 : 8 }}
|
193
|
+
type="dashed"
|
194
|
+
>
|
195
|
+
{addButtonText || t('KeyValueEditor.addButton')}
|
196
|
+
</Button>
|
197
|
+
</Flexbox>
|
198
|
+
</div>
|
199
|
+
);
|
200
|
+
},
|
201
|
+
);
|
202
|
+
|
203
|
+
export default KeyValueEditor;
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
2
|
+
|
3
|
+
export interface KeyValueItem {
|
4
|
+
id: string;
|
5
|
+
key: string;
|
6
|
+
value: string;
|
7
|
+
}
|
8
|
+
|
9
|
+
export const recordToLocalList = (
|
10
|
+
record: Record<string, string> | undefined | null = {},
|
11
|
+
): KeyValueItem[] =>
|
12
|
+
Object.entries(record || {}).map(([key, val]) => ({
|
13
|
+
id: uuidv4(),
|
14
|
+
key,
|
15
|
+
value: typeof val === 'string' ? val : '',
|
16
|
+
}));
|
17
|
+
|
18
|
+
export const localListToRecord = (
|
19
|
+
list: KeyValueItem[] | undefined | null = [],
|
20
|
+
): Record<string, string> => {
|
21
|
+
const record: Record<string, string> = {};
|
22
|
+
const keys = new Set<string>();
|
23
|
+
(list || [])
|
24
|
+
.slice()
|
25
|
+
.reverse()
|
26
|
+
.forEach((item) => {
|
27
|
+
const trimmedKey = item.key.trim();
|
28
|
+
if (trimmedKey && !keys.has(trimmedKey)) {
|
29
|
+
record[trimmedKey] = typeof item.value === 'string' ? item.value : '';
|
30
|
+
keys.add(trimmedKey);
|
31
|
+
}
|
32
|
+
});
|
33
|
+
return Object.keys(record)
|
34
|
+
.reverse()
|
35
|
+
.reduce(
|
36
|
+
(acc, key) => {
|
37
|
+
acc[key] = record[key];
|
38
|
+
return acc;
|
39
|
+
},
|
40
|
+
{} as Record<string, string>,
|
41
|
+
);
|
42
|
+
};
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import { AIImageModelCard } from '@/types/aiModel';
|
2
|
+
|
3
|
+
import { fluxKontextDevParamsSchema } from '../paramsSchemas/fal/flux-kontext-dev';
|
4
|
+
import { fluxProKontextParamsSchema } from '../paramsSchemas/fal/flux-pro-kontext';
|
5
|
+
import { fluxSchnellParamsSchema } from '../paramsSchemas/fal/flux-schnell';
|
6
|
+
import { imagen4ParamsSchema } from '../paramsSchemas/fal/imagen4';
|
7
|
+
|
8
|
+
const falImageModels: AIImageModelCard[] = [
|
9
|
+
{
|
10
|
+
description: 'Frontier image editing model.',
|
11
|
+
displayName: 'FLUX.1 Kontext Dev',
|
12
|
+
enabled: true,
|
13
|
+
id: 'flux-kontext/dev',
|
14
|
+
parameters: fluxKontextDevParamsSchema,
|
15
|
+
releasedAt: '2025-06-28',
|
16
|
+
type: 'image',
|
17
|
+
},
|
18
|
+
{
|
19
|
+
description:
|
20
|
+
'FLUX.1 Kontext [pro] 能够处理文本和参考图像作为输入,无缝实现目标性的局部编辑和复杂的整体场景变换。',
|
21
|
+
displayName: 'FLUX.1 Kontext [pro]',
|
22
|
+
enabled: true,
|
23
|
+
id: 'flux-pro/kontext',
|
24
|
+
parameters: fluxProKontextParamsSchema,
|
25
|
+
releasedAt: '2025-05-01',
|
26
|
+
type: 'image',
|
27
|
+
},
|
28
|
+
{
|
29
|
+
description:
|
30
|
+
'FLUX.1 [schnell] 是一个拥有120亿参数的流式转换器模型,能够在1到4步内从文本生成高质量图像,适合个人和商业用途。',
|
31
|
+
displayName: 'FLUX.1 Schnell',
|
32
|
+
enabled: true,
|
33
|
+
id: 'flux/schnell',
|
34
|
+
parameters: fluxSchnellParamsSchema,
|
35
|
+
releasedAt: '2024-08-01',
|
36
|
+
type: 'image',
|
37
|
+
},
|
38
|
+
{
|
39
|
+
description: 'Google 最高质量的图像生成模型',
|
40
|
+
displayName: 'Imagen 4',
|
41
|
+
enabled: true,
|
42
|
+
id: 'imagen4/preview',
|
43
|
+
organization: 'Deepmind',
|
44
|
+
parameters: imagen4ParamsSchema,
|
45
|
+
releasedAt: '2025-05-21',
|
46
|
+
type: 'image',
|
47
|
+
},
|
48
|
+
];
|
49
|
+
|
50
|
+
export const allModels = [...falImageModels];
|
51
|
+
|
52
|
+
export default allModels;
|
@@ -10,6 +10,7 @@ import { default as bedrock } from './bedrock';
|
|
10
10
|
import { default as cloudflare } from './cloudflare';
|
11
11
|
import { default as cohere } from './cohere';
|
12
12
|
import { default as deepseek } from './deepseek';
|
13
|
+
import { default as fal } from './fal';
|
13
14
|
import { default as fireworksai } from './fireworksai';
|
14
15
|
import { default as giteeai } from './giteeai';
|
15
16
|
import { default as github } from './github';
|
@@ -85,6 +86,7 @@ export const LOBE_DEFAULT_MODEL_LIST = buildDefaultModelList({
|
|
85
86
|
cloudflare,
|
86
87
|
cohere,
|
87
88
|
deepseek,
|
89
|
+
fal,
|
88
90
|
fireworksai,
|
89
91
|
giteeai,
|
90
92
|
github,
|
@@ -141,6 +143,7 @@ export { default as bedrock } from './bedrock';
|
|
141
143
|
export { default as cloudflare } from './cloudflare';
|
142
144
|
export { default as cohere } from './cohere';
|
143
145
|
export { default as deepseek } from './deepseek';
|
146
|
+
export { default as fal } from './fal';
|
144
147
|
export { default as fireworksai } from './fireworksai';
|
145
148
|
export { default as giteeai } from './giteeai';
|
146
149
|
export { default as github } from './github';
|
@@ -1,10 +1,11 @@
|
|
1
|
+
import { gptImage1ParamsSchema } from '@/config/paramsSchemas/openai/gpt-image-1';
|
1
2
|
import {
|
2
3
|
AIChatModelCard,
|
3
4
|
AIEmbeddingModelCard,
|
5
|
+
AIImageModelCard,
|
4
6
|
AIRealtimeModelCard,
|
5
7
|
AISTTModelCard,
|
6
8
|
AITTSModelCard,
|
7
|
-
AIText2ImageModelCard,
|
8
9
|
} from '@/types/aiModel';
|
9
10
|
|
10
11
|
export const openaiChatModels: AIChatModelCard[] = [
|
@@ -691,7 +692,8 @@ export const openaiChatModels: AIChatModelCard[] = [
|
|
691
692
|
vision: true,
|
692
693
|
},
|
693
694
|
contextWindowTokens: 200_000,
|
694
|
-
description:
|
695
|
+
description:
|
696
|
+
'codex-mini-latest 是 o4-mini 的微调版本,专门用于 Codex CLI。对于直接通过 API 使用,我们推荐从 gpt-4.1 开始。',
|
695
697
|
displayName: 'Codex mini',
|
696
698
|
id: 'codex-mini-latest',
|
697
699
|
maxOutput: 100_000,
|
@@ -713,7 +715,8 @@ export const openaiChatModels: AIChatModelCard[] = [
|
|
713
715
|
vision: true,
|
714
716
|
},
|
715
717
|
contextWindowTokens: 8192,
|
716
|
-
description:
|
718
|
+
description:
|
719
|
+
'computer-use-preview 模型是专为“计算机使用工具”设计的专用模型,经过训练以理解并执行计算机相关任务。',
|
717
720
|
displayName: 'Computer Use Preview',
|
718
721
|
id: 'computer-use-preview',
|
719
722
|
maxOutput: 1024,
|
@@ -804,7 +807,8 @@ export const openaiSTTModels: AISTTModelCard[] = [
|
|
804
807
|
},
|
805
808
|
{
|
806
809
|
contextWindowTokens: 16_000,
|
807
|
-
description:
|
810
|
+
description:
|
811
|
+
'GPT-4o Transcribe 是一种使用 GPT-4o 转录音频的语音转文本模型。与原始 Whisper 模型相比,它提高了单词错误率,并提高了语言识别和准确性。使用它来获得更准确的转录。',
|
808
812
|
displayName: 'GPT-4o Transcribe',
|
809
813
|
id: 'gpt-4o-transcribe',
|
810
814
|
maxOutput: 2000,
|
@@ -816,7 +820,8 @@ export const openaiSTTModels: AISTTModelCard[] = [
|
|
816
820
|
},
|
817
821
|
{
|
818
822
|
contextWindowTokens: 16_000,
|
819
|
-
description:
|
823
|
+
description:
|
824
|
+
'GPT-4o Mini Transcribe 是一种使用 GPT-4o 转录音频的语音转文本模型。与原始 Whisper 模型相比,它提高了单词错误率,并提高了语言识别和准确性。使用它来获得更准确的转录。',
|
820
825
|
displayName: 'GPT-4o Mini Transcribe',
|
821
826
|
id: 'gpt-4o-mini-transcribe',
|
822
827
|
maxOutput: 2000,
|
@@ -829,7 +834,7 @@ export const openaiSTTModels: AISTTModelCard[] = [
|
|
829
834
|
];
|
830
835
|
|
831
836
|
// 图像生成模型
|
832
|
-
export const openaiImageModels:
|
837
|
+
export const openaiImageModels: AIImageModelCard[] = [
|
833
838
|
{
|
834
839
|
description:
|
835
840
|
'最新的 DALL·E 模型,于2023年11月发布。支持更真实、准确的图像生成,具有更强的细节表现力',
|
@@ -852,6 +857,15 @@ export const openaiImageModels: AIText2ImageModelCard[] = [
|
|
852
857
|
resolutions: ['256x256', '512x512', '1024x1024'],
|
853
858
|
type: 'image',
|
854
859
|
},
|
860
|
+
// https://platform.openai.com/docs/models/gpt-image-1
|
861
|
+
{
|
862
|
+
description: 'ChatGPT 原生多模态图片生成模型',
|
863
|
+
displayName: 'GPT Image 1',
|
864
|
+
enabled: true,
|
865
|
+
id: 'gpt-image-1',
|
866
|
+
parameters: gptImage1ParamsSchema,
|
867
|
+
type: 'image',
|
868
|
+
},
|
855
869
|
];
|
856
870
|
|
857
871
|
// GPT-4o 和 GPT-4o-mini 实时模型
|
package/src/config/llm.ts
CHANGED
@@ -163,6 +163,9 @@ export const getLLMConfig = () => {
|
|
163
163
|
ENABLED_INFINIAI: z.boolean(),
|
164
164
|
INFINIAI_API_KEY: z.string().optional(),
|
165
165
|
|
166
|
+
ENABLED_FAL: z.boolean(),
|
167
|
+
FAL_API_KEY: z.string().optional(),
|
168
|
+
|
166
169
|
ENABLED_MODELSCOPE: z.boolean(),
|
167
170
|
MODELSCOPE_API_KEY: z.string().optional(),
|
168
171
|
|
@@ -329,6 +332,9 @@ export const getLLMConfig = () => {
|
|
329
332
|
ENABLED_INFINIAI: !!process.env.INFINIAI_API_KEY,
|
330
333
|
INFINIAI_API_KEY: process.env.INFINIAI_API_KEY,
|
331
334
|
|
335
|
+
ENABLED_FAL: process.env.ENABLED_FAL !== '0',
|
336
|
+
FAL_API_KEY: process.env.FAL_API_KEY,
|
337
|
+
|
332
338
|
ENABLED_MODELSCOPE: !!process.env.MODELSCOPE_API_KEY,
|
333
339
|
MODELSCOPE_API_KEY: process.env.MODELSCOPE_API_KEY,
|
334
340
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { ModelProviderCard } from '@/types/llm';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* @see https://fal.ai/models/fal-ai/flux/schnell
|
5
|
+
*/
|
6
|
+
const Fal: ModelProviderCard = {
|
7
|
+
chatModels: [],
|
8
|
+
description: '面向开发者的生成式媒体平台',
|
9
|
+
enabled: true,
|
10
|
+
id: 'fal',
|
11
|
+
name: 'Fal',
|
12
|
+
settings: {
|
13
|
+
disableBrowserRequest: true,
|
14
|
+
showAddNewModel: false,
|
15
|
+
showChecker: false,
|
16
|
+
showModelFetcher: false,
|
17
|
+
},
|
18
|
+
url: 'https://fal.ai',
|
19
|
+
};
|
20
|
+
|
21
|
+
export default Fal;
|
@@ -10,6 +10,7 @@ import BedrockProvider from './bedrock';
|
|
10
10
|
import CloudflareProvider from './cloudflare';
|
11
11
|
import CohereProvider from './cohere';
|
12
12
|
import DeepSeekProvider from './deepseek';
|
13
|
+
import FalProvider from './fal';
|
13
14
|
import FireworksAIProvider from './fireworksai';
|
14
15
|
import GiteeAIProvider from './giteeai';
|
15
16
|
import GithubProvider from './github';
|
@@ -123,6 +124,7 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [
|
|
123
124
|
DeepSeekProvider,
|
124
125
|
HuggingFaceProvider,
|
125
126
|
OpenRouterProvider,
|
127
|
+
FalProvider,
|
126
128
|
CloudflareProvider,
|
127
129
|
GithubProvider,
|
128
130
|
NovitaProvider,
|
@@ -185,6 +187,7 @@ export { default as BedrockProviderCard } from './bedrock';
|
|
185
187
|
export { default as CloudflareProviderCard } from './cloudflare';
|
186
188
|
export { default as CohereProviderCard } from './cohere';
|
187
189
|
export { default as DeepSeekProviderCard } from './deepseek';
|
190
|
+
export { default as FalProviderCard } from './fal';
|
188
191
|
export { default as FireworksAIProviderCard } from './fireworksai';
|
189
192
|
export { default as GiteeAIProviderCard } from './giteeai';
|
190
193
|
export { default as GithubProviderCard } from './github';
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
+
|
3
|
+
export const fluxKontextDevParamsSchema: ModelParamsSchema = {
|
4
|
+
imageUrl: { default: null },
|
5
|
+
prompt: { default: '' },
|
6
|
+
seed: { default: null },
|
7
|
+
steps: { default: 28, max: 50, min: 10 },
|
8
|
+
};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
+
|
3
|
+
export const fluxProKontextParamsSchema: ModelParamsSchema = {
|
4
|
+
aspectRatio: {
|
5
|
+
default: '1:1',
|
6
|
+
enum: ['21:9', '16:9', '4:3', '3:2', '1:1', '2:3', '3:4', '9:16', '9:21'],
|
7
|
+
},
|
8
|
+
imageUrl: { default: null },
|
9
|
+
prompt: { default: '' },
|
10
|
+
seed: { default: null },
|
11
|
+
};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
+
|
3
|
+
export const fluxSchnellParamsSchema: ModelParamsSchema = {
|
4
|
+
height: { default: 1024, max: 1536, min: 512, step: 1 },
|
5
|
+
prompt: { default: '' },
|
6
|
+
seed: { default: null },
|
7
|
+
steps: { default: 4, max: 12, min: 1 },
|
8
|
+
width: { default: 1024, max: 1536, min: 512, step: 1 },
|
9
|
+
};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
+
|
3
|
+
export const imagen4ParamsSchema: ModelParamsSchema = {
|
4
|
+
aspectRatio: {
|
5
|
+
default: '1:1',
|
6
|
+
enum: ['1:1', '16:9', '9:16', '3:4', '4:3'],
|
7
|
+
},
|
8
|
+
prompt: { default: '' },
|
9
|
+
seed: { default: null },
|
10
|
+
};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { type ModelParamsSchema } from '@/libs/standard-parameters/meta-schema';
|
2
|
+
|
3
|
+
export const gptImage1ParamsSchema: ModelParamsSchema = {
|
4
|
+
imageUrls: { default: [] },
|
5
|
+
prompt: { default: '' },
|
6
|
+
size: {
|
7
|
+
default: 'auto',
|
8
|
+
enum: ['auto', '1024x1024', '1536x1024', '1024x1536'],
|
9
|
+
},
|
10
|
+
};
|
package/src/const/hotkeys.ts
CHANGED
@@ -41,13 +41,13 @@ export const HOTKEYS_REGISTRATION: HotkeyRegistration = [
|
|
41
41
|
group: HotkeyGroupEnum.Essential,
|
42
42
|
id: HotkeyEnum.ToggleLeftPanel,
|
43
43
|
keys: combineKeys([KeyEnum.Mod, KeyEnum.BracketLeft]),
|
44
|
-
scopes: [HotkeyScopeEnum.Chat, HotkeyScopeEnum.Files],
|
44
|
+
scopes: [HotkeyScopeEnum.Chat, HotkeyScopeEnum.Files, HotkeyScopeEnum.Image],
|
45
45
|
},
|
46
46
|
{
|
47
47
|
group: HotkeyGroupEnum.Essential,
|
48
48
|
id: HotkeyEnum.ToggleRightPanel,
|
49
49
|
keys: combineKeys([KeyEnum.Mod, KeyEnum.BracketRight]),
|
50
|
-
scopes: [HotkeyScopeEnum.Chat],
|
50
|
+
scopes: [HotkeyScopeEnum.Chat, HotkeyScopeEnum.Image],
|
51
51
|
},
|
52
52
|
{
|
53
53
|
group: HotkeyGroupEnum.Essential,
|
@@ -22,6 +22,7 @@ export const DEFAULT_QUERY_REWRITE_SYSTEM_AGENT_ITEM: QueryRewriteSystemAgent =
|
|
22
22
|
|
23
23
|
export const DEFAULT_SYSTEM_AGENT_CONFIG: UserSystemAgentConfig = {
|
24
24
|
agentMeta: DEFAULT_SYSTEM_AGENT_ITEM,
|
25
|
+
generationTopic: DEFAULT_SYSTEM_AGENT_ITEM,
|
25
26
|
historyCompress: DEFAULT_SYSTEM_AGENT_ITEM,
|
26
27
|
queryRewrite: DEFAULT_QUERY_REWRITE_SYSTEM_AGENT_ITEM,
|
27
28
|
thread: DEFAULT_SYSTEM_AGENT_ITEM,
|
@@ -514,5 +514,32 @@
|
|
514
514
|
"bps": true,
|
515
515
|
"folderMillis": 1749309388370,
|
516
516
|
"hash": "39cea379f08ee4cb944875c0b67f7791387b508c2d47958bb4cd501ed1ef33eb"
|
517
|
+
},
|
518
|
+
{
|
519
|
+
"sql": [
|
520
|
+
"-- Migration to apply specific autovacuum settings to high-traffic tables\n-- This is crucial to prevent table and TOAST bloat for 'embeddings' and 'chunks'\n-- https://github.com/lobehub/lobe-chat/issues/8316\n\n-- Tuning for the 'embeddings' table\n-- Default scale factor (0.2) is too high, leading to infrequent vacuuming.\n-- Lowering to 2% to ensure frequent cleanup.\nALTER TABLE \"embeddings\" SET (autovacuum_vacuum_scale_factor = 0.02, autovacuum_vacuum_threshold = 1000);\n\n",
|
521
|
+
"\n\n-- Tuning for the 'chunks' table\n-- This table also experiences many updates/deletes and requires similar tuning.\nALTER TABLE \"chunks\" SET (autovacuum_vacuum_scale_factor = 0.02, autovacuum_vacuum_threshold = 1000);\n"
|
522
|
+
],
|
523
|
+
"bps": true,
|
524
|
+
"folderMillis": 1752212281564,
|
525
|
+
"hash": "e445db851f792aac49482e04689569a37939f7d0a3851cbcdf10dc24e8943b2c"
|
526
|
+
},
|
527
|
+
{
|
528
|
+
"sql": [
|
529
|
+
"CREATE TABLE \"generation_batches\" (\n\t\"id\" text PRIMARY KEY NOT NULL,\n\t\"user_id\" text NOT NULL,\n\t\"generation_topic_id\" text NOT NULL,\n\t\"provider\" text NOT NULL,\n\t\"model\" text NOT NULL,\n\t\"prompt\" text NOT NULL,\n\t\"width\" integer,\n\t\"height\" integer,\n\t\"ratio\" varchar(64),\n\t\"config\" jsonb,\n\t\"accessed_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"created_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"updated_at\" timestamp with time zone DEFAULT now() NOT NULL\n);\n",
|
530
|
+
"\nCREATE TABLE \"generation_topics\" (\n\t\"id\" text PRIMARY KEY NOT NULL,\n\t\"user_id\" text NOT NULL,\n\t\"title\" text,\n\t\"cover_url\" text,\n\t\"accessed_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"created_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"updated_at\" timestamp with time zone DEFAULT now() NOT NULL\n);\n",
|
531
|
+
"\nCREATE TABLE \"generations\" (\n\t\"id\" text PRIMARY KEY NOT NULL,\n\t\"user_id\" text NOT NULL,\n\t\"generation_batch_id\" varchar(64) NOT NULL,\n\t\"async_task_id\" uuid,\n\t\"file_id\" text,\n\t\"seed\" integer,\n\t\"asset\" jsonb,\n\t\"accessed_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"created_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"updated_at\" timestamp with time zone DEFAULT now() NOT NULL\n);\n",
|
532
|
+
"\nALTER TABLE \"files\" ADD COLUMN \"source\" text;",
|
533
|
+
"\nALTER TABLE \"generation_batches\" ADD CONSTRAINT \"generation_batches_user_id_users_id_fk\" FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\") ON DELETE cascade ON UPDATE no action;",
|
534
|
+
"\nALTER TABLE \"generation_batches\" ADD CONSTRAINT \"generation_batches_generation_topic_id_generation_topics_id_fk\" FOREIGN KEY (\"generation_topic_id\") REFERENCES \"public\".\"generation_topics\"(\"id\") ON DELETE cascade ON UPDATE no action;",
|
535
|
+
"\nALTER TABLE \"generation_topics\" ADD CONSTRAINT \"generation_topics_user_id_users_id_fk\" FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\") ON DELETE cascade ON UPDATE no action;",
|
536
|
+
"\nALTER TABLE \"generations\" ADD CONSTRAINT \"generations_user_id_users_id_fk\" FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\") ON DELETE cascade ON UPDATE no action;",
|
537
|
+
"\nALTER TABLE \"generations\" ADD CONSTRAINT \"generations_generation_batch_id_generation_batches_id_fk\" FOREIGN KEY (\"generation_batch_id\") REFERENCES \"public\".\"generation_batches\"(\"id\") ON DELETE cascade ON UPDATE no action;",
|
538
|
+
"\nALTER TABLE \"generations\" ADD CONSTRAINT \"generations_async_task_id_async_tasks_id_fk\" FOREIGN KEY (\"async_task_id\") REFERENCES \"public\".\"async_tasks\"(\"id\") ON DELETE set null ON UPDATE no action;",
|
539
|
+
"\nALTER TABLE \"generations\" ADD CONSTRAINT \"generations_file_id_files_id_fk\" FOREIGN KEY (\"file_id\") REFERENCES \"public\".\"files\"(\"id\") ON DELETE cascade ON UPDATE no action;"
|
540
|
+
],
|
541
|
+
"bps": true,
|
542
|
+
"folderMillis": 1752413805765,
|
543
|
+
"hash": "abed92b1356df6d7eb35c03f47fbbdcdaf25aefda750dc3e4963c1c2a0d38b54"
|
517
544
|
}
|
518
545
|
]
|
@@ -7,6 +7,8 @@
|
|
7
7
|
-- Lowering to 2% to ensure frequent cleanup.
|
8
8
|
ALTER TABLE "embeddings" SET (autovacuum_vacuum_scale_factor = 0.02, autovacuum_vacuum_threshold = 1000);
|
9
9
|
|
10
|
+
--> statement-breakpoint
|
11
|
+
|
10
12
|
-- Tuning for the 'chunks' table
|
11
13
|
-- This table also experiences many updates/deletes and requires similar tuning.
|
12
14
|
ALTER TABLE "chunks" SET (autovacuum_vacuum_scale_factor = 0.02, autovacuum_vacuum_threshold = 1000);
|
@@ -0,0 +1,47 @@
|
|
1
|
+
CREATE TABLE "generation_batches" (
|
2
|
+
"id" text PRIMARY KEY NOT NULL,
|
3
|
+
"user_id" text NOT NULL,
|
4
|
+
"generation_topic_id" text NOT NULL,
|
5
|
+
"provider" text NOT NULL,
|
6
|
+
"model" text NOT NULL,
|
7
|
+
"prompt" text NOT NULL,
|
8
|
+
"width" integer,
|
9
|
+
"height" integer,
|
10
|
+
"ratio" varchar(64),
|
11
|
+
"config" jsonb,
|
12
|
+
"accessed_at" timestamp with time zone DEFAULT now() NOT NULL,
|
13
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
14
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
15
|
+
);
|
16
|
+
--> statement-breakpoint
|
17
|
+
CREATE TABLE "generation_topics" (
|
18
|
+
"id" text PRIMARY KEY NOT NULL,
|
19
|
+
"user_id" text NOT NULL,
|
20
|
+
"title" text,
|
21
|
+
"cover_url" text,
|
22
|
+
"accessed_at" timestamp with time zone DEFAULT now() NOT NULL,
|
23
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
24
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
25
|
+
);
|
26
|
+
--> statement-breakpoint
|
27
|
+
CREATE TABLE "generations" (
|
28
|
+
"id" text PRIMARY KEY NOT NULL,
|
29
|
+
"user_id" text NOT NULL,
|
30
|
+
"generation_batch_id" varchar(64) NOT NULL,
|
31
|
+
"async_task_id" uuid,
|
32
|
+
"file_id" text,
|
33
|
+
"seed" integer,
|
34
|
+
"asset" jsonb,
|
35
|
+
"accessed_at" timestamp with time zone DEFAULT now() NOT NULL,
|
36
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
37
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
38
|
+
);
|
39
|
+
--> statement-breakpoint
|
40
|
+
ALTER TABLE "files" ADD COLUMN "source" text;--> statement-breakpoint
|
41
|
+
ALTER TABLE "generation_batches" ADD CONSTRAINT "generation_batches_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
42
|
+
ALTER TABLE "generation_batches" ADD CONSTRAINT "generation_batches_generation_topic_id_generation_topics_id_fk" FOREIGN KEY ("generation_topic_id") REFERENCES "public"."generation_topics"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
43
|
+
ALTER TABLE "generation_topics" ADD CONSTRAINT "generation_topics_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
44
|
+
ALTER TABLE "generations" ADD CONSTRAINT "generations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
45
|
+
ALTER TABLE "generations" ADD CONSTRAINT "generations_generation_batch_id_generation_batches_id_fk" FOREIGN KEY ("generation_batch_id") REFERENCES "public"."generation_batches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
46
|
+
ALTER TABLE "generations" ADD CONSTRAINT "generations_async_task_id_async_tasks_id_fk" FOREIGN KEY ("async_task_id") REFERENCES "public"."async_tasks"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
47
|
+
ALTER TABLE "generations" ADD CONSTRAINT "generations_file_id_files_id_fk" FOREIGN KEY ("file_id") REFERENCES "public"."files"("id") ON DELETE cascade ON UPDATE no action;
|