@lobehub/chat 0.162.16 → 0.162.17

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.
Files changed (71) hide show
  1. package/.env.example +4 -0
  2. package/CHANGELOG.md +25 -0
  3. package/Dockerfile +3 -0
  4. package/README.md +1 -0
  5. package/README.zh-CN.md +1 -0
  6. package/docs/self-hosting/advanced/upstream-sync.mdx +1 -1
  7. package/docs/self-hosting/environment-variables/model-provider.mdx +10 -1
  8. package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +9 -0
  9. package/docs/usage/features/multi-ai-providers.mdx +1 -0
  10. package/docs/usage/features/multi-ai-providers.zh-CN.mdx +1 -0
  11. package/locales/ar/error.json +3 -1
  12. package/locales/ar/modelProvider.json +12 -0
  13. package/locales/bg-BG/error.json +2 -0
  14. package/locales/bg-BG/modelProvider.json +12 -0
  15. package/locales/de-DE/error.json +2 -0
  16. package/locales/de-DE/modelProvider.json +12 -0
  17. package/locales/en-US/error.json +2 -0
  18. package/locales/en-US/modelProvider.json +12 -0
  19. package/locales/es-ES/error.json +2 -0
  20. package/locales/es-ES/modelProvider.json +12 -0
  21. package/locales/fr-FR/error.json +2 -0
  22. package/locales/fr-FR/modelProvider.json +12 -0
  23. package/locales/it-IT/error.json +2 -0
  24. package/locales/it-IT/modelProvider.json +12 -0
  25. package/locales/ja-JP/error.json +2 -0
  26. package/locales/ja-JP/modelProvider.json +12 -0
  27. package/locales/ko-KR/error.json +2 -0
  28. package/locales/ko-KR/modelProvider.json +12 -0
  29. package/locales/nl-NL/error.json +2 -0
  30. package/locales/nl-NL/modelProvider.json +12 -0
  31. package/locales/pl-PL/error.json +2 -0
  32. package/locales/pl-PL/modelProvider.json +12 -0
  33. package/locales/pt-BR/error.json +2 -0
  34. package/locales/pt-BR/modelProvider.json +12 -0
  35. package/locales/ru-RU/error.json +2 -0
  36. package/locales/ru-RU/modelProvider.json +12 -0
  37. package/locales/tr-TR/error.json +2 -0
  38. package/locales/tr-TR/modelProvider.json +12 -0
  39. package/locales/vi-VN/error.json +2 -0
  40. package/locales/vi-VN/modelProvider.json +12 -0
  41. package/locales/zh-CN/error.json +2 -0
  42. package/locales/zh-CN/modelProvider.json +12 -0
  43. package/locales/zh-TW/error.json +2 -0
  44. package/locales/zh-TW/modelProvider.json +12 -0
  45. package/package.json +1 -1
  46. package/src/app/(main)/settings/llm/Qwen/index.tsx +21 -0
  47. package/src/app/(main)/settings/llm/index.tsx +2 -0
  48. package/src/app/api/chat/agentRuntime.test.ts +17 -0
  49. package/src/app/api/chat/agentRuntime.ts +7 -0
  50. package/src/app/api/errorResponse.test.ts +6 -0
  51. package/src/app/api/errorResponse.ts +3 -0
  52. package/src/components/ModelProviderIcon/index.tsx +5 -0
  53. package/src/config/llm.ts +6 -0
  54. package/src/config/modelProviders/index.ts +4 -0
  55. package/src/config/modelProviders/qwen.ts +32 -0
  56. package/src/const/settings/llm.ts +5 -0
  57. package/src/features/Conversation/Error/APIKeyForm/ProviderAvatar.tsx +5 -0
  58. package/src/features/Conversation/Error/APIKeyForm/index.tsx +4 -0
  59. package/src/features/Conversation/Error/index.tsx +1 -0
  60. package/src/libs/agent-runtime/AgentRuntime.ts +8 -1
  61. package/src/libs/agent-runtime/error.ts +3 -0
  62. package/src/libs/agent-runtime/index.ts +1 -0
  63. package/src/libs/agent-runtime/qwen/index.test.ts +251 -0
  64. package/src/libs/agent-runtime/qwen/index.ts +33 -0
  65. package/src/libs/agent-runtime/types/type.ts +1 -1
  66. package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.test.ts +121 -0
  67. package/src/libs/agent-runtime/utils/streams/openai.ts +1 -1
  68. package/src/server/globalConfig/index.ts +2 -0
  69. package/src/services/__tests__/chat.test.ts +16 -0
  70. package/src/services/chat.ts +3 -0
  71. package/src/types/user/settings/keyVaults.ts +1 -0
