@lobehub/lobehub 2.0.0-next.194 → 2.0.0-next.196
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/setting.json +0 -3
- package/locales/bg-BG/setting.json +0 -3
- package/locales/de-DE/setting.json +0 -3
- package/locales/en-US/setting.json +0 -3
- package/locales/es-ES/setting.json +0 -3
- package/locales/fa-IR/setting.json +0 -3
- package/locales/fr-FR/setting.json +0 -3
- package/locales/it-IT/setting.json +0 -3
- package/locales/ja-JP/setting.json +0 -3
- package/locales/ko-KR/setting.json +0 -3
- package/locales/nl-NL/setting.json +0 -3
- package/locales/pl-PL/setting.json +0 -3
- package/locales/pt-BR/setting.json +0 -3
- package/locales/ru-RU/setting.json +0 -3
- package/locales/tr-TR/setting.json +0 -3
- package/locales/vi-VN/setting.json +0 -3
- package/locales/zh-CN/setting.json +0 -3
- package/locales/zh-TW/setting.json +0 -3
- package/package.json +1 -1
- package/packages/const/src/fetch.ts +1 -4
- package/packages/database/src/models/user.ts +8 -0
- package/packages/database/src/repositories/aiInfra/index.test.ts +11 -8
- package/packages/database/src/repositories/dataExporter/index.test.ts +11 -9
- package/packages/database/src/repositories/tableViewer/index.test.ts +13 -14
- package/packages/model-runtime/src/providers/zhipu/index.ts +6 -6
- package/packages/types/src/auth.ts +0 -4
- package/packages/utils/src/server/xor.test.ts +1 -2
- package/src/app/(backend)/_deprecated/createBizOpenAI/auth.test.ts +7 -41
- package/src/app/(backend)/_deprecated/createBizOpenAI/auth.ts +1 -15
- package/src/app/(backend)/_deprecated/createBizOpenAI/index.ts +2 -9
- package/src/app/(backend)/middleware/auth/index.ts +0 -1
- package/src/app/(backend)/middleware/auth/utils.test.ts +2 -42
- package/src/app/(backend)/middleware/auth/utils.ts +3 -17
- package/src/app/(backend)/webapi/chat/[provider]/route.test.ts +0 -5
- package/src/app/(backend)/webapi/models/[provider]/route.test.ts +0 -6
- package/src/app/(backend)/webapi/plugin/gateway/route.ts +2 -32
- package/src/app/[variants]/(main)/settings/common/features/Common/Common.tsx +1 -16
- package/src/envs/app.ts +2 -0
- package/src/libs/trpc/lambda/middleware/index.ts +1 -0
- package/src/libs/trpc/lambda/middleware/telemetry.test.ts +237 -0
- package/src/libs/trpc/lambda/middleware/telemetry.ts +74 -0
- package/src/locales/default/setting.ts +0 -3
- package/src/server/routers/lambda/market/index.ts +1 -93
- package/src/server/routers/tools/_helpers/index.ts +1 -0
- package/src/server/routers/tools/_helpers/scheduleToolCallReport.ts +113 -0
- package/src/server/routers/tools/index.ts +2 -2
- package/src/server/routers/tools/market.ts +375 -0
- package/src/server/routers/tools/mcp.ts +77 -20
- package/src/services/chat/index.ts +0 -2
- package/src/services/codeInterpreter.ts +6 -6
- package/src/services/mcp.test.ts +60 -46
- package/src/services/mcp.ts +67 -48
- package/src/store/chat/slices/plugin/action.test.ts +191 -0
- package/src/store/chat/slices/plugin/actions/internals.ts +2 -18
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +31 -44
- package/packages/database/src/client/db.test.ts +0 -52
- package/packages/database/src/client/db.ts +0 -195
- package/packages/database/src/client/type.ts +0 -6
- package/src/server/routers/tools/codeInterpreter.ts +0 -255
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.196](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.195...v2.0.0-next.196)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-03**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Refactor to remove access code.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Code refactoring
|
|
19
|
+
|
|
20
|
+
- **misc**: Refactor to remove access code, closes [#11120](https://github.com/lobehub/lobe-chat/issues/11120) ([0e9f98c](https://github.com/lobehub/lobe-chat/commit/0e9f98c))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.195](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.194...v2.0.0-next.195)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2026-01-03**</sup>
|
|
33
|
+
|
|
34
|
+
#### 🐛 Bug Fixes
|
|
35
|
+
|
|
36
|
+
- **misc**: Fix tool call message content missing.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### What's fixed
|
|
44
|
+
|
|
45
|
+
- **misc**: Fix tool call message content missing, closes [#11116](https://github.com/lobehub/lobe-chat/issues/11116) ([885964e](https://github.com/lobehub/lobe-chat/commit/885964e))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
## [Version 2.0.0-next.194](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.193...v2.0.0-next.194)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2026-01-03**</sup>
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"children": {
|
|
4
|
+
"improvements": [
|
|
5
|
+
"Refactor to remove access code."
|
|
6
|
+
]
|
|
7
|
+
},
|
|
8
|
+
"date": "2026-01-03",
|
|
9
|
+
"version": "2.0.0-next.196"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"children": {
|
|
13
|
+
"fixes": [
|
|
14
|
+
"Fix tool call message content missing."
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"date": "2026-01-03",
|
|
18
|
+
"version": "2.0.0-next.195"
|
|
19
|
+
},
|
|
2
20
|
{
|
|
3
21
|
"children": {
|
|
4
22
|
"improvements": [
|
package/locales/ar/setting.json
CHANGED
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "الأسئلة الافتتاحية",
|
|
385
385
|
"settingOpening.title": "إعدادات البداية",
|
|
386
386
|
"settingPlugin.title": "قائمة المهارات",
|
|
387
|
-
"settingSystem.accessCode.desc": "تم تفعيل الوصول المشفر من قبل المسؤول",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "أدخل كلمة مرور الوصول",
|
|
389
|
-
"settingSystem.accessCode.title": "كلمة مرور الوصول",
|
|
390
387
|
"settingSystem.oauth.info.desc": "تم تسجيل الدخول",
|
|
391
388
|
"settingSystem.oauth.info.title": "معلومات الحساب",
|
|
392
389
|
"settingSystem.oauth.signin.action": "تسجيل الدخول",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Начални въпроси",
|
|
385
385
|
"settingOpening.title": "Настройки за начало",
|
|
386
386
|
"settingPlugin.title": "Списък с умения",
|
|
387
|
-
"settingSystem.accessCode.desc": "Достъпът с шифроване е активиран от администратора",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Въведете парола за достъп",
|
|
389
|
-
"settingSystem.accessCode.title": "Парола за достъп",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Вход изпълнен",
|
|
391
388
|
"settingSystem.oauth.info.title": "Информация за акаунта",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Вход",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Einstiegsfragen",
|
|
385
385
|
"settingOpening.title": "Begrüßungseinstellungen",
|
|
386
386
|
"settingPlugin.title": "Fähigkeitenliste",
|
|
387
|
-
"settingSystem.accessCode.desc": "Zugriff mit Verschlüsselung ist vom Administrator aktiviert",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Zugangspasswort eingeben",
|
|
389
|
-
"settingSystem.accessCode.title": "Zugangspasswort",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Angemeldet",
|
|
391
388
|
"settingSystem.oauth.info.title": "Kontoinformationen",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Anmelden",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Opening Questions",
|
|
385
385
|
"settingOpening.title": "Opening Settings",
|
|
386
386
|
"settingPlugin.title": "Skill List",
|
|
387
|
-
"settingSystem.accessCode.desc": "Encryption access is enabled by the administrator",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Enter access password",
|
|
389
|
-
"settingSystem.accessCode.title": "Access Password",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Logged in",
|
|
391
388
|
"settingSystem.oauth.info.title": "Account Information",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Sign In",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Preguntas de Apertura",
|
|
385
385
|
"settingOpening.title": "Configuración de Apertura",
|
|
386
386
|
"settingPlugin.title": "Lista de Habilidades",
|
|
387
|
-
"settingSystem.accessCode.desc": "El administrador ha habilitado el acceso cifrado",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Introduce la contraseña de acceso",
|
|
389
|
-
"settingSystem.accessCode.title": "Contraseña de Acceso",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Sesión iniciada",
|
|
391
388
|
"settingSystem.oauth.info.title": "Información de la Cuenta",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Iniciar Sesión",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "سؤالات آغازین",
|
|
385
385
|
"settingOpening.title": "تنظیمات آغازین",
|
|
386
386
|
"settingPlugin.title": "فهرست مهارتها",
|
|
387
|
-
"settingSystem.accessCode.desc": "دسترسی رمزگذاریشده توسط مدیر فعال شده است",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "رمز عبور دسترسی را وارد کنید",
|
|
389
|
-
"settingSystem.accessCode.title": "رمز عبور دسترسی",
|
|
390
387
|
"settingSystem.oauth.info.desc": "وارد شدهاید",
|
|
391
388
|
"settingSystem.oauth.info.title": "اطلاعات حساب",
|
|
392
389
|
"settingSystem.oauth.signin.action": "ورود",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Questions d’accueil",
|
|
385
385
|
"settingOpening.title": "Paramètres d’accueil",
|
|
386
386
|
"settingPlugin.title": "Liste des compétences",
|
|
387
|
-
"settingSystem.accessCode.desc": "L’accès chiffré est activé par l’administrateur",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Saisir le mot de passe d’accès",
|
|
389
|
-
"settingSystem.accessCode.title": "Mot de passe d’accès",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Connecté",
|
|
391
388
|
"settingSystem.oauth.info.title": "Informations du compte",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Se connecter",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Domande di Apertura",
|
|
385
385
|
"settingOpening.title": "Impostazioni di Apertura",
|
|
386
386
|
"settingPlugin.title": "Elenco Competenze",
|
|
387
|
-
"settingSystem.accessCode.desc": "L'accesso crittografato è abilitato dall'amministratore",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Inserisci la password di accesso",
|
|
389
|
-
"settingSystem.accessCode.title": "Password di Accesso",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Accesso effettuato",
|
|
391
388
|
"settingSystem.oauth.info.title": "Informazioni Account",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Accedi",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "オープニング質問",
|
|
385
385
|
"settingOpening.title": "オープニング設定",
|
|
386
386
|
"settingPlugin.title": "スキルリスト",
|
|
387
|
-
"settingSystem.accessCode.desc": "管理者が暗号化アクセスを有効にしています",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "アクセスコードを入力してください",
|
|
389
|
-
"settingSystem.accessCode.title": "アクセスコード",
|
|
390
387
|
"settingSystem.oauth.info.desc": "ログイン済み",
|
|
391
388
|
"settingSystem.oauth.info.title": "アカウント情報",
|
|
392
389
|
"settingSystem.oauth.signin.action": "ログイン",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "오프닝 질문",
|
|
385
385
|
"settingOpening.title": "오프닝 설정",
|
|
386
386
|
"settingPlugin.title": "기능 목록",
|
|
387
|
-
"settingSystem.accessCode.desc": "관리자가 암호화된 액세스를 활성화했습니다",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "액세스 암호를 입력하세요",
|
|
389
|
-
"settingSystem.accessCode.title": "액세스 암호",
|
|
390
387
|
"settingSystem.oauth.info.desc": "로그인됨",
|
|
391
388
|
"settingSystem.oauth.info.title": "계정 정보",
|
|
392
389
|
"settingSystem.oauth.signin.action": "로그인",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Openingsvragen",
|
|
385
385
|
"settingOpening.title": "Openingsinstellingen",
|
|
386
386
|
"settingPlugin.title": "Vaardighedenlijst",
|
|
387
|
-
"settingSystem.accessCode.desc": "Versleutelde toegang is ingeschakeld door de beheerder",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Voer toegangswachtwoord in",
|
|
389
|
-
"settingSystem.accessCode.title": "Toegangswachtwoord",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Ingelogd",
|
|
391
388
|
"settingSystem.oauth.info.title": "Accountinformatie",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Inloggen",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Pytania wprowadzające",
|
|
385
385
|
"settingOpening.title": "Ustawienia powitania",
|
|
386
386
|
"settingPlugin.title": "Lista umiejętności",
|
|
387
|
-
"settingSystem.accessCode.desc": "Dostęp szyfrowany został włączony przez administratora",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Wprowadź hasło dostępu",
|
|
389
|
-
"settingSystem.accessCode.title": "Hasło dostępu",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Zalogowano",
|
|
391
388
|
"settingSystem.oauth.info.title": "Informacje o koncie",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Zaloguj się",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Perguntas de Abertura",
|
|
385
385
|
"settingOpening.title": "Configurações de Abertura",
|
|
386
386
|
"settingPlugin.title": "Lista de Habilidades",
|
|
387
|
-
"settingSystem.accessCode.desc": "O acesso criptografado foi ativado pelo administrador",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Digite a senha de acesso",
|
|
389
|
-
"settingSystem.accessCode.title": "Senha de Acesso",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Conectado",
|
|
391
388
|
"settingSystem.oauth.info.title": "Informações da Conta",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Entrar",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Вводные вопросы",
|
|
385
385
|
"settingOpening.title": "Настройки приветствия",
|
|
386
386
|
"settingPlugin.title": "Список навыков",
|
|
387
|
-
"settingSystem.accessCode.desc": "Доступ по паролю включён администратором",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Введите пароль доступа",
|
|
389
|
-
"settingSystem.accessCode.title": "Пароль доступа",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Вы вошли в систему",
|
|
391
388
|
"settingSystem.oauth.info.title": "Информация об аккаунте",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Войти",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Açılış Soruları",
|
|
385
385
|
"settingOpening.title": "Açılış Ayarları",
|
|
386
386
|
"settingPlugin.title": "Yetenek Listesi",
|
|
387
|
-
"settingSystem.accessCode.desc": "Şifreli erişim, yönetici tarafından etkinleştirilmiştir",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Erişim şifresini girin",
|
|
389
|
-
"settingSystem.accessCode.title": "Erişim Şifresi",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Giriş yapıldı",
|
|
391
388
|
"settingSystem.oauth.info.title": "Hesap Bilgileri",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Giriş Yap",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "Câu Hỏi Mở Đầu",
|
|
385
385
|
"settingOpening.title": "Cài Đặt Mở Đầu",
|
|
386
386
|
"settingPlugin.title": "Danh Sách Kỹ Năng",
|
|
387
|
-
"settingSystem.accessCode.desc": "Mã truy cập được mã hóa do quản trị viên bật",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "Nhập mật khẩu truy cập",
|
|
389
|
-
"settingSystem.accessCode.title": "Mật Khẩu Truy Cập",
|
|
390
387
|
"settingSystem.oauth.info.desc": "Đã đăng nhập",
|
|
391
388
|
"settingSystem.oauth.info.title": "Thông Tin Tài Khoản",
|
|
392
389
|
"settingSystem.oauth.signin.action": "Đăng Nhập",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "开场问题",
|
|
385
385
|
"settingOpening.title": "开场设置",
|
|
386
386
|
"settingPlugin.title": "技能列表",
|
|
387
|
-
"settingSystem.accessCode.desc": "管理员已开启加密访问",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "请输入访问密码",
|
|
389
|
-
"settingSystem.accessCode.title": "访问密码",
|
|
390
387
|
"settingSystem.oauth.info.desc": "已登录",
|
|
391
388
|
"settingSystem.oauth.info.title": "账户信息",
|
|
392
389
|
"settingSystem.oauth.signin.action": "登录",
|
|
@@ -384,9 +384,6 @@
|
|
|
384
384
|
"settingOpening.openingQuestions.title": "開場問題",
|
|
385
385
|
"settingOpening.title": "開場設定",
|
|
386
386
|
"settingPlugin.title": "插件列表",
|
|
387
|
-
"settingSystem.accessCode.desc": "管理員已開啟加密訪問",
|
|
388
|
-
"settingSystem.accessCode.placeholder": "請輸入訪問密碼",
|
|
389
|
-
"settingSystem.accessCode.title": "訪問密碼",
|
|
390
387
|
"settingSystem.oauth.info.desc": "已登錄",
|
|
391
388
|
"settingSystem.oauth.info.title": "帳戶資訊",
|
|
392
389
|
"settingSystem.oauth.signin.action": "登錄",
|
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.196",
|
|
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",
|
|
@@ -6,8 +6,6 @@ export const USE_AZURE_OPENAI = 'X-use-azure-openai';
|
|
|
6
6
|
|
|
7
7
|
export const AZURE_OPENAI_API_VERSION = 'X-azure-openai-api-version';
|
|
8
8
|
|
|
9
|
-
export const LOBE_CHAT_ACCESS_CODE = 'X-lobe-chat-access-code';
|
|
10
|
-
|
|
11
9
|
export const OAUTH_AUTHORIZED = 'X-oauth-authorized';
|
|
12
10
|
|
|
13
11
|
/**
|
|
@@ -16,7 +14,6 @@ export const OAUTH_AUTHORIZED = 'X-oauth-authorized';
|
|
|
16
14
|
export const getOpenAIAuthFromRequest = (req: Request) => {
|
|
17
15
|
const apiKey = req.headers.get(OPENAI_API_KEY_HEADER_KEY);
|
|
18
16
|
const endpoint = req.headers.get(OPENAI_END_POINT);
|
|
19
|
-
const accessCode = req.headers.get(LOBE_CHAT_ACCESS_CODE);
|
|
20
17
|
const useAzureStr = req.headers.get(USE_AZURE_OPENAI);
|
|
21
18
|
const apiVersion = req.headers.get(AZURE_OPENAI_API_VERSION);
|
|
22
19
|
const oauthAuthorizedStr = req.headers.get(OAUTH_AUTHORIZED);
|
|
@@ -25,5 +22,5 @@ export const getOpenAIAuthFromRequest = (req: Request) => {
|
|
|
25
22
|
const oauthAuthorized = !!oauthAuthorizedStr;
|
|
26
23
|
const useAzure = !!useAzureStr;
|
|
27
24
|
|
|
28
|
-
return {
|
|
25
|
+
return { apiKey, apiVersion, endpoint, oauthAuthorized, useAzure, userId };
|
|
29
26
|
};
|
|
@@ -165,6 +165,14 @@ export class UserModel {
|
|
|
165
165
|
return this.db.query.userSettings.findFirst({ where: eq(userSettings.id, this.userId) });
|
|
166
166
|
};
|
|
167
167
|
|
|
168
|
+
getUserPreference = async (): Promise<UserPreference | undefined> => {
|
|
169
|
+
const user = await this.db.query.users.findFirst({
|
|
170
|
+
columns: { preference: true },
|
|
171
|
+
where: eq(users.id, this.userId),
|
|
172
|
+
});
|
|
173
|
+
return user?.preference as UserPreference | undefined;
|
|
174
|
+
};
|
|
175
|
+
|
|
168
176
|
getUserSettingsDefaultAgentConfig = async () => {
|
|
169
177
|
const result = await this.db
|
|
170
178
|
.select({ defaultAgent: userSettings.defaultAgent })
|
|
@@ -6,10 +6,10 @@ import type {
|
|
|
6
6
|
} from '@lobechat/types';
|
|
7
7
|
import { AiProviderModelListItem, EnabledAiModel } from 'model-bank';
|
|
8
8
|
import { DEFAULT_MODEL_PROVIDER_LIST } from 'model-bank/modelProviders';
|
|
9
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
10
|
-
|
|
11
|
-
import { clientDB, initializeDB } from '@/database/client/db';
|
|
9
|
+
import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
12
10
|
|
|
11
|
+
import { getTestDB } from '../../models/__tests__/_util';
|
|
12
|
+
import { LobeChatDatabase } from '../../type';
|
|
13
13
|
import { AiInfraRepos } from './index';
|
|
14
14
|
|
|
15
15
|
const userId = 'test-user-id';
|
|
@@ -18,15 +18,18 @@ const mockProviderConfigs = {
|
|
|
18
18
|
anthropic: { enabled: false },
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
let serverDB: LobeChatDatabase;
|
|
21
22
|
let repo: AiInfraRepos;
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
await
|
|
25
|
-
vi.clearAllMocks();
|
|
26
|
-
|
|
27
|
-
repo = new AiInfraRepos(clientDB as any, userId, mockProviderConfigs);
|
|
24
|
+
beforeAll(async () => {
|
|
25
|
+
serverDB = await getTestDB();
|
|
28
26
|
}, 30000);
|
|
29
27
|
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
vi.clearAllMocks();
|
|
30
|
+
repo = new AiInfraRepos(serverDB, userId, mockProviderConfigs);
|
|
31
|
+
});
|
|
32
|
+
|
|
30
33
|
describe('AiInfraRepos', () => {
|
|
31
34
|
describe('getAiProviderList', () => {
|
|
32
35
|
it('should merge builtin and user providers correctly', async () => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { clientDB, initializeDB } from '@/database/client/db';
|
|
1
|
+
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
2
|
|
|
3
|
+
import { getTestDB } from '../../models/__tests__/_util';
|
|
5
4
|
import {
|
|
6
5
|
agents,
|
|
7
6
|
agentsKnowledgeBases,
|
|
@@ -21,7 +20,7 @@ import {
|
|
|
21
20
|
import { LobeChatDatabase } from '../../type';
|
|
22
21
|
import { DATA_EXPORT_CONFIG, DataExporterRepos } from './index';
|
|
23
22
|
|
|
24
|
-
let db
|
|
23
|
+
let db: LobeChatDatabase;
|
|
25
24
|
|
|
26
25
|
// 设置测试数据
|
|
27
26
|
describe('DataExporterRepos', () => {
|
|
@@ -38,7 +37,11 @@ describe('DataExporterRepos', () => {
|
|
|
38
37
|
};
|
|
39
38
|
|
|
40
39
|
// 设置测试环境
|
|
41
|
-
|
|
40
|
+
const userId: string = testIds.userId;
|
|
41
|
+
|
|
42
|
+
beforeAll(async () => {
|
|
43
|
+
db = await getTestDB();
|
|
44
|
+
}, 30000);
|
|
42
45
|
|
|
43
46
|
const setupTestData = async () => {
|
|
44
47
|
await db.transaction(async (trx) => {
|
|
@@ -152,10 +155,9 @@ describe('DataExporterRepos', () => {
|
|
|
152
155
|
};
|
|
153
156
|
|
|
154
157
|
beforeEach(async () => {
|
|
155
|
-
//
|
|
156
|
-
await
|
|
157
|
-
|
|
158
|
-
// 插入测试数据
|
|
158
|
+
// 清理并插入测试数据
|
|
159
|
+
await db.delete(users);
|
|
160
|
+
await db.delete(globalFiles);
|
|
159
161
|
await setupTestData();
|
|
160
162
|
}, 30000);
|
|
161
163
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { clientDB, initializeDB } from '@/database/client/db';
|
|
1
|
+
import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
2
|
|
|
3
|
+
import { getTestDB } from '../../models/__tests__/_util';
|
|
4
|
+
import { LobeChatDatabase } from '../../type';
|
|
5
5
|
import { TableViewerRepo } from './index';
|
|
6
6
|
|
|
7
7
|
const userId = 'user-table-viewer';
|
|
8
|
-
const repo = new TableViewerRepo(clientDB as any, userId);
|
|
9
8
|
|
|
10
9
|
// Mock database execution
|
|
11
10
|
const mockExecute = vi.fn();
|
|
@@ -13,20 +12,20 @@ const mockDB = {
|
|
|
13
12
|
execute: mockExecute,
|
|
14
13
|
};
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
let serverDB: LobeChatDatabase;
|
|
16
|
+
let repo: TableViewerRepo;
|
|
17
|
+
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
serverDB = await getTestDB();
|
|
20
|
+
repo = new TableViewerRepo(serverDB, userId);
|
|
19
21
|
}, 30000);
|
|
20
22
|
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vi.clearAllMocks();
|
|
25
|
+
});
|
|
26
|
+
|
|
21
27
|
describe('TableViewerRepo', () => {
|
|
22
28
|
describe('getAllTables', () => {
|
|
23
|
-
it('should return all tables with counts', async () => {
|
|
24
|
-
const result = await repo.getAllTables();
|
|
25
|
-
|
|
26
|
-
expect(result.length).toEqual(73);
|
|
27
|
-
expect(result[0]).toEqual({ name: 'accounts', count: 0, type: 'BASE TABLE' });
|
|
28
|
-
});
|
|
29
|
-
|
|
30
29
|
it('should handle custom schema', async () => {
|
|
31
30
|
const result = await repo.getAllTables('custom_schema');
|
|
32
31
|
expect(result).toBeDefined();
|
|
@@ -29,7 +29,7 @@ export const params = {
|
|
|
29
29
|
type: 'web_search',
|
|
30
30
|
web_search: {
|
|
31
31
|
enable: true,
|
|
32
|
-
result_sequence: 'before', //
|
|
32
|
+
result_sequence: 'before', // Change search result return sequence to 'before' to minimize OpenAIStream modifications
|
|
33
33
|
search_engine: process.env.ZHIPU_SEARCH_ENGINE || 'search_std', // search_std, search_pro
|
|
34
34
|
search_result: true,
|
|
35
35
|
},
|
|
@@ -69,16 +69,16 @@ export const params = {
|
|
|
69
69
|
const readableStream =
|
|
70
70
|
stream instanceof ReadableStream ? stream : convertIterableToStream(stream);
|
|
71
71
|
|
|
72
|
-
// GLM-4.5
|
|
73
|
-
//
|
|
72
|
+
// GLM-4.5 series models return index -1 in tool_calls, needs to be fixed before entering OpenAIStream
|
|
73
|
+
// because OpenAIStream internally filters out tool_calls with index < 0 (openai.ts:58-60)
|
|
74
74
|
const preprocessedStream = readableStream.pipeThrough(
|
|
75
75
|
new TransformStream({
|
|
76
76
|
transform(chunk, controller) {
|
|
77
|
-
//
|
|
77
|
+
// Handle raw OpenAI ChatCompletionChunk format
|
|
78
78
|
if (chunk.choices && chunk.choices[0]) {
|
|
79
79
|
const choice = chunk.choices[0];
|
|
80
80
|
if (choice.delta?.tool_calls && Array.isArray(choice.delta.tool_calls)) {
|
|
81
|
-
//
|
|
81
|
+
// Fix negative index, convert -1 to positive index based on array position
|
|
82
82
|
const fixedToolCalls = choice.delta.tool_calls.map(
|
|
83
83
|
(toolCall: any, globalIndex: number) => ({
|
|
84
84
|
...toolCall,
|
|
@@ -86,7 +86,7 @@ export const params = {
|
|
|
86
86
|
}),
|
|
87
87
|
);
|
|
88
88
|
|
|
89
|
-
//
|
|
89
|
+
// Create fixed chunk
|
|
90
90
|
const fixedChunk = {
|
|
91
91
|
...chunk,
|
|
92
92
|
choices: [
|
|
@@ -7,7 +7,6 @@ describe('getXorPayload', () => {
|
|
|
7
7
|
it('should correctly decode XOR obfuscated payload with user data', () => {
|
|
8
8
|
const originalPayload = {
|
|
9
9
|
userId: '001362c3-48c5-4635-bd3b-837bfff58fc0',
|
|
10
|
-
accessCode: 'test-access-code',
|
|
11
10
|
apiKey: 'test-api-key',
|
|
12
11
|
baseURL: 'https://api.example.com',
|
|
13
12
|
};
|
|
@@ -86,7 +85,7 @@ describe('getXorPayload', () => {
|
|
|
86
85
|
it('should handle payload with undefined values', () => {
|
|
87
86
|
const originalPayload = {
|
|
88
87
|
userId: 'test-user',
|
|
89
|
-
|
|
88
|
+
baseURL: undefined,
|
|
90
89
|
apiKey: 'test-key',
|
|
91
90
|
};
|
|
92
91
|
|
|
@@ -1,53 +1,19 @@
|
|
|
1
1
|
// @vitest-environment node
|
|
2
2
|
import { checkAuth } from './auth';
|
|
3
3
|
|
|
4
|
-
describe('
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
auth = false;
|
|
9
|
-
process.env.ACCESS_CODE = undefined;
|
|
10
|
-
// Reset environment variables before each test case
|
|
11
|
-
vi.restoreAllMocks();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('set multiple access codes', () => {
|
|
15
|
-
process.env.ACCESS_CODE = ',code1,code2,code3';
|
|
16
|
-
({ auth } = checkAuth({ accessCode: 'code1' }));
|
|
17
|
-
expect(auth).toBe(true);
|
|
18
|
-
({ auth } = checkAuth({ accessCode: 'code2' }));
|
|
19
|
-
expect(auth).toBe(true);
|
|
20
|
-
({ auth } = checkAuth({ accessCode: 'code1,code2' }));
|
|
21
|
-
expect(auth).toBe(false);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('set individual access code', () => {
|
|
25
|
-
process.env.ACCESS_CODE = 'code1';
|
|
26
|
-
({ auth } = checkAuth({ accessCode: 'code1' }));
|
|
4
|
+
describe('checkAuth', () => {
|
|
5
|
+
it('should pass with oauth authorized', () => {
|
|
6
|
+
const { auth } = checkAuth({ oauthAuthorized: true });
|
|
27
7
|
expect(auth).toBe(true);
|
|
28
|
-
({ auth } = checkAuth({ accessCode: 'code2' }));
|
|
29
|
-
expect(auth).toBe(false);
|
|
30
8
|
});
|
|
31
9
|
|
|
32
|
-
it('
|
|
33
|
-
|
|
34
|
-
({ auth } = checkAuth({ accessCode: 'code1' }));
|
|
35
|
-
expect(auth).toBe(true);
|
|
36
|
-
({ auth } = checkAuth({}));
|
|
10
|
+
it('should pass with api key', () => {
|
|
11
|
+
const { auth } = checkAuth({ apiKey: 'test-api-key' });
|
|
37
12
|
expect(auth).toBe(true);
|
|
38
13
|
});
|
|
39
14
|
|
|
40
|
-
it('
|
|
41
|
-
|
|
42
|
-
({ auth } = checkAuth({ accessCode: 'code1' }));
|
|
43
|
-
expect(auth).toBe(true);
|
|
44
|
-
({ auth } = checkAuth({}));
|
|
45
|
-
expect(auth).toBe(true);
|
|
46
|
-
|
|
47
|
-
process.env.ACCESS_CODE = ',,';
|
|
48
|
-
({ auth } = checkAuth({ accessCode: 'code1' }));
|
|
49
|
-
expect(auth).toBe(true);
|
|
50
|
-
({ auth } = checkAuth({}));
|
|
15
|
+
it('should pass with no params', () => {
|
|
16
|
+
const { auth } = checkAuth({});
|
|
51
17
|
expect(auth).toBe(true);
|
|
52
18
|
});
|
|
53
19
|
});
|
|
@@ -1,32 +1,18 @@
|
|
|
1
|
-
import { ChatErrorType } from '@lobechat/types';
|
|
2
|
-
|
|
3
|
-
import { getAppConfig } from '@/envs/app';
|
|
4
|
-
|
|
5
1
|
interface AuthConfig {
|
|
6
|
-
accessCode?: string | null;
|
|
7
2
|
apiKey?: string | null;
|
|
8
3
|
oauthAuthorized?: boolean;
|
|
9
4
|
}
|
|
10
5
|
|
|
11
|
-
export const checkAuth = ({ apiKey,
|
|
6
|
+
export const checkAuth = ({ apiKey, oauthAuthorized }: AuthConfig) => {
|
|
12
7
|
// If authorized by oauth
|
|
13
8
|
if (oauthAuthorized) {
|
|
14
9
|
return { auth: true };
|
|
15
10
|
}
|
|
16
11
|
|
|
17
|
-
const { ACCESS_CODES } = getAppConfig();
|
|
18
|
-
|
|
19
12
|
// if apiKey exist
|
|
20
13
|
if (apiKey) {
|
|
21
14
|
return { auth: true };
|
|
22
15
|
}
|
|
23
16
|
|
|
24
|
-
// if accessCode doesn't exist
|
|
25
|
-
if (!ACCESS_CODES.length) return { auth: true };
|
|
26
|
-
|
|
27
|
-
if (!accessCode || !ACCESS_CODES.includes(accessCode)) {
|
|
28
|
-
return { auth: false, error: ChatErrorType.InvalidAccessCode };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
17
|
return { auth: true };
|
|
32
18
|
};
|