@lobehub/chat 0.123.1 → 0.123.3

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 (44) hide show
  1. package/.env.example +3 -3
  2. package/CHANGELOG.md +50 -0
  3. package/Dockerfile +1 -1
  4. package/README.md +7 -9
  5. package/README.zh-CN.md +7 -9
  6. package/docs/Deployment/Environment-Variable.md +3 -2
  7. package/docs/Deployment/Environment-Variable.zh-CN.md +3 -2
  8. package/locales/ar/common.json +1 -0
  9. package/locales/de-DE/common.json +1 -0
  10. package/locales/en-US/common.json +1 -0
  11. package/locales/es-ES/common.json +1 -0
  12. package/locales/fr-FR/common.json +1 -0
  13. package/locales/it-IT/common.json +1 -0
  14. package/locales/ja-JP/common.json +1 -0
  15. package/locales/ko-KR/common.json +1 -0
  16. package/locales/nl-NL/common.json +1 -0
  17. package/locales/pl-PL/common.json +1 -0
  18. package/locales/pt-BR/common.json +1 -0
  19. package/locales/ru-RU/common.json +1 -0
  20. package/locales/tr-TR/common.json +1 -0
  21. package/locales/vi-VN/common.json +1 -0
  22. package/locales/zh-CN/common.json +1 -0
  23. package/locales/zh-TW/common.json +1 -0
  24. package/package.json +3 -1
  25. package/src/app/api/chat/[provider]/route.ts +7 -5
  26. package/src/app/api/chat/auth.ts +13 -2
  27. package/src/app/api/chat/google/route.ts +1 -1
  28. package/src/app/api/errorResponse.ts +9 -11
  29. package/src/components/ModelProviderIcon/index.tsx +4 -1
  30. package/src/components/ModelSelect/index.tsx +8 -2
  31. package/src/config/modelProviders/openai.ts +3 -0
  32. package/src/const/auth.ts +1 -0
  33. package/src/features/Conversation/Error/index.tsx +2 -7
  34. package/src/layout/GlobalLayout/Locale.tsx +1 -0
  35. package/src/libs/agent-runtime/error.ts +3 -4
  36. package/src/libs/agent-runtime/types/type.ts +1 -1
  37. package/src/libs/agent-runtime/utils/createError.ts +1 -1
  38. package/src/locales/default/common.ts +1 -0
  39. package/src/services/_auth.ts +3 -29
  40. package/src/store/global/slices/settings/selectors/__snapshots__/modelProvider.test.ts.snap +1 -0
  41. package/src/store/global/slices/settings/selectors/modelProvider.test.ts +57 -0
  42. package/src/store/global/slices/settings/selectors/modelProvider.ts +19 -17
  43. package/src/utils/jwt.test.ts +26 -0
  44. package/src/utils/jwt.ts +37 -0
package/.env.example CHANGED
@@ -40,13 +40,13 @@ OPENAI_API_KEY=sk-xxxxxxxxx
40
40
  #ZHIPU_API_KEY=xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxx
41
41
 
42
42
  ########################################
43
- ############ Google AI Service ##########
43
+ ########### Google AI Service ##########
44
44
  ########################################
45
45
 
46
- #GOOGLE_API_KEY=xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxx
46
+ #GOOGLE_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
47
47
 
48
48
  ########################################
49
- ############ AWS Bedrock Service ##########
49
+ ######### AWS Bedrock Service ##########
50
50
  ########################################
51
51
 
52
52
  #AWS_REGION=us-east-1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.123.3](https://github.com/lobehub/lobe-chat/compare/v0.123.2...v0.123.3)
