@lobehub/chat 1.16.10 → 1.16.12
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.
Potentially problematic release.
This version of @lobehub/chat might be problematic. Click here for more details.
- package/CHANGELOG.md +58 -0
- package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +1 -1
- package/docs/self-hosting/server-database/docker-compose.mdx +1 -0
- package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +1 -0
- package/locales/ar/modelProvider.json +6 -0
- package/locales/bg-BG/modelProvider.json +6 -0
- package/locales/de-DE/modelProvider.json +6 -0
- package/locales/en-US/modelProvider.json +6 -0
- package/locales/es-ES/modelProvider.json +6 -0
- package/locales/fr-FR/modelProvider.json +6 -0
- package/locales/it-IT/modelProvider.json +6 -0
- package/locales/ja-JP/modelProvider.json +6 -0
- package/locales/ko-KR/modelProvider.json +6 -0
- package/locales/nl-NL/modelProvider.json +6 -0
- package/locales/pl-PL/modelProvider.json +6 -0
- package/locales/pt-BR/modelProvider.json +6 -0
- package/locales/ru-RU/modelProvider.json +6 -0
- package/locales/tr-TR/modelProvider.json +6 -0
- package/locales/vi-VN/modelProvider.json +6 -0
- package/locales/zh-CN/modelProvider.json +6 -0
- package/locales/zh-TW/modelProvider.json +6 -0
- package/package.json +1 -1
- package/src/app/(main)/settings/llm/ProviderList/Bedrock/index.tsx +11 -0
- package/src/app/api/chat/agentRuntime.test.ts +1 -0
- package/src/app/api/chat/agentRuntime.ts +5 -2
- package/src/app/api/webhooks/logto/__tests__/route.test.ts +92 -0
- package/src/app/api/webhooks/logto/route.ts +40 -0
- package/src/app/api/webhooks/logto/validateRequest.ts +50 -0
- package/src/config/auth.ts +2 -0
- package/src/config/llm.ts +2 -0
- package/src/config/modelProviders/bedrock.ts +14 -14
- package/src/config/modelProviders/mistral.ts +0 -3
- package/src/config/modelProviders/openai.ts +10 -10
- package/src/const/auth.ts +1 -0
- package/src/features/Conversation/Error/APIKeyForm/Bedrock.tsx +26 -2
- package/src/libs/agent-runtime/AgentRuntime.ts +4 -4
- package/src/libs/agent-runtime/baichuan/index.ts +3 -6
- package/src/libs/agent-runtime/bedrock/index.ts +3 -1
- package/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap +6 -6
- package/src/libs/agent-runtime/qwen/index.test.ts +1 -1
- package/src/libs/agent-runtime/qwen/index.ts +2 -4
- package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +1 -1
- package/src/locales/default/modelProvider.ts +6 -0
- package/src/server/globalConfig/index.ts +6 -6
- package/src/server/routers/edge/config/__snapshots__/index.test.ts.snap +3 -3
- package/src/server/services/nextAuthUser/index.ts +42 -0
- package/src/services/_auth.ts +9 -4
- package/src/services/chat.ts +1 -0
- package/src/types/user/settings/keyVaults.ts +1 -0
- package/src/utils/format.ts +1 -1
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,64 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.16.12](https://github.com/lobehub/lobe-chat/compare/v1.16.11...v1.16.12)
|
6
|
+
|
7
|
+
<sup>Released on **2024-09-12**</sup>
|
8
|
+
|
9
|
+
#### 💄 Styles
|
10
|
+
|
11
|
+
- **misc**: Remove brackets from model names with dates in OpenAI.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Styles
|
19
|
+
|
20
|
+
- **misc**: Remove brackets from model names with dates in OpenAI, closes [#3927](https://github.com/lobehub/lobe-chat/issues/3927) ([2a937bc](https://github.com/lobehub/lobe-chat/commit/2a937bc))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.16.11](https://github.com/lobehub/lobe-chat/compare/v1.16.10...v1.16.11)
|
31
|
+
|
32
|
+
<sup>Released on **2024-09-12**</sup>
|
33
|
+
|
34
|
+
#### 🐛 Bug Fixes
|
35
|
+
|
36
|
+
- **misc**: Support webhooks for logto.
|
37
|
+
|
38
|
+
#### 💄 Styles
|
39
|
+
|
40
|
+
- **misc**: Default disable mistral provider useless models.
|
41
|
+
|
42
|
+
<br/>
|
43
|
+
|
44
|
+
<details>
|
45
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
46
|
+
|
47
|
+
#### What's fixed
|
48
|
+
|
49
|
+
- **misc**: Support webhooks for logto, closes [#3774](https://github.com/lobehub/lobe-chat/issues/3774) ([0cfee6b](https://github.com/lobehub/lobe-chat/commit/0cfee6b))
|
50
|
+
|
51
|
+
#### Styles
|
52
|
+
|
53
|
+
- **misc**: Default disable mistral provider useless models, closes [#3922](https://github.com/lobehub/lobe-chat/issues/3922) ([bdbc647](https://github.com/lobehub/lobe-chat/commit/bdbc647))
|
54
|
+
|
55
|
+
</details>
|
56
|
+
|
57
|
+
<div align="right">
|
58
|
+
|
59
|
+
[](#readme-top)
|
60
|
+
|
61
|
+
</div>
|
62
|
+
|
5
63
|
### [Version 1.16.10](https://github.com/lobehub/lobe-chat/compare/v1.16.9...v1.16.10)
|
6
64
|
|
7
65
|
<sup>Released on **2024-09-12**</sup>
|
@@ -186,6 +186,7 @@ And the service port without reverse proxy:
|
|
186
186
|
|
187
187
|
<Callout type="warning">
|
188
188
|
Please note that CORS cross-origin is configured internally in MinIO / Logto service, do not configure CORS additionally in your reverse proxy, as this will cause errors.
|
189
|
+
For minio ports other than 443, Host must be $http_host (with port number), otherwise a 403 error will occur: proxy_set_header Host $http_host.
|
189
190
|
|
190
191
|
If you need to configure SSL certificates, please configure them uniformly in the outer Nginx reverse proxy, rather than in MinIO.
|
191
192
|
|
@@ -185,6 +185,7 @@ docker compose up -d
|
|
185
185
|
|
186
186
|
<Callout type="warning">
|
187
187
|
请务必注意,CORS 跨域是在 MinIO / Logto 服务端内部配置的,请勿在你的反向代理中额外配置 CORS,这会导致错误。
|
188
|
+
对于minio非443端口时,Host必须是$http_host(带端口号),否则会403错误:proxy_set_header Host $http_host。
|
188
189
|
|
189
190
|
如果你需要配置 SSL 证书,请统一在外层的 Nginx 反向代理中配置,而不是在 MinIO 中配置。
|
190
191
|
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "إذا كنت تستخدم AWS SSO/STS، يرجى إدخال رمز جلسة AWS الخاص بك",
|
43
|
+
"placeholder": "رمز جلسة AWS",
|
44
|
+
"title": "رمز جلسة AWS (اختياري)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "منطقة خدمة مخصصة",
|
49
|
+
"customSessionToken": "رمز الجلسة المخصص",
|
44
50
|
"description": "أدخل معرف الوصول / مفتاح الوصول السري الخاص بك في AWS لبدء الجلسة. لن يتم تسجيل تكوين المصادقة الخاص بك من قبل التطبيق",
|
45
51
|
"title": "استخدام معلومات المصادقة الخاصة بـ Bedrock المخصصة"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Ако използвате AWS SSO/STS, моля, въведете вашия AWS Session Token",
|
43
|
+
"placeholder": "AWS Session Token",
|
44
|
+
"title": "AWS Session Token (по избор)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Персонализиран регион за услуги",
|
49
|
+
"customSessionToken": "Персонализиран токен за сесия",
|
44
50
|
"description": "Въведете вашия AWS AccessKeyId / SecretAccessKey, за да започнете сесия. Приложението няма да запази вашата удостоверителна конфигурация",
|
45
51
|
"title": "Използване на персонализирана информация за удостоверяване на Bedrock"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Wenn Sie AWS SSO/STS verwenden, geben Sie Ihr AWS Session Token ein",
|
43
|
+
"placeholder": "AWS Session Token",
|
44
|
+
"title": "AWS Session Token (optional)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Benutzerdefinierter Regionsservice",
|
49
|
+
"customSessionToken": "Benutzerdefiniertes Sitzungstoken",
|
44
50
|
"description": "Geben Sie Ihren AWS AccessKeyId / SecretAccessKey ein, um das Gespräch zu beginnen. Die App speichert Ihre Authentifizierungsinformationen nicht.",
|
45
51
|
"title": "Verwenden Sie benutzerdefinierte Bedrock-Authentifizierungsinformationen"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "If you are using AWS SSO/STS, please enter your AWS Session Token",
|
43
|
+
"placeholder": "AWS Session Token",
|
44
|
+
"title": "AWS Session Token (optional)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Custom Service Region",
|
49
|
+
"customSessionToken": "Custom Session Token",
|
44
50
|
"description": "Enter your AWS AccessKeyId / SecretAccessKey to start the session. The app will not store your authentication configuration",
|
45
51
|
"title": "Use Custom Bedrock Authentication Information"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Si estás utilizando AWS SSO/STS, introduce tu Token de Sesión de AWS",
|
43
|
+
"placeholder": "Token de Sesión de AWS",
|
44
|
+
"title": "Token de Sesión de AWS (opcional)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Región de servicio personalizada",
|
49
|
+
"customSessionToken": "Token de sesión personalizado",
|
44
50
|
"description": "Introduce tu AWS AccessKeyId / SecretAccessKey para comenzar la sesión. La aplicación no guardará tu configuración de autenticación.",
|
45
51
|
"title": "Usar información de autenticación de Bedrock personalizada"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "Clé d'accès secrète AWS",
|
39
39
|
"title": "Clé d'accès secrète AWS"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Si vous utilisez AWS SSO/STS, veuillez entrer votre jeton de session AWS",
|
43
|
+
"placeholder": "Jeton de session AWS",
|
44
|
+
"title": "Jeton de session AWS (facultatif)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Région de service personnalisée",
|
49
|
+
"customSessionToken": "Jeton de session personnalisé",
|
44
50
|
"description": "Entrez votre ID de clé d'accès AWS / SecretAccessKey pour commencer la session. L'application ne stockera pas votre configuration d'authentification.",
|
45
51
|
"title": "Utiliser des informations d'authentification Bedrock personnalisées"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "Chiave di accesso segreta AWS",
|
39
39
|
"title": "Chiave di accesso segreta AWS"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Se stai utilizzando AWS SSO/STS, inserisci il tuo AWS Session Token",
|
43
|
+
"placeholder": "AWS Session Token",
|
44
|
+
"title": "AWS Session Token (opzionale)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Regione del servizio personalizzata",
|
49
|
+
"customSessionToken": "Token di sessione personalizzato",
|
44
50
|
"description": "Inserisci la tua chiave di accesso AWS AccessKeyId / SecretAccessKey per avviare la sessione. L'applicazione non memorizzerà la tua configurazione di autenticazione",
|
45
51
|
"title": "Usa le informazioni di autenticazione Bedrock personalizzate"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "AWS SSO/STSを使用している場合は、AWSセッショントークンを入力してください。",
|
43
|
+
"placeholder": "AWSセッショントークン",
|
44
|
+
"title": "AWSセッショントークン(オプション)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "カスタムサービスリージョン",
|
49
|
+
"customSessionToken": "カスタムセッショントークン",
|
44
50
|
"description": "AWS AccessKeyId / SecretAccessKey を入力するとセッションを開始できます。アプリは認証情報を記録しません",
|
45
51
|
"title": "使用カスタム Bedrock 認証情報"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS 비밀 액세스 키",
|
39
39
|
"title": "AWS 비밀 액세스 키"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "AWS SSO/STS를 사용 중이라면 AWS 세션 토큰을 입력하세요.",
|
43
|
+
"placeholder": "AWS 세션 토큰",
|
44
|
+
"title": "AWS 세션 토큰 (선택 사항)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "사용자 정의 서비스 지역",
|
49
|
+
"customSessionToken": "사용자 정의 세션 토큰",
|
44
50
|
"description": "AWS AccessKeyId / SecretAccessKey를 입력하면 세션이 시작됩니다. 애플리케이션은 인증 구성을 기록하지 않습니다.",
|
45
51
|
"title": "사용자 정의 Bedrock 인증 정보 사용"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Als je AWS SSO/STS gebruikt, voer dan je AWS Sessie Token in",
|
43
|
+
"placeholder": "AWS Sessie Token",
|
44
|
+
"title": "AWS Sessie Token (optioneel)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Aangepaste regio",
|
49
|
+
"customSessionToken": "Aangepaste sessietoken",
|
44
50
|
"description": "Voer uw AWS AccessKeyId / SecretAccessKey in om een sessie te starten. De app zal uw verificatiegegevens niet opslaan",
|
45
51
|
"title": "Gebruik aangepaste Bedrock-verificatiegegevens"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Jeśli korzystasz z AWS SSO/STS, wprowadź swój token sesji AWS",
|
43
|
+
"placeholder": "Token sesji AWS",
|
44
|
+
"title": "Token sesji AWS (opcjonalnie)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Niestandardowy region usługi",
|
49
|
+
"customSessionToken": "Niestandardowy token sesji",
|
44
50
|
"description": "Wprowadź swój AWS AccessKeyId / SecretAccessKey, aby rozpocząć sesję. Aplikacja nie będzie przechowywać Twojej konfiguracji uwierzytelniania",
|
45
51
|
"title": "Użyj niestandardowych informacji uwierzytelniających Bedrock"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Se você estiver usando AWS SSO/STS, insira seu Token de Sessão da AWS",
|
43
|
+
"placeholder": "Token de Sessão da AWS",
|
44
|
+
"title": "Token de Sessão da AWS (opcional)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Região de serviço personalizada",
|
49
|
+
"customSessionToken": "Token de Sessão Personalizado",
|
44
50
|
"description": "Digite sua AWS AccessKeyId / SecretAccessKey para iniciar a sessão. O aplicativo não irá armazenar suas configurações de autenticação",
|
45
51
|
"title": "Usar informações de autenticação Bedrock personalizadas"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Если вы используете AWS SSO/STS, введите ваш AWS Session Token",
|
43
|
+
"placeholder": "AWS Session Token",
|
44
|
+
"title": "AWS Session Token (необязательно)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Пользовательский регион обслуживания",
|
49
|
+
"customSessionToken": "Пользовательский токен сессии",
|
44
50
|
"description": "Введите свой ключ доступа AWS AccessKeyId / SecretAccessKey, чтобы начать сеанс. Приложение не будет сохранять вашу конфигурацию аутентификации",
|
45
51
|
"title": "Использовать пользовательскую информацию аутентификации Bedrock"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "AWS SSO/STS kullanıyorsanız, lütfen AWS Oturum Tokeninizi girin",
|
43
|
+
"placeholder": "AWS Oturum Tokeni",
|
44
|
+
"title": "AWS Oturum Tokeni (isteğe bağlı)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Özel Bölge",
|
49
|
+
"customSessionToken": "Özel Oturum Tokeni",
|
44
50
|
"description": "AWS AccessKeyId / SecretAccessKey bilgilerinizi girerek oturumu başlatabilirsiniz. Uygulama kimlik doğrulama bilgilerinizi kaydetmez.",
|
45
51
|
"title": "Özel Bedrock Kimlik Bilgilerini Kullan"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "Nếu bạn đang sử dụng AWS SSO/STS, hãy nhập AWS Session Token của bạn",
|
43
|
+
"placeholder": "AWS Session Token",
|
44
|
+
"title": "AWS Session Token (tùy chọn)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "Vùng Dịch vụ Tùy chỉnh",
|
49
|
+
"customSessionToken": "Mã thông báo phiên tùy chỉnh",
|
44
50
|
"description": "Nhập AWS AccessKeyId / SecretAccessKey của bạn để bắt đầu phiên làm việc. Ứng dụng sẽ không lưu trữ cấu hình xác thực của bạn",
|
45
51
|
"title": "Sử dụng Thông tin Xác thực Bedrock tùy chỉnh"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "如果你正在使用 AWS SSO/STS,请输入你的 AWS Session Token",
|
43
|
+
"placeholder": "AWS Session Token",
|
44
|
+
"title": "AWS Session Token (可选)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "自定义服务区域",
|
49
|
+
"customSessionToken": "自定义 Session Token",
|
44
50
|
"description": "输入你的 AWS AccessKeyId / SecretAccessKey 即可开始会话。应用不会记录你的鉴权配置",
|
45
51
|
"title": "使用自定义 Bedrock 鉴权信息"
|
46
52
|
}
|
@@ -38,9 +38,15 @@
|
|
38
38
|
"placeholder": "AWS Secret Access Key",
|
39
39
|
"title": "AWS Secret Access Key"
|
40
40
|
},
|
41
|
+
"sessionToken": {
|
42
|
+
"desc": "如果你正在使用 AWS SSO/STS,請輸入你的 AWS Session Token",
|
43
|
+
"placeholder": "AWS Session Token",
|
44
|
+
"title": "AWS Session Token (可選)"
|
45
|
+
},
|
41
46
|
"title": "Bedrock",
|
42
47
|
"unlock": {
|
43
48
|
"customRegion": "自定義服務區域",
|
49
|
+
"customSessionToken": "自訂 Session Token",
|
44
50
|
"description": "輸入你的 AWS AccessKeyId / SecretAccessKey 即可開始會話。應用程式不會記錄你的驗證配置",
|
45
51
|
"title": "使用自定義 Bedrock 驗證資訊"
|
46
52
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.16.
|
3
|
+
"version": "1.16.12",
|
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",
|
@@ -39,6 +39,17 @@ export const useBedrockProvider = (): ProviderItem => {
|
|
39
39
|
label: t(`${providerKey}.secretAccessKey.title`),
|
40
40
|
name: [KeyVaultsConfigKey, providerKey, 'secretAccessKey'],
|
41
41
|
},
|
42
|
+
{
|
43
|
+
children: (
|
44
|
+
<Input.Password
|
45
|
+
autoComplete={'new-password'}
|
46
|
+
placeholder={t(`${providerKey}.sessionToken.placeholder`)}
|
47
|
+
/>
|
48
|
+
),
|
49
|
+
desc: t(`${providerKey}.sessionToken.desc`),
|
50
|
+
label: t(`${providerKey}.sessionToken.title`),
|
51
|
+
name: [KeyVaultsConfigKey, providerKey, 'sessionToken'],
|
52
|
+
},
|
42
53
|
{
|
43
54
|
children: (
|
44
55
|
<Select
|
@@ -43,6 +43,7 @@ vi.mock('@/config/llm', () => ({
|
|
43
43
|
AWS_SECRET_ACCESS_KEY: 'test-aws-secret',
|
44
44
|
AWS_ACCESS_KEY_ID: 'test-aws-id',
|
45
45
|
AWS_REGION: 'test-aws-region',
|
46
|
+
AWS_SESSION_TOKEN: 'test-aws-session-token',
|
46
47
|
OLLAMA_PROXY_URL: 'https://test-ollama-url.local',
|
47
48
|
PERPLEXITY_API_KEY: 'test-perplexity-key',
|
48
49
|
DEEPSEEK_API_KEY: 'test-deepseek-key',
|
@@ -75,17 +75,20 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => {
|
|
75
75
|
};
|
76
76
|
}
|
77
77
|
case ModelProvider.Bedrock: {
|
78
|
-
const { AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_REGION } =
|
78
|
+
const { AWS_SECRET_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_REGION, AWS_SESSION_TOKEN } =
|
79
|
+
getLLMConfig();
|
79
80
|
let accessKeyId: string | undefined = AWS_ACCESS_KEY_ID;
|
80
81
|
let accessKeySecret: string | undefined = AWS_SECRET_ACCESS_KEY;
|
81
82
|
let region = AWS_REGION;
|
83
|
+
let sessionToken: string | undefined = AWS_SESSION_TOKEN;
|
82
84
|
// if the payload has the api key, use user
|
83
85
|
if (payload.apiKey) {
|
84
86
|
accessKeyId = payload?.awsAccessKeyId;
|
85
87
|
accessKeySecret = payload?.awsSecretAccessKey;
|
88
|
+
sessionToken = payload?.awsSessionToken;
|
86
89
|
region = payload?.awsRegion;
|
87
90
|
}
|
88
|
-
return { accessKeyId, accessKeySecret, region };
|
91
|
+
return { accessKeyId, accessKeySecret, region, sessionToken };
|
89
92
|
}
|
90
93
|
case ModelProvider.Ollama: {
|
91
94
|
const { OLLAMA_PROXY_URL } = getLLMConfig();
|
@@ -0,0 +1,92 @@
|
|
1
|
+
import { createHmac } from 'node:crypto';
|
2
|
+
import { describe, expect, it } from 'vitest';
|
3
|
+
|
4
|
+
interface UserDataUpdatedEvent {
|
5
|
+
event: string;
|
6
|
+
createdAt: string;
|
7
|
+
userAgent: string;
|
8
|
+
ip: string;
|
9
|
+
path: string;
|
10
|
+
method: string;
|
11
|
+
status: number;
|
12
|
+
params: {
|
13
|
+
userId: string;
|
14
|
+
};
|
15
|
+
matchedRoute: string;
|
16
|
+
data: {
|
17
|
+
id: string;
|
18
|
+
username: string;
|
19
|
+
primaryEmail: string;
|
20
|
+
primaryPhone: string | null;
|
21
|
+
name: string;
|
22
|
+
avatar: string | null;
|
23
|
+
customData: Record<string, unknown>;
|
24
|
+
identities: Record<string, unknown>;
|
25
|
+
lastSignInAt: number;
|
26
|
+
createdAt: number;
|
27
|
+
updatedAt: number;
|
28
|
+
profile: Record<string, unknown>;
|
29
|
+
applicationId: string;
|
30
|
+
isSuspended: boolean;
|
31
|
+
};
|
32
|
+
hookId: string;
|
33
|
+
}
|
34
|
+
|
35
|
+
const userDataUpdatedEvent: UserDataUpdatedEvent = {
|
36
|
+
event: 'User.Data.Updated',
|
37
|
+
createdAt: '2024-09-07T08:29:09.381Z',
|
38
|
+
userAgent:
|
39
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0',
|
40
|
+
ip: '223.104.76.217',
|
41
|
+
path: '/users/rra41h9vmpnd',
|
42
|
+
method: 'PATCH',
|
43
|
+
status: 200,
|
44
|
+
params: {
|
45
|
+
userId: 'rra41h9vmpnd',
|
46
|
+
},
|
47
|
+
matchedRoute: '/users/:userId',
|
48
|
+
data: {
|
49
|
+
id: 'uid',
|
50
|
+
username: 'test',
|
51
|
+
primaryEmail: 'user@example.com',
|
52
|
+
primaryPhone: null,
|
53
|
+
name: 'test',
|
54
|
+
avatar: null,
|
55
|
+
customData: {},
|
56
|
+
identities: {},
|
57
|
+
lastSignInAt: 1725446291545,
|
58
|
+
createdAt: 1725440405556,
|
59
|
+
updatedAt: 1725697749337,
|
60
|
+
profile: {},
|
61
|
+
applicationId: 'appid',
|
62
|
+
isSuspended: false,
|
63
|
+
},
|
64
|
+
hookId: 'hookId',
|
65
|
+
};
|
66
|
+
|
67
|
+
const LOGTO_WEBHOOK_SIGNING_KEY = 'logto-signing-key';
|
68
|
+
|
69
|
+
// Test Logto Webhooks in Local dev, here is some tips:
|
70
|
+
// - Replace the var `LOGTO_WEBHOOK_SIGNING_KEY` with the actual value in your `.env` file
|
71
|
+
// - Start web request: If you want to run the test, replace `describe.skip` with `describe` below
|
72
|
+
|
73
|
+
describe.skip('Test Logto Webhooks in Local dev', () => {
|
74
|
+
// describe('Test Logto Webhooks in Local dev', () => {
|
75
|
+
it('should send a POST request with logto headers', async () => {
|
76
|
+
const url = 'http://localhost:3010/api/webhooks/logto'; // 替换为目标URL
|
77
|
+
const data = userDataUpdatedEvent;
|
78
|
+
// Generate data signature
|
79
|
+
const hmac = createHmac('sha256', LOGTO_WEBHOOK_SIGNING_KEY!);
|
80
|
+
hmac.update(JSON.stringify(data));
|
81
|
+
const signature = hmac.digest('hex');
|
82
|
+
const response = await fetch(url, {
|
83
|
+
method: 'POST',
|
84
|
+
headers: {
|
85
|
+
'Content-Type': 'application/json',
|
86
|
+
'logto-signature-sha-256': signature,
|
87
|
+
},
|
88
|
+
body: JSON.stringify(data),
|
89
|
+
});
|
90
|
+
expect(response.status).toBe(200); // 检查响应状态
|
91
|
+
});
|
92
|
+
});
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { NextResponse } from 'next/server';
|
2
|
+
|
3
|
+
import { authEnv } from '@/config/auth';
|
4
|
+
import { pino } from '@/libs/logger';
|
5
|
+
import { NextAuthUserService } from '@/server/services/nextAuthUser';
|
6
|
+
|
7
|
+
import { validateRequest } from './validateRequest';
|
8
|
+
|
9
|
+
export const POST = async (req: Request): Promise<NextResponse> => {
|
10
|
+
const payload = await validateRequest(req, authEnv.LOGTO_WEBHOOK_SIGNING_KEY!);
|
11
|
+
|
12
|
+
if (!payload) {
|
13
|
+
return NextResponse.json(
|
14
|
+
{ error: 'webhook verification failed or payload was malformed' },
|
15
|
+
{ status: 400 },
|
16
|
+
);
|
17
|
+
}
|
18
|
+
|
19
|
+
const { event, data } = payload;
|
20
|
+
|
21
|
+
pino.trace(`logto webhook payload: ${{ data, event }}`);
|
22
|
+
|
23
|
+
const nextAuthUserService = new NextAuthUserService();
|
24
|
+
switch (event) {
|
25
|
+
case 'User.Data.Updated': {
|
26
|
+
return nextAuthUserService.safeUpdateUser(data.id, {
|
27
|
+
avatar: data?.avatar,
|
28
|
+
email: data?.primaryEmail,
|
29
|
+
fullName: data?.name,
|
30
|
+
});
|
31
|
+
}
|
32
|
+
|
33
|
+
default: {
|
34
|
+
pino.warn(
|
35
|
+
`${req.url} received event type "${event}", but no handler is defined for this type`,
|
36
|
+
);
|
37
|
+
return NextResponse.json({ error: `unrecognised payload type: ${event}` }, { status: 400 });
|
38
|
+
}
|
39
|
+
}
|
40
|
+
};
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import { headers } from 'next/headers';
|
2
|
+
import { createHmac } from 'node:crypto';
|
3
|
+
|
4
|
+
import { authEnv } from '@/config/auth';
|
5
|
+
|
6
|
+
export type LogtToUserEntity = {
|
7
|
+
applicationId?: string;
|
8
|
+
avatar?: string;
|
9
|
+
createdAt?: string;
|
10
|
+
customData?: object;
|
11
|
+
id: string;
|
12
|
+
identities?: object;
|
13
|
+
isSuspended?: boolean;
|
14
|
+
lastSignInAt?: string;
|
15
|
+
name?: string;
|
16
|
+
primaryEmail?: string;
|
17
|
+
primaryPhone?: string;
|
18
|
+
username?: string;
|
19
|
+
};
|
20
|
+
|
21
|
+
interface LogtoWebhookPayload {
|
22
|
+
// Only support user event currently
|
23
|
+
data: LogtToUserEntity;
|
24
|
+
event: string;
|
25
|
+
}
|
26
|
+
|
27
|
+
export const validateRequest = async (request: Request, signingKey: string) => {
|
28
|
+
const payloadString = await request.text();
|
29
|
+
const headerPayload = headers();
|
30
|
+
const logtoHeaderSignature = headerPayload.get('logto-signature-sha-256')!;
|
31
|
+
try {
|
32
|
+
const hmac = createHmac('sha256', signingKey);
|
33
|
+
hmac.update(payloadString);
|
34
|
+
const signature = hmac.digest('hex');
|
35
|
+
if (signature === logtoHeaderSignature) {
|
36
|
+
return JSON.parse(payloadString) as LogtoWebhookPayload;
|
37
|
+
} else {
|
38
|
+
console.warn(
|
39
|
+
'[logto]: signature verify failed, please check your logto signature in `LOGTO_WEBHOOK_SIGNING_KEY`',
|
40
|
+
);
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
} catch (e) {
|
44
|
+
if (!authEnv.LOGTO_WEBHOOK_SIGNING_KEY) {
|
45
|
+
throw new Error('`LOGTO_WEBHOOK_SIGNING_KEY` environment variable is missing.');
|
46
|
+
}
|
47
|
+
console.error('[logto]: incoming webhook failed in verification.\n', e);
|
48
|
+
return;
|
49
|
+
}
|
50
|
+
};
|
package/src/config/auth.ts
CHANGED
@@ -200,6 +200,7 @@ export const getAuthConfig = () => {
|
|
200
200
|
LOGTO_CLIENT_ID: z.string().optional(),
|
201
201
|
LOGTO_CLIENT_SECRET: z.string().optional(),
|
202
202
|
LOGTO_ISSUER: z.string().optional(),
|
203
|
+
LOGTO_WEBHOOK_SIGNING_KEY: z.string().optional(),
|
203
204
|
},
|
204
205
|
|
205
206
|
runtimeEnv: {
|
@@ -257,6 +258,7 @@ export const getAuthConfig = () => {
|
|
257
258
|
LOGTO_CLIENT_ID: process.env.LOGTO_CLIENT_ID,
|
258
259
|
LOGTO_CLIENT_SECRET: process.env.LOGTO_CLIENT_SECRET,
|
259
260
|
LOGTO_ISSUER: process.env.LOGTO_ISSUER,
|
261
|
+
LOGTO_WEBHOOK_SIGNING_KEY: process.env.LOGTO_WEBHOOK_SIGNING_KEY,
|
260
262
|
},
|
261
263
|
});
|
262
264
|
};
|
package/src/config/llm.ts
CHANGED
@@ -73,6 +73,7 @@ export const getLLMConfig = () => {
|
|
73
73
|
AWS_REGION: z.string().optional(),
|
74
74
|
AWS_ACCESS_KEY_ID: z.string().optional(),
|
75
75
|
AWS_SECRET_ACCESS_KEY: z.string().optional(),
|
76
|
+
AWS_SESSION_TOKEN: z.string().optional(),
|
76
77
|
|
77
78
|
ENABLED_OLLAMA: z.boolean(),
|
78
79
|
OLLAMA_PROXY_URL: z.string().optional(),
|
@@ -178,6 +179,7 @@ export const getLLMConfig = () => {
|
|
178
179
|
AWS_REGION: process.env.AWS_REGION,
|
179
180
|
AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID,
|
180
181
|
AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY,
|
182
|
+
AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN,
|
181
183
|
|
182
184
|
ENABLED_OLLAMA: process.env.ENABLED_OLLAMA !== '0',
|
183
185
|
OLLAMA_PROXY_URL: process.env.OLLAMA_PROXY_URL || '',
|
@@ -40,6 +40,20 @@ const Bedrock: ModelProviderCard = {
|
|
40
40
|
tokens: 200_000,
|
41
41
|
vision: true,
|
42
42
|
},
|
43
|
+
{
|
44
|
+
description:
|
45
|
+
'Claude 3 Haiku 是 Anthropic 最快、最紧凑的模型,提供近乎即时的响应速度。它可以快速回答简单的查询和请求。客户将能够构建模仿人类互动的无缝 AI 体验。Claude 3 Haiku 可以处理图像并返回文本输出,具有 200K 的上下文窗口。',
|
46
|
+
displayName: 'Claude 3 Haiku',
|
47
|
+
enabled: true,
|
48
|
+
functionCall: true,
|
49
|
+
id: 'anthropic.claude-3-haiku-20240307-v1:0',
|
50
|
+
pricing: {
|
51
|
+
input: 0.25,
|
52
|
+
output: 1.25,
|
53
|
+
},
|
54
|
+
tokens: 200_000,
|
55
|
+
vision: true,
|
56
|
+
},
|
43
57
|
{
|
44
58
|
description:
|
45
59
|
'Anthropic 的 Claude 3 Sonnet 在智能和速度之间达到了理想的平衡——特别适合企业工作负载。它以低于竞争对手的价格提供最大的效用,并被设计成为可靠的、高耐用的主力机,适用于规模化的 AI 部署。Claude 3 Sonnet 可以处理图像并返回文本输出,具有 200K 的上下文窗口。',
|
@@ -68,20 +82,6 @@ const Bedrock: ModelProviderCard = {
|
|
68
82
|
tokens: 200_000,
|
69
83
|
vision: true,
|
70
84
|
},
|
71
|
-
{
|
72
|
-
description:
|
73
|
-
'Claude 3 Haiku 是 Anthropic 最快、最紧凑的模型,提供近乎即时的响应速度。它可以快速回答简单的查询和请求。客户将能够构建模仿人类互动的无缝 AI 体验。Claude 3 Haiku 可以处理图像并返回文本输出,具有 200K 的上下文窗口。',
|
74
|
-
displayName: 'Claude 3 Haiku',
|
75
|
-
enabled: true,
|
76
|
-
functionCall: true,
|
77
|
-
id: 'anthropic.claude-3-haiku-20240307-v1:0',
|
78
|
-
pricing: {
|
79
|
-
input: 0.25,
|
80
|
-
output: 1.25,
|
81
|
-
},
|
82
|
-
tokens: 200_000,
|
83
|
-
vision: true,
|
84
|
-
},
|
85
85
|
{
|
86
86
|
description:
|
87
87
|
'Claude 2 的更新版,具有双倍的上下文窗口,以及在长文档和 RAG 上下文中的可靠性、幻觉率和基于证据的准确性的改进。',
|
@@ -8,7 +8,6 @@ const Mistral: ModelProviderCard = {
|
|
8
8
|
description:
|
9
9
|
'Mistral 7B是一款紧凑但高性能的模型,擅长批量处理和简单任务,如分类和文本生成,具有良好的推理能力。',
|
10
10
|
displayName: 'Mistral 7B',
|
11
|
-
enabled: true,
|
12
11
|
id: 'open-mistral-7b',
|
13
12
|
tokens: 32_768,
|
14
13
|
},
|
@@ -16,7 +15,6 @@ const Mistral: ModelProviderCard = {
|
|
16
15
|
description:
|
17
16
|
'Mixtral 8x7B是一个稀疏专家模型,利用多个参数提高推理速度,适合处理多语言和代码生成任务。',
|
18
17
|
displayName: 'Mixtral 8x7B',
|
19
|
-
enabled: true,
|
20
18
|
id: 'open-mixtral-8x7b',
|
21
19
|
tokens: 32_768,
|
22
20
|
},
|
@@ -57,7 +55,6 @@ const Mistral: ModelProviderCard = {
|
|
57
55
|
description:
|
58
56
|
'Codestral Mamba是专注于代码生成的Mamba 2语言模型,为先进的代码和推理任务提供强力支持。',
|
59
57
|
displayName: 'Codestral Mamba',
|
60
|
-
enabled: true,
|
61
58
|
id: 'open-codestral-mamba',
|
62
59
|
tokens: 256_000,
|
63
60
|
},
|
@@ -35,7 +35,7 @@ const OpenAI: ModelProviderCard = {
|
|
35
35
|
{
|
36
36
|
description:
|
37
37
|
'ChatGPT-4o 是一款动态模型,实时更新以保持当前最新版本。它结合了强大的语言理解与生成能力,适合于大规模应用场景,包括客户服务、教育和技术支持。',
|
38
|
-
displayName: 'GPT-4o
|
38
|
+
displayName: 'GPT-4o 0806',
|
39
39
|
enabled: true,
|
40
40
|
functionCall: true,
|
41
41
|
id: 'gpt-4o-2024-08-06',
|
@@ -49,7 +49,7 @@ const OpenAI: ModelProviderCard = {
|
|
49
49
|
{
|
50
50
|
description:
|
51
51
|
'ChatGPT-4o 是一款动态模型,实时更新以保持当前最新版本。它结合了强大的语言理解与生成能力,适合于大规模应用场景,包括客户服务、教育和技术支持。',
|
52
|
-
displayName: 'GPT-4o
|
52
|
+
displayName: 'GPT-4o 0513',
|
53
53
|
functionCall: true,
|
54
54
|
id: 'gpt-4o-2024-05-13',
|
55
55
|
pricing: {
|
@@ -88,7 +88,7 @@ const OpenAI: ModelProviderCard = {
|
|
88
88
|
{
|
89
89
|
description:
|
90
90
|
'最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。',
|
91
|
-
displayName: 'GPT-4 Turbo Vision
|
91
|
+
displayName: 'GPT-4 Turbo Vision 0409',
|
92
92
|
functionCall: true,
|
93
93
|
id: 'gpt-4-turbo-2024-04-09',
|
94
94
|
pricing: {
|
@@ -113,7 +113,7 @@ const OpenAI: ModelProviderCard = {
|
|
113
113
|
{
|
114
114
|
description:
|
115
115
|
'最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。',
|
116
|
-
displayName: 'GPT-4 Turbo Preview
|
116
|
+
displayName: 'GPT-4 Turbo Preview 0125',
|
117
117
|
functionCall: true,
|
118
118
|
id: 'gpt-4-0125-preview',
|
119
119
|
pricing: {
|
@@ -148,7 +148,7 @@ const OpenAI: ModelProviderCard = {
|
|
148
148
|
{
|
149
149
|
description:
|
150
150
|
'最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。',
|
151
|
-
displayName: 'GPT-4 Turbo Preview
|
151
|
+
displayName: 'GPT-4 Turbo Preview 1106',
|
152
152
|
functionCall: true,
|
153
153
|
id: 'gpt-4-1106-preview',
|
154
154
|
pricing: {
|
@@ -172,7 +172,7 @@ const OpenAI: ModelProviderCard = {
|
|
172
172
|
{
|
173
173
|
description:
|
174
174
|
'GPT-4 提供了一个更大的上下文窗口,能够处理更长的文本输入,适用于需要广泛信息整合和数据分析的场景。',
|
175
|
-
displayName: 'GPT-4
|
175
|
+
displayName: 'GPT-4 0613',
|
176
176
|
functionCall: true,
|
177
177
|
id: 'gpt-4-0613',
|
178
178
|
pricing: {
|
@@ -197,7 +197,7 @@ const OpenAI: ModelProviderCard = {
|
|
197
197
|
// Will be discontinued on June 6, 2025
|
198
198
|
description:
|
199
199
|
'GPT-4 提供了一个更大的上下文窗口,能够处理更长的文本输入,适用于需要广泛信息整合和数据分析的场景。',
|
200
|
-
displayName: 'GPT-4 32K
|
200
|
+
displayName: 'GPT-4 32K 0613',
|
201
201
|
functionCall: true,
|
202
202
|
id: 'gpt-4-32k-0613',
|
203
203
|
pricing: {
|
@@ -221,7 +221,7 @@ const OpenAI: ModelProviderCard = {
|
|
221
221
|
{
|
222
222
|
description:
|
223
223
|
'GPT 3.5 Turbo,适用于各种文本生成和理解任务,Currently points to gpt-3.5-turbo-0125',
|
224
|
-
displayName: 'GPT-3.5 Turbo
|
224
|
+
displayName: 'GPT-3.5 Turbo 0125',
|
225
225
|
functionCall: true,
|
226
226
|
id: 'gpt-3.5-turbo-0125',
|
227
227
|
pricing: {
|
@@ -233,7 +233,7 @@ const OpenAI: ModelProviderCard = {
|
|
233
233
|
{
|
234
234
|
description:
|
235
235
|
'GPT 3.5 Turbo,适用于各种文本生成和理解任务,Currently points to gpt-3.5-turbo-0125',
|
236
|
-
displayName: 'GPT-3.5 Turbo
|
236
|
+
displayName: 'GPT-3.5 Turbo 1106',
|
237
237
|
functionCall: true,
|
238
238
|
id: 'gpt-3.5-turbo-1106',
|
239
239
|
pricing: {
|
@@ -269,7 +269,7 @@ const OpenAI: ModelProviderCard = {
|
|
269
269
|
{
|
270
270
|
description:
|
271
271
|
'GPT-3.5 Turbo 是 OpenAI 的一款基础模型,结合了高效性和经济性,广泛用于文本生成、理解和分析,专为指导性提示进行调整,去除了与聊天相关的优化。',
|
272
|
-
displayName: 'GPT-3.5 Turbo
|
272
|
+
displayName: 'GPT-3.5 Turbo 0613',
|
273
273
|
// Will be discontinued on September 13, 2024
|
274
274
|
id: 'gpt-3.5-turbo-0613',
|
275
275
|
legacy: true,
|
package/src/const/auth.ts
CHANGED
@@ -2,7 +2,7 @@ import { Aws } from '@lobehub/icons';
|
|
2
2
|
import { Icon } from '@lobehub/ui';
|
3
3
|
import { Button, Input, Select } from 'antd';
|
4
4
|
import { useTheme } from 'antd-style';
|
5
|
-
import { Network } from 'lucide-react';
|
5
|
+
import { Network, ShieldPlus } from 'lucide-react';
|
6
6
|
import { memo, useState } from 'react';
|
7
7
|
import { useTranslation } from 'react-i18next';
|
8
8
|
|
@@ -15,10 +15,12 @@ import { FormAction } from '../style';
|
|
15
15
|
const BedrockForm = memo(() => {
|
16
16
|
const { t } = useTranslation('modelProvider');
|
17
17
|
const [showRegion, setShow] = useState(false);
|
18
|
+
const [showSessionToken, setShowSessionToken] = useState(false);
|
18
19
|
|
19
|
-
const [accessKeyId, secretAccessKey, region, setConfig] = useUserStore((s) => [
|
20
|
+
const [accessKeyId, secretAccessKey, sessionToken, region, setConfig] = useUserStore((s) => [
|
20
21
|
keyVaultsConfigSelectors.bedrockConfig(s).accessKeyId,
|
21
22
|
keyVaultsConfigSelectors.bedrockConfig(s).secretAccessKey,
|
23
|
+
keyVaultsConfigSelectors.bedrockConfig(s).sessionToken,
|
22
24
|
keyVaultsConfigSelectors.bedrockConfig(s).region,
|
23
25
|
s.updateKeyVaultConfig,
|
24
26
|
]);
|
@@ -48,6 +50,28 @@ const BedrockForm = memo(() => {
|
|
48
50
|
type={'block'}
|
49
51
|
value={secretAccessKey}
|
50
52
|
/>
|
53
|
+
{showSessionToken ? (
|
54
|
+
<Input.Password
|
55
|
+
autoComplete={'new-password'}
|
56
|
+
onChange={(e) => {
|
57
|
+
setConfig(ModelProvider.Bedrock, { sessionToken: e.target.value });
|
58
|
+
}}
|
59
|
+
placeholder={'Aws Session Token'}
|
60
|
+
type={'block'}
|
61
|
+
value={sessionToken}
|
62
|
+
/>
|
63
|
+
) : (
|
64
|
+
<Button
|
65
|
+
block
|
66
|
+
icon={<Icon icon={ShieldPlus} />}
|
67
|
+
onClick={() => {
|
68
|
+
setShowSessionToken(true);
|
69
|
+
}}
|
70
|
+
type={'text'}
|
71
|
+
>
|
72
|
+
{t('bedrock.unlock.customSessionToken')}
|
73
|
+
</Button>
|
74
|
+
)}
|
51
75
|
{showRegion ? (
|
52
76
|
<Select
|
53
77
|
onChange={(region) => {
|
@@ -26,7 +26,6 @@ import { LobeSparkAI } from './spark';
|
|
26
26
|
import { LobeStepfunAI } from './stepfun';
|
27
27
|
import { LobeTaichuAI } from './taichu';
|
28
28
|
import { LobeTogetherAI } from './togetherai';
|
29
|
-
import { LobeUpstageAI } from './upstage';
|
30
29
|
import {
|
31
30
|
ChatCompetitionOptions,
|
32
31
|
ChatStreamPayload,
|
@@ -35,6 +34,7 @@ import {
|
|
35
34
|
ModelProvider,
|
36
35
|
TextToImagePayload,
|
37
36
|
} from './types';
|
37
|
+
import { LobeUpstageAI } from './upstage';
|
38
38
|
import { LobeZeroOneAI } from './zeroone';
|
39
39
|
import { LobeZhipuAI } from './zhipu';
|
40
40
|
|
@@ -230,7 +230,7 @@ class AgentRuntime {
|
|
230
230
|
|
231
231
|
case ModelProvider.FireworksAI: {
|
232
232
|
runtimeModel = new LobeFireworksAI(params.fireworksai);
|
233
|
-
break
|
233
|
+
break;
|
234
234
|
}
|
235
235
|
|
236
236
|
case ModelProvider.ZeroOne: {
|
@@ -275,12 +275,12 @@ class AgentRuntime {
|
|
275
275
|
|
276
276
|
case ModelProvider.Upstage: {
|
277
277
|
runtimeModel = new LobeUpstageAI(params.upstage);
|
278
|
-
break
|
278
|
+
break;
|
279
279
|
}
|
280
280
|
|
281
281
|
case ModelProvider.Spark: {
|
282
282
|
runtimeModel = new LobeSparkAI(params.spark);
|
283
|
-
break
|
283
|
+
break;
|
284
284
|
}
|
285
285
|
}
|
286
286
|
|
@@ -9,14 +9,11 @@ export const LobeBaichuanAI = LobeOpenAICompatibleFactory({
|
|
9
9
|
handlePayload: (payload: ChatStreamPayload) => {
|
10
10
|
const { temperature, ...rest } = payload;
|
11
11
|
|
12
|
-
return {
|
13
|
-
...rest,
|
12
|
+
return {
|
13
|
+
...rest,
|
14
14
|
// [baichuan] frequency_penalty must be between 1 and 2.
|
15
15
|
frequency_penalty: undefined,
|
16
|
-
temperature:
|
17
|
-
temperature !== undefined
|
18
|
-
? temperature / 2
|
19
|
-
: undefined,
|
16
|
+
temperature: temperature !== undefined ? temperature / 2 : undefined,
|
20
17
|
} as OpenAI.ChatCompletionCreateParamsStreaming;
|
21
18
|
},
|
22
19
|
},
|
@@ -21,6 +21,7 @@ export interface LobeBedrockAIParams {
|
|
21
21
|
accessKeyId?: string;
|
22
22
|
accessKeySecret?: string;
|
23
23
|
region?: string;
|
24
|
+
sessionToken?: string;
|
24
25
|
}
|
25
26
|
|
26
27
|
export class LobeBedrockAI implements LobeRuntimeAI {
|
@@ -28,7 +29,7 @@ export class LobeBedrockAI implements LobeRuntimeAI {
|
|
28
29
|
|
29
30
|
region: string;
|
30
31
|
|
31
|
-
constructor({ region, accessKeyId, accessKeySecret }: LobeBedrockAIParams = {}) {
|
32
|
+
constructor({ region, accessKeyId, accessKeySecret, sessionToken }: LobeBedrockAIParams = {}) {
|
32
33
|
if (!(accessKeyId && accessKeySecret))
|
33
34
|
throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidBedrockCredentials);
|
34
35
|
|
@@ -38,6 +39,7 @@ export class LobeBedrockAI implements LobeRuntimeAI {
|
|
38
39
|
credentials: {
|
39
40
|
accessKeyId: accessKeyId,
|
40
41
|
secretAccessKey: accessKeySecret,
|
42
|
+
sessionToken: sessionToken,
|
41
43
|
},
|
42
44
|
region: this.region,
|
43
45
|
});
|
@@ -49,7 +49,7 @@ exports[`LobeOpenAI > models > should get models 1`] = `
|
|
49
49
|
},
|
50
50
|
{
|
51
51
|
"description": "最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。",
|
52
|
-
"displayName": "GPT-4 Turbo Preview
|
52
|
+
"displayName": "GPT-4 Turbo Preview 0125",
|
53
53
|
"functionCall": true,
|
54
54
|
"id": "gpt-4-0125-preview",
|
55
55
|
"pricing": {
|
@@ -84,7 +84,7 @@ exports[`LobeOpenAI > models > should get models 1`] = `
|
|
84
84
|
},
|
85
85
|
{
|
86
86
|
"description": "GPT-3.5 Turbo 是 OpenAI 的一款基础模型,结合了高效性和经济性,广泛用于文本生成、理解和分析,专为指导性提示进行调整,去除了与聊天相关的优化。",
|
87
|
-
"displayName": "GPT-3.5 Turbo
|
87
|
+
"displayName": "GPT-3.5 Turbo 0613",
|
88
88
|
"id": "gpt-3.5-turbo-0613",
|
89
89
|
"legacy": true,
|
90
90
|
"pricing": {
|
@@ -95,7 +95,7 @@ exports[`LobeOpenAI > models > should get models 1`] = `
|
|
95
95
|
},
|
96
96
|
{
|
97
97
|
"description": "GPT 3.5 Turbo,适用于各种文本生成和理解任务,Currently points to gpt-3.5-turbo-0125",
|
98
|
-
"displayName": "GPT-3.5 Turbo
|
98
|
+
"displayName": "GPT-3.5 Turbo 1106",
|
99
99
|
"functionCall": true,
|
100
100
|
"id": "gpt-3.5-turbo-1106",
|
101
101
|
"pricing": {
|
@@ -106,7 +106,7 @@ exports[`LobeOpenAI > models > should get models 1`] = `
|
|
106
106
|
},
|
107
107
|
{
|
108
108
|
"description": "最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。",
|
109
|
-
"displayName": "GPT-4 Turbo Preview
|
109
|
+
"displayName": "GPT-4 Turbo Preview 1106",
|
110
110
|
"functionCall": true,
|
111
111
|
"id": "gpt-4-1106-preview",
|
112
112
|
"pricing": {
|
@@ -139,7 +139,7 @@ exports[`LobeOpenAI > models > should get models 1`] = `
|
|
139
139
|
},
|
140
140
|
{
|
141
141
|
"description": "GPT 3.5 Turbo,适用于各种文本生成和理解任务,Currently points to gpt-3.5-turbo-0125",
|
142
|
-
"displayName": "GPT-3.5 Turbo
|
142
|
+
"displayName": "GPT-3.5 Turbo 0125",
|
143
143
|
"functionCall": true,
|
144
144
|
"id": "gpt-3.5-turbo-0125",
|
145
145
|
"pricing": {
|
@@ -150,7 +150,7 @@ exports[`LobeOpenAI > models > should get models 1`] = `
|
|
150
150
|
},
|
151
151
|
{
|
152
152
|
"description": "GPT-4 提供了一个更大的上下文窗口,能够处理更长的文本输入,适用于需要广泛信息整合和数据分析的场景。",
|
153
|
-
"displayName": "GPT-4
|
153
|
+
"displayName": "GPT-4 0613",
|
154
154
|
"functionCall": true,
|
155
155
|
"id": "gpt-4-0613",
|
156
156
|
"pricing": {
|
@@ -213,7 +213,7 @@ describe('LobeQwenAI', () => {
|
|
213
213
|
expect.any(Object),
|
214
214
|
);
|
215
215
|
const callArgs = createMock.mock.calls[0][0];
|
216
|
-
expect(Number.isInteger(callArgs.temperature)).toBe(false); // Temperature is always not an integer
|
216
|
+
expect(Number.isInteger(callArgs.temperature)).toBe(false); // Temperature is always not an integer
|
217
217
|
});
|
218
218
|
});
|
219
219
|
|
@@ -108,10 +108,8 @@ export class LobeQwenAI implements LobeRuntimeAI {
|
|
108
108
|
messages,
|
109
109
|
result_format: 'message',
|
110
110
|
stream: !!tools?.length ? false : (stream ?? true),
|
111
|
-
temperature:
|
112
|
-
temperature === 0 || temperature >= 2
|
113
|
-
? undefined
|
114
|
-
: (temperature === 1 ? 0.999 : temperature), // 'temperature' must be Float
|
111
|
+
temperature:
|
112
|
+
temperature === 0 || temperature >= 2 ? undefined : temperature === 1 ? 0.999 : temperature, // 'temperature' must be Float
|
115
113
|
top_p: top_p && top_p >= 1 ? 0.999 : top_p,
|
116
114
|
};
|
117
115
|
|
@@ -18,9 +18,9 @@ import { AgentRuntimeError } from '../createError';
|
|
18
18
|
import { debugResponse, debugStream } from '../debugStream';
|
19
19
|
import { desensitizeUrl } from '../desensitizeUrl';
|
20
20
|
import { handleOpenAIError } from '../handleOpenAIError';
|
21
|
+
import { convertOpenAIMessages } from '../openaiHelpers';
|
21
22
|
import { StreamingResponse } from '../response';
|
22
23
|
import { OpenAIStream } from '../streams';
|
23
|
-
import { convertOpenAIMessages } from '../openaiHelpers';
|
24
24
|
|
25
25
|
// the model contains the following keywords is not a chat model, so we should filter them out
|
26
26
|
const CHAT_MODELS_BLOCK_LIST = [
|
@@ -38,9 +38,15 @@ export default {
|
|
38
38
|
placeholder: 'AWS Secret Access Key',
|
39
39
|
title: 'AWS Secret Access Key',
|
40
40
|
},
|
41
|
+
sessionToken: {
|
42
|
+
desc: '如果你正在使用 AWS SSO/STS,请输入你的 AWS Session Token',
|
43
|
+
placeholder: 'AWS Session Token',
|
44
|
+
title: 'AWS Session Token (可选)',
|
45
|
+
},
|
41
46
|
title: 'Bedrock',
|
42
47
|
unlock: {
|
43
48
|
customRegion: '自定义服务区域',
|
49
|
+
customSessionToken: '自定义 Session Token',
|
44
50
|
description:
|
45
51
|
'输入你的 AWS AccessKeyId / SecretAccessKey 即可开始会话。应用不会记录你的鉴权配置',
|
46
52
|
title: '使用自定义 Bedrock 鉴权信息',
|
@@ -211,12 +211,12 @@ export const getServerGlobalConfig = () => {
|
|
211
211
|
modelString: ZEROONE_MODEL_LIST,
|
212
212
|
}),
|
213
213
|
},
|
214
|
-
zhipu: {
|
215
|
-
enabled: ENABLED_ZHIPU,
|
216
|
-
enabledModels: extractEnabledModels(ZHIPU_MODEL_LIST),
|
217
|
-
serverModelCards: transformToChatModelCards({
|
218
|
-
defaultChatModels: ZhiPuProviderCard.chatModels,
|
219
|
-
modelString: ZHIPU_MODEL_LIST
|
214
|
+
zhipu: {
|
215
|
+
enabled: ENABLED_ZHIPU,
|
216
|
+
enabledModels: extractEnabledModels(ZHIPU_MODEL_LIST),
|
217
|
+
serverModelCards: transformToChatModelCards({
|
218
|
+
defaultChatModels: ZhiPuProviderCard.chatModels,
|
219
|
+
modelString: ZHIPU_MODEL_LIST,
|
220
220
|
}),
|
221
221
|
},
|
222
222
|
},
|
@@ -39,7 +39,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST
|
|
39
39
|
[
|
40
40
|
{
|
41
41
|
"description": "GPT 3.5 Turbo,适用于各种文本生成和理解任务,Currently points to gpt-3.5-turbo-0125",
|
42
|
-
"displayName": "GPT-3.5 Turbo
|
42
|
+
"displayName": "GPT-3.5 Turbo 1106",
|
43
43
|
"enabled": true,
|
44
44
|
"functionCall": true,
|
45
45
|
"id": "gpt-3.5-turbo-1106",
|
@@ -99,7 +99,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST
|
|
99
99
|
},
|
100
100
|
{
|
101
101
|
"description": "最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。",
|
102
|
-
"displayName": "GPT-4 Turbo Preview
|
102
|
+
"displayName": "GPT-4 Turbo Preview 1106",
|
103
103
|
"enabled": true,
|
104
104
|
"functionCall": true,
|
105
105
|
"id": "gpt-4-1106-preview",
|
@@ -127,7 +127,7 @@ exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST
|
|
127
127
|
exports[`configRouter > getGlobalConfig > Model Provider env > OPENAI_MODEL_LIST > show the hidden model 1`] = `
|
128
128
|
{
|
129
129
|
"description": "最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。",
|
130
|
-
"displayName": "GPT-4 Turbo Preview
|
130
|
+
"displayName": "GPT-4 Turbo Preview 1106",
|
131
131
|
"enabled": true,
|
132
132
|
"functionCall": true,
|
133
133
|
"id": "gpt-4-1106-preview",
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { NextResponse } from 'next/server';
|
2
|
+
|
3
|
+
import { serverDB } from '@/database/server';
|
4
|
+
import { UserModel } from '@/database/server/models/user';
|
5
|
+
import { UserItem } from '@/database/server/schemas/lobechat';
|
6
|
+
import { pino } from '@/libs/logger';
|
7
|
+
import { LobeNextAuthDbAdapter } from '@/libs/next-auth/adapter';
|
8
|
+
|
9
|
+
export class NextAuthUserService {
|
10
|
+
userModel;
|
11
|
+
adapter;
|
12
|
+
|
13
|
+
constructor() {
|
14
|
+
this.userModel = new UserModel();
|
15
|
+
this.adapter = LobeNextAuthDbAdapter(serverDB);
|
16
|
+
}
|
17
|
+
|
18
|
+
safeUpdateUser = async (providerAccountId: string, data: Partial<UserItem>) => {
|
19
|
+
pino.info('updating user due to webhook');
|
20
|
+
// 1. Find User by account
|
21
|
+
// @ts-expect-error: Already impl in `LobeNextauthDbAdapter`
|
22
|
+
const user = await this.adapter.getUserByAccount({
|
23
|
+
provider: 'logto',
|
24
|
+
providerAccountId,
|
25
|
+
});
|
26
|
+
|
27
|
+
// 2. If found, Update user data from provider
|
28
|
+
if (user?.id) {
|
29
|
+
// Perform update
|
30
|
+
await this.userModel.updateUser(user.id, {
|
31
|
+
avatar: data?.avatar,
|
32
|
+
email: data?.email,
|
33
|
+
fullName: data?.fullName,
|
34
|
+
});
|
35
|
+
} else {
|
36
|
+
pino.warn(
|
37
|
+
`[logto]: Webhooks handler user update for "${JSON.stringify(data)}", but no user was found by the providerAccountId.`,
|
38
|
+
);
|
39
|
+
}
|
40
|
+
return NextResponse.json({ message: 'user updated', success: true }, { status: 200 });
|
41
|
+
};
|
42
|
+
}
|
package/src/services/_auth.ts
CHANGED
@@ -8,16 +8,21 @@ import { createJWT } from '@/utils/jwt';
|
|
8
8
|
export const getProviderAuthPayload = (provider: string) => {
|
9
9
|
switch (provider) {
|
10
10
|
case ModelProvider.Bedrock: {
|
11
|
-
const { accessKeyId, region, secretAccessKey } =
|
12
|
-
useUserStore.getState()
|
13
|
-
);
|
11
|
+
const { accessKeyId, region, secretAccessKey, sessionToken } =
|
12
|
+
keyVaultsConfigSelectors.bedrockConfig(useUserStore.getState());
|
14
13
|
|
15
14
|
const awsSecretAccessKey = secretAccessKey;
|
16
15
|
const awsAccessKeyId = accessKeyId;
|
17
16
|
|
18
17
|
const apiKey = (awsSecretAccessKey || '') + (awsAccessKeyId || '');
|
19
18
|
|
20
|
-
return {
|
19
|
+
return {
|
20
|
+
apiKey,
|
21
|
+
awsAccessKeyId,
|
22
|
+
awsRegion: region,
|
23
|
+
awsSecretAccessKey,
|
24
|
+
awsSessionToken: sessionToken,
|
25
|
+
};
|
21
26
|
}
|
22
27
|
|
23
28
|
case ModelProvider.Azure: {
|
package/src/services/chat.ts
CHANGED
@@ -114,6 +114,7 @@ export function initializeWithClientStore(provider: string, payload: any) {
|
|
114
114
|
accessKeyId: providerAuthPayload?.awsAccessKeyId,
|
115
115
|
accessKeySecret: providerAuthPayload?.awsSecretAccessKey,
|
116
116
|
region: providerAuthPayload?.awsRegion,
|
117
|
+
sessionToken: providerAuthPayload?.awsSessionToken,
|
117
118
|
};
|
118
119
|
}
|
119
120
|
break;
|
package/src/utils/format.ts
CHANGED
@@ -59,7 +59,7 @@ export const formatTokenNumber = (num: number): string => {
|
|
59
59
|
if (num > 0 && num < 1024) return '1K';
|
60
60
|
|
61
61
|
let kiloToken = Math.floor(num / 1024);
|
62
|
-
if (num >= 1024 && num < 1024 * 41 || num >= 128_000) {
|
62
|
+
if ((num >= 1024 && num < 1024 * 41) || num >= 128_000) {
|
63
63
|
kiloToken = Math.floor(num / 1000);
|
64
64
|
}
|
65
65
|
if (num === 131_072) return '128K';
|