@lobehub/chat 1.91.0 → 1.91.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/docs/changelog/2023-09-09-plugin-system.mdx +2 -3
- package/docs/changelog/2023-11-14-gpt4-vision.mdx +4 -6
- package/docs/changelog/2023-11-19-tts-stt.mdx +2 -3
- package/docs/changelog/2023-12-22-dalle-3.mdx +2 -5
- package/docs/changelog/2023-12-22-dalle-3.zh-CN.mdx +2 -2
- package/docs/changelog/2024-02-08-sso-oauth.mdx +2 -2
- package/docs/changelog/2024-06-19-lobe-chat-v1.mdx +2 -3
- package/docs/changelog/2024-06-19-lobe-chat-v1.zh-CN.mdx +2 -2
- package/docs/changelog/2024-07-19-gpt-4o-mini.mdx +2 -3
- package/docs/changelog/2024-07-19-gpt-4o-mini.zh-CN.mdx +2 -2
- package/docs/changelog/2024-08-02-lobe-chat-database-docker.mdx +2 -3
- package/docs/changelog/2024-08-21-file-upload-and-knowledge-base.mdx +4 -5
- package/docs/changelog/2024-09-13-openai-o1-models.mdx +2 -2
- package/docs/changelog/2024-09-20-artifacts.mdx +2 -3
- package/docs/changelog/2024-09-20-artifacts.zh-CN.mdx +2 -2
- package/docs/changelog/2024-10-27-pin-assistant.mdx +2 -3
- package/docs/changelog/2024-11-06-share-text-json.mdx +2 -4
- package/docs/changelog/2024-11-06-share-text-json.zh-CN.mdx +2 -2
- package/docs/changelog/2024-11-25-november-providers.mdx +2 -2
- package/docs/changelog/2024-11-27-forkable-chat.mdx +2 -2
- package/docs/changelog/2025-01-03-user-profile.mdx +2 -2
- package/docs/changelog/2025-01-22-new-ai-provider.mdx +2 -2
- package/docs/changelog/2025-02-02-deepseek-r1.mdx +4 -4
- package/docs/development/basic/add-new-authentication-providers.zh-CN.mdx +1 -2
- package/docs/development/basic/chat-api.mdx +2 -4
- package/docs/development/basic/chat-api.zh-CN.mdx +2 -4
- package/docs/development/internationalization/internationalization-implementation.mdx +10 -10
- package/docs/development/internationalization/internationalization-implementation.zh-CN.mdx +10 -10
- package/docs/self-hosting/advanced/analytics.mdx +2 -2
- package/docs/self-hosting/advanced/auth/clerk.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/auth0.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/authelia.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/authentik.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +4 -7
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +0 -3
- package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.mdx +2 -3
- 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 -3
- package/docs/self-hosting/advanced/auth/next-auth/keycloak.mdx +12 -6
- package/docs/self-hosting/advanced/auth/next-auth/keycloak.zh-CN.mdx +5 -1
- package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +8 -14
- package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +6 -12
- package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/wechat.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/zitadel.mdx +2 -3
- package/docs/self-hosting/advanced/auth.mdx +2 -3
- package/docs/self-hosting/advanced/desktop.mdx +2 -1
- package/docs/self-hosting/advanced/desktop.zh-CN.mdx +1 -3
- package/docs/self-hosting/advanced/feature-flags.mdx +2 -3
- package/docs/self-hosting/advanced/knowledge-base.mdx +4 -3
- package/docs/self-hosting/advanced/model-list.mdx +11 -10
- package/docs/self-hosting/advanced/model-list.zh-CN.mdx +10 -9
- package/docs/self-hosting/advanced/observability/langfuse.mdx +2 -3
- package/docs/self-hosting/advanced/online-search.mdx +11 -10
- package/docs/self-hosting/advanced/online-search.zh-CN.mdx +7 -7
- package/docs/self-hosting/advanced/s3/tencent-cloud.mdx +2 -2
- package/docs/self-hosting/advanced/settings-url-share.mdx +2 -3
- package/docs/self-hosting/advanced/upstream-sync.mdx +2 -3
- package/docs/self-hosting/advanced/webrtc.mdx +2 -2
- package/docs/self-hosting/environment-variables/analytics.mdx +2 -3
- package/docs/self-hosting/environment-variables/auth.mdx +2 -3
- package/docs/self-hosting/environment-variables/basic.mdx +4 -5
- package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +2 -2
- package/docs/self-hosting/environment-variables/model-provider.mdx +2 -3
- package/docs/self-hosting/environment-variables/s3.mdx +3 -5
- package/docs/self-hosting/environment-variables.mdx +2 -2
- package/docs/self-hosting/examples/azure-openai.mdx +2 -2
- package/docs/self-hosting/examples/ollama.mdx +2 -3
- package/docs/self-hosting/faq/no-v1-suffix.mdx +4 -4
- package/docs/self-hosting/faq/proxy-with-unable-to-verify-leaf-signature.mdx +2 -3
- package/docs/self-hosting/platform/alibaba-cloud.mdx +2 -3
- package/docs/self-hosting/platform/btpanel.mdx +5 -5
- package/docs/self-hosting/platform/btpanel.zh-CN.mdx +4 -3
- package/docs/self-hosting/platform/docker-compose.mdx +2 -3
- package/docs/self-hosting/platform/docker-compose.zh-CN.mdx +0 -2
- package/docs/self-hosting/platform/docker.mdx +2 -2
- package/docs/self-hosting/platform/netlify.mdx +2 -4
- package/docs/self-hosting/platform/netlify.zh-CN.mdx +2 -2
- package/docs/self-hosting/platform/railway.mdx +2 -3
- package/docs/self-hosting/platform/repocloud.mdx +2 -3
- package/docs/self-hosting/platform/sealos.mdx +2 -2
- package/docs/self-hosting/platform/tencentcloud-lighthouse.mdx +2 -3
- package/docs/self-hosting/platform/vercel.mdx +2 -3
- package/docs/self-hosting/platform/zeabur.mdx +2 -2
- package/docs/self-hosting/server-database/docker-compose.mdx +65 -44
- package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +48 -55
- package/docs/self-hosting/server-database/docker.mdx +2 -2
- package/docs/self-hosting/server-database/docker.zh-CN.mdx +2 -2
- package/docs/self-hosting/server-database/dokploy.mdx +4 -5
- package/docs/self-hosting/server-database/dokploy.zh-CN.mdx +137 -138
- package/docs/self-hosting/server-database/netlify.mdx +2 -2
- package/docs/self-hosting/server-database/netlify.zh-CN.mdx +2 -2
- package/docs/self-hosting/server-database/railway.mdx +2 -2
- package/docs/self-hosting/server-database/repocloud.mdx +2 -2
- package/docs/self-hosting/server-database/sealos.mdx +4 -5
- package/docs/self-hosting/server-database/sealos.zh-CN.mdx +18 -20
- package/docs/self-hosting/server-database/vercel.mdx +5 -3
- package/docs/self-hosting/server-database/vercel.zh-CN.mdx +2 -2
- package/docs/self-hosting/server-database/zeabur.mdx +2 -2
- package/docs/self-hosting/server-database.mdx +1 -1
- package/docs/self-hosting/server-database.zh-CN.mdx +2 -1
- package/docs/self-hosting/start.mdx +2 -2
- package/docs/self-hosting/start.zh-CN.mdx +2 -2
- package/docs/usage/agents/agent-organization.mdx +2 -2
- package/docs/usage/agents/concepts.mdx +4 -5
- package/docs/usage/agents/concepts.zh-CN.mdx +2 -2
- package/docs/usage/agents/custom-agent.mdx +3 -4
- package/docs/usage/agents/custom-agent.zh-CN.mdx +1 -1
- package/docs/usage/agents/model.mdx +5 -5
- package/docs/usage/agents/model.zh-CN.mdx +3 -5
- package/docs/usage/agents/prompt.mdx +4 -5
- package/docs/usage/agents/topics.mdx +3 -4
- package/docs/usage/agents/topics.zh-CN.mdx +1 -1
- package/docs/usage/features/agent-market.mdx +3 -11
- package/docs/usage/features/agent-market.zh-CN.mdx +2 -7
- package/docs/usage/features/artifacts.mdx +2 -2
- package/docs/usage/features/auth.mdx +2 -3
- package/docs/usage/features/cot.mdx +2 -2
- package/docs/usage/features/database.mdx +2 -2
- package/docs/usage/features/knowledge-base.mdx +4 -3
- package/docs/usage/features/knowledge-base.zh-CN.mdx +2 -1
- package/docs/usage/features/local-llm.mdx +2 -3
- package/docs/usage/features/mobile.mdx +2 -2
- package/docs/usage/features/more.mdx +2 -3
- package/docs/usage/features/multi-ai-providers.mdx +2 -3
- package/docs/usage/features/plugin-system.mdx +3 -11
- package/docs/usage/features/plugin-system.zh-CN.mdx +1 -8
- package/docs/usage/features/pwa.mdx +4 -4
- package/docs/usage/features/pwa.zh-CN.mdx +2 -1
- package/docs/usage/features/text-to-image.mdx +3 -11
- package/docs/usage/features/text-to-image.zh-CN.mdx +3 -10
- package/docs/usage/features/theme.mdx +2 -3
- package/docs/usage/features/tts.mdx +3 -11
- package/docs/usage/features/tts.zh-CN.mdx +1 -8
- package/docs/usage/features/vision.mdx +3 -11
- package/docs/usage/features/vision.zh-CN.mdx +1 -8
- package/docs/usage/foundation/basic.mdx +2 -3
- package/docs/usage/foundation/share.mdx +2 -3
- package/docs/usage/foundation/text2image.mdx +2 -2
- package/docs/usage/foundation/translate.mdx +2 -2
- package/docs/usage/foundation/tts-stt.mdx +2 -2
- package/docs/usage/foundation/vision.mdx +2 -3
- package/docs/usage/plugins/basic-usage.mdx +2 -3
- package/docs/usage/plugins/custom-plugin.mdx +2 -2
- package/docs/usage/plugins/development.mdx +2 -4
- package/docs/usage/plugins/store.mdx +2 -2
- package/docs/usage/providers/ai21.mdx +2 -2
- package/docs/usage/providers/anthropic.mdx +2 -3
- package/docs/usage/providers/anthropic.zh-CN.mdx +2 -2
- package/docs/usage/providers/azure.mdx +2 -3
- package/docs/usage/providers/azureai.mdx +4 -2
- package/docs/usage/providers/azureai.zh-CN.mdx +2 -1
- package/docs/usage/providers/baichuan.mdx +2 -3
- package/docs/usage/providers/bedrock.mdx +2 -3
- package/docs/usage/providers/cloudflare.mdx +3 -2
- package/docs/usage/providers/deepseek.mdx +2 -2
- package/docs/usage/providers/fireworksai.mdx +2 -2
- package/docs/usage/providers/giteeai.mdx +2 -2
- package/docs/usage/providers/github.mdx +1 -1
- package/docs/usage/providers/github.zh-CN.mdx +1 -1
- package/docs/usage/providers/google.mdx +2 -3
- package/docs/usage/providers/groq.mdx +2 -2
- package/docs/usage/providers/hunyuan.mdx +2 -2
- package/docs/usage/providers/infiniai.zh-CN.mdx +3 -1
- package/docs/usage/providers/internlm.mdx +2 -2
- package/docs/usage/providers/jina.mdx +4 -3
- package/docs/usage/providers/jina.zh-CN.mdx +2 -2
- package/docs/usage/providers/lmstudio.mdx +2 -2
- package/docs/usage/providers/lmstudio.zh-CN.mdx +2 -4
- package/docs/usage/providers/minimax.mdx +2 -3
- package/docs/usage/providers/minimax.zh-CN.mdx +2 -2
- package/docs/usage/providers/mistral.mdx +2 -3
- package/docs/usage/providers/modelscope.mdx +4 -0
- package/docs/usage/providers/modelscope.zh-CN.mdx +4 -0
- package/docs/usage/providers/moonshot.mdx +2 -3
- package/docs/usage/providers/novita.mdx +2 -3
- package/docs/usage/providers/novita.zh-CN.mdx +2 -2
- package/docs/usage/providers/nvidia.mdx +3 -2
- package/docs/usage/providers/ollama/gemma.mdx +2 -3
- package/docs/usage/providers/ollama/gemma.zh-CN.mdx +2 -2
- package/docs/usage/providers/ollama.mdx +2 -2
- package/docs/usage/providers/openai.mdx +5 -5
- package/docs/usage/providers/openai.zh-CN.mdx +3 -3
- package/docs/usage/providers/openrouter.mdx +2 -3
- package/docs/usage/providers/perplexity.mdx +2 -2
- package/docs/usage/providers/ppio.mdx +5 -6
- package/docs/usage/providers/ppio.zh-CN.mdx +6 -6
- package/docs/usage/providers/qiniu.mdx +6 -6
- package/docs/usage/providers/qiniu.zh-CN.mdx +2 -1
- package/docs/usage/providers/qwen.mdx +2 -4
- package/docs/usage/providers/sambanova.mdx +2 -1
- package/docs/usage/providers/sensenova.mdx +2 -2
- package/docs/usage/providers/siliconcloud.mdx +2 -2
- package/docs/usage/providers/stepfun.mdx +2 -3
- package/docs/usage/providers/taichu.mdx +2 -3
- package/docs/usage/providers/togetherai.mdx +2 -2
- package/docs/usage/providers/vllm.mdx +15 -12
- package/docs/usage/providers/vllm.zh-CN.mdx +9 -7
- package/docs/usage/providers/volcengine.mdx +16 -14
- package/docs/usage/providers/wenxin.mdx +2 -2
- package/docs/usage/providers/xai.mdx +2 -2
- package/docs/usage/providers/zeroone.mdx +2 -3
- package/docs/usage/providers/zeroone.zh-CN.mdx +2 -2
- package/docs/usage/providers/zhipu.mdx +2 -3
- package/docs/usage/providers/zhipu.zh-CN.mdx +1 -1
- package/docs/usage/providers.mdx +2 -3
- package/docs/usage/start.mdx +2 -3
- package/docs/usage/tools-calling/anthropic.mdx +2 -2
- package/docs/usage/tools-calling/anthropic.zh-CN.mdx +2 -2
- package/docs/usage/tools-calling/google.mdx +2 -2
- package/docs/usage/tools-calling/google.zh-CN.mdx +4 -4
- package/docs/usage/tools-calling/groq.zh-CN.mdx +2 -2
- package/docs/usage/tools-calling/openai.mdx +2 -2
- package/docs/usage/tools-calling/openai.zh-CN.mdx +2 -2
- package/package.json +2 -2
- package/src/app/(backend)/middleware/auth/utils.ts +2 -1
- package/src/app/(backend)/webapi/user/avatar/[id]/[image]/route.ts +1 -1
- package/src/app/[variants]/(main)/repos/[id]/_layout/Mobile.tsx +7 -7
- package/src/config/aiModels/deepseek.ts +1 -0
- package/src/config/aiModels/hunyuan.ts +1 -0
- package/src/config/aiModels/mistral.ts +1 -2
- package/src/config/aiModels/novita.ts +23 -22
- package/src/config/aiModels/openrouter.ts +1 -0
- package/src/config/aiModels/qwen.ts +11 -11
- package/src/config/aiModels/siliconcloud.ts +7 -6
- package/src/config/aiModels/vertexai.ts +2 -2
- package/src/config/aiModels/wenxin.ts +1 -2
- package/src/config/modelProviders/baichuan.ts +3 -0
- package/src/config/modelProviders/fireworksai.ts +3 -0
- package/src/config/modelProviders/giteeai.ts +3 -0
- package/src/config/modelProviders/github.ts +1 -2
- package/src/config/modelProviders/groq.ts +0 -3
- package/src/config/modelProviders/hunyuan.ts +3 -0
- package/src/config/modelProviders/infiniai.ts +0 -3
- package/src/config/modelProviders/internlm.ts +3 -0
- package/src/config/modelProviders/minimax.ts +3 -4
- package/src/config/modelProviders/moonshot.ts +0 -7
- package/src/config/modelProviders/novita.ts +3 -0
- package/src/config/modelProviders/openrouter.ts +0 -4
- package/src/config/modelProviders/perplexity.ts +0 -3
- package/src/config/modelProviders/qiniu.ts +0 -3
- package/src/config/modelProviders/qwen.ts +0 -3
- package/src/config/modelProviders/sensenova.ts +3 -0
- package/src/config/modelProviders/siliconcloud.ts +0 -3
- package/src/config/modelProviders/spark.ts +0 -5
- package/src/config/modelProviders/stepfun.ts +3 -6
- package/src/config/modelProviders/taichu.ts +3 -0
- package/src/config/modelProviders/tencentcloud.ts +3 -0
- package/src/config/modelProviders/togetherai.ts +3 -0
- package/src/config/modelProviders/upstage.ts +3 -0
- package/src/config/modelProviders/wenxin.ts +3 -4
- package/src/config/modelProviders/xai.ts +0 -3
- package/src/config/modelProviders/zhipu.ts +3 -0
- package/src/database/migrations/meta/0014_snapshot.json +182 -539
- package/src/database/migrations/meta/0016_snapshot.json +182 -539
- package/src/database/repositories/dataImporter/__tests__/fixtures/with-client-id.json +13 -58
- package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +1 -8
- package/src/features/ChatInput/ActionBar/Model/index.tsx +8 -16
- package/src/features/ChatInput/ActionBar/Search/Controls.tsx +4 -12
- package/src/features/ChatInput/ActionBar/Search/FCSearchModel.tsx +1 -7
- package/src/features/ChatInput/ActionBar/Search/index.tsx +2 -4
- package/src/features/ModelSwitchPanel/index.tsx +1 -4
- package/src/libs/model-runtime/anthropic/index.test.ts +4 -2
- package/src/libs/model-runtime/google/index.ts +30 -40
- package/src/libs/model-runtime/novita/__snapshots__/index.test.ts.snap +19 -1
- package/src/libs/model-runtime/novita/index.ts +14 -15
- package/src/libs/model-runtime/nvidia/index.ts +2 -21
- package/src/libs/model-runtime/openai/__snapshots__/index.test.ts.snap +39 -11
- package/src/libs/model-runtime/openai/index.ts +3 -38
- package/src/libs/model-runtime/openrouter/__snapshots__/index.test.ts.snap +3 -0
- package/src/libs/model-runtime/openrouter/index.ts +45 -54
- package/src/libs/model-runtime/qwen/index.ts +2 -45
- package/src/libs/model-runtime/siliconcloud/index.ts +2 -51
- package/src/libs/model-runtime/utils/modelParse.test.ts +761 -0
- package/src/libs/model-runtime/utils/modelParse.ts +186 -0
- package/src/libs/model-runtime/utils/streams/anthropic.ts +12 -11
- package/src/libs/model-runtime/utils/streams/openai.ts +6 -4
- package/src/libs/model-runtime/utils/streams/protocol.ts +1 -1
- package/src/libs/model-runtime/utils/streams/spark.test.ts +1 -1
- package/src/libs/model-runtime/utils/streams/spark.ts +1 -2
- package/src/libs/model-runtime/volcengine/index.ts +11 -0
- package/src/libs/model-runtime/zeroone/index.ts +2 -23
- package/src/libs/model-runtime/zhipu/index.ts +7 -34
- package/src/middleware.ts +1 -1
- package/src/server/services/user/index.ts +3 -4
- package/src/services/__tests__/assistant.test.ts +4 -6
- package/src/services/__tests__/tool.test.ts +3 -1
- package/src/store/user/slices/auth/selectors.ts +1 -1
- package/src/store/user/slices/common/action.test.ts +1 -1
- package/src/tools/web-browsing/index.ts +1 -7
@@ -0,0 +1,186 @@
|
|
1
|
+
import type { ChatModelCard } from '@/types/llm';
|
2
|
+
|
3
|
+
export interface ModelProcessorConfig {
|
4
|
+
excludeKeywords?: readonly string[]; // 对符合的模型不添加标签
|
5
|
+
functionCallKeywords?: readonly string[];
|
6
|
+
reasoningKeywords?: readonly string[];
|
7
|
+
visionKeywords?: readonly string[];
|
8
|
+
}
|
9
|
+
|
10
|
+
// 模型标签关键词配置
|
11
|
+
export const MODEL_LIST_CONFIGS = {
|
12
|
+
anthropic: {
|
13
|
+
functionCallKeywords: ['claude'],
|
14
|
+
reasoningKeywords: ['-3-7', '3.7', '-4'],
|
15
|
+
visionKeywords: ['claude'],
|
16
|
+
},
|
17
|
+
deepseek: {
|
18
|
+
functionCallKeywords: ['v3', 'r1'],
|
19
|
+
reasoningKeywords: ['r1'],
|
20
|
+
},
|
21
|
+
google: {
|
22
|
+
functionCallKeywords: ['gemini'],
|
23
|
+
reasoningKeywords: ['thinking', '-2.5-'],
|
24
|
+
visionKeywords: ['gemini', 'learnlm'],
|
25
|
+
},
|
26
|
+
llama: {
|
27
|
+
functionCallKeywords: ['llama-3.2', 'llama-3.3', 'llama-4'],
|
28
|
+
reasoningKeywords: [],
|
29
|
+
visionKeywords: [],
|
30
|
+
},
|
31
|
+
openai: {
|
32
|
+
excludeKeywords: ['audio'],
|
33
|
+
functionCallKeywords: ['4o', '4.1', 'o3', 'o4'],
|
34
|
+
reasoningKeywords: ['o1', 'o3', 'o4'],
|
35
|
+
visionKeywords: ['4o', '4.1', 'o4'],
|
36
|
+
},
|
37
|
+
qwen: {
|
38
|
+
functionCallKeywords: [
|
39
|
+
'qwen-max',
|
40
|
+
'qwen-plus',
|
41
|
+
'qwen-turbo',
|
42
|
+
'qwen-long',
|
43
|
+
'qwen1.5',
|
44
|
+
'qwen2',
|
45
|
+
'qwen2.5',
|
46
|
+
'qwen3',
|
47
|
+
],
|
48
|
+
reasoningKeywords: ['qvq', 'qwq', 'qwen3'],
|
49
|
+
visionKeywords: ['qvq', 'vl'],
|
50
|
+
},
|
51
|
+
volcengine: {
|
52
|
+
functionCallKeywords: ['doubao-1.5'],
|
53
|
+
reasoningKeywords: ['thinking', '-r1'],
|
54
|
+
visionKeywords: ['vision', '-m'],
|
55
|
+
},
|
56
|
+
zeroone: {
|
57
|
+
functionCallKeywords: ['fc'],
|
58
|
+
visionKeywords: ['vision'],
|
59
|
+
},
|
60
|
+
zhipu: {
|
61
|
+
functionCallKeywords: ['glm-4', 'glm-z1'],
|
62
|
+
reasoningKeywords: ['glm-zero', 'glm-z1'],
|
63
|
+
visionKeywords: ['glm-4v'],
|
64
|
+
},
|
65
|
+
} as const;
|
66
|
+
|
67
|
+
// 模型提供商关键词配置
|
68
|
+
export const PROVIDER_DETECTION_CONFIG = {
|
69
|
+
anthropic: ['claude'],
|
70
|
+
deepseek: ['deepseek'],
|
71
|
+
google: ['gemini'],
|
72
|
+
llama: ['llama'],
|
73
|
+
openai: ['o1', 'o3', 'o4', 'gpt-'],
|
74
|
+
qwen: ['qwen', 'qwq', 'qvq'],
|
75
|
+
volcengine: ['doubao'],
|
76
|
+
zeroone: ['yi-'],
|
77
|
+
zhipu: ['glm'],
|
78
|
+
} as const;
|
79
|
+
|
80
|
+
/**
|
81
|
+
* 检测单个模型的提供商类型
|
82
|
+
* @param modelId 模型ID
|
83
|
+
* @returns 检测到的提供商配置键名,默认为 'openai'
|
84
|
+
*/
|
85
|
+
export const detectModelProvider = (modelId: string): keyof typeof MODEL_LIST_CONFIGS => {
|
86
|
+
const lowerModelId = modelId.toLowerCase();
|
87
|
+
|
88
|
+
for (const [provider, keywords] of Object.entries(PROVIDER_DETECTION_CONFIG)) {
|
89
|
+
const hasKeyword = keywords.some((keyword) => lowerModelId.includes(keyword));
|
90
|
+
|
91
|
+
if (hasKeyword && provider in MODEL_LIST_CONFIGS) {
|
92
|
+
return provider as keyof typeof MODEL_LIST_CONFIGS;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
return 'openai';
|
97
|
+
};
|
98
|
+
|
99
|
+
/**
|
100
|
+
* 处理模型卡片的通用逻辑
|
101
|
+
*/
|
102
|
+
const processModelCard = (
|
103
|
+
model: { [key: string]: any; id: string },
|
104
|
+
config: ModelProcessorConfig,
|
105
|
+
knownModel?: any,
|
106
|
+
): ChatModelCard => {
|
107
|
+
const {
|
108
|
+
functionCallKeywords = [],
|
109
|
+
visionKeywords = [],
|
110
|
+
reasoningKeywords = [],
|
111
|
+
excludeKeywords = [],
|
112
|
+
} = config;
|
113
|
+
|
114
|
+
const isExcludedModel = excludeKeywords.some((keyword) =>
|
115
|
+
model.id.toLowerCase().includes(keyword),
|
116
|
+
);
|
117
|
+
|
118
|
+
return {
|
119
|
+
contextWindowTokens: model.contextWindowTokens ?? knownModel?.contextWindowTokens ?? undefined,
|
120
|
+
displayName: model.displayName ?? knownModel?.displayName ?? model.id,
|
121
|
+
enabled: knownModel?.enabled || false,
|
122
|
+
functionCall:
|
123
|
+
(functionCallKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)) &&
|
124
|
+
!isExcludedModel) ||
|
125
|
+
knownModel?.abilities?.functionCall ||
|
126
|
+
false,
|
127
|
+
id: model.id,
|
128
|
+
maxOutput: model.maxOutput ?? knownModel?.maxOutput ?? undefined,
|
129
|
+
reasoning:
|
130
|
+
reasoningKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)) ||
|
131
|
+
knownModel?.abilities?.reasoning ||
|
132
|
+
false,
|
133
|
+
vision:
|
134
|
+
(visionKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)) &&
|
135
|
+
!isExcludedModel) ||
|
136
|
+
knownModel?.abilities?.vision ||
|
137
|
+
false,
|
138
|
+
};
|
139
|
+
};
|
140
|
+
|
141
|
+
/**
|
142
|
+
* 处理单一提供商的模型列表
|
143
|
+
* @param modelList 模型列表
|
144
|
+
* @param config 提供商配置
|
145
|
+
* @returns 处理后的模型卡片列表
|
146
|
+
*/
|
147
|
+
export const processModelList = async (
|
148
|
+
modelList: Array<{ id: string }>,
|
149
|
+
config: ModelProcessorConfig,
|
150
|
+
): Promise<ChatModelCard[]> => {
|
151
|
+
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
|
152
|
+
|
153
|
+
return modelList
|
154
|
+
.map((model) => {
|
155
|
+
const knownModel = LOBE_DEFAULT_MODEL_LIST.find(
|
156
|
+
(m) => model.id.toLowerCase() === m.id.toLowerCase(),
|
157
|
+
);
|
158
|
+
|
159
|
+
return processModelCard(model, config, knownModel);
|
160
|
+
})
|
161
|
+
.filter(Boolean);
|
162
|
+
};
|
163
|
+
|
164
|
+
/**
|
165
|
+
* 处理混合提供商的模型列表
|
166
|
+
* @param modelList 模型列表
|
167
|
+
* @returns 处理后的模型卡片列表
|
168
|
+
*/
|
169
|
+
export const processMultiProviderModelList = async (
|
170
|
+
modelList: Array<{ id: string }>,
|
171
|
+
): Promise<ChatModelCard[]> => {
|
172
|
+
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
|
173
|
+
|
174
|
+
return modelList
|
175
|
+
.map((model) => {
|
176
|
+
const detectedProvider = detectModelProvider(model.id);
|
177
|
+
const config = MODEL_LIST_CONFIGS[detectedProvider];
|
178
|
+
|
179
|
+
const knownModel = LOBE_DEFAULT_MODEL_LIST.find(
|
180
|
+
(m) => model.id.toLowerCase() === m.id.toLowerCase(),
|
181
|
+
);
|
182
|
+
|
183
|
+
return processModelCard(model, config, knownModel);
|
184
|
+
})
|
185
|
+
.filter(Boolean);
|
186
|
+
};
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
2
2
|
import type { Stream } from '@anthropic-ai/sdk/streaming';
|
3
3
|
|
4
|
-
import {
|
4
|
+
import { CitationItem, ModelTokensUsage } from '@/types/message';
|
5
5
|
|
6
6
|
import { ChatStreamCallbacks } from '../../types';
|
7
7
|
import {
|
@@ -180,7 +180,7 @@ export const transformAnthropicStream = (
|
|
180
180
|
context.returnedCitationArray.push({
|
181
181
|
title: citations.title,
|
182
182
|
url: citations.url,
|
183
|
-
} as CitationItem)
|
183
|
+
} as CitationItem);
|
184
184
|
}
|
185
185
|
|
186
186
|
return { data: null, id: context.id, type: 'text' };
|
@@ -219,15 +219,16 @@ export const transformAnthropicStream = (
|
|
219
219
|
|
220
220
|
case 'message_stop': {
|
221
221
|
return [
|
222
|
-
...(context.returnedCitationArray?.length
|
223
|
-
? [
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
222
|
+
...(context.returnedCitationArray?.length
|
223
|
+
? [
|
224
|
+
{
|
225
|
+
data: { citations: context.returnedCitationArray },
|
226
|
+
id: context.id,
|
227
|
+
type: 'grounding',
|
228
|
+
},
|
229
|
+
]
|
230
|
+
: []),
|
231
|
+
{ data: 'message_stop', id: context.id, type: 'stop' },
|
231
232
|
] as any;
|
232
233
|
}
|
233
234
|
|
@@ -227,10 +227,12 @@ export const transformOpenAIStream = (
|
|
227
227
|
return [
|
228
228
|
{
|
229
229
|
data: {
|
230
|
-
citations: (citations as any[])
|
231
|
-
|
232
|
-
|
233
|
-
|
230
|
+
citations: (citations as any[])
|
231
|
+
.map((item) => ({
|
232
|
+
title: typeof item === 'string' ? item : item.title,
|
233
|
+
url: typeof item === 'string' ? item : item.url || item.link,
|
234
|
+
}))
|
235
|
+
.filter((c) => c.title && c.url), // Zhipu 内建搜索工具有时会返回空 link 引发程序崩溃
|
234
236
|
},
|
235
237
|
id: chunk.id,
|
236
238
|
type: 'grounding',
|
@@ -18,7 +18,7 @@ export interface StreamContext {
|
|
18
18
|
returnedCitation?: boolean;
|
19
19
|
/**
|
20
20
|
* Claude's citations are inline and interleaved with text output.
|
21
|
-
* Each text segment may carry references to sources (e.g., web search results)
|
21
|
+
* Each text segment may carry references to sources (e.g., web search results)
|
22
22
|
* relevant to that specific portion of the generated content.
|
23
23
|
* This array accumulates all citation items received during the streaming response.
|
24
24
|
*/
|
@@ -2,6 +2,7 @@ import OpenAI from 'openai';
|
|
2
2
|
import type { Stream } from 'openai/streaming';
|
3
3
|
|
4
4
|
import { ChatStreamCallbacks } from '../../types';
|
5
|
+
import { convertUsage } from '../usageConverter';
|
5
6
|
import {
|
6
7
|
StreamProtocolChunk,
|
7
8
|
StreamProtocolToolCallChunk,
|
@@ -11,8 +12,6 @@ import {
|
|
11
12
|
generateToolCallId,
|
12
13
|
} from './protocol';
|
13
14
|
|
14
|
-
import { convertUsage } from '../usageConverter';
|
15
|
-
|
16
15
|
export function transformSparkResponseToStream(data: OpenAI.ChatCompletion) {
|
17
16
|
return new ReadableStream({
|
18
17
|
start(controller) {
|
@@ -1,5 +1,10 @@
|
|
1
1
|
import { ModelProvider } from '../types';
|
2
2
|
import { createOpenAICompatibleRuntime } from '../utils/openaiCompatibleFactory';
|
3
|
+
import { MODEL_LIST_CONFIGS, processModelList } from '../utils/modelParse';
|
4
|
+
|
5
|
+
export interface VolcengineModelCard {
|
6
|
+
id: string;
|
7
|
+
}
|
3
8
|
|
4
9
|
export const LobeVolcengineAI = createOpenAICompatibleRuntime({
|
5
10
|
baseURL: 'https://ark.cn-beijing.volces.com/api/v3',
|
@@ -24,5 +29,11 @@ export const LobeVolcengineAI = createOpenAICompatibleRuntime({
|
|
24
29
|
debug: {
|
25
30
|
chatCompletion: () => process.env.DEBUG_VOLCENGINE_CHAT_COMPLETION === '1',
|
26
31
|
},
|
32
|
+
models: async ({ client }) => {
|
33
|
+
const modelsPage = (await client.models.list()) as any;
|
34
|
+
const modelList: VolcengineModelCard[] = modelsPage.data;
|
35
|
+
|
36
|
+
return processModelList(modelList, MODEL_LIST_CONFIGS.volcengine);
|
37
|
+
},
|
27
38
|
provider: ModelProvider.Volcengine,
|
28
39
|
});
|
@@ -1,6 +1,5 @@
|
|
1
|
-
import type { ChatModelCard } from '@/types/llm';
|
2
|
-
|
3
1
|
import { ModelProvider } from '../types';
|
2
|
+
import { MODEL_LIST_CONFIGS, processModelList } from '../utils/modelParse';
|
4
3
|
import { createOpenAICompatibleRuntime } from '../utils/openaiCompatibleFactory';
|
5
4
|
|
6
5
|
export interface ZeroOneModelCard {
|
@@ -13,30 +12,10 @@ export const LobeZeroOneAI = createOpenAICompatibleRuntime({
|
|
13
12
|
chatCompletion: () => process.env.DEBUG_ZEROONE_CHAT_COMPLETION === '1',
|
14
13
|
},
|
15
14
|
models: async ({ client }) => {
|
16
|
-
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
|
17
|
-
|
18
15
|
const modelsPage = (await client.models.list()) as any;
|
19
16
|
const modelList: ZeroOneModelCard[] = modelsPage.data;
|
20
17
|
|
21
|
-
return modelList
|
22
|
-
.map((model) => {
|
23
|
-
const knownModel = LOBE_DEFAULT_MODEL_LIST.find(
|
24
|
-
(m) => model.id.toLowerCase() === m.id.toLowerCase(),
|
25
|
-
);
|
26
|
-
|
27
|
-
return {
|
28
|
-
contextWindowTokens: knownModel?.contextWindowTokens ?? undefined,
|
29
|
-
displayName: knownModel?.displayName ?? undefined,
|
30
|
-
enabled: knownModel?.enabled || false,
|
31
|
-
functionCall:
|
32
|
-
model.id.toLowerCase().includes('fc') || knownModel?.abilities?.functionCall || false,
|
33
|
-
id: model.id,
|
34
|
-
reasoning: knownModel?.abilities?.reasoning || false,
|
35
|
-
vision:
|
36
|
-
model.id.toLowerCase().includes('vision') || knownModel?.abilities?.vision || false,
|
37
|
-
};
|
38
|
-
})
|
39
|
-
.filter(Boolean) as ChatModelCard[];
|
18
|
+
return processModelList(modelList, MODEL_LIST_CONFIGS.zeroone);
|
40
19
|
},
|
41
20
|
provider: ModelProvider.ZeroOne,
|
42
21
|
});
|
@@ -1,6 +1,5 @@
|
|
1
|
-
import type { ChatModelCard } from '@/types/llm';
|
2
|
-
|
3
1
|
import { ModelProvider } from '../types';
|
2
|
+
import { MODEL_LIST_CONFIGS, processModelList } from '../utils/modelParse';
|
4
3
|
import { createOpenAICompatibleRuntime } from '../utils/openaiCompatibleFactory';
|
5
4
|
|
6
5
|
export interface ZhipuModelCard {
|
@@ -60,10 +59,6 @@ export const LobeZhipuAI = createOpenAICompatibleRuntime({
|
|
60
59
|
chatCompletion: () => process.env.DEBUG_ZHIPU_CHAT_COMPLETION === '1',
|
61
60
|
},
|
62
61
|
models: async ({ client }) => {
|
63
|
-
const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
|
64
|
-
|
65
|
-
const reasoningKeywords = ['glm-zero', 'glm-z1'];
|
66
|
-
|
67
62
|
// ref: https://open.bigmodel.cn/console/modelcenter/square
|
68
63
|
const url = 'https://open.bigmodel.cn/api/fine-tuning/model_center/list?pageSize=100&pageNum=1';
|
69
64
|
const response = await fetch(url, {
|
@@ -78,34 +73,12 @@ export const LobeZhipuAI = createOpenAICompatibleRuntime({
|
|
78
73
|
|
79
74
|
const modelList: ZhipuModelCard[] = json.rows;
|
80
75
|
|
81
|
-
|
82
|
-
.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
return {
|
88
|
-
contextWindowTokens: knownModel?.contextWindowTokens ?? undefined,
|
89
|
-
description: model.description,
|
90
|
-
displayName: model.modelName,
|
91
|
-
enabled: knownModel?.enabled || false,
|
92
|
-
functionCall:
|
93
|
-
(model.modelCode.toLowerCase().includes('glm-4') &&
|
94
|
-
!model.modelCode.toLowerCase().includes('glm-4v')) ||
|
95
|
-
knownModel?.abilities?.functionCall ||
|
96
|
-
false,
|
97
|
-
id: model.modelCode,
|
98
|
-
reasoning:
|
99
|
-
reasoningKeywords.some((keyword) => model.modelCode.toLowerCase().includes(keyword)) ||
|
100
|
-
knownModel?.abilities?.reasoning ||
|
101
|
-
false,
|
102
|
-
vision:
|
103
|
-
model.modelCode.toLowerCase().includes('glm-4v') ||
|
104
|
-
knownModel?.abilities?.vision ||
|
105
|
-
false,
|
106
|
-
};
|
107
|
-
})
|
108
|
-
.filter(Boolean) as ChatModelCard[];
|
76
|
+
const standardModelList = modelList.map((model) => ({
|
77
|
+
description: model.description,
|
78
|
+
displayName: model.modelName,
|
79
|
+
id: model.modelCode,
|
80
|
+
}));
|
81
|
+
return processModelList(standardModelList, MODEL_LIST_CONFIGS.zhipu);
|
109
82
|
},
|
110
83
|
provider: ModelProvider.ZhiPu,
|
111
84
|
});
|
package/src/middleware.ts
CHANGED
@@ -100,16 +100,15 @@ export class UserService {
|
|
100
100
|
const s3 = new S3();
|
101
101
|
const s3FileUrl = `user/avatar/${id}/${image}`;
|
102
102
|
|
103
|
-
try{
|
103
|
+
try {
|
104
104
|
const file = await s3.getFileByteArray(s3FileUrl);
|
105
105
|
if (!file) {
|
106
106
|
return null;
|
107
107
|
}
|
108
108
|
const fileBuffer = Buffer.from(file);
|
109
109
|
return fileBuffer;
|
110
|
-
}
|
111
|
-
catch (error) {
|
110
|
+
} catch (error) {
|
112
111
|
pino.error('Failed to get user avatar:', error);
|
113
112
|
}
|
114
|
-
}
|
113
|
+
};
|
115
114
|
}
|
@@ -36,7 +36,7 @@ describe('AssistantService', () => {
|
|
36
36
|
// Arrange
|
37
37
|
const fakeResponse = { agents: [{ name: 'TestAssisstant' }] };
|
38
38
|
(globalHelpers.getCurrentLanguage as Mock).mockReturnValue('tt');
|
39
|
-
|
39
|
+
|
40
40
|
(edgeClient.market.getAgentIndex.query as Mock).mockResolvedValue(fakeResponse);
|
41
41
|
|
42
42
|
// Act
|
@@ -50,21 +50,19 @@ describe('AssistantService', () => {
|
|
50
50
|
it('should handle fetch error', async () => {
|
51
51
|
// Arrange
|
52
52
|
(globalHelpers.getCurrentLanguage as Mock).mockReturnValue('en');
|
53
|
-
(edgeClient.market.getAgentIndex.query as Mock).mockRejectedValue(
|
54
|
-
new Error('Network error'),
|
55
|
-
);
|
53
|
+
(edgeClient.market.getAgentIndex.query as Mock).mockRejectedValue(new Error('Network error'));
|
56
54
|
|
57
55
|
// Act & Assert
|
58
56
|
await expect(assistantService.getAssistantList()).rejects.toThrow('Network error');
|
59
57
|
});
|
60
58
|
});
|
61
|
-
|
59
|
+
|
62
60
|
describe('getAssistantById', () => {
|
63
61
|
it('should fetch and return the assistant by id', async () => {
|
64
62
|
// Arrange
|
65
63
|
const fakeResponse = { identifier: 'test-assisstant' };
|
66
64
|
(globalHelpers.getCurrentLanguage as Mock).mockReturnValue('tt');
|
67
|
-
|
65
|
+
|
68
66
|
(edgeClient.market.getAgent.query as Mock).mockResolvedValue(fakeResponse);
|
69
67
|
|
70
68
|
// Act
|
@@ -49,7 +49,9 @@ describe('ToolService', () => {
|
|
49
49
|
it('should handle fetch error', async () => {
|
50
50
|
// Arrange
|
51
51
|
(globalHelpers.getCurrentLanguage as Mock).mockReturnValue('en');
|
52
|
-
(edgeClient.market.getPluginIndex.query as Mock).mockRejectedValue(
|
52
|
+
(edgeClient.market.getPluginIndex.query as Mock).mockRejectedValue(
|
53
|
+
new Error('Network error'),
|
54
|
+
);
|
53
55
|
|
54
56
|
// Act & Assert
|
55
57
|
await expect(toolService.getToolList()).rejects.toThrow('Network error');
|
@@ -2,9 +2,9 @@ import { t } from 'i18next';
|
|
2
2
|
|
3
3
|
import { enableAuth, enableClerk, enableNextAuth } from '@/const/auth';
|
4
4
|
import { BRANDING_NAME } from '@/const/branding';
|
5
|
+
import { isDesktop } from '@/const/version';
|
5
6
|
import { UserStore } from '@/store/user';
|
6
7
|
import { LobeUser } from '@/types/user';
|
7
|
-
import { isDesktop } from '@/const/version';
|
8
8
|
|
9
9
|
const DEFAULT_USERNAME = BRANDING_NAME;
|
10
10
|
|
@@ -25,13 +25,7 @@ export const WebBrowsingManifest: BuiltinToolManifest = {
|
|
25
25
|
searchCategories: {
|
26
26
|
description: 'The search categories you can set:',
|
27
27
|
items: {
|
28
|
-
enum: [
|
29
|
-
'general',
|
30
|
-
'images',
|
31
|
-
'news',
|
32
|
-
'science',
|
33
|
-
'videos',
|
34
|
-
],
|
28
|
+
enum: ['general', 'images', 'news', 'science', 'videos'],
|
35
29
|
type: 'string',
|
36
30
|
},
|
37
31
|
type: 'array',
|