@lobehub/chat 1.21.16 → 1.22.1
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 +58 -0
- package/README.zh-CN.md +8 -6
- package/docs/usage/providers/wenxin.mdx +4 -3
- package/docs/usage/providers/wenxin.zh-CN.mdx +4 -3
- package/locales/ar/error.json +1 -0
- package/locales/ar/modelProvider.json +7 -0
- package/locales/ar/models.json +18 -6
- package/locales/ar/providers.json +3 -0
- package/locales/bg-BG/error.json +1 -0
- package/locales/bg-BG/modelProvider.json +7 -0
- package/locales/bg-BG/models.json +18 -6
- package/locales/bg-BG/providers.json +3 -0
- package/locales/de-DE/error.json +1 -0
- package/locales/de-DE/modelProvider.json +7 -0
- package/locales/de-DE/models.json +18 -6
- package/locales/de-DE/providers.json +3 -0
- package/locales/en-US/error.json +1 -0
- package/locales/en-US/modelProvider.json +7 -0
- package/locales/en-US/models.json +18 -6
- package/locales/en-US/providers.json +3 -0
- package/locales/es-ES/error.json +1 -0
- package/locales/es-ES/modelProvider.json +7 -0
- package/locales/es-ES/models.json +18 -6
- package/locales/es-ES/providers.json +3 -0
- package/locales/fr-FR/error.json +1 -0
- package/locales/fr-FR/modelProvider.json +7 -0
- package/locales/fr-FR/models.json +17 -5
- package/locales/fr-FR/providers.json +3 -0
- package/locales/it-IT/error.json +1 -0
- package/locales/it-IT/modelProvider.json +7 -0
- package/locales/it-IT/models.json +18 -6
- package/locales/it-IT/providers.json +3 -0
- package/locales/ja-JP/error.json +1 -0
- package/locales/ja-JP/modelProvider.json +7 -0
- package/locales/ja-JP/models.json +18 -6
- package/locales/ja-JP/providers.json +3 -0
- package/locales/ko-KR/error.json +1 -0
- package/locales/ko-KR/modelProvider.json +7 -0
- package/locales/ko-KR/models.json +17 -5
- package/locales/ko-KR/providers.json +3 -0
- package/locales/nl-NL/error.json +1 -0
- package/locales/nl-NL/modelProvider.json +7 -0
- package/locales/nl-NL/models.json +17 -5
- package/locales/nl-NL/providers.json +3 -0
- package/locales/pl-PL/error.json +1 -0
- package/locales/pl-PL/modelProvider.json +7 -0
- package/locales/pl-PL/models.json +18 -6
- package/locales/pl-PL/providers.json +3 -0
- package/locales/pt-BR/error.json +1 -0
- package/locales/pt-BR/modelProvider.json +7 -0
- package/locales/pt-BR/models.json +18 -6
- package/locales/pt-BR/providers.json +3 -0
- package/locales/ru-RU/error.json +1 -0
- package/locales/ru-RU/modelProvider.json +7 -0
- package/locales/ru-RU/models.json +18 -6
- package/locales/ru-RU/providers.json +3 -0
- package/locales/tr-TR/error.json +1 -0
- package/locales/tr-TR/modelProvider.json +7 -0
- package/locales/tr-TR/models.json +18 -6
- package/locales/tr-TR/providers.json +3 -0
- package/locales/vi-VN/error.json +1 -0
- package/locales/vi-VN/modelProvider.json +7 -0
- package/locales/vi-VN/models.json +18 -6
- package/locales/vi-VN/providers.json +3 -0
- package/locales/zh-CN/error.json +2 -1
- package/locales/zh-CN/modelProvider.json +8 -1
- package/locales/zh-CN/models.json +16 -4
- package/locales/zh-CN/providers.json +3 -0
- package/locales/zh-TW/error.json +1 -0
- package/locales/zh-TW/modelProvider.json +7 -0
- package/locales/zh-TW/models.json +16 -4
- package/locales/zh-TW/providers.json +3 -0
- package/package.json +5 -3
- package/src/app/(main)/settings/llm/ProviderList/HuggingFace/index.tsx +53 -0
- package/src/app/(main)/settings/llm/ProviderList/providers.tsx +12 -1
- package/src/config/llm.ts +10 -0
- package/src/config/modelProviders/huggingface.ts +50 -0
- package/src/config/modelProviders/index.ts +4 -0
- package/src/const/settings/llm.ts +5 -0
- package/src/features/Conversation/Error/index.tsx +1 -0
- package/src/libs/agent-runtime/AgentRuntime.ts +7 -0
- package/src/libs/agent-runtime/error.ts +1 -0
- package/src/libs/agent-runtime/groq/index.ts +1 -1
- package/src/libs/agent-runtime/huggingface/index.ts +48 -0
- package/src/libs/agent-runtime/siliconcloud/index.ts +8 -0
- package/src/libs/agent-runtime/types/type.ts +1 -0
- package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +58 -20
- package/src/libs/agent-runtime/utils/streams/openai.test.ts +78 -7
- package/src/libs/agent-runtime/utils/streams/openai.ts +38 -5
- package/src/libs/agent-runtime/utils/streams/protocol.ts +63 -4
- package/src/locales/default/error.ts +2 -2
- package/src/locales/default/modelProvider.ts +8 -1
- package/src/server/globalConfig/index.ts +12 -1
- package/src/server/modules/AgentRuntime/index.ts +10 -0
- package/src/services/_url.ts +4 -5
- package/src/types/user/settings/keyVaults.ts +1 -0
- /package/src/app/(backend)/{api → webapi}/chat/[provider]/route.test.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/[provider]/route.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/anthropic/route.test.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/anthropic/route.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/google/route.test.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/google/route.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/minimax/route.test.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/minimax/route.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/models/[provider]/route.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/openai/route.test.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/openai/route.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/wenxin/route.test.ts +0 -0
- /package/src/app/(backend)/{api → webapi}/chat/wenxin/route.ts +0 -0
@@ -458,6 +458,9 @@
|
|
458
458
|
"google/gemma-2-27b-it": {
|
459
459
|
"description": "Gemma 2 延續了輕量化與高效的設計理念。"
|
460
460
|
},
|
461
|
+
"google/gemma-2-2b-it": {
|
462
|
+
"description": "Google的輕量級指令調優模型"
|
463
|
+
},
|
461
464
|
"google/gemma-2-9b-it": {
|
462
465
|
"description": "Gemma 2 是 Google 輕量化的開源文本模型系列。"
|
463
466
|
},
|
@@ -589,6 +592,12 @@
|
|
589
592
|
"llama-3.1-sonar-small-128k-online": {
|
590
593
|
"description": "Llama 3.1 Sonar Small Online 模型,具備 8B 參數,支持約 127,000 個標記的上下文長度,專為在線聊天設計,能高效處理各種文本交互。"
|
591
594
|
},
|
595
|
+
"llama-3.2-11b-vision-preview": {
|
596
|
+
"description": "Llama 3.2 旨在處理結合視覺和文本數據的任務。它在圖像描述和視覺問答等任務中表現出色,跨越了語言生成和視覺推理之間的鴻溝。"
|
597
|
+
},
|
598
|
+
"llama-3.2-90b-vision-preview": {
|
599
|
+
"description": "Llama 3.2 旨在處理結合視覺和文本數據的任務。它在圖像描述和視覺問答等任務中表現出色,跨越了語言生成和視覺推理之間的鴻溝。"
|
600
|
+
},
|
592
601
|
"llama3-70b-8192": {
|
593
602
|
"description": "Meta Llama 3 70B 提供無與倫比的複雜性處理能力,為高要求項目量身定制。"
|
594
603
|
},
|
@@ -643,6 +652,9 @@
|
|
643
652
|
"meta-llama/Llama-2-13b-chat-hf": {
|
644
653
|
"description": "LLaMA-2 Chat (13B) 提供優秀的語言處理能力和出色的互動體驗。"
|
645
654
|
},
|
655
|
+
"meta-llama/Llama-2-7b-chat-hf": {
|
656
|
+
"description": "最佳對話模型之一"
|
657
|
+
},
|
646
658
|
"meta-llama/Llama-3-70b-chat-hf": {
|
647
659
|
"description": "LLaMA-3 Chat (70B) 是功能強大的聊天模型,支持複雜的對話需求。"
|
648
660
|
},
|
@@ -811,7 +823,7 @@
|
|
811
823
|
"open-mixtral-8x7b": {
|
812
824
|
"description": "Mixtral 8x7B 是一個稀疏專家模型,利用多個參數提高推理速度,適合處理多語言和代碼生成任務。"
|
813
825
|
},
|
814
|
-
"openai/gpt-4o
|
826
|
+
"openai/gpt-4o": {
|
815
827
|
"description": "ChatGPT-4o 是一款動態模型,實時更新以保持當前最新版本。它結合了強大的語言理解與生成能力,適合於大規模應用場景,包括客戶服務、教育和技術支持。"
|
816
828
|
},
|
817
829
|
"openai/gpt-4o-mini": {
|
@@ -862,11 +874,11 @@
|
|
862
874
|
"qwen-vl-chat-v1": {
|
863
875
|
"description": "通義千問VL支持靈活的交互方式,包括多圖、多輪問答、創作等能力的模型。"
|
864
876
|
},
|
865
|
-
"qwen-vl-max": {
|
877
|
+
"qwen-vl-max-latest": {
|
866
878
|
"description": "通義千問超大規模視覺語言模型。相比增強版,再次提升視覺推理能力和指令遵循能力,提供更高的視覺感知和認知水平。"
|
867
879
|
},
|
868
|
-
"qwen-vl-plus": {
|
869
|
-
"description": "
|
880
|
+
"qwen-vl-plus-latest": {
|
881
|
+
"description": "通義千問大規模視覺語言模型增強版。大幅提升細節識別能力和文字識別能力,支持超百萬像素解析度和任意長寬比規格的圖像。"
|
870
882
|
},
|
871
883
|
"qwen-vl-v1": {
|
872
884
|
"description": "以Qwen-7B語言模型初始化,添加圖像模型,圖像輸入分辨率為448的預訓練模型。"
|
@@ -30,6 +30,9 @@
|
|
30
30
|
"groq": {
|
31
31
|
"description": "Groq 的 LPU 推理引擎在最新的獨立大語言模型(LLM)基準測試中表現卓越,以其驚人的速度和效率重新定義了 AI 解決方案的標準。Groq 是一種即時推理速度的代表,在基於雲的部署中展現了良好的性能。"
|
32
32
|
},
|
33
|
+
"huggingface": {
|
34
|
+
"description": "HuggingFace Inference API 提供了一種快速且免費的方式,讓您可以探索成千上萬種模型,適用於各種任務。無論您是在為新應用程式進行原型設計,還是在嘗試機器學習的功能,這個 API 都能讓您即時訪問多個領域的高性能模型。"
|
35
|
+
},
|
33
36
|
"hunyuan": {
|
34
37
|
"description": "由騰訊研發的大語言模型,具備強大的中文創作能力、複雜語境下的邏輯推理能力,以及可靠的任務執行能力"
|
35
38
|
},
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.22.1",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -116,12 +116,13 @@
|
|
116
116
|
"@codesandbox/sandpack-react": "^2.19.8",
|
117
117
|
"@cyntler/react-doc-viewer": "^1.16.6",
|
118
118
|
"@google/generative-ai": "^0.16.0",
|
119
|
+
"@huggingface/inference": "^2.8.1",
|
119
120
|
"@icons-pack/react-simple-icons": "9.6.0",
|
120
121
|
"@khmyznikov/pwa-install": "^0.3.9",
|
121
122
|
"@langchain/community": "^0.2.31",
|
122
123
|
"@lobehub/chat-plugin-sdk": "^1.32.4",
|
123
124
|
"@lobehub/chat-plugins-gateway": "^1.9.0",
|
124
|
-
"@lobehub/icons": "^1.
|
125
|
+
"@lobehub/icons": "^1.35.3",
|
125
126
|
"@lobehub/tts": "^1.24.3",
|
126
127
|
"@lobehub/ui": "^1.150.3",
|
127
128
|
"@neondatabase/serverless": "^0.9.4",
|
@@ -163,7 +164,7 @@
|
|
163
164
|
"jose": "^5.7.0",
|
164
165
|
"js-sha256": "^0.11.0",
|
165
166
|
"jsonl-parse-stringify": "^1.0.3",
|
166
|
-
"langchain": "^0.
|
167
|
+
"langchain": "^0.3.0",
|
167
168
|
"langfuse": "^3.19.0",
|
168
169
|
"langfuse-core": "^3.19.0",
|
169
170
|
"lodash-es": "^4.17.21",
|
@@ -235,6 +236,7 @@
|
|
235
236
|
"devDependencies": {
|
236
237
|
"@commitlint/cli": "^19.4.0",
|
237
238
|
"@edge-runtime/vm": "^4.0.2",
|
239
|
+
"@huggingface/tasks": "^0.12.12",
|
238
240
|
"@lobehub/i18n-cli": "^1.19.1",
|
239
241
|
"@lobehub/lint": "^1.24.4",
|
240
242
|
"@lobehub/seo-cli": "^1.4.2",
|
@@ -0,0 +1,53 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import { Markdown } from '@lobehub/ui';
|
4
|
+
import { Input } from 'antd';
|
5
|
+
import { createStyles } from 'antd-style';
|
6
|
+
import { useTranslation } from 'react-i18next';
|
7
|
+
|
8
|
+
import { HuggingFaceProviderCard } from '@/config/modelProviders';
|
9
|
+
import { GlobalLLMProviderKey } from '@/types/user/settings';
|
10
|
+
|
11
|
+
import { KeyVaultsConfigKey, LLMProviderApiTokenKey } from '../../const';
|
12
|
+
import { ProviderItem } from '../../type';
|
13
|
+
|
14
|
+
const useStyles = createStyles(({ css, token }) => ({
|
15
|
+
markdown: css`
|
16
|
+
p {
|
17
|
+
color: ${token.colorTextDescription} !important;
|
18
|
+
}
|
19
|
+
`,
|
20
|
+
tip: css`
|
21
|
+
font-size: 12px;
|
22
|
+
color: ${token.colorTextDescription};
|
23
|
+
`,
|
24
|
+
}));
|
25
|
+
|
26
|
+
const providerKey: GlobalLLMProviderKey = 'huggingface';
|
27
|
+
|
28
|
+
// Same as OpenAIProvider, but replace API Key with HuggingFace Access Token
|
29
|
+
export const useHuggingFaceProvider = (): ProviderItem => {
|
30
|
+
const { t } = useTranslation('modelProvider');
|
31
|
+
const { styles } = useStyles();
|
32
|
+
|
33
|
+
return {
|
34
|
+
...HuggingFaceProviderCard,
|
35
|
+
apiKeyItems: [
|
36
|
+
{
|
37
|
+
children: (
|
38
|
+
<Input.Password
|
39
|
+
autoComplete={'new-password'}
|
40
|
+
placeholder={t(`${providerKey}.accessToken.placeholder`)}
|
41
|
+
/>
|
42
|
+
),
|
43
|
+
desc: (
|
44
|
+
<Markdown className={styles.markdown} fontSize={12} variant={'chat'}>
|
45
|
+
{t(`${providerKey}.accessToken.desc`)}
|
46
|
+
</Markdown>
|
47
|
+
),
|
48
|
+
label: t(`${providerKey}.accessToken.title`),
|
49
|
+
name: [KeyVaultsConfigKey, providerKey, LLMProviderApiTokenKey],
|
50
|
+
},
|
51
|
+
],
|
52
|
+
};
|
53
|
+
};
|
@@ -31,6 +31,7 @@ import { ProviderItem } from '../type';
|
|
31
31
|
import { useAzureProvider } from './Azure';
|
32
32
|
import { useBedrockProvider } from './Bedrock';
|
33
33
|
import { useGithubProvider } from './Github';
|
34
|
+
import { useHuggingFaceProvider } from './HuggingFace';
|
34
35
|
import { useOllamaProvider } from './Ollama';
|
35
36
|
import { useOpenAIProvider } from './OpenAI';
|
36
37
|
import { useWenxinProvider } from './Wenxin';
|
@@ -41,6 +42,7 @@ export const useProviderList = (): ProviderItem[] => {
|
|
41
42
|
const OpenAIProvider = useOpenAIProvider();
|
42
43
|
const BedrockProvider = useBedrockProvider();
|
43
44
|
const GithubProvider = useGithubProvider();
|
45
|
+
const HuggingFaceProvider = useHuggingFaceProvider();
|
44
46
|
const WenxinProvider = useWenxinProvider();
|
45
47
|
|
46
48
|
return useMemo(
|
@@ -52,6 +54,7 @@ export const useProviderList = (): ProviderItem[] => {
|
|
52
54
|
BedrockProvider,
|
53
55
|
GoogleProviderCard,
|
54
56
|
DeepSeekProviderCard,
|
57
|
+
HuggingFaceProvider,
|
55
58
|
OpenRouterProviderCard,
|
56
59
|
GithubProvider,
|
57
60
|
NovitaProviderCard,
|
@@ -76,6 +79,14 @@ export const useProviderList = (): ProviderItem[] => {
|
|
76
79
|
TaichuProviderCard,
|
77
80
|
SiliconCloudProviderCard,
|
78
81
|
],
|
79
|
-
[
|
82
|
+
[
|
83
|
+
AzureProvider,
|
84
|
+
OllamaProvider,
|
85
|
+
OpenAIProvider,
|
86
|
+
BedrockProvider,
|
87
|
+
GithubProvider,
|
88
|
+
WenxinProvider,
|
89
|
+
HuggingFaceProvider,
|
90
|
+
],
|
80
91
|
);
|
81
92
|
};
|
package/src/config/llm.ts
CHANGED
@@ -125,6 +125,11 @@ export const getLLMConfig = () => {
|
|
125
125
|
ENABLED_HUNYUAN: z.boolean(),
|
126
126
|
HUNYUAN_API_KEY: z.string().optional(),
|
127
127
|
HUNYUAN_MODEL_LIST: z.string().optional(),
|
128
|
+
|
129
|
+
ENABLED_HUGGINGFACE: z.boolean(),
|
130
|
+
HUGGINGFACE_API_KEY: z.string().optional(),
|
131
|
+
HUGGINGFACE_PROXY_URL: z.string().optional(),
|
132
|
+
HUGGINGFACE_MODEL_LIST: z.string().optional(),
|
128
133
|
},
|
129
134
|
runtimeEnv: {
|
130
135
|
API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE,
|
@@ -247,6 +252,11 @@ export const getLLMConfig = () => {
|
|
247
252
|
ENABLED_HUNYUAN: !!process.env.HUNYUAN_API_KEY,
|
248
253
|
HUNYUAN_API_KEY: process.env.HUNYUAN_API_KEY,
|
249
254
|
HUNYUAN_MODEL_LIST: process.env.HUNYUAN_MODEL_LIST,
|
255
|
+
|
256
|
+
ENABLED_HUGGINGFACE: !!process.env.HUGGINGFACE_API_KEY,
|
257
|
+
HUGGINGFACE_API_KEY: process.env.HUGGINGFACE_API_KEY,
|
258
|
+
HUGGINGFACE_PROXY_URL: process.env.HUGGINGFACE_PROXY_URL,
|
259
|
+
HUGGINGFACE_MODEL_LIST: process.env.HUGGINGFACE_MODEL_LIST,
|
250
260
|
},
|
251
261
|
});
|
252
262
|
};
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import { ModelProviderCard } from '@/types/llm';
|
2
|
+
|
3
|
+
const HuggingFace: ModelProviderCard = {
|
4
|
+
chatModels: [
|
5
|
+
{
|
6
|
+
description: 'Mistral AI的指令调优模型',
|
7
|
+
displayName: 'Mistral 7B Instruct v0.2',
|
8
|
+
enabled: true,
|
9
|
+
id: 'mistralai/Mistral-7B-Instruct-v0.2',
|
10
|
+
tokens: 8192,
|
11
|
+
},
|
12
|
+
{
|
13
|
+
description: '高质量多语言聊天模型,具有大型上下文长度',
|
14
|
+
displayName: 'Meta Llama 3.1 70B Instruct',
|
15
|
+
enabled: true,
|
16
|
+
id: 'meta-llama/Meta-Llama-3.1-70B-Instruct',
|
17
|
+
tokens: 32_768,
|
18
|
+
},
|
19
|
+
{
|
20
|
+
description: '高质量多语言聊天模型,具有较大上下文长度',
|
21
|
+
displayName: 'Meta Llama 3.1 8B Instruct',
|
22
|
+
enabled: true,
|
23
|
+
id: 'meta-llama/Meta-Llama-3.1-8B-Instruct',
|
24
|
+
tokens: 8192,
|
25
|
+
},
|
26
|
+
{
|
27
|
+
description: '最佳对话模型之一',
|
28
|
+
displayName: 'Llama 2 7B Chat',
|
29
|
+
id: 'meta-llama/Llama-2-7b-chat-hf',
|
30
|
+
tokens: 4096,
|
31
|
+
},
|
32
|
+
{
|
33
|
+
description: 'Google的轻量级指令调优模型',
|
34
|
+
displayName: 'Gemma 2B Instruct',
|
35
|
+
id: 'google/gemma-2-2b-it',
|
36
|
+
tokens: 8192,
|
37
|
+
},
|
38
|
+
],
|
39
|
+
checkModel: 'mistralai/Mistral-7B-Instruct-v0.2',
|
40
|
+
description:
|
41
|
+
'HuggingFace Inference API 提供了一种快速且免费的方式,让您可以探索成千上万种模型,适用于各种任务。无论您是在为新应用程序进行原型设计,还是在尝试机器学习的功能,这个 API 都能让您即时访问多个领域的高性能模型。',
|
42
|
+
disableBrowserRequest: true,
|
43
|
+
id: 'huggingface',
|
44
|
+
modelList: { showModelFetcher: true },
|
45
|
+
modelsUrl: 'https://huggingface.co/docs/api-inference/en/supported-models',
|
46
|
+
name: 'HuggingFace',
|
47
|
+
url: 'https://huggingface.co',
|
48
|
+
};
|
49
|
+
|
50
|
+
export default HuggingFace;
|
@@ -11,6 +11,7 @@ import FireworksAIProvider from './fireworksai';
|
|
11
11
|
import GithubProvider from './github';
|
12
12
|
import GoogleProvider from './google';
|
13
13
|
import GroqProvider from './groq';
|
14
|
+
import HuggingFaceProvider from './huggingface';
|
14
15
|
import HunyuanProvider from './hunyuan';
|
15
16
|
import MinimaxProvider from './minimax';
|
16
17
|
import MistralProvider from './mistral';
|
@@ -49,6 +50,7 @@ export const LOBE_DEFAULT_MODEL_LIST: ChatModelCard[] = [
|
|
49
50
|
FireworksAIProvider.chatModels,
|
50
51
|
PerplexityProvider.chatModels,
|
51
52
|
AnthropicProvider.chatModels,
|
53
|
+
HuggingFaceProvider.chatModels,
|
52
54
|
ZeroOneProvider.chatModels,
|
53
55
|
StepfunProvider.chatModels,
|
54
56
|
NovitaProvider.chatModels,
|
@@ -71,6 +73,7 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [
|
|
71
73
|
BedrockProvider,
|
72
74
|
GoogleProvider,
|
73
75
|
DeepSeekProvider,
|
76
|
+
HuggingFaceProvider,
|
74
77
|
OpenRouterProvider,
|
75
78
|
GithubProvider,
|
76
79
|
NovitaProvider,
|
@@ -116,6 +119,7 @@ export { default as FireworksAIProviderCard } from './fireworksai';
|
|
116
119
|
export { default as GithubProviderCard } from './github';
|
117
120
|
export { default as GoogleProviderCard } from './google';
|
118
121
|
export { default as GroqProviderCard } from './groq';
|
122
|
+
export { default as HuggingFaceProviderCard } from './huggingface';
|
119
123
|
export { default as HunyuanProviderCard } from './hunyuan';
|
120
124
|
export { default as MinimaxProviderCard } from './minimax';
|
121
125
|
export { default as MistralProviderCard } from './mistral';
|
@@ -9,6 +9,7 @@ import {
|
|
9
9
|
GithubProviderCard,
|
10
10
|
GoogleProviderCard,
|
11
11
|
GroqProviderCard,
|
12
|
+
HuggingFaceProviderCard,
|
12
13
|
HunyuanProviderCard,
|
13
14
|
MinimaxProviderCard,
|
14
15
|
MistralProviderCard,
|
@@ -77,6 +78,10 @@ export const DEFAULT_LLM_CONFIG: UserModelProviderConfig = {
|
|
77
78
|
enabled: false,
|
78
79
|
enabledModels: filterEnabledModels(GroqProviderCard),
|
79
80
|
},
|
81
|
+
huggingface: {
|
82
|
+
enabled: false,
|
83
|
+
enabledModels: filterEnabledModels(HuggingFaceProviderCard),
|
84
|
+
},
|
80
85
|
hunyuan: {
|
81
86
|
enabled: false,
|
82
87
|
enabledModels: filterEnabledModels(HunyuanProviderCard),
|
@@ -14,6 +14,7 @@ import { LobeFireworksAI } from './fireworksai';
|
|
14
14
|
import { LobeGithubAI } from './github';
|
15
15
|
import { LobeGoogleAI } from './google';
|
16
16
|
import { LobeGroq } from './groq';
|
17
|
+
import { LobeHuggingFaceAI } from './huggingface';
|
17
18
|
import { LobeHunyuanAI } from './hunyuan';
|
18
19
|
import { LobeMinimaxAI } from './minimax';
|
19
20
|
import { LobeMistralAI } from './mistral';
|
@@ -134,6 +135,7 @@ class AgentRuntime {
|
|
134
135
|
github: Partial<ClientOptions>;
|
135
136
|
google: { apiKey?: string; baseURL?: string };
|
136
137
|
groq: Partial<ClientOptions>;
|
138
|
+
huggingface: { apiKey?: string; baseURL?: string };
|
137
139
|
hunyuan: Partial<ClientOptions>;
|
138
140
|
minimax: Partial<ClientOptions>;
|
139
141
|
mistral: Partial<ClientOptions>;
|
@@ -213,6 +215,11 @@ class AgentRuntime {
|
|
213
215
|
break;
|
214
216
|
}
|
215
217
|
|
218
|
+
case ModelProvider.HuggingFace: {
|
219
|
+
runtimeModel = new LobeHuggingFaceAI(params.huggingface);
|
220
|
+
break;
|
221
|
+
}
|
222
|
+
|
216
223
|
case ModelProvider.Minimax: {
|
217
224
|
runtimeModel = new LobeMinimaxAI(params.minimax);
|
218
225
|
break;
|
@@ -4,6 +4,7 @@ export const AgentRuntimeErrorType = {
|
|
4
4
|
AgentRuntimeError: 'AgentRuntimeError', // Agent Runtime 模块运行时错误
|
5
5
|
LocationNotSupportError: 'LocationNotSupportError',
|
6
6
|
QuotaLimitReached: 'QuotaLimitReached',
|
7
|
+
PermissionDenied: 'PermissionDenied',
|
7
8
|
|
8
9
|
InvalidProviderAPIKey: 'InvalidProviderAPIKey',
|
9
10
|
ProviderBizError: 'ProviderBizError',
|
@@ -6,7 +6,7 @@ export const LobeGroq = LobeOpenAICompatibleFactory({
|
|
6
6
|
baseURL: 'https://api.groq.com/openai/v1',
|
7
7
|
chatCompletion: {
|
8
8
|
handleError: (error) => {
|
9
|
-
// 403 means the location is not
|
9
|
+
// 403 means the location is not supported
|
10
10
|
if (error.status === 403)
|
11
11
|
return { error, errorType: AgentRuntimeErrorType.LocationNotSupportError };
|
12
12
|
},
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import { HfInference } from '@huggingface/inference';
|
2
|
+
|
3
|
+
import { AgentRuntimeErrorType } from '../error';
|
4
|
+
import { ModelProvider } from '../types';
|
5
|
+
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
6
|
+
import { convertIterableToStream } from '../utils/streams';
|
7
|
+
|
8
|
+
export const LobeHuggingFaceAI = LobeOpenAICompatibleFactory({
|
9
|
+
chatCompletion: {
|
10
|
+
handleStreamBizErrorType: (error) => {
|
11
|
+
// e.g.: Server meta-llama/Meta-Llama-3.1-8B-Instruct does not seem to support chat completion. Error: Model requires a Pro subscription; check out hf.co/pricing to learn more. Make sure to include your HF token in your query.
|
12
|
+
if (error.message?.includes('Model requires a Pro subscription')) {
|
13
|
+
return AgentRuntimeErrorType.PermissionDenied;
|
14
|
+
}
|
15
|
+
|
16
|
+
// e.g.: Server meta-llama/Meta-Llama-3.1-8B-Instruct does not seem to support chat completion. Error: Authorization header is correct, but the token seems invalid
|
17
|
+
if (error.message?.includes('the token seems invalid')) {
|
18
|
+
return AgentRuntimeErrorType.InvalidProviderAPIKey;
|
19
|
+
}
|
20
|
+
},
|
21
|
+
},
|
22
|
+
customClient: {
|
23
|
+
createChatCompletionStream: (client: HfInference, payload, instance) => {
|
24
|
+
const hfRes = client.chatCompletionStream({
|
25
|
+
endpointUrl: instance.baseURL,
|
26
|
+
messages: payload.messages,
|
27
|
+
model: payload.model,
|
28
|
+
stream: true,
|
29
|
+
temperature: payload.temperature,
|
30
|
+
// `top_p` must be > 0.0 and < 1.0
|
31
|
+
top_p: payload?.top_p
|
32
|
+
? payload?.top_p >= 1
|
33
|
+
? 0.99
|
34
|
+
: payload?.top_p <= 0
|
35
|
+
? 0.01
|
36
|
+
: payload?.top_p
|
37
|
+
: undefined,
|
38
|
+
});
|
39
|
+
|
40
|
+
return convertIterableToStream(hfRes);
|
41
|
+
},
|
42
|
+
createClient: (options) => new HfInference(options.apiKey),
|
43
|
+
},
|
44
|
+
debug: {
|
45
|
+
chatCompletion: () => process.env.DEBUG_HUGGINGFACE_CHAT_COMPLETION === '1',
|
46
|
+
},
|
47
|
+
provider: ModelProvider.HuggingFace,
|
48
|
+
});
|
@@ -3,6 +3,14 @@ import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
|
3
3
|
|
4
4
|
export const LobeSiliconCloudAI = LobeOpenAICompatibleFactory({
|
5
5
|
baseURL: 'https://api.siliconflow.cn/v1',
|
6
|
+
chatCompletion: {
|
7
|
+
handlePayload: (payload) => {
|
8
|
+
return {
|
9
|
+
...payload,
|
10
|
+
stream: !payload.tools,
|
11
|
+
} as any;
|
12
|
+
},
|
13
|
+
},
|
6
14
|
debug: {
|
7
15
|
chatCompletion: () => process.env.DEBUG_SILICONCLOUD_CHAT_COMPLETION === '1',
|
8
16
|
},
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import OpenAI, { ClientOptions } from 'openai';
|
2
|
+
import { Stream } from 'openai/streaming';
|
2
3
|
|
3
4
|
import { LOBE_DEFAULT_MODEL_LIST } from '@/config/modelProviders';
|
4
5
|
import { ChatModelCard } from '@/types/llm';
|
@@ -22,7 +23,7 @@ import { desensitizeUrl } from '../desensitizeUrl';
|
|
22
23
|
import { handleOpenAIError } from '../handleOpenAIError';
|
23
24
|
import { convertOpenAIMessages } from '../openaiHelpers';
|
24
25
|
import { StreamingResponse } from '../response';
|
25
|
-
import { OpenAIStream } from '../streams';
|
26
|
+
import { OpenAIStream, OpenAIStreamOptions } from '../streams';
|
26
27
|
|
27
28
|
// the model contains the following keywords is not a chat model, so we should filter them out
|
28
29
|
const CHAT_MODELS_BLOCK_LIST = [
|
@@ -39,6 +40,15 @@ const CHAT_MODELS_BLOCK_LIST = [
|
|
39
40
|
|
40
41
|
type ConstructorOptions<T extends Record<string, any> = any> = ClientOptions & T;
|
41
42
|
|
43
|
+
export interface CustomClientOptions<T extends Record<string, any> = any> {
|
44
|
+
createChatCompletionStream?: (
|
45
|
+
client: any,
|
46
|
+
payload: ChatStreamPayload,
|
47
|
+
instance: any,
|
48
|
+
) => ReadableStream<any>;
|
49
|
+
createClient?: (options: ConstructorOptions<T>) => any;
|
50
|
+
}
|
51
|
+
|
42
52
|
interface OpenAICompatibleFactoryOptions<T extends Record<string, any> = any> {
|
43
53
|
baseURL?: string;
|
44
54
|
chatCompletion?: {
|
@@ -50,9 +60,14 @@ interface OpenAICompatibleFactoryOptions<T extends Record<string, any> = any> {
|
|
50
60
|
payload: ChatStreamPayload,
|
51
61
|
options: ConstructorOptions<T>,
|
52
62
|
) => OpenAI.ChatCompletionCreateParamsStreaming;
|
63
|
+
handleStreamBizErrorType?: (error: {
|
64
|
+
message: string;
|
65
|
+
name: string;
|
66
|
+
}) => ILobeAgentRuntimeErrorType | undefined;
|
53
67
|
noUserId?: boolean;
|
54
68
|
};
|
55
69
|
constructorOptions?: ConstructorOptions<T>;
|
70
|
+
customClient?: CustomClientOptions<T>;
|
56
71
|
debug?: {
|
57
72
|
chatCompletion: () => boolean;
|
58
73
|
};
|
@@ -129,6 +144,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
|
|
129
144
|
constructorOptions,
|
130
145
|
chatCompletion,
|
131
146
|
models,
|
147
|
+
customClient,
|
132
148
|
}: OpenAICompatibleFactoryOptions<T>) => {
|
133
149
|
const ErrorType = {
|
134
150
|
bizError: errorType?.bizError || AgentRuntimeErrorType.ProviderBizError,
|
@@ -136,9 +152,9 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
|
|
136
152
|
};
|
137
153
|
|
138
154
|
return class LobeOpenAICompatibleAI implements LobeRuntimeAI {
|
139
|
-
client
|
155
|
+
client!: OpenAI;
|
140
156
|
|
141
|
-
baseURL
|
157
|
+
baseURL!: string;
|
142
158
|
private _options: ConstructorOptions<T>;
|
143
159
|
|
144
160
|
constructor(options: ClientOptions & Record<string, any> = {}) {
|
@@ -148,8 +164,16 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
|
|
148
164
|
|
149
165
|
if (!apiKey) throw AgentRuntimeError.createError(ErrorType?.invalidAPIKey);
|
150
166
|
|
151
|
-
|
152
|
-
|
167
|
+
const initOptions = { apiKey, baseURL, ...constructorOptions, ...res };
|
168
|
+
|
169
|
+
// if the custom client is provided, use it as client
|
170
|
+
if (customClient?.createClient) {
|
171
|
+
this.client = customClient.createClient(initOptions as any);
|
172
|
+
} else {
|
173
|
+
this.client = new OpenAI(initOptions);
|
174
|
+
}
|
175
|
+
|
176
|
+
this.baseURL = baseURL || this.client.baseURL;
|
153
177
|
}
|
154
178
|
|
155
179
|
async chat({ responseMode, ...payload }: ChatStreamPayload, options?: ChatCompetitionOptions) {
|
@@ -163,27 +187,41 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
|
|
163
187
|
|
164
188
|
const messages = await convertOpenAIMessages(postPayload.messages);
|
165
189
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
190
|
+
let response: Stream<OpenAI.Chat.Completions.ChatCompletionChunk>;
|
191
|
+
|
192
|
+
const streamOptions: OpenAIStreamOptions = {
|
193
|
+
bizErrorTypeTransformer: chatCompletion?.handleStreamBizErrorType,
|
194
|
+
callbacks: options?.callback,
|
195
|
+
provider,
|
196
|
+
};
|
197
|
+
if (customClient?.createChatCompletionStream) {
|
198
|
+
response = customClient.createChatCompletionStream(this.client, payload, this) as any;
|
199
|
+
} else {
|
200
|
+
response = await this.client.chat.completions.create(
|
201
|
+
{
|
202
|
+
...postPayload,
|
203
|
+
messages,
|
204
|
+
...(chatCompletion?.noUserId ? {} : { user: options?.user }),
|
205
|
+
},
|
206
|
+
{
|
207
|
+
// https://github.com/lobehub/lobe-chat/pull/318
|
208
|
+
headers: { Accept: '*/*' },
|
209
|
+
signal: options?.signal,
|
210
|
+
},
|
211
|
+
);
|
212
|
+
}
|
178
213
|
|
179
214
|
if (postPayload.stream) {
|
180
215
|
const [prod, useForDebug] = response.tee();
|
181
216
|
|
182
217
|
if (debug?.chatCompletion?.()) {
|
183
|
-
|
218
|
+
const useForDebugStream =
|
219
|
+
useForDebug instanceof ReadableStream ? useForDebug : useForDebug.toReadableStream();
|
220
|
+
|
221
|
+
debugStream(useForDebugStream).catch(console.error);
|
184
222
|
}
|
185
223
|
|
186
|
-
return StreamingResponse(OpenAIStream(prod,
|
224
|
+
return StreamingResponse(OpenAIStream(prod, streamOptions), {
|
187
225
|
headers: options?.headers,
|
188
226
|
});
|
189
227
|
}
|
@@ -196,7 +234,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
|
|
196
234
|
|
197
235
|
const stream = transformResponseToStream(response as unknown as OpenAI.ChatCompletion);
|
198
236
|
|
199
|
-
return StreamingResponse(OpenAIStream(stream,
|
237
|
+
return StreamingResponse(OpenAIStream(stream, streamOptions), {
|
200
238
|
headers: options?.headers,
|
201
239
|
});
|
202
240
|
} catch (error) {
|