@@ -74,6 +74,7 @@
74
74
  "InvalidOllamaArgs": "Неверная конфигурация Ollama, пожалуйста, проверьте конфигурацию Ollama и повторите попытку",
75
75
  "InvalidOpenRouterAPIKey": "OpenRouter API Key недействителен или отсутствует. Пожалуйста, проверьте правильность OpenRouter API Key и повторите попытку",
76
76
  "InvalidPerplexityAPIKey": "Неверный или пустой ключ API Perplexity. Пожалуйста, проверьте ключ API Perplexity и повторите попытку",
77
+ "InvalidQwenAPIKey": "Неверный или пустой ключ API Qwen, пожалуйста, проверьте ключ API Qwen и повторите попытку",
77
78
  "InvalidTogetherAIAPIKey": "TogetherAI API Key недействителен или отсутствует. Пожалуйста, проверьте правильность TogetherAI API Key и повторите попытку",
78
79
  "InvalidZeroOneAPIKey": "Неверный или пустой ключ API ZeroOne. Пожалуйста, проверьте ключ API ZeroOne и повторите попытку",
79
80
  "InvalidZhipuAPIKey": "Неверный или пустой ключ API Zhipu, пожалуйста, проверьте ключ API Zhipu и повторите попытку",
@@ -99,6 +100,7 @@
99
100
  "PluginOpenApiInitError": "Извините, не удалось инициализировать клиент OpenAPI. Пожалуйста, проверьте правильность информации конфигурации OpenAPI.",
100
101
  "PluginServerError": "Запрос сервера плагина возвратил ошибку. Проверьте файл манифеста плагина, конфигурацию плагина или реализацию сервера на основе информации об ошибке ниже",
101
102
  "PluginSettingsInvalid": "Этот плагин необходимо правильно настроить, прежде чем его можно будет использовать. Пожалуйста, проверьте правильность вашей конфигурации",
103
+ "QwenBizError": "Ошибка запроса службы Qwen, пожалуйста, проверьте и повторите попытку в соответствии с предоставленной информацией",
102
104
  "TogetherAIBizError": "Ошибка запроса к сервису TogetherAI AI. Пожалуйста, проверьте информацию ниже или повторите попытку",
103
105
  "ZeroOneBizError": "Ошибка обслуживания запроса к сервису ZeroOneBiz. Пожалуйста, проверьте следующую информацию и повторите попытку",
104
106
  "ZhipuBizError": "Ошибка запроса службы Zhipu, пожалуйста, проверьте и повторите попытку в соответствии с предоставленной информацией"
@@ -217,6 +217,18 @@
217
217
  "title": "Использовать пользовательский ключ API Perplexity"
218
218
  }
219
219
  },
