@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.
Files changed (61) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/locales/ar/setting.json +0 -3
  4. package/locales/bg-BG/setting.json +0 -3
  5. package/locales/de-DE/setting.json +0 -3
  6. package/locales/en-US/setting.json +0 -3
  7. package/locales/es-ES/setting.json +0 -3
  8. package/locales/fa-IR/setting.json +0 -3
  9. package/locales/fr-FR/setting.json +0 -3
  10. package/locales/it-IT/setting.json +0 -3
  11. package/locales/ja-JP/setting.json +0 -3
  12. package/locales/ko-KR/setting.json +0 -3
  13. package/locales/nl-NL/setting.json +0 -3
  14. package/locales/pl-PL/setting.json +0 -3
  15. package/locales/pt-BR/setting.json +0 -3
  16. package/locales/ru-RU/setting.json +0 -3
  17. package/locales/tr-TR/setting.json +0 -3
  18. package/locales/vi-VN/setting.json +0 -3
  19. package/locales/zh-CN/setting.json +0 -3
  20. package/locales/zh-TW/setting.json +0 -3
  21. package/package.json +1 -1
  22. package/packages/const/src/fetch.ts +1 -4
  23. package/packages/database/src/models/user.ts +8 -0
  24. package/packages/database/src/repositories/aiInfra/index.test.ts +11 -8
  25. package/packages/database/src/repositories/dataExporter/index.test.ts +11 -9
  26. package/packages/database/src/repositories/tableViewer/index.test.ts +13 -14
  27. package/packages/model-runtime/src/providers/zhipu/index.ts +6 -6
  28. package/packages/types/src/auth.ts +0 -4
  29. package/packages/utils/src/server/xor.test.ts +1 -2
  30. package/src/app/(backend)/_deprecated/createBizOpenAI/auth.test.ts +7 -41
  31. package/src/app/(backend)/_deprecated/createBizOpenAI/auth.ts +1 -15
  32. package/src/app/(backend)/_deprecated/createBizOpenAI/index.ts +2 -9
  33. package/src/app/(backend)/middleware/auth/index.ts +0 -1
  34. package/src/app/(backend)/middleware/auth/utils.test.ts +2 -42
  35. package/src/app/(backend)/middleware/auth/utils.ts +3 -17
  36. package/src/app/(backend)/webapi/chat/[provider]/route.test.ts +0 -5
  37. package/src/app/(backend)/webapi/models/[provider]/route.test.ts +0 -6
  38. package/src/app/(backend)/webapi/plugin/gateway/route.ts +2 -32
  39. package/src/app/[variants]/(main)/settings/common/features/Common/Common.tsx +1 -16
  40. package/src/envs/app.ts +2 -0
  41. package/src/libs/trpc/lambda/middleware/index.ts +1 -0
  42. package/src/libs/trpc/lambda/middleware/telemetry.test.ts +237 -0
  43. package/src/libs/trpc/lambda/middleware/telemetry.ts +74 -0
  44. package/src/locales/default/setting.ts +0 -3
  45. package/src/server/routers/lambda/market/index.ts +1 -93
  46. package/src/server/routers/tools/_helpers/index.ts +1 -0
  47. package/src/server/routers/tools/_helpers/scheduleToolCallReport.ts +113 -0
  48. package/src/server/routers/tools/index.ts +2 -2
  49. package/src/server/routers/tools/market.ts +375 -0
  50. package/src/server/routers/tools/mcp.ts +77 -20
  51. package/src/services/chat/index.ts +0 -2
  52. package/src/services/codeInterpreter.ts +6 -6
  53. package/src/services/mcp.test.ts +60 -46
  54. package/src/services/mcp.ts +67 -48
  55. package/src/store/chat/slices/plugin/action.test.ts +191 -0
  56. package/src/store/chat/slices/plugin/actions/internals.ts +2 -18
  57. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +31 -44
  58. package/packages/database/src/client/db.test.ts +0 -52
  59. package/packages/database/src/client/db.ts +0 -195
  60. package/packages/database/src/client/type.ts +0 -6
  61. 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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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": [
@@ -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.194",
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 { accessCode, apiKey, apiVersion, endpoint, oauthAuthorized, useAzure, userId };
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
- beforeEach(async () => {
24
- await initializeDB();
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 = clientDB as LobeChatDatabase;
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
- let userId: string = testIds.userId;
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 initializeDB();
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
- beforeEach(async () => {
17
- await initializeDB();
18
- vi.clearAllMocks();
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', // 将搜索结果返回顺序更改为 before 适配最小化 OpenAIStream 改动
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 系列模型在 tool_calls 中返回的 index -1,需要在进入 OpenAIStream 之前修正
73
- // 因为 OpenAIStream 内部会过滤掉 index < 0 的 tool_calls (openai.ts:58-60)
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
- // 处理原始的 OpenAI ChatCompletionChunk 格式
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
- // 修正负数 index,将 -1 转换为基于数组位置的正数 index
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
- // 创建修正后的 chunk
89
+ // Create fixed chunk
90
90
  const fixedChunk = {
91
91
  ...chunk,
92
92
  choices: [
@@ -1,9 +1,5 @@
1
1
  /* eslint-disable typescript-sort-keys/interface */
2
2
  export interface ClientSecretPayload {
3
- /**
4
- * password
5
- */
6
- accessCode?: string;
7
3
  /**
8
4
  * Represents the user's API key
9
5
  *
@@ -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
- accessCode: undefined,
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('ACCESS_CODE', () => {
5
- let auth = false;
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('no access code', () => {
33
- delete process.env.ACCESS_CODE;
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('empty access code', () => {
41
- process.env.ACCESS_CODE = '';
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, accessCode, oauthAuthorized }: AuthConfig) => {
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
  };