@lobehub/lobehub 2.0.0-next.102 → 2.0.0-next.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/locales/ar/file.json +2 -2
- package/locales/bg-BG/file.json +2 -2
- package/locales/de-DE/file.json +2 -2
- package/locales/en-US/file.json +2 -2
- package/locales/es-ES/file.json +2 -2
- package/locales/fa-IR/file.json +2 -2
- package/locales/fr-FR/file.json +2 -2
- package/locales/it-IT/file.json +2 -2
- package/locales/ja-JP/file.json +2 -2
- package/locales/ko-KR/file.json +2 -2
- package/locales/nl-NL/file.json +2 -2
- package/locales/pl-PL/file.json +2 -2
- package/locales/pt-BR/file.json +2 -2
- package/locales/ru-RU/file.json +2 -2
- package/locales/tr-TR/file.json +2 -2
- package/locales/vi-VN/file.json +2 -2
- package/locales/zh-CN/file.json +2 -2
- package/locales/zh-TW/file.json +2 -2
- package/package.json +1 -1
- package/packages/database/src/models/aiModel.ts +1 -0
- package/packages/model-bank/src/aiModels/aihubmix.ts +2 -0
- package/packages/model-bank/src/aiModels/google.ts +3 -0
- package/packages/model-bank/src/aiModels/ollamacloud.ts +1 -0
- package/packages/model-bank/src/aiModels/vertexai.ts +2 -0
- package/packages/model-bank/src/aiModels/zenmux.ts +3 -0
- package/packages/model-bank/src/types/aiModel.ts +1 -0
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ModelSelect/ImageModelItem.tsx +16 -1
- package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ModelSelect/index.tsx +10 -9
- package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +3 -3
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelItem.tsx +2 -7
- package/src/components/ModelSelect/NewModelBadge.tsx +23 -0
- package/src/components/ModelSelect/index.tsx +4 -0
- package/src/store/aiInfra/slices/aiProvider/action.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.104](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.103...v2.0.0-next.104)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2025-11-22**</sup>
|
|
8
|
+
|
|
9
|
+
#### 💄 Styles
|
|
10
|
+
|
|
11
|
+
- **misc**: Update i18n.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Styles
|
|
19
|
+
|
|
20
|
+
- **misc**: Update i18n, closes [#10349](https://github.com/lobehub/lobe-chat/issues/10349) ([3482d38](https://github.com/lobehub/lobe-chat/commit/3482d38))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.103](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.102...v2.0.0-next.103)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2025-11-22**</sup>
|
|
33
|
+
|
|
34
|
+
#### 🐛 Bug Fixes
|
|
35
|
+
|
|
36
|
+
- **misc**: Hide ai image config item in settings category.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### What's fixed
|
|
44
|
+
|
|
45
|
+
- **misc**: Hide ai image config item in settings category, closes [#10066](https://github.com/lobehub/lobe-chat/issues/10066) ([90354eb](https://github.com/lobehub/lobe-chat/commit/90354eb))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
## [Version 2.0.0-next.102](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.101...v2.0.0-next.102)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2025-11-22**</sup>
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"children": {
|
|
4
|
+
"improvements": [
|
|
5
|
+
"Update i18n."
|
|
6
|
+
]
|
|
7
|
+
},
|
|
8
|
+
"date": "2025-11-22",
|
|
9
|
+
"version": "2.0.0-next.104"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"children": {
|
|
13
|
+
"fixes": [
|
|
14
|
+
"Hide ai image config item in settings category."
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"date": "2025-11-22",
|
|
18
|
+
"version": "2.0.0-next.103"
|
|
19
|
+
},
|
|
2
20
|
{
|
|
3
21
|
"children": {
|
|
4
22
|
"features": [
|
package/locales/ar/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "المكتبة المعرفية"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "جميع الملفات",
|
|
120
|
+
"allPages": "جميع المستندات"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "فشل في الحصول على قاعدة المعرفة، يرجى التحقق من اتصال الشبكة ثم إعادة المحاولة",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/bg-BG/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "База знания"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Всички файлове",
|
|
120
|
+
"allPages": "Всички документи"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Неуспешно получаване на базата от знания, моля, проверете интернет връзката и опитайте отново",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/de-DE/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Wissensdatenbank"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Alle Dateien",
|
|
120
|
+
"allPages": "Alle Dokumente"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Fehler beim Abrufen der Wissensdatenbank. Bitte überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es erneut.",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/en-US/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Knowledge Base"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "All Files",
|
|
120
|
+
"allPages": "All Documents"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Failed to retrieve the knowledge base. Please check your network connection and try again.",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/es-ES/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Base de conocimientos"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Todos los archivos",
|
|
120
|
+
"allPages": "Todos los documentos"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Error al obtener la base de conocimientos, por favor verifica la conexión a internet y vuelve a intentarlo",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/fa-IR/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "پایگاه دانش"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "تمام فایلها",
|
|
120
|
+
"allPages": "همهٔ نوشتهها"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "دریافت مخزن دانش ناموفق بود، لطفاً پس از بررسی اتصال شبکه دوباره تلاش کنید.",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/fr-FR/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Base de connaissances"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Tous les fichiers",
|
|
120
|
+
"allPages": "Tous les documents"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Échec de l'accès à la base de connaissances, veuillez vérifier votre connexion réseau et réessayer",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/it-IT/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Knowledge Base"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Tutti i file",
|
|
120
|
+
"allPages": "Tutti i documenti"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Impossibile ottenere la knowledge base, controlla la connessione di rete e riprova",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/ja-JP/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "知識ベース"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "すべてのファイル",
|
|
120
|
+
"allPages": "すべてのドキュメント"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "知識ベースの取得に失敗しました。ネットワーク接続を確認してから再試行してください",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/ko-KR/file.json
CHANGED
package/locales/nl-NL/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Kennisbank"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Alle bestanden",
|
|
120
|
+
"allPages": "Alle documenten"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Kon de kennisbank niet ophalen, controleer uw netwerkverbinding en probeer het opnieuw",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/pl-PL/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Baza wiedzy"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Wszystkie pliki",
|
|
120
|
+
"allPages": "Wszystkie dokumenty"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Nie udało się uzyskać dostępu do bazy wiedzy, proszę sprawdzić połączenie sieciowe i spróbować ponownie",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/pt-BR/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Repositório de conhecimento"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Todos os arquivos",
|
|
120
|
+
"allPages": "Todos os Documentos"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Falha ao acessar a base de conhecimento, por favor verifique a conexão de rede e tente novamente",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/ru-RU/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "База знаний"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Все файлы",
|
|
120
|
+
"allPages": "Все документы"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Не удалось получить базу знаний, пожалуйста, проверьте сетевое соединение и попробуйте снова",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/tr-TR/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Bilgi Tabanı"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Tüm Dosyalar",
|
|
120
|
+
"allPages": "Tüm Belgeler"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Bilgi bankası alınamadı, lütfen ağ bağlantınızı kontrol edip tekrar deneyin",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/vi-VN/file.json
CHANGED
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"title": "Kho tri thức"
|
|
117
117
|
},
|
|
118
118
|
"menu": {
|
|
119
|
-
"
|
|
120
|
-
"
|
|
119
|
+
"allFiles": "Tất cả tệp",
|
|
120
|
+
"allPages": "Tất cả tài liệu"
|
|
121
121
|
},
|
|
122
122
|
"networkError": "Không thể lấy kho tri thức, vui lòng kiểm tra kết nối mạng và thử lại",
|
|
123
123
|
"notSupportGuide": {
|
package/locales/zh-CN/file.json
CHANGED
package/locales/zh-TW/file.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.104",
|
|
4
4
|
"description": "LobeHub - an open-source,comprehensive AI Agent 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",
|
|
@@ -1057,6 +1057,7 @@ const aihubmixModels: AIChatModelCard[] = [
|
|
|
1057
1057
|
description:
|
|
1058
1058
|
'Gemini 3 Pro Image(Nano Banana Pro)是 Google 的图像生成模型,同时支持多模态对话。',
|
|
1059
1059
|
displayName: 'Nano Banana Pro',
|
|
1060
|
+
enabled: true,
|
|
1060
1061
|
id: 'gemini-3-pro-image-preview',
|
|
1061
1062
|
maxOutput: 32_768,
|
|
1062
1063
|
pricing: {
|
|
@@ -1067,6 +1068,7 @@ const aihubmixModels: AIChatModelCard[] = [
|
|
|
1067
1068
|
{ name: 'textOutput', rate: 12, strategy: 'fixed', unit: 'millionTokens' },
|
|
1068
1069
|
],
|
|
1069
1070
|
},
|
|
1071
|
+
releasedAt: '2025-11-20',
|
|
1070
1072
|
settings: {
|
|
1071
1073
|
searchImpl: 'params',
|
|
1072
1074
|
searchProvider: 'google',
|
|
@@ -184,6 +184,7 @@ const googleChatModels: AIChatModelCard[] = [
|
|
|
184
184
|
description:
|
|
185
185
|
'Gemini 3 Pro Image(Nano Banana Pro)是 Google 的图像生成模型,同时支持多模态对话。',
|
|
186
186
|
displayName: 'Nano Banana Pro',
|
|
187
|
+
enabled: true,
|
|
187
188
|
id: 'gemini-3-pro-image-preview',
|
|
188
189
|
maxOutput: 32_768,
|
|
189
190
|
pricing: {
|
|
@@ -194,6 +195,7 @@ const googleChatModels: AIChatModelCard[] = [
|
|
|
194
195
|
{ name: 'textOutput', rate: 12, strategy: 'fixed', unit: 'millionTokens' },
|
|
195
196
|
],
|
|
196
197
|
},
|
|
198
|
+
releasedAt: '2025-11-20',
|
|
197
199
|
settings: {
|
|
198
200
|
searchImpl: 'params',
|
|
199
201
|
searchProvider: 'google',
|
|
@@ -891,6 +893,7 @@ const googleImageModels: AIImageModelCard[] = [
|
|
|
891
893
|
displayName: 'Nano Banana Pro',
|
|
892
894
|
id: 'gemini-3-pro-image-preview:image',
|
|
893
895
|
type: 'image',
|
|
896
|
+
enabled: true,
|
|
894
897
|
description:
|
|
895
898
|
'Gemini 3 Pro Image(Nano Banana Pro)是 Google 的图像生成模型,同时支持多模态对话。',
|
|
896
899
|
releasedAt: '2025-11-18',
|
|
@@ -14,6 +14,7 @@ const vertexaiChatModels: AIChatModelCard[] = [
|
|
|
14
14
|
description:
|
|
15
15
|
'Gemini 3 Pro Image(Nano Banana Pro)是 Google 的图像生成模型,同时支持多模态对话。',
|
|
16
16
|
displayName: 'Nano Banana Pro',
|
|
17
|
+
enabled: true,
|
|
17
18
|
id: 'gemini-3-pro-image-preview',
|
|
18
19
|
maxOutput: 32_768,
|
|
19
20
|
pricing: {
|
|
@@ -24,6 +25,7 @@ const vertexaiChatModels: AIChatModelCard[] = [
|
|
|
24
25
|
{ name: 'textOutput', rate: 12, strategy: 'fixed', unit: 'millionTokens' },
|
|
25
26
|
],
|
|
26
27
|
},
|
|
28
|
+
releasedAt: '2025-11-20',
|
|
27
29
|
settings: {
|
|
28
30
|
searchImpl: 'params',
|
|
29
31
|
searchProvider: 'google',
|
|
@@ -19,6 +19,7 @@ const zenmuxChatModels: AIChatModelCard[] = [
|
|
|
19
19
|
description:
|
|
20
20
|
'Gemini 3 Pro Image(Nano Banana Pro)是 Google 的图像生成模型,同时支持多模态对话。',
|
|
21
21
|
displayName: 'Gemini 3 Pro Image (Nano Banana Pro)',
|
|
22
|
+
enabled: true,
|
|
22
23
|
id: 'google/gemini-3-pro-image-preview',
|
|
23
24
|
maxOutput: 32_768,
|
|
24
25
|
pricing: {
|
|
@@ -28,6 +29,7 @@ const zenmuxChatModels: AIChatModelCard[] = [
|
|
|
28
29
|
{ name: 'textOutput', rate: 12, strategy: 'fixed', unit: 'millionTokens' },
|
|
29
30
|
],
|
|
30
31
|
},
|
|
32
|
+
releasedAt: '2025-11-20',
|
|
31
33
|
type: 'chat',
|
|
32
34
|
},
|
|
33
35
|
{
|
|
@@ -68,6 +70,7 @@ const zenmuxChatModels: AIChatModelCard[] = [
|
|
|
68
70
|
{ name: 'textOutput', rate: 12, strategy: 'fixed', unit: 'millionTokens' },
|
|
69
71
|
],
|
|
70
72
|
},
|
|
73
|
+
releasedAt: '2025-11-20',
|
|
71
74
|
type: 'chat',
|
|
72
75
|
},
|
|
73
76
|
{
|
|
@@ -7,6 +7,8 @@ import numeral from 'numeral';
|
|
|
7
7
|
import { memo, useMemo } from 'react';
|
|
8
8
|
import { Flexbox } from 'react-layout-kit';
|
|
9
9
|
|
|
10
|
+
import NewModelBadge from '@/components/ModelSelect/NewModelBadge';
|
|
11
|
+
|
|
10
12
|
const POPOVER_MAX_WIDTH = 320;
|
|
11
13
|
|
|
12
14
|
const useStyles = createStyles(({ css, token, isDarkMode }) => ({
|
|
@@ -25,6 +27,11 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
|
|
|
25
27
|
}));
|
|
26
28
|
|
|
27
29
|
type ImageModelItemProps = AiModelForSelect & {
|
|
30
|
+
/**
|
|
31
|
+
* Whether to show new model badge
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
showBadge?: boolean;
|
|
28
35
|
/**
|
|
29
36
|
* Whether to show popover on hover
|
|
30
37
|
* @default true
|
|
@@ -33,7 +40,14 @@ type ImageModelItemProps = AiModelForSelect & {
|
|
|
33
40
|
};
|
|
34
41
|
|
|
35
42
|
const ImageModelItem = memo<ImageModelItemProps>(
|
|
36
|
-
({
|
|
43
|
+
({
|
|
44
|
+
approximatePricePerImage,
|
|
45
|
+
description,
|
|
46
|
+
pricePerImage,
|
|
47
|
+
showPopover = true,
|
|
48
|
+
showBadge = true,
|
|
49
|
+
...model
|
|
50
|
+
}) => {
|
|
37
51
|
const { styles } = useStyles();
|
|
38
52
|
|
|
39
53
|
const priceLabel = useMemo(() => {
|
|
@@ -67,6 +81,7 @@ const ImageModelItem = memo<ImageModelItemProps>(
|
|
|
67
81
|
<Text ellipsis title={model.displayName || model.id}>
|
|
68
82
|
{model.displayName || model.id}
|
|
69
83
|
</Text>
|
|
84
|
+
{showBadge && <NewModelBadge releasedAt={model.releasedAt} />}
|
|
70
85
|
</Flexbox>
|
|
71
86
|
);
|
|
72
87
|
|
package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ModelSelect/index.tsx
CHANGED
|
@@ -2,7 +2,6 @@ import { EnabledProviderWithModels } from '@lobechat/types';
|
|
|
2
2
|
import { ActionIcon, Icon, Select, type SelectProps } from '@lobehub/ui';
|
|
3
3
|
import { createStyles, useTheme } from 'antd-style';
|
|
4
4
|
import { LucideArrowRight, LucideBolt } from 'lucide-react';
|
|
5
|
-
import Link from 'next/link';
|
|
6
5
|
import { memo, useMemo } from 'react';
|
|
7
6
|
import { useTranslation } from 'react-i18next';
|
|
8
7
|
import { Flexbox } from 'react-layout-kit';
|
|
@@ -107,13 +106,15 @@ const ModelSelect = memo(() => {
|
|
|
107
106
|
provider={provider.id}
|
|
108
107
|
source={provider.source}
|
|
109
108
|
/>
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
109
|
+
<ActionIcon
|
|
110
|
+
icon={LucideBolt}
|
|
111
|
+
onClick={(e) => {
|
|
112
|
+
e.stopPropagation();
|
|
113
|
+
navigate(`/settings?active=provider&provider=${provider.id}`);
|
|
114
|
+
}}
|
|
115
|
+
size={'small'}
|
|
116
|
+
title={t('ModelSwitchPanel.goToSettings')}
|
|
117
|
+
/>
|
|
117
118
|
</Flexbox>
|
|
118
119
|
),
|
|
119
120
|
options: getImageModels(provider),
|
|
@@ -129,7 +130,7 @@ const ModelSelect = memo(() => {
|
|
|
129
130
|
|
|
130
131
|
if (!modelInfo) return props.label;
|
|
131
132
|
|
|
132
|
-
return <ImageModelItem {...modelInfo} showPopover={false} />;
|
|
133
|
+
return <ImageModelItem {...modelInfo} showBadge={false} showPopover={false} />;
|
|
133
134
|
};
|
|
134
135
|
|
|
135
136
|
return (
|
|
@@ -22,7 +22,7 @@ import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfi
|
|
|
22
22
|
export const useCategory = () => {
|
|
23
23
|
const { t } = useTranslation('setting');
|
|
24
24
|
const mobile = useServerConfigStore((s) => s.isMobile);
|
|
25
|
-
const { enableSTT, hideDocs } = useServerConfigStore(featureFlagsSelectors);
|
|
25
|
+
const { enableSTT, hideDocs, showAiImage } = useServerConfigStore(featureFlagsSelectors);
|
|
26
26
|
|
|
27
27
|
const cateItems: MenuProps['items'] = useMemo(
|
|
28
28
|
() =>
|
|
@@ -50,7 +50,7 @@ export const useCategory = () => {
|
|
|
50
50
|
key: SettingsTabs.Provider,
|
|
51
51
|
label: t('tab.provider'),
|
|
52
52
|
},
|
|
53
|
-
{
|
|
53
|
+
showAiImage && {
|
|
54
54
|
icon: <Icon icon={ImageIcon} />,
|
|
55
55
|
key: SettingsTabs.Image,
|
|
56
56
|
label: t('tab.image'),
|
|
@@ -84,7 +84,7 @@ export const useCategory = () => {
|
|
|
84
84
|
label: t('tab.about'),
|
|
85
85
|
},
|
|
86
86
|
].filter(Boolean) as MenuProps['items'],
|
|
87
|
-
[t, enableSTT, hideDocs, mobile],
|
|
87
|
+
[t, enableSTT, hideDocs, mobile, showAiImage],
|
|
88
88
|
);
|
|
89
89
|
|
|
90
90
|
return cateItems;
|
|
@@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
9
9
|
import { Flexbox } from 'react-layout-kit';
|
|
10
10
|
|
|
11
11
|
import { ModelInfoTags } from '@/components/ModelSelect';
|
|
12
|
+
import NewModelBadge from '@/components/ModelSelect/NewModelBadge';
|
|
12
13
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
|
13
14
|
import { aiModelSelectors, useAiInfraStore } from '@/store/aiInfra';
|
|
14
15
|
import { formatPriceByCurrency } from '@/utils/format';
|
|
@@ -17,7 +18,6 @@ import {
|
|
|
17
18
|
getTextInputUnitRate,
|
|
18
19
|
getTextOutputUnitRate,
|
|
19
20
|
} from '@/utils/pricing';
|
|
20
|
-
import { isNewReleaseDate } from '@/utils/time';
|
|
21
21
|
|
|
22
22
|
import ModelConfigModal from './ModelConfigModal';
|
|
23
23
|
import { ProviderSettingsContext } from './ProviderSettingsContext';
|
|
@@ -163,12 +163,7 @@ const ModelItem = memo<ModelItemProps>(
|
|
|
163
163
|
|
|
164
164
|
const isMobile = useIsMobile();
|
|
165
165
|
|
|
166
|
-
const NewTag =
|
|
167
|
-
releasedAt && isNewReleaseDate(releasedAt) ? (
|
|
168
|
-
<Tag color="blue" style={{ marginLeft: 8 }}>
|
|
169
|
-
{t('new', { ns: 'common' })}
|
|
170
|
-
</Tag>
|
|
171
|
-
) : null;
|
|
166
|
+
const NewTag = <NewModelBadge releasedAt={releasedAt} />;
|
|
172
167
|
|
|
173
168
|
const ModelIdTag = (
|
|
174
169
|
<Tag onClick={copyModelId} style={{ cursor: 'pointer', marginRight: 0 }}>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Tag } from '@lobehub/ui';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
|
|
5
|
+
import { isNewReleaseDate } from '@/utils/time';
|
|
6
|
+
|
|
7
|
+
interface NewModelBadgeProps {
|
|
8
|
+
releasedAt?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const NewModelBadge = memo<NewModelBadgeProps>(({ releasedAt }) => {
|
|
12
|
+
const { t } = useTranslation('common');
|
|
13
|
+
|
|
14
|
+
if (!releasedAt || !isNewReleaseDate(releasedAt)) return null;
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Tag color="blue" size="small">
|
|
18
|
+
{t('new')}
|
|
19
|
+
</Tag>
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export default NewModelBadge;
|
|
@@ -21,6 +21,8 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
21
21
|
import { AiProviderSourceType } from '@/types/aiProvider';
|
|
22
22
|
import { formatTokenNumber } from '@/utils/format';
|
|
23
23
|
|
|
24
|
+
import NewModelBadge from './NewModelBadge';
|
|
25
|
+
|
|
24
26
|
export const TAG_CLASSNAME = 'lobe-model-info-tags';
|
|
25
27
|
|
|
26
28
|
const useStyles = createStyles(({ css, token }) => ({
|
|
@@ -179,6 +181,7 @@ interface ModelItemRenderProps extends ChatModelCard {
|
|
|
179
181
|
|
|
180
182
|
export const ModelItemRender = memo<ModelItemRenderProps>(({ showInfoTag = true, ...model }) => {
|
|
181
183
|
const { mobile } = useResponsive();
|
|
184
|
+
|
|
182
185
|
return (
|
|
183
186
|
<Flexbox
|
|
184
187
|
align={'center'}
|
|
@@ -202,6 +205,7 @@ export const ModelItemRender = memo<ModelItemRenderProps>(({ showInfoTag = true,
|
|
|
202
205
|
<Text style={mobile ? { maxWidth: '60vw', overflowX: 'auto', whiteSpace: 'nowrap' } : {}}>
|
|
203
206
|
{model.displayName || model.id}
|
|
204
207
|
</Text>
|
|
208
|
+
<NewModelBadge releasedAt={model.releasedAt} />
|
|
205
209
|
</Flexbox>
|
|
206
210
|
{showInfoTag && <ModelInfoTags {...model} />}
|
|
207
211
|
</Flexbox>
|
|
@@ -40,6 +40,7 @@ export type ProviderModelListItem = {
|
|
|
40
40
|
parameters?: ModelParamsSchema;
|
|
41
41
|
pricePerImage?: number;
|
|
42
42
|
pricing?: Pricing;
|
|
43
|
+
releasedAt?: string;
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
type ModelNormalizer = (model: EnabledAiModel) => Promise<ProviderModelListItem>;
|
|
@@ -67,6 +68,7 @@ export const normalizeChatModel = (model: EnabledAiModel): ProviderModelListItem
|
|
|
67
68
|
contextWindowTokens: model.contextWindowTokens,
|
|
68
69
|
displayName: model.displayName ?? '',
|
|
69
70
|
id: model.id,
|
|
71
|
+
releasedAt: model.releasedAt,
|
|
70
72
|
});
|
|
71
73
|
|
|
72
74
|
export const normalizeImageModel = async (
|
|
@@ -107,6 +109,7 @@ export const normalizeImageModel = async (
|
|
|
107
109
|
contextWindowTokens: model.contextWindowTokens,
|
|
108
110
|
displayName: model.displayName ?? '',
|
|
109
111
|
id: model.id,
|
|
112
|
+
releasedAt: model.releasedAt,
|
|
110
113
|
...(parameters && { parameters }),
|
|
111
114
|
...(description && { description }),
|
|
112
115
|
...(pricing && { pricing }),
|