220
+ "qwen": {
221
+ "title": "Qwen",
222
+ "token": {
223
+ "desc": "Введите свой API Key от Qwen",
224
+ "placeholder": "Qwen API Key",
225
+ "title": "API Key"
226
+ },
227
+ "unlock": {
228
+ "description": "Введите свой ключ API Qwen, чтобы начать сеанс. Приложение не будет сохранять ваш ключ API",
229
+ "title": "Использовать пользовательский ключ API Qwen"
230
+ }
231
+ },
220
232
  "togetherai": {
221
233
  "checker": {
222
234
  "desc": "Проверить правильность адреса прокси"
@@ -74,6 +74,7 @@
74
74
  "InvalidOllamaArgs": "Ollama yapılandırması yanlış, lütfen Ollama yapılandırmasını kontrol edip tekrar deneyin",
75
75
  "InvalidOpenRouterAPIKey": "OpenRouter API Anahtarı geçersiz veya boş, lütfen OpenRouter API Anahtarınızı kontrol edip tekrar deneyin",
76
76
  "InvalidPerplexityAPIKey": "Perplexity API Key geçersiz veya boş, lütfen Perplexity API Key'inizi kontrol edip tekrar deneyin",
77
+ "InvalidQwenAPIKey": "Qwen API Anahtarı yanlış veya boş, lütfen Qwen API Anahtarınızı kontrol edip tekrar deneyin",
77
78
  "InvalidTogetherAIAPIKey": "TogetherAI API Anahtarı geçersiz veya boş, lütfen TogetherAI API Anahtarınızı kontrol edip tekrar deneyin",
78
79
  "InvalidZeroOneAPIKey": "SıfırBirIoT API Anahtarı geçersiz veya boş. Lütfen SıfırBirIoT API Anahtarınızı kontrol edip tekrar deneyin",
79
80
  "InvalidZhipuAPIKey": "Zhipu API Anahtarı yanlış veya boş, lütfen Zhipu API Anahtarınızı kontrol edip tekrar deneyin",
@@ -99,6 +100,7 @@
99
100
  "PluginOpenApiInitError": "Üzgünüz, OpenAPI istemci başlatma hatası, lütfen OpenAPI yapılandırma bilgilerini kontrol edin",
100
101
  "PluginServerError": "Eklenti sunucusu isteği bir hata ile döndü. Lütfen aşağıdaki hata bilgilerine dayanarak eklenti bildirim dosyanızı, eklenti yapılandırmanızı veya sunucu uygulamanızı kontrol edin",
101
102
  "PluginSettingsInvalid": "Bu eklenti, kullanılmadan önce doğru şekilde yapılandırılmalıdır. Lütfen yapılandırmanızın doğru olup olmadığını kontrol edin",
103
+ "QwenBizError": "Qwen servisi isteği hatası, lütfen aşağıdaki bilgilere göre sorunu gidermeye çalışın veya tekrar deneyin",
102
104
  "TogetherAIBizError": "TogetherAI AI hizmetine yönelik istek hatası, lütfen aşağıdaki bilgilere göre sorunu gidermeye çalışın veya tekrar deneyin",
103
105
  "ZeroOneBizError": "SıfırBirIoT hizmetine yapılan istekte bir hata oluştu. Lütfen aşağıdaki bilgilere göre sorunu gidermeye çalışın veya tekrar deneyin",
104
106
  "ZhipuBizError": "Zhipu servisi isteği hatası, lütfen aşağıdaki bilgilere göre sorunu gidermeye çalışın veya tekrar deneyin"
@@ -1,4 +1,16 @@
1
1
  {
2
+ "Qwen": {
3
+ "title": "Qwen",
4
+ "token": {
5
+ "desc": "Qwen'dan gelen API Key'i girin",
6
+ "placeholder": "Qwen API Key",
7
+ "title": "API Key"
8
+ },
9
+ "unlock": {
10
+ "description": "Qwen API Anahtarınızı girerek oturumu başlatabilirsiniz. Uygulama API Anahtarınızı kaydetmez.",
11
+ "title": "Özel Qwen API Anahtarı Kullan"
12
+ }
13
+ },
2
14
  "anthropic": {
3
15
  "title": "Anthropic",
4
16
  "token": {
@@ -74,6 +74,7 @@
74
74
  "InvalidOllamaArgs": "Cấu hình Ollama không hợp lệ, vui lòng kiểm tra lại cấu hình Ollama và thử lại",
75
75
  "InvalidOpenRouterAPIKey": "OpenRouter API Key không hợp lệ hoặc trống, vui lòng kiểm tra lại và thử lại",
76
76
  "InvalidPerplexityAPIKey": "Khóa API Perplexity không hợp lệ hoặc trống, vui lòng kiểm tra lại và thử lại sau",
77
+ "InvalidQwenAPIKey": "Khóa API Qwen không chính xác hoặc trống, vui lòng kiểm tra lại Khóa API Qwen và thử lại",
77
78
  "InvalidTogetherAIAPIKey": "TogetherAI API Key không hợp lệ hoặc trống, vui lòng kiểm tra lại và thử lại",
78
79
  "InvalidZeroOneAPIKey": "Khóa API ZeroOne không hợp lệ hoặc trống, vui lòng kiểm tra lại khóa API ZeroOne và thử lại",
79
80
  "InvalidZhipuAPIKey": "Khóa API Zhipu không chính xác hoặc trống, vui lòng kiểm tra lại Khóa API Zhipu và thử lại",
@@ -88,6 +89,7 @@
88
89
  "OpenRouterBizError": "Yêu cầu dịch vụ OpenRouter AI gặp lỗi, vui lòng kiểm tra thông tin dưới đây hoặc thử lại",
89
90
  "PerplexityBizError": "Yêu cầu dịch vụ AI Perplexity gặp lỗi, vui lòng kiểm tra thông tin dưới đây hoặc thử lại sau",
90
91
  "PluginApiNotFound": "Xin lỗi, không có API nào trong tệp mô tả plugin, vui lòng kiểm tra phương thức yêu cầu của bạn có khớp với API mô tả plugin không",
92
+ "QwenBizError": "Yêu cầu dịch vụ Qwen gặp lỗi, vui lòng kiểm tra thông tin dưới đây hoặc thử lại sau",
91
93
  "PluginApiParamsError": "Xin lỗi, kiểm tra tham số đầu vào yêu cầu của plugin không thông qua, vui lòng kiểm tra tham số đầu vào có khớp với thông tin mô tả API không",
92
94
  "PluginGatewayError": "Xin lỗi, cổng plugin gặp lỗi, vui lòng kiểm tra cấu hình cổng plugin có đúng không",
93
95
  "PluginManifestInvalid": "Xin lỗi, kiểm tra mô tả plugin không thông qua, vui lòng kiểm tra định dạng mô tả có đúng không",
@@ -217,6 +217,18 @@
217
217
  "title": "Sử dụng Khóa API Perplexity tùy chỉnh"
218
218
  }
219
219
  },
220
+ "qwen": {
221
+ "title": "Qwen",
222
+ "token": {
223
+ "desc": "Nhập API Key từ Qwen",
224
+ "placeholder": "Qwen API Key",
225
+ "title": "API Key"
226
+ },
227
+ "unlock": {
228
+ "description": "Nhập Khóa API Qwen của bạn để bắt đầu phiên làm việc. Ứng dụng sẽ không lưu trữ Khóa API của bạn",
229
+ "title": "Sử dụng Khóa API Qwen tùy chỉnh"
230
+ }
231
+ },
220
232
  "togetherai": {
221
233
  "checker": {
222
234
  "desc": "Kiểm tra địa chỉ proxy có được nhập chính xác không"
@@ -101,6 +101,8 @@
101
101
  "OllamaServiceUnavailable": "Ollama 服务连接失败,请检查 Ollama 是否运行正常,或是否正确设置 Ollama 的跨域配置",
102
102
  "MinimaxBizError": "请求 Minimax 服务出错,请根据以下信息排查或重试",
103
103
  "InvalidMinimaxAPIKey": "Minimax API Key 不正确或为空,请检查 Minimax API Key 后重试",
104
+ "QwenBizError": "请求 Qwen 服务出错,请根据以下信息排查或重试",
105
+ "InvalidQwenAPIKey": "Qwen API Key 不正确或为空,请检查 Qwen API Key 后重试",
104
106
  "AgentRuntimeError": "Lobe AI Runtime 执行出错,请根据以下信息排查或重试"
105
107
  },
106
108
  "stt": {
@@ -217,6 +217,18 @@
217
217
  "title": "使用自定义 Perplexity API Key"
218
218
  }
219
219
  },
220
+ "qwen": {
221
+ "title": "Qwen",
222
+ "token": {
223
+ "desc": "填入来自 DashScope 的 Qwen API Key",
224
+ "placeholder": "Qwen API Key",
225
+ "title": "Qwen API Key"
226
+ },
227
+ "unlock": {
228
+ "description": "输入你的 Qwen API Key 即可开始会话。应用不会记录你的 API Key",
229
+ "title": "使用自定义 Qwen API Key"
230
+ }
231
+ },
220
232
  "togetherai": {
221
233
  "checker": {
222
234
  "desc": "测试代理地址是否正确填写"
@@ -74,6 +74,7 @@
74
74
  "InvalidOllamaArgs": "Ollama 配置不正確,請檢查 Ollama 配置後重試",
75
75
  "InvalidOpenRouterAPIKey": "OpenRouter API 金鑰不正確或為空,請檢查 OpenRouter API 金鑰後重試",
76
76
  "InvalidPerplexityAPIKey": "Perplexity API Key 不正確或為空,請檢查 Perplexity API Key 後重試",
77
+ "InvalidQwenAPIKey": "Qwen API Key 不正確或為空,請檢查 Qwen API Key 後重試",
77
78
  "InvalidTogetherAIAPIKey": "TogetherAI API 金鑰不正確或為空,請檢查 TogetherAI API 金鑰後重試",
78
79
  "InvalidZeroOneAPIKey": "零一萬物 API Key 不正確或為空,請檢查零一萬物 API Key 後重試",
79
80
  "InvalidZhipuAPIKey": "Zhipu API Key 不正確或為空,請檢查 Zhipu API Key 後重試",
@@ -99,6 +100,7 @@
99
100
  "PluginOpenApiInitError": "很抱歉,OpenAPI 客戶端初始化失敗,請檢查 OpenAPI 的配置信息是否正確",
100
101
  "PluginServerError": "外掛伺服器請求回傳錯誤。請根據下面的錯誤資訊檢查您的外掛描述檔案、外掛設定或伺服器實作",
101
102
  "PluginSettingsInvalid": "該外掛需要正確設定後才可以使用。請檢查您的設定是否正確",
103
+ "QwenBizError": "請求通義千問服務出錯,請根據以下信息排查或重試",
102
104
  "TogetherAIBizError": "請求 TogetherAI AI 服務出錯,請根據以下信息排查或重試",
103
105
  "ZeroOneBizError": "請求零一萬物服務出錯,請根據以下信息排查或重試",
104
106
  "ZhipuBizError": "請求智譜服務出錯,請根據以下信息排查或重試"
@@ -217,6 +217,18 @@
217
217
  "title": "使用自定義 Perplexity API 金鑰"
218
218
  }
219
219
  },
220
+ "qwen": {
221
+ "title": "通義千問",
222
+ "token": {
223
+ "desc": "填入來自通義千問的 API 金鑰",
224
+ "placeholder": "通義千問 API 金鑰",
225
+ "title": "API 金鑰"
226
+ },
227
+ "unlock": {
228
+ "description": "輸入你的 通義千問 API 金鑰即可開始會話。應用不會記錄你的 API 金鑰",
229
+ "title": "使用自定義 通義千問 API 金鑰"
230
+ }
231
+ },
220
232
  "togetherai": {
221
233
  "checker": {
222
234
  "desc": "測試代理地址是否正確填寫"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.162.16",
3
+ "version": "0.162.17",
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",
@@ -0,0 +1,21 @@
1
+ 'use client';
2
+
3
+ import { Tongyi } from '@lobehub/icons';
4
+ import { memo } from 'react';
5
+
6
+ import { ModelProvider } from '@/libs/agent-runtime';
7
+
8
+ import ProviderConfig from '../components/ProviderConfig';
9
+
10
+ const QwenProvider = memo(() => {
11
+ return (
12
+ <ProviderConfig
13
+ checkModel={'qwen-turbo'}
14
+ modelList={{ showModelFetcher: true }}
15
+ provider={ModelProvider.Qwen}
16
+ title={<Tongyi.Combine extra={'千问'} size={26} type={'color'} />}
17
+ />
18
+ );
19
+ });
20
+
21
+ export default QwenProvider;
@@ -15,6 +15,7 @@ import Ollama from './Ollama';
15
15
  import OpenAI from './OpenAI';
16
16
  import OpenRouter from './OpenRouter';
17
17
  import Perplexity from './Perplexity';
18
+ import Qwen from './Qwen';
18
19
  import TogetherAI from './TogetherAI';
19
20
  import ZeroOne from './ZeroOne';
20
21
  import Zhipu from './Zhipu';
@@ -34,6 +35,7 @@ const Page = () => {
34
35
  <TogetherAI />
35
36
  <Groq />
36
37
  <Perplexity />
38
+ <Qwen />
37
39
  <Minimax />
38
40
  <Mistral />
39
41
  <Moonshot />
@@ -16,6 +16,7 @@ import {
16
16
  LobeOpenAI,
17
17
  LobeOpenRouterAI,
18
18
  LobePerplexityAI,
19
+ LobeQwenAI,
19
20
  LobeRuntimeAI,
20
21
  LobeTogetherAI,
21
22
  LobeZeroOneAI,
@@ -49,6 +50,7 @@ vi.mock('@/config/llm', () => ({
49
50
  MISTRAL_API_KEY: 'test-mistral-key',
50
51
  OPENROUTER_API_KEY: 'test-openrouter-key',
51
52
  TOGETHERAI_API_KEY: 'test-togetherai-key',
53
+ QWEN_API_KEY: 'test-qwen-key',
52
54
  })),
53
55
  }));
54
56
 
@@ -101,6 +103,13 @@ describe('initAgentRuntimeWithUserPayload method', () => {
101
103
  expect(runtime['_runtime']).toBeInstanceOf(LobeMoonshotAI);
102
104
  });
103
105
 
106
+ it('Qwen AI provider: with apikey', async () => {
107
+ const jwtPayload: JWTPayload = { apiKey: 'user-qwen-key' };
108
+ const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Qwen, jwtPayload);
109
+ expect(runtime).toBeInstanceOf(AgentRuntime);
110
+ expect(runtime['_runtime']).toBeInstanceOf(LobeQwenAI);
111
+ });
112
+
104
113
  it('Bedrock AI provider: with apikey, awsAccessKeyId, awsSecretAccessKey, awsRegion', async () => {
105
114
  const jwtPayload: JWTPayload = {
106
115
  apiKey: 'user-bedrock-key',
@@ -232,6 +241,14 @@ describe('initAgentRuntimeWithUserPayload method', () => {
232
241
  expect(runtime['_runtime']).toBeInstanceOf(LobeMoonshotAI);
233
242
  });
234
243
 
244
+ it('Qwen AI provider: without apikey', async () => {
245
+ const jwtPayload: JWTPayload = {};
246
+ const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Qwen, jwtPayload);
247
+
248
+ // 假设 LobeQwenAI 是 Qwen 提供者的实现类
249
+ expect(runtime['_runtime']).toBeInstanceOf(LobeQwenAI);
250
+ });
251
+
235
252
  it('Bedrock AI provider: without apikey', async () => {
236
253
  const jwtPayload = {};
237
254
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Bedrock, jwtPayload);
@@ -156,6 +156,13 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => {
156
156
 
157
157
  const apiKey = apiKeyManager.pick(payload?.apiKey || ZEROONE_API_KEY);
158
158
 
159
+ return { apiKey };
160
+ }
161
+ case ModelProvider.Qwen: {
162
+ const { QWEN_API_KEY } = getLLMConfig();
163
+
164
+ const apiKey = apiKeyManager.pick(payload?.apiKey || QWEN_API_KEY);
165
+
159
166
  return { apiKey };
160
167
  }
161
168
  }
@@ -138,6 +138,12 @@ describe('createErrorResponse', () => {
138
138
  const response = createErrorResponse(errorType);
139
139
  expect(response.status).toBe(486);
140
140
  });
141
+
142
+ it('returns a 487 status for QwenBizError error type', () => {
143
+ const errorType = AgentRuntimeErrorType.QwenBizError;
144
+ const response = createErrorResponse(errorType);
145
+ expect(response.status).toBe(487);
146
+ });
141
147
  });
142
148
 
143
149
  // 测试状态码不在200-599范围内的情况
@@ -68,6 +68,9 @@ const getStatus = (errorType: ILobeAgentRuntimeErrorType | ErrorType) => {
68
68
  case AgentRuntimeErrorType.DeepSeekBizError: {
69
69
  return 486;
70
70
  }
71
+ case AgentRuntimeErrorType.QwenBizError: {
72
+ return 487;
73
+ }
71
74
  }
72
75
  return errorType as number;
73
76
  };
@@ -14,6 +14,7 @@ import {
14
14
  OpenRouter,
15
15
  Perplexity,
16
16
  Together,
17
+ Tongyi,
17
18
  ZeroOne,
18
19
  Zhipu,
19
20
  } from '@lobehub/icons';
@@ -104,6 +105,10 @@ const ModelProviderIcon = memo<ModelProviderIconProps>(({ provider }) => {
104
105
  return <Together size={20} />;
105
106
  }
106
107
 
108
+ case ModelProvider.Qwen: {
109
+ return <Tongyi size={20} />;
110
+ }
111
+
107
112
  default: {
108
113
  return null;
109
114
  }
package/src/config/llm.ts CHANGED
@@ -114,6 +114,9 @@ export const getLLMConfig = () => {
114
114
  ENABLED_OLLAMA: z.boolean(),
115
115
  OLLAMA_PROXY_URL: z.string().optional(),
116
116
  OLLAMA_MODEL_LIST: z.string().optional(),
117
+
118
+ ENABLED_QWEN: z.boolean(),
119
+ QWEN_API_KEY: z.string().optional(),
117
120
  },
118
121
  runtimeEnv: {
119
122
  API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE,
@@ -182,6 +185,9 @@ export const getLLMConfig = () => {
182
185
  ENABLED_OLLAMA: process.env.ENABLED_OLLAMA !== '0',
183
186
  OLLAMA_PROXY_URL: process.env.OLLAMA_PROXY_URL || '',
184
187
  OLLAMA_MODEL_LIST: process.env.OLLAMA_MODEL_LIST || process.env.OLLAMA_CUSTOM_MODELS,
188
+
189
+ ENABLED_QWEN: !!process.env.QWEN_API_KEY,
190
+ QWEN_API_KEY: process.env.QWEN_API_KEY,
185
191
  },
186
192
  });
187
193
  };
@@ -13,12 +13,14 @@ import OllamaProvider from './ollama';
13
13
  import OpenAIProvider from './openai';
14
14
  import OpenRouterProvider from './openrouter';
15
15
  import PerplexityProvider from './perplexity';
16
+ import QwenProvider from './qwen';
16
17
  import TogetherAIProvider from './togetherai';
17
18
  import ZeroOneProvider from './zeroone';
18
19
  import ZhiPuProvider from './zhipu';
19
20
 
20
21
  export const LOBE_DEFAULT_MODEL_LIST: ChatModelCard[] = [
21
22
  OpenAIProvider.chatModels,
23
+ QwenProvider.chatModels,
22
24
  ZhiPuProvider.chatModels,
23
25
  BedrockProvider.chatModels,
24
26
  DeepSeekProvider.chatModels,
@@ -38,6 +40,7 @@ export const LOBE_DEFAULT_MODEL_LIST: ChatModelCard[] = [
38
40
  export const DEFAULT_MODEL_PROVIDER_LIST = [
39
41
  OpenAIProvider,
40
42
  { ...AzureProvider, chatModels: [] },
43
+ QwenProvider,
41
44
  OllamaProvider,
42
45
  AnthropicProvider,
43
46
  DeepSeekProvider,
@@ -71,6 +74,7 @@ export { default as OllamaProviderCard } from './ollama';
71
74
  export { default as OpenAIProviderCard } from './openai';
72
75
  export { default as OpenRouterProviderCard } from './openrouter';
73
76
  export { default as PerplexityProviderCard } from './perplexity';
77
+ export { default as QwenProviderCard } from './qwen';
74
78
  export { default as TogetherAIProviderCard } from './togetherai';
75
79
  export { default as ZeroOneProviderCard } from './zeroone';
76
80
  export { default as ZhiPuProviderCard } from './zhipu';
@@ -0,0 +1,32 @@
1
+ import { ModelProviderCard } from '@/types/llm';
2
+
3
+ // ref https://help.aliyun.com/zh/dashscope/developer-reference/api-details
4
+ const Qwen: ModelProviderCard = {
5
+ chatModels: [
6
+ {
7
+ description: '通义千问超大规模语言模型,支持中文、英文等不同语言输入。',
8
+ displayName: 'Qwen Turbo',
9
+ enabled: true,
10
+ id: 'qwen-turbo',
11
+ tokens: 8192,
12
+ },
13
+ {
14
+ description: '通义千问超大规模语言模型增强版,支持中文、英文等不同语言输入。',
15
+ displayName: 'Qwen Plus',
16
+ enabled: true,
17
+ id: 'qwen-plus',
18
+ tokens: 30_720,
19
+ },
20
+ {
21
+ description:
22
+ '通义千问千亿级别超大规模语言模型,支持中文、英文等不同语言输入,当前通义千问2.5产品版本背后的API模型。',
23
+ displayName: 'Qwen Max',
24
+ enabled: true,
25
+ id: 'qwen-max',
26
+ tokens: 8192,
27
+ },
28
+ ],
29
+ id: 'qwen',
30
+ };
31
+
32
+ export default Qwen;
@@ -11,6 +11,7 @@ import {
11
11
  OpenAIProviderCard,
12
12
  OpenRouterProviderCard,
13
13
  PerplexityProviderCard,
14
+ QwenProviderCard,
14
15
  TogetherAIProviderCard,
15
16
  ZeroOneProviderCard,
16
17
  ZhiPuProviderCard,
@@ -72,6 +73,10 @@ export const DEFAULT_LLM_CONFIG: UserModelProviderConfig = {
72
73
  enabled: false,
73
74
  enabledModels: filterEnabledModels(PerplexityProviderCard),
74
75
  },
76
+ qwen: {
77
+ enabled: false,
78
+ enabledModels: filterEnabledModels(QwenProviderCard),
79
+ },
75
80
  togetherai: {
76
81
  enabled: false,
77
82
  enabledModels: filterEnabledModels(TogetherAIProviderCard),
@@ -10,6 +10,7 @@ import {
10
10
  OpenRouter,
11
11
  Perplexity,
12
12
  Together,
13
+ Tongyi,
13
14
  ZeroOne,
14
15
  Zhipu,
15
16
  } from '@lobehub/icons';
@@ -66,6 +67,10 @@ const ProviderAvatar = memo<ProviderAvatarProps>(({ provider }) => {
66
67
  return <OpenRouter color={OpenRouter.colorPrimary} size={56} />;
67
68
  }
68
69
 
70
+ case ModelProvider.Qwen: {
71
+ return <Tongyi color={Tongyi.colorPrimary} size={56} />;
72
+ }
73
+
69
74
  case ModelProvider.TogetherAI: {
70
75
  return <Together color={Together.colorPrimary} size={56} />;
71
76
  }
@@ -47,6 +47,10 @@ const APIKeyForm = memo<APIKeyFormProps>(({ id, provider }) => {
47
47
  return 'sk_******************************';
48
48
  }
49
49
 
50
+ case ModelProvider.Qwen: {
51
+ return 'sk-********************************';
52
+ }
53
+
50
54
  default: {
51
55
  return '*********************************';
52
56
  }
@@ -88,6 +88,7 @@ const ErrorMessageExtra = memo<{ data: ChatMessage }>(({ data }) => {
88
88
  case AgentRuntimeErrorType.InvalidAnthropicAPIKey:
89
89
  case AgentRuntimeErrorType.InvalidGroqAPIKey:
90
90
  case AgentRuntimeErrorType.InvalidOpenRouterAPIKey:
91
+ case AgentRuntimeErrorType.InvalidQwenAPIKey:
91
92
  case AgentRuntimeErrorType.InvalidTogetherAIAPIKey:
92
93
  case AgentRuntimeErrorType.InvalidZeroOneAPIKey:
93
94
  case AgentRuntimeErrorType.NoOpenAIAPIKey: {
@@ -16,6 +16,7 @@ import { LobeOllamaAI } from './ollama';
16
16
  import { LobeOpenAI } from './openai';
17
17
  import { LobeOpenRouterAI } from './openrouter';
18
18
  import { LobePerplexityAI } from './perplexity';
19
+ import { LobeQwenAI } from './qwen';
19
20
  import { LobeTogetherAI } from './togetherai';
20
21
  import {
21
22
  ChatCompetitionOptions,
@@ -112,6 +113,7 @@ class AgentRuntime {
112
113
  openai: Partial<ClientOptions>;
113
114
  openrouter: Partial<ClientOptions>;
114
115
  perplexity: Partial<ClientOptions>;
116
+ qwen: Partial<ClientOptions>;
115
117
  togetherai: Partial<ClientOptions>;
116
118
  zeroone: Partial<ClientOptions>;
117
119
  zhipu: Partial<ClientOptions>;
@@ -175,7 +177,7 @@ class AgentRuntime {
175
177
  runtimeModel = new LobeDeepSeekAI(params.deepseek ?? {});
176
178
  break;
177
179
  }
178
-
180
+
179
181
  case ModelProvider.Minimax: {
180
182
  runtimeModel = new LobeMinimaxAI(params.minimax ?? {});
181
183
  break;
@@ -205,6 +207,11 @@ class AgentRuntime {
205
207
  runtimeModel = new LobeZeroOneAI(params.zeroone ?? {});
206
208
  break;
207
209
  }
210
+
211
+ case ModelProvider.Qwen: {
212
+ runtimeModel = new LobeQwenAI(params.qwen ?? {});
213
+ break;
214
+ }
208
215
  }
209
216
 
210
217
  return new AgentRuntime(runtimeModel);
@@ -52,6 +52,9 @@ export const AgentRuntimeErrorType = {
52
52
 
53
53
  InvalidDeepSeekAPIKey: 'InvalidDeepSeekAPIKey',
54
54
  DeepSeekBizError: 'DeepSeekBizError',
55
+
56
+ InvalidQwenAPIKey: 'InvalidQwenAPIKey',
57
+ QwenBizError: 'QwenBizError',
55
58
  } as const;
56
59
 
57
60
  export type ILobeAgentRuntimeErrorType =
@@ -14,6 +14,7 @@ export { LobeOllamaAI } from './ollama';
14
14
  export { LobeOpenAI } from './openai';
15
15
  export { LobeOpenRouterAI } from './openrouter';
16
16
  export { LobePerplexityAI } from './perplexity';
17
+ export { LobeQwenAI } from './qwen';
17
18
  export { LobeTogetherAI } from './togetherai';
18
19
  export * from './types';
19
20
  export { AgentRuntimeError } from './utils/createError';