6
+
7
+ <sup>Released on **2024-02-06**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix non-https `crypto.subtile` missing error.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix non-https `crypto.subtile` missing error, closes [#1238](https://github.com/lobehub/lobe-chat/issues/1238) ([1750d0b](https://github.com/lobehub/lobe-chat/commit/1750d0b))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 0.123.2](https://github.com/lobehub/lobe-chat/compare/v0.123.1...v0.123.2)
31
+
32
+ <sup>Released on **2024-02-06**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Fix docker build.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Fix docker build, closes [#1231](https://github.com/lobehub/lobe-chat/issues/1231) ([e180722](https://github.com/lobehub/lobe-chat/commit/e180722))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 0.123.1](https://github.com/lobehub/lobe-chat/compare/v0.123.0...v0.123.1)
6
56
 
7
57
  <sup>Released on **2024-02-05**</sup>
package/Dockerfile CHANGED
@@ -73,6 +73,6 @@ ENV AZURE_API_VERSION ""
73
73
  ENV GOOGLE_API_KEY ""
74
74
 
75
75
  # Zhipu
76
- ENV Zhipu_API_KEY ""
76
+ ENV ZHIPU_API_KEY ""
77
77
 
78
78
  CMD ["node", "server.js"]
package/README.md CHANGED
@@ -193,7 +193,7 @@ e-commerce platform data access, and various third-party services.
193
193
  | [TokenInsights](https://chat-preview.lobehub.com/settings/agent)<br/><sup>By **feednews** on **2024-01-27**</sup> | Get realtime crypto price, BTC, ETH, BNB, and the latest insights.The latest coin news and airdrop opportunities.<br/>`crypto` `btc` `eth` `bnb` |
194
194
  | [Bilibili](https://chat-preview.lobehub.com/settings/agent)<br/><sup>By **LobeHub** on **2024-01-27**</sup> | Dive into Bilibili's vast content with features like keyword video search, replay access, interactive danmaku, trending video recommendations, and hot-search insights, all at your fingertips.<br/>`video` `bilibili` `search` |
195
195
 
196
- > 📊 Total plugins: [<kbd>**62**</kbd>](https://github.com/lobehub/lobe-chat-plugins)
196
+ > 📊 Total plugins: [<kbd>**61**</kbd>](https://github.com/lobehub/lobe-chat-plugins)
197
197
 
198
198
  <!-- PLUGIN LIST -->
199
199
 
@@ -225,14 +225,12 @@ Our marketplace is not just a showcase platform but also a collaborative space.
225
225
 
226
226
  <!-- AGENT LIST -->
227
227
 
228
- | Recent Submits | Description |
229
- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
230
- | [Database Expert](https://chat-preview.lobehub.com/market?agent=dba)<br/><sup>By **[xuzhen1994](https://github.com/xuzhen1994)** on **2024-02-03**</sup> | Role: Database Expert |
231
- | Expertise: Possesses professional knowledge in the field of databases. Understands the working principles, advantages and disadvantages, applicable scenarios, and best practices of relational databases such as MySQL, PostgreSQL, Oracle, etc. Also familiar with the characteristics and usage scenarios of non-relational databases like MongoDB, Cassandra, Redis, as well as the advantages and applicable situations of columnar databases such as ClickHouse, Vertica, etc. Additionally, has knowledge of distributed database systems like Doris, HBase, CockroachDB, including their principles and applications. | |
232
- | Responsibilities: Provides professional advice on database design paradigms, index optimization, query performance tuning, data security, backup and recovery, and advanced topics such as database cluster deployment, disaster recovery design, and data migration.<br/>`database` `dba` `mysql` `clickhouse` `doris` `mongo-db` `oracle` | |
233
- | [Presentation Wizard](https://chat-preview.lobehub.com/market?agent=word)<br/><sup>By **[MYSeaIT](https://github.com/MYSeaIT)** on **2024-02-03**</sup> | App Presentation Maker Bot for Word: Assists in creating impressive and professional app presentations in Microsoft Word.<br/>`app-presentation` `microsoft-word` `bot` `assistance` `template` |
234
- | [SagePathfinder](https://chat-preview.lobehub.com/market?agent=sage-pathfinder)<br/><sup>By **[Ajasra](https://github.com/Ajasra)** on **2024-01-31**</sup> | Expert in personal growth coaching with a focus on stoicism, deep reflection, and strategic questioning.<br/>`personal-growth` `coaching` `reflection` `goal-setting` `well-being` |
235
- | [Variable Naming Master](https://chat-preview.lobehub.com/market?agent=variable-naming-assistant)<br/><sup>By **[undefinedZNN](https://github.com/undefinedZNN)** on **2024-01-31**</sup> | Master the art of programming variable naming, providing multiple suggestions and explaining their usage scenarios.<br/>`variable-naming` `programming` `suggestions` |
228
+ | Recent Submits | Description |
229
+ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
230
+ | [Database Expert](https://chat-preview.lobehub.com/market?agent=dba)<br/><sup>By **[xuzhen1994](https://github.com/xuzhen1994)** on **2024-02-03**</sup> | Provides professional advice on database design paradigms, index optimization, query performance tuning, data security, backup and recovery.<br/>`database` `dba` `mysql` `clickhouse` `doris` `mongo-db` `oracle` |
231
+ | [Presentation Wizard](https://chat-preview.lobehub.com/market?agent=word)<br/><sup>By **[MYSeaIT](https://github.com/MYSeaIT)** on **2024-02-03**</sup> | App Presentation Maker Bot for Word: Assists in creating impressive and professional app presentations in Microsoft Word.<br/>`app-presentation` `microsoft-word` `bot` `assistance` `template` |
232
+ | [SagePathfinder](https://chat-preview.lobehub.com/market?agent=sage-pathfinder)<br/><sup>By **[Ajasra](https://github.com/Ajasra)** on **2024-01-31**</sup> | Expert in personal growth coaching with a focus on stoicism, deep reflection, and strategic questioning.<br/>`personal-growth` `coaching` `reflection` `goal-setting` `well-being` |
233
+ | [Variable Naming Master](https://chat-preview.lobehub.com/market?agent=variable-naming-assistant)<br/><sup>By **[undefinedZNN](https://github.com/undefinedZNN)** on **2024-01-31**</sup> | Master the art of programming variable naming, providing multiple suggestions and explaining their usage scenarios.<br/>`variable-naming` `programming` `suggestions` |
236
234
 
237
235
  > 📊 Total agents: [<kbd>**149**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
238
236
 
package/README.zh-CN.md CHANGED
@@ -177,7 +177,7 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
177
177
  | [TokenInsights](https://chat-preview.lobehub.com/settings/agent)<br/><sup>By **feednews** on **2024-01-27**</sup> | 获取实时加密货币价格,BTC,ETH,BNB 和最新见解。最新的币新闻和空投机会。<br/>`加密货币` `btc` `eth` `bnb` |
178
178
  | [哔哩哔哩](https://chat-preview.lobehub.com/settings/agent)<br/><sup>By **LobeHub** on **2024-01-27**</sup> | 通过关键词视频搜索、回放访问、互动弹幕、热门视频推荐和热搜洞察等功能,深入体验哔哩哔哩丰富的内容,尽在您的指尖。<br/>`视频` `哔哩哔哩` `搜索` |
179
179
 
180
- > 📊 Total plugins: [<kbd>**62**</kbd>](https://github.com/lobehub/lobe-chat-plugins)
180
+ > 📊 Total plugins: [<kbd>**61**</kbd>](https://github.com/lobehub/lobe-chat-plugins)
181
181
 
182
182
  <!-- PLUGIN LIST -->
183
183
 
@@ -205,14 +205,12 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
205
205
 
206
206
  <!-- AGENT LIST -->
207
207
 
208
- | 最近新增 | 助手说明 |
209
- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
210
- | [数据库专家](https://chat-preview.lobehub.com/market?agent=dba)<br/><sup>By **[xuzhen1994](https://github.com/xuzhen1994)** on **2024-02-03**</sup> | 角色:数据库专家 |
211
- | 专长:具备数据库方面的专业知识。关系型数据库,比如 MySQL、PostgreSQL、Oracle 等的工作原理、优缺点、适用场景以及最佳实践。非关系型数据库,比如 MongoDB、Cassandra、Redis 等的特点和使用场景。列式数据库,例如 ClickHouse、Vertica 等的优势和适用情况。分布式数据库系统,例如 Doris、HBase、CockroachDB 等的原理和应用等。 | |
212
- | 职责:提供关于数据库设计范式、索引优化、查询性能调优、数据安全、备份与恢复等方面的专业建议。另外还有对于数据库集群部署、容灾设计、数据迁移等高级主题的指导。<br/>`数据库` `dba` `mysql` `clickhouse` `doris` `mongo-db` `oracle` | |
213
- | [演示向导](https://chat-preview.lobehub.com/market?agent=word)<br/><sup>By **[MYSeaIT](https://github.com/MYSeaIT)** on **2024-02-03**</sup> | Word 应用演示制作机器人:帮助在 Microsoft Word 中创建令人印象深刻和专业的应用程序演示。<br/>`应用程序演示` `微软-word` `机器人` `辅助` `模板` |
214
- | [SagePathfinder](https://chat-preview.lobehub.com/market?agent=sage-pathfinder)<br/><sup>By **[Ajasra](https://github.com/Ajasra)** on **2024-01-31**</sup> | 专注于斯多葛主义、深度反思和战略性提问的个人成长教练专家。<br/>`个人成长` `教练` `反思` `目标设定` `幸福感` |
215
- | [变量命名大师](https://chat-preview.lobehub.com/market?agent=variable-naming-assistant)<br/><sup>By **[undefinedZNN](https://github.com/undefinedZNN)** on **2024-01-31**</sup> | 精通编程变量命名,提供多个建议并解释使用场景。<br/>`变量命名` `编程` `建议` |
208
+ | 最近新增 | 助手说明 |
209
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
210
+ | [数据库专家](https://chat-preview.lobehub.com/market?agent=dba)<br/><sup>By **[xuzhen1994](https://github.com/xuzhen1994)** on **2024-02-03**</sup> | 提供关于数据库设计范式、索引优化、查询性能调优、数据安全、备份与恢复等方面的专业建议<br/>`数据库` `dba` `mysql` `clickhouse` `doris` `mongo-db` `oracle` |
211
+ | [演示向导](https://chat-preview.lobehub.com/market?agent=word)<br/><sup>By **[MYSeaIT](https://github.com/MYSeaIT)** on **2024-02-03**</sup> | Word 应用演示制作机器人:帮助在 Microsoft Word 中创建令人印象深刻和专业的应用程序演示。<br/>`应用程序演示` `微软-word` `机器人` `辅助` `模板` |
212
+ | [SagePathfinder](https://chat-preview.lobehub.com/market?agent=sage-pathfinder)<br/><sup>By **[Ajasra](https://github.com/Ajasra)** on **2024-01-31**</sup> | 专注于斯多葛主义、深度反思和战略性提问的个人成长教练专家。<br/>`个人成长` `教练` `反思` `目标设定` `幸福感` |
213
+ | [变量命名大师](https://chat-preview.lobehub.com/market?agent=variable-naming-assistant)<br/><sup>By **[undefinedZNN](https://github.com/undefinedZNN)** on **2024-01-31**</sup> | 精通编程变量命名,提供多个建议并解释使用场景。<br/>`变量命名` `编程` `建议` |
216
214
 
217
215
  > 📊 Total agents: [<kbd>**149**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
218
216
 
@@ -8,7 +8,6 @@ LobeChat provides additional configuration options during deployment, which can
8
8
  - [`ACCESS_CODE`](#access_code)
9
9
  - [Model Service Providers](#model-service-providers)
10
10
  - [OpenAI](#openai)
11
- - [`CUSTOM_MODELS`](#custom_models)
12
11
  - [Azure OpenAI](#azure-openai)
13
12
  - [Zhipu AI](#zhipu-ai)
14
13
  - [Google AI](#google-ai)
@@ -62,7 +61,7 @@ Related discussions:
62
61
  - [Reasons for errors when using third-party interfaces](https://github.com/lobehub/lobe-chat/discussions/734)
63
62
  - [No response when filling in the proxy server address for chatting](https://github.com/lobehub/lobe-chat/discussions/1065)
64
63
 
65
- ### `CUSTOM_MODELS`
64
+ #### `CUSTOM_MODELS`
66
65
 
67
66
  - Type: Optional
68
67
  - Description: Used to control the model list. Use `+` to add a model, `-` to hide a model, and `model_name=display_name` to customize the display name of a model, separated by commas.
@@ -71,6 +70,8 @@ Related discussions:
71
70
 
72
71
  The above example adds `qwen-7b-chat` and `glm-6b` to the model list, removes `gpt-3.5-turbo` from the list, and displays the model name `gpt-4-0125-preview` as `gpt-4-turbo`. If you want to disable all models first and then enable specific models, you can use `-all,+gpt-3.5-turbo`, which means only `gpt-3.5-turbo` will be enabled.
73
72
 
73
+ You can find all current model names in [modelProviders](https://github.com/lobehub/lobe-chat/tree/main/src/config/modelProviders).
74
+
74
75
  ### Azure OpenAI
75
76
 
76
77
  If you need to use Azure OpenAI to provide model services, you can refer to the [Deploy with Azure OpenAI](Deploy-with-Azure-OpenAI.zh-CN.md) section for detailed steps. Here are the environment variables related to Azure OpenAI.
@@ -8,7 +8,6 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
8
8
  - [`ACCESS_CODE`](#access_code)
9
9
  - [模型服务商](#模型服务商)
10
10
  - [OpenAI](#openai)
11
- - [`CUSTOM_MODELS`](#custom_models)
12
11
  - [Azure OpenAI](#azure-openai)
13
12
  - [智谱 AI](#智谱-ai)
14
13
  - [Google AI](#google-ai)
@@ -62,7 +61,7 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
62
61
  - [使用第三方接口报错的原因](https://github.com/lobehub/lobe-chat/discussions/734)
63
62
  - [代理服务器地址填了聊天没任何反应](https://github.com/lobehub/lobe-chat/discussions/1065)
64
63
 
65
- ### `CUSTOM_MODELS`
64
+ #### `CUSTOM_MODELS`
66
65
 
67
66
  - 类型:可选
68
67
  - 描述:用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。
@@ -71,6 +70,8 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
71
70
 
72
71
  上面示例表示增加 `qwen-7b-chat` 和 `glm-6b` 到模型列表,而从列表中删除 `gpt-3.5-turbo`,并将 `gpt-4-0125-preview` 模型名字展示为 `gpt-4-turbo`。如果你想先禁用所有模型,再启用指定模型,可以使用 `-all,+gpt-3.5-turbo`,则表示仅启用 `gpt-3.5-turbo`。
73
72
 
73
+ 你可以在 [modelProviders](https://github.com/lobehub/lobe-chat/tree/main/src/config/modelProviders) 查找到当前的所有模型名。
74
+
74
75
  ### Azure OpenAI
75
76
 
76
77
  如果你需要使用 Azure OpenAI 来提供模型服务,可以查阅 [使用 Azure OpenAI 部署](Deploy-with-Azure-OpenAI.zh-CN.md) 章节查看详细步骤,这里将列举和 Azure OpenAI 相关的环境变量。
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "نموذج مخصص، يدعم الوظائف والتعرف على الرؤية، يرجى التحقق من قدرة النموذج على القيام بذلك وفقًا للحالة الفعلية",
5
+ "file": "يدعم هذا النموذج قراءة وتعرف على الملفات المرفقة",
5
6
  "functionCall": "يدعم هذا النموذج استدعاء الوظائف",
6
7
  "tokens": "هذا النموذج يدعم حتى {{tokens}} رموز في جلسة واحدة",
7
8
  "vision": "يدعم هذا النموذج التعرف على الرؤية"
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Benutzerdefiniertes Modell, das standardmäßig sowohl Funktionsaufrufe als auch visuelle Erkennung unterstützt. Bitte überprüfen Sie die Verfügbarkeit dieser Fähigkeiten basierend auf den tatsächlichen Anforderungen.",
5
+ "file": "Dieses Modell unterstützt das Hochladen von Dateien zur Erkennung.",
5
6
  "functionCall": "Dieses Modell unterstützt Funktionsaufrufe (Function Call).",
6
7
  "tokens": "Dieses Modell unterstützt maximal {{tokens}} Tokens pro einzelner Sitzung.",
7
8
  "vision": "Dieses Modell unterstützt visuelle Erkennung."
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Custom model, by default, supports both function call and visual recognition. Please verify the availability of the above capabilities based on actual situations.",
5
+ "file": "This model supports file upload for reading and recognition",
5
6
  "functionCall": "This model supports function call.",
6
7
  "tokens": "This model supports a maximum of {{tokens}} tokens per session.",
7
8
  "vision": "This model supports visual recognition."
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Modelo personalizado: admite tanto la llamada de funciones como el reconocimiento visual. Por favor, verifique la disponibilidad de estas capacidades según sea necesario.",
5
+ "file": "Este modelo admite la carga y reconocimiento de archivos",
5
6
  "functionCall": "Este modelo admite la llamada de funciones (Function Call).",
6
7
  "tokens": "Este modelo admite un máximo de {{tokens}} tokens por sesión.",
7
8
  "vision": "Este modelo admite el reconocimiento visual."
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Modèle personnalisé, par défaut prend en charge à la fois l'appel de fonction et la reconnaissance visuelle. Veuillez vérifier la disponibilité de ces capacités selon les besoins réels.",
5
+ "file": "Ce modèle prend en charge la lecture et la reconnaissance de fichiers",
5
6
  "functionCall": "Ce modèle prend en charge l'appel de fonction (Function Call).",
6
7
  "tokens": "Ce modèle prend en charge jusqu'à {{tokens}} jetons par session.",
7
8
  "vision": "Ce modèle prend en charge la reconnaissance visuelle."
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Modello personalizzato, di default supporta sia la chiamata di funzioni che il riconoscimento visivo. Si prega di verificare l'effettiva disponibilità di tali funzionalità in base alle esigenze specifiche.",
5
+ "file": "Questo modello supporta il caricamento e il riconoscimento dei file",
5
6
  "functionCall": "Questo modello supporta la chiamata di funzioni (Function Call)",
6
7
  "tokens": "Questo modello supporta un massimo di {{tokens}} token per singola sessione",
7
8
  "vision": "Questo modello supporta il riconoscimento visivo"
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "カスタムモデル、デフォルトでは関数呼び出しとビジョン認識の両方をサポートしています。上記の機能の有効性を実際の状況で検証してください。",
5
+ "file": "このモデルはファイルのアップロードと認識をサポートしています",
5
6
  "functionCall": "このモデルは関数呼び出し(Function Call)をサポートしています。",
6
7
  "tokens": "このモデルは1つのセッションあたり最大{{tokens}}トークンをサポートしています。",
7
8
  "vision": "このモデルはビジョン認識をサポートしています。"
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "사용자 정의 모델, 기본적으로 함수 호출 및 시각 인식을 모두 지원하며, 상기 기능의 가용성을 실제로 확인하십시오",
5
+ "file": "이 모델은 파일 업로드를 지원하여 인식할 수 있습니다.",
5
6
  "functionCall": "이 모델은 함수 호출을 지원합니다",
6
7
  "tokens": "이 모델은 단일 세션당 최대 {{tokens}} 토큰을 지원합니다",
7
8
  "vision": "이 모델은 시각 인식을 지원합니다"
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Aangepast model, standaard ingesteld om zowel functieoproep als visuele herkenning te ondersteunen. Verifieer de beschikbaarheid van deze mogelijkheden op basis van de werkelijke situatie.",
5
+ "file": "Dit model ondersteunt het uploaden van bestanden voor lezen en herkenning",
5
6
  "functionCall": "Dit model ondersteunt functieoproep (Function Call).",
6
7
  "tokens": "Dit model ondersteunt maximaal {{tokens}} tokens per sessie.",
7
8
  "vision": "Dit model ondersteunt visuele herkenning."
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Niestandardowy model, domyślnie obsługujący zarówno wywołania funkcji, jak i rozpoznawanie wizualne. Proszę zweryfikować możliwość użycia tych funkcji w praktyce.",
5
+ "file": "Ten model obsługuje wczytywanie plików i rozpoznawanie",
5
6
  "functionCall": "Ten model obsługuje wywołania funkcji (Function Call).",
6
7
  "tokens": "Ten model obsługuje maksymalnie {{tokens}} tokenów w pojedynczej sesji.",
7
8
  "vision": "Ten model obsługuje rozpoznawanie wizualne."
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Modelo personalizado, suporta chamadas de função e reconhecimento visual. Por favor, verifique a disponibilidade dessas capacidades de acordo com a situação real.",
5
+ "file": "Este modelo suporta o carregamento de arquivos para leitura e reconhecimento",
5
6
  "functionCall": "Este modelo suporta chamadas de função (Function Call)",
6
7
  "tokens": "Este modelo suporta no máximo {{tokens}} tokens por sessão",
7
8
  "vision": "Este modelo suporta reconhecimento visual"
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Пользовательская модель. По умолчанию поддерживает как вызов функций, так и визуальное распознавание. Пожалуйста, проверьте возможность использования указанных функций в вашем конкретном случае.",
5
+ "file": "Эта модель поддерживает загрузку файлов для чтения и распознавания",
5
6
  "functionCall": "Эта модель поддерживает вызов функций (Function Call).",
6
7
  "tokens": "Эта модель поддерживает до {{tokens}} токенов в одной сессии.",
7
8
  "vision": "Эта модель поддерживает визуальное распознавание."
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Özel model, varsayılan olarak hem fonksiyon çağrısını hem de görüntü tanımayı destekler, lütfen yukarıdaki yeteneklerin kullanılabilirliğini doğrulayın",
5
+ "file": "Bu model dosya yükleme ve tanıma desteği sağlar",
5
6
  "functionCall": "Bu model fonksiyon çağrısını destekler (Function Call)",
6
7
  "tokens": "Bu model, tek bir oturumda en fazla {{tokens}} Token'ı destekler",
7
8
  "vision": "Bu model görüntü tanımı destekler"
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "Chọn mô hình tùy chỉnh, mặc định hỗ trợ cả cuộc gọi hàm và nhận diện thị giác, vui lòng xác minh khả năng sử dụng của các tính năng trên dựa trên tình hình thực tế",
5
+ "file": "Mô hình này hỗ trợ tải lên tệp để đọc và nhận dạng",
5
6
  "functionCall": "Mô hình này hỗ trợ cuộc gọi hàm (Function Call)",
6
7
  "tokens": "Mô hình này hỗ trợ tối đa {{tokens}} Tokens cho mỗi phiên",
7
8
  "vision": "Mô hình này hỗ trợ nhận diện thị giác"
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "自定义模型,默认设定同时支持函数调用与视觉识别,请根据实际情况验证上述能力的可用性",
5
+ "file": "该模型支持上传文件读取与识别",
5
6
  "functionCall": "该模型支持函数调用(Function Call)",
6
7
  "tokens": "该模型单个会话最多支持 {{tokens}} Tokens",
7
8
  "vision": "该模型支持视觉识别"
@@ -2,6 +2,7 @@
2
2
  "ModelSelect": {
3
3
  "featureTag": {
4
4
  "custom": "自訂模型,預設支援函數呼叫與視覺辨識,請根據實際情況驗證上述能力的可用性",
5
+ "file": "該模型支援上傳檔案讀取與識別",
5
6
  "functionCall": "該模型支援函數呼叫(Function Call)",
6
7
  "tokens": "該模型單個會話最多支援 {{tokens}} Tokens",
7
8
  "vision": "該模型支援視覺辨識"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.123.1",
3
+ "version": "0.123.3",
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",
@@ -84,6 +84,7 @@
84
84
  "@lobehub/tts": "latest",
85
85
  "@lobehub/ui": "latest",
86
86
  "@vercel/analytics": "^1",
87
+ "ahooks": "^3",
87
88
  "ai": "^2",
88
89
  "antd": "^5",
89
90
  "antd-style": "^3",
@@ -144,6 +145,7 @@
144
145
  "@lobehub/lint": "latest",
145
146
  "@next/bundle-analyzer": "^14",
146
147
  "@next/eslint-plugin-next": "^14",
148
+ "@peculiar/webcrypto": "^1.4.5",
147
149
  "@testing-library/jest-dom": "^6",
148
150
  "@testing-library/react": "^14",
149
151
  "@types/chroma-js": "^2",
@@ -40,11 +40,13 @@ export const POST = async (req: Request, { params }: { params: { provider: strin
40
40
  } catch (e) {
41
41
  // if catch the error, just return it
42
42
  const err = e as AgentInitErrorPayload;
43
-
44
- return createErrorResponse(err.type as ILobeAgentRuntimeErrorType, {
45
- error: err.error,
46
- provider: params.provider,
47
- });
43
+ return createErrorResponse(
44
+ (err.errorType || ChatErrorType.InternalServerError) as ILobeAgentRuntimeErrorType,
45
+ {
46
+ error: err.error || e,
47
+ provider: params.provider,
48
+ },
49
+ );
48
50
  }
49
51
 
50
52
  // ============ 2. create chat completion ============ //
@@ -1,11 +1,22 @@
1
1
  import { importJWK, jwtVerify } from 'jose';
2
2
 
3
3
  import { getServerConfig } from '@/config/server';
4
- import { JWTPayload, JWT_SECRET_KEY } from '@/const/auth';
4
+ import { JWTPayload, JWT_SECRET_KEY, NON_HTTP_PREFIX } from '@/const/auth';
5
5
  import { AgentRuntimeError } from '@/libs/agent-runtime';
6
6
  import { ChatErrorType } from '@/types/fetch';
7
7
 
8
- export const getJWTPayload = async (token: string) => {
8
+ export const getJWTPayload = async (token: string): Promise<JWTPayload> => {
9
+ //如果是 HTTP 协议发起的请求,直接解析 token
10
+ // 这是一个非常 hack 的解决方案,未来要找更好的解决方案来处理这个问题
11
+ // refs: https://github.com/lobehub/lobe-chat/pull/1238
12
+ if (token.startsWith(NON_HTTP_PREFIX)) {
13
+ const jwtParts = token.split('.');
14
+
15
+ const payload = jwtParts[1];
16
+
17
+ return JSON.parse(atob(payload));
18
+ }
19
+
9
20
  const encoder = new TextEncoder();
10
21
  const secretKey = await crypto.subtle.digest('SHA-256', encoder.encode(JWT_SECRET_KEY));
11
22
 
@@ -63,7 +63,7 @@ export const POST = async (req: Request) => {
63
63
  // if catch the error, just return it
64
64
  const err = e as AgentInitErrorPayload;
65
65
 
66
- return createErrorResponse(err.type as ILobeAgentRuntimeErrorType, {
66
+ return createErrorResponse(err.errorType as ILobeAgentRuntimeErrorType, {
67
67
  error: err.error,
68
68
  provider: 'google',
69
69
  });
@@ -1,16 +1,13 @@
1
- import { consola } from 'consola';
2
-
3
1
  import { AgentRuntimeErrorType, ILobeAgentRuntimeErrorType } from '@/libs/agent-runtime';
4
- import { ChatErrorType, ErrorResponse, ErrorType } from '@/types/fetch';
2
+ import { ErrorResponse, ErrorType } from '@/types/fetch';
5
3
 
6
4
  const getStatus = (errorType: ILobeAgentRuntimeErrorType | ErrorType) => {
5
+ // InvalidAccessCode / InvalidAzureAPIKey / InvalidOpenAIAPIKey / InvalidZhipuAPIKey ....
6
+ if (errorType.toString().includes('Invalid')) return 401;
7
+
7
8
  switch (errorType) {
8
- case ChatErrorType.InvalidAccessCode:
9
- case AgentRuntimeErrorType.NoOpenAIAPIKey:
10
- case AgentRuntimeErrorType.InvalidAzureAPIKey:
11
- case AgentRuntimeErrorType.InvalidBedrockCredentials:
12
- case AgentRuntimeErrorType.InvalidZhipuAPIKey:
13
- case AgentRuntimeErrorType.InvalidGoogleAPIKey: {
9
+ // TODO: Need to refactor to Invalid OpenAI API Key
10
+ case AgentRuntimeErrorType.NoOpenAIAPIKey: {
14
11
  return 401;
15
12
  }
16
13
 
@@ -38,7 +35,8 @@ const getStatus = (errorType: ILobeAgentRuntimeErrorType | ErrorType) => {
38
35
  return 475;
39
36
  }
40
37
  }
41
- return errorType;
38
+
39
+ return errorType as number;
42
40
  };
43
41
 
44
42
  export const createErrorResponse = (
@@ -50,7 +48,7 @@ export const createErrorResponse = (
50
48
  const data: ErrorResponse = { body, errorType };
51
49
 
52
50
  if (typeof statusCode !== 'number' || statusCode < 200 || statusCode > 599) {
53
- consola.error(
51
+ console.error(
54
52
  `current StatusCode: \`${statusCode}\` .`,
55
53
  'Please go to `./src/app/api/errorResponse.ts` to defined the statusCode.',
56
54
  );
@@ -34,10 +34,13 @@ const ModelProviderIcon = memo<ModelProviderIconProps>(({ provider }) => {
34
34
  );
35
35
  }
36
36
 
37
- default:
38
37
  case ModelProvider.OpenAI: {
39
38
  return <OpenAI size={20} />;
40
39
  }
40
+
41
+ default: {
42
+ return null;
43
+ }
41
44
  }
42
45
  });
43
46
 
@@ -1,6 +1,6 @@
1
1
  import { Icon, Tooltip } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
- import { LucideEye, ToyBrick } from 'lucide-react';
3
+ import { LucideEye, LucidePaperclip, ToyBrick } from 'lucide-react';
4
4
  import numeral from 'numeral';
5
5
  import { rgba } from 'polished';
6
6
  import { memo } from 'react';
@@ -72,6 +72,13 @@ export const ModelItemRender = memo<ModelItemRenderProps>(({ showInfoTag = true,
72
72
 
73
73
  {showInfoTag && (
74
74
  <Flexbox gap={4} horizontal>
75
+ {model.files && (
76
+ <Tooltip placement={'right'} title={t('ModelSelect.featureTag.file')}>
77
+ <div className={cx(styles.tag, styles.tagGreen)}>
78
+ <Icon icon={LucidePaperclip} />
79
+ </div>
80
+ </Tooltip>
81
+ )}
75
82
  {model.vision && (
76
83
  <Tooltip placement={'right'} title={t('ModelSelect.featureTag.vision')}>
77
84
  <div className={cx(styles.tag, styles.tagGreen)}>
@@ -90,7 +97,6 @@ export const ModelItemRender = memo<ModelItemRenderProps>(({ showInfoTag = true,
90
97
  </div>
91
98
  </Tooltip>
92
99
  )}
93
-
94
100
  {model.tokens && (
95
101
  <Tooltip
96
102
  overlayStyle={{ maxWidth: 'unset' }}
@@ -29,6 +29,7 @@ const OpenAI: ModelProviderCard = {
29
29
  tokens: 4096,
30
30
  },
31
31
  {
32
+ displayName: 'GPT-3.5 Turbo 16K',
32
33
  hidden: true,
33
34
  id: 'gpt-3.5-turbo-16k',
34
35
  tokens: 16_385,
@@ -65,12 +66,14 @@ const OpenAI: ModelProviderCard = {
65
66
  vision: true,
66
67
  },
67
68
  {
69
+ displayName: 'GPT-4 Turbo Preview (1106)',
68
70
  functionCall: true,
69
71
  hidden: true,
70
72
  id: 'gpt-4-1106-preview',
71
73
  tokens: 128_000,
72
74
  },
73
75
  {
76
+ displayName: 'GPT-4',
74
77
  functionCall: true,
75
78
  hidden: true,
76
79
  id: 'gpt-4',
package/src/const/auth.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export const LOBE_CHAT_AUTH_HEADER = 'X-lobe-chat-auth';
2
2
 
3
3
  export const JWT_SECRET_KEY = 'LobeHub · LobeChat';
4
+ export const NON_HTTP_PREFIX = 'http_nosafe';
4
5
 
5
6
  /* eslint-disable typescript-sort-keys/interface */
6
7
  export interface JWTPayload {
@@ -17,7 +17,7 @@ export const getErrorAlertConfig = (
17
17
  errorType?: IPluginErrorType | ILobeAgentRuntimeErrorType | ErrorType,
18
18
  ): AlertProps | undefined => {
19
19
  // OpenAIBizError / ZhipuBizError / GoogleBizError / ...
20
- if (typeof errorType === 'string' && errorType.includes('Biz'))
20
+ if (typeof errorType === 'string' && (errorType.includes('Biz') || errorType.includes('Invalid')))
21
21
  return {
22
22
  extraDefaultExpand: true,
23
23
  extraIsolate: true,
@@ -31,12 +31,7 @@ export const getErrorAlertConfig = (
31
31
  };
32
32
  }
33
33
 
34
- case PluginErrorType.PluginSettingsInvalid:
35
- case ChatErrorType.InvalidAccessCode:
36
- case AgentRuntimeErrorType.NoOpenAIAPIKey:
37
- case AgentRuntimeErrorType.InvalidBedrockCredentials:
38
- case AgentRuntimeErrorType.InvalidGoogleAPIKey:
39
- case AgentRuntimeErrorType.InvalidZhipuAPIKey: {
34
+ case ChatErrorType.InvalidAccessCode: {
40
35
  return {
41
36
  extraDefaultExpand: true,
42
37
  extraIsolate: true,
@@ -33,6 +33,7 @@ const Locale = memo<LocaleLayoutProps>(({ children, defaultLang }) => {
33
33
  const [lang, setLang] = useState(defaultLang);
34
34
 
35
35
  const { data: locale } = useSWR(['antd-locale', lang], ([, key]) => getAntdLocale(key), {
36
+ dedupingInterval: 0,
36
37
  revalidateOnFocus: false,
37
38
  });
38
39
 
@@ -1,16 +1,15 @@
1
1
  /* eslint-disable sort-keys-fix/sort-keys-fix */
2
-
3
2
  // ******* Runtime Biz Error ******* //
4
3
  export const AgentRuntimeErrorType = {
5
4
  AgentRuntimeError: 'AgentRuntimeError', // Agent Runtime 模块运行时错误
6
5
  LocationNotSupportError: 'LocationNotSupportError',
7
6
 
8
- OpenAIBizError: 'OpenAIBizError', // OpenAI 返回的业务错误
7
+ OpenAIBizError: 'OpenAIBizError',
9
8
 
10
9
  NoOpenAIAPIKey: 'NoOpenAIAPIKey',
11
10
 
12
11
  InvalidAzureAPIKey: 'InvalidAzureAPIKey',
13
- AzureBizError: 'AzureBizError', // Azure 返回的业务错误
12
+ AzureBizError: 'AzureBizError',
14
13
 
15
14
  InvalidZhipuAPIKey: 'InvalidZhipuAPIKey',
16
15
  ZhipuBizError: 'ZhipuBizError',
@@ -19,7 +18,7 @@ export const AgentRuntimeErrorType = {
19
18
  GoogleBizError: 'GoogleBizError',
20
19
 
21
20
  InvalidBedrockCredentials: 'InvalidBedrockCredentials',
22
- BedrockBizError: 'BedrockBizError', // Bedrock 返回的业务错误
21
+ BedrockBizError: 'BedrockBizError',
23
22
  } as const;
24
23
 
25
24
  export type ILobeAgentRuntimeErrorType =
@@ -5,7 +5,7 @@ import { ChatStreamPayload } from './chat';
5
5
 
6
6
  export interface AgentInitErrorPayload {
7
7
  error: object;
8
- type: string | number;
8
+ errorType: string | number;
9
9
  }
10
10
 
11
11
  export interface ChatCompletionErrorPayload {
@@ -6,5 +6,5 @@ export const AgentRuntimeError = {
6
6
  createError: (
7
7
  errorType: ILobeAgentRuntimeErrorType | string | number,
8
8
  error?: any,
9
- ): AgentInitErrorPayload => ({ error, type: errorType }),
9
+ ): AgentInitErrorPayload => ({ error, errorType }),
10
10
  };
@@ -2,6 +2,7 @@ export default {
2
2
  ModelSelect: {
3
3
  featureTag: {
4
4
  custom: '自定义模型,默认设定同时支持函数调用与视觉识别,请根据实际情况验证上述能力的可用性',
5
+ file: '该模型支持上传文件读取与识别',
5
6
  functionCall: '该模型支持函数调用(Function Call)',
6
7
  tokens: '该模型单个会话最多支持 {{tokens}} Tokens',
7
8
  vision: '该模型支持视觉识别',
@@ -1,34 +1,8 @@
1
- import { SignJWT, importJWK } from 'jose';
2
-
3
- import { JWTPayload, JWT_SECRET_KEY, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
1
+ import { JWTPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
4
2
  import { ModelProvider } from '@/libs/agent-runtime';
5
3
  import { useGlobalStore } from '@/store/global';
6
4
  import { modelProviderSelectors, settingsSelectors } from '@/store/global/selectors';
7
-
8
- const createJWT = async (payload: JWTPayload) => {
9
- // 将AccessCode转换成适合作为密钥的格式,例如使用SHA-256进行哈希
10
- const encoder = new TextEncoder();
11
- const secretKey = await crypto.subtle.digest('SHA-256', encoder.encode(JWT_SECRET_KEY));
12
-
13
- // 将密钥导入为JWK格式
14
- const jwkSecretKey = await importJWK(
15
- {
16
- k: Buffer.from(secretKey).toString('base64'),
17
- kty: 'oct',
18
- },
19
- 'HS256',
20
- );
21
-
22
- // 获取当前时间戳
23
- const now = Math.floor(Date.now() / 1000);
24
-
25
- // 创建JWT
26
- return new SignJWT(payload as Record<string, any>)
27
- .setProtectedHeader({ alg: 'HS256' })
28
- .setIssuedAt(now) // 设置JWT的iat(签发时间)声明
29
- .setExpirationTime(now + 100) // 设置 JWT 的 exp(过期时间)为 100 s
30
- .sign(jwkSecretKey);
31
- };
5
+ import { createJWT } from '@/utils/jwt';
32
6
 
33
7
  const getProviderAuthPayload = (provider: string) => {
34
8
  switch (provider) {
@@ -81,7 +55,7 @@ const getProviderAuthPayload = (provider: string) => {
81
55
  const createAuthTokenWithPayload = async (payload = {}) => {
82
56
  const accessCode = settingsSelectors.password(useGlobalStore.getState());
83
57
 
84
- return await createJWT({ accessCode, ...payload });
58
+ return await createJWT<JWTPayload>({ accessCode, ...payload });
85
59
  };
86
60
 
87
61
  interface AuthParams {
@@ -21,6 +21,7 @@ exports[`modelProviderSelectors > CUSTOM_MODELS > custom deletion, addition, and
21
21
  {
22
22
  "displayName": "gpt-4-32k",
23
23
  "functionCall": true,
24
+ "hidden": undefined,
24
25
  "id": "gpt-4-0125-preview",
25
26
  "tokens": 128000,
26
27
  },
@@ -23,6 +23,62 @@ describe('modelProviderSelectors', () => {
23
23
  expect(result).toMatchSnapshot();
24
24
  });
25
25
 
26
+ it('should work correct with gpt-4', () => {
27
+ const s = merge(initialSettingsState, {
28
+ serverConfig: {
29
+ customModelName:
30
+ '-all,+gpt-3.5-turbo-1106,+gpt-3.5-turbo,+gpt-3.5-turbo-16k,+gpt-4,+gpt-4-32k,+gpt-4-1106-preview,+gpt-4-vision-preview',
31
+ },
32
+ }) as unknown as GlobalStore;
33
+
34
+ const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
35
+
36
+ expect(result[0].chatModels).toEqual([
37
+ {
38
+ displayName: 'GPT-3.5 Turbo (1106)',
39
+ functionCall: true,
40
+ id: 'gpt-3.5-turbo-1106',
41
+ tokens: 16385,
42
+ },
43
+ {
44
+ description: 'GPT 3.5 Turbo,适用于各种文本生成和理解任务',
45
+ displayName: 'GPT-3.5 Turbo',
46
+ functionCall: true,
47
+ id: 'gpt-3.5-turbo',
48
+ tokens: 4096,
49
+ },
50
+ {
51
+ displayName: 'GPT-3.5 Turbo 16K',
52
+ id: 'gpt-3.5-turbo-16k',
53
+ tokens: 16385,
54
+ },
55
+ {
56
+ displayName: 'GPT-4',
57
+ functionCall: true,
58
+ id: 'gpt-4',
59
+ tokens: 8192,
60
+ },
61
+ {
62
+ displayName: 'gpt-4-32k',
63
+ functionCall: true,
64
+ id: 'gpt-4-32k',
65
+ tokens: 32768,
66
+ },
67
+ {
68
+ displayName: 'GPT-4 Turbo Preview (1106)',
69
+ functionCall: true,
70
+ id: 'gpt-4-1106-preview',
71
+ tokens: 128000,
72
+ },
73
+ {
74
+ description: 'GPT-4 视觉预览版,支持视觉任务',
75
+ displayName: 'GPT-4 Turbo Vision (Preview)',
76
+ id: 'gpt-4-vision-preview',
77
+ tokens: 128000,
78
+ vision: true,
79
+ },
80
+ ]);
81
+ });
26
82
  it('duplicate naming model', () => {
27
83
  const s = merge(initialSettingsState, {
28
84
  serverConfig: {},
@@ -67,6 +123,7 @@ describe('modelProviderSelectors', () => {
67
123
  const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
68
124
 
69
125
  expect(result[0].chatModels.find((o) => o.id === 'gpt-4-1106-preview')).toEqual({
126
+ displayName: 'GPT-4 Turbo Preview (1106)',
70
127
  functionCall: true,
71
128
  id: 'gpt-4-1106-preview',
72
129
  tokens: 128000,
@@ -52,29 +52,31 @@ const processChatModels = (modelConfig: ReturnType<typeof parseModelString>): Ch
52
52
 
53
53
  return produce(chatModels, (draft) => {
54
54
  // 处理添加或替换逻辑
55
- for (const customModel of modelConfig.add) {
56
- // 首先尝试在 LOBE_DEFAULT_MODEL_LIST 中查找模型
57
- const defaultModel = LOBE_DEFAULT_MODEL_LIST.find((model) => model.id === customModel.id);
58
-
59
- // 如果在默认列表中找到了模型,则基于该模型进行更新
60
- if (defaultModel) {
61
- const model = draft.find((model) => model.id === customModel.id);
62
- // 如果当前 chatModels 中已有该模型,更新它
63
- if (model) {
64
- if (model.hidden) delete model.hidden;
65
- if (customModel.displayName) model.displayName = customModel.displayName;
55
+ for (const toAddModel of modelConfig.add) {
56
+ // first try to find the model in LOBE_DEFAULT_MODEL_LIST to confirm if it is a known model
57
+ const knownModel = LOBE_DEFAULT_MODEL_LIST.find((model) => model.id === toAddModel.id);
58
+
59
+ // if the model is known, update it based on the known model
60
+ if (knownModel) {
61
+ const modelInList = draft.find((model) => model.id === toAddModel.id);
62
+
63
+ // if the model is already in chatModels, update it
64
+ if (modelInList) {
65
+ if (modelInList.hidden) delete modelInList.hidden;
66
+ if (toAddModel.displayName) modelInList.displayName = toAddModel.displayName;
66
67
  } else {
67
- // 如果当前 chatModels 中没有该模型,添加它
68
+ // if the model is not in chatModels, add it
68
69
  draft.push({
69
- ...defaultModel,
70
- displayName: customModel.displayName || defaultModel.displayName,
70
+ ...knownModel,
71
+ displayName: toAddModel.displayName || knownModel.displayName || knownModel.id,
72
+ hidden: undefined,
71
73
  });
72
74
  }
73
75
  } else {
74
- // 如果在默认列表中未找到模型,作为新的自定义模型添加
76
+ // if the model is not in LOBE_DEFAULT_MODEL_LIST, add it as a new custom model
75
77
  draft.push({
76
- ...customModel,
77
- displayName: customModel.displayName || customModel.id,
78
+ ...toAddModel,
79
+ displayName: toAddModel.displayName || toAddModel.id,
78
80
  functionCall: true,
79
81
  isCustom: true,
80
82
  vision: true,
@@ -0,0 +1,26 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { NON_HTTP_PREFIX } from '@/const/auth';
4
+
5
+ import { createJWT } from './jwt';
6
+
7
+ describe('createJWT', () => {
8
+ it('should create a JWT token', async () => {
9
+ const payload = { test: 'test' };
10
+ const token = await createJWT(payload);
11
+ expect(token).toBeTruthy();
12
+ });
13
+ it('should return a token with NON_HTTP_PREFIX when crypto.subtle does not exist', async () => {
14
+ const originalCryptoSubtle = crypto.subtle;
15
+ // @ts-ignore
16
+ crypto['subtle'] = undefined;
17
+
18
+ const payload = { test: 'test' };
19
+ const token = await createJWT(payload);
20
+
21
+ expect(token.startsWith(NON_HTTP_PREFIX)).toBeTruthy();
22
+
23
+ // @ts-ignore
24
+ crypto['subtle'] = originalCryptoSubtle;
25
+ });
26
+ });
@@ -0,0 +1,37 @@
1
+ import { SignJWT, importJWK } from 'jose';
2
+
3
+ import { JWT_SECRET_KEY, NON_HTTP_PREFIX } from '@/const/auth';
4
+
5
+ export const createJWT = async <T>(payload: T) => {
6
+ const now = Math.floor(Date.now() / 1000);
7
+ const duration = 100; // 100s
8
+
9
+ const encoder = new TextEncoder();
10
+
11
+ // fix the issue that crypto.subtle is not available in non-HTTPS environment
12
+ // refs: https://github.com/lobehub/lobe-chat/pull/1238
13
+ if (!crypto.subtle) {
14
+ const buffer = encoder.encode(JSON.stringify(payload));
15
+
16
+ return `${NON_HTTP_PREFIX}.${Buffer.from(buffer).toString('base64')}`;
17
+ }
18
+
19
+ // create a secret key
20
+ const secretKey = await crypto.subtle.digest('SHA-256', encoder.encode(JWT_SECRET_KEY));
21
+
22
+ // get the JWK from the secret key
23
+ const jwkSecretKey = await importJWK(
24
+ {
25
+ k: Buffer.from(secretKey).toString('base64'),
26
+ kty: 'oct',
27
+ },
28
+ 'HS256',
29
+ );
30
+
31
+ // 创建JWT
32
+ return new SignJWT(payload as Record<string, any>)
33
+ .setProtectedHeader({ alg: 'HS256' })
34
+ .setIssuedAt(now) // 设置JWT的iat(签发时间)声明
35
+ .setExpirationTime(now + duration) // 设置 JWT 的 exp(过期时间)为 100 s
36
+ .sign(jwkSecretKey);
37
+ };