@lobehub/lobehub 2.0.0-next.127 → 2.0.0-next.129

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/.env.example +23 -3
  2. package/.env.example.development +5 -0
  3. package/CHANGELOG.md +50 -0
  4. package/README.md +6 -6
  5. package/README.zh-CN.md +6 -6
  6. package/changelog/v1.json +18 -0
  7. package/docker-compose/local/docker-compose.yml +24 -1
  8. package/docker-compose/local/logto/docker-compose.yml +25 -2
  9. package/docker-compose.development.yml +6 -0
  10. package/docs/development/database-schema.dbml +8 -6
  11. package/locales/ar/auth.json +114 -1
  12. package/locales/bg-BG/auth.json +114 -1
  13. package/locales/de-DE/auth.json +114 -1
  14. package/locales/en-US/auth.json +42 -22
  15. package/locales/es-ES/auth.json +114 -1
  16. package/locales/fa-IR/auth.json +114 -1
  17. package/locales/fr-FR/auth.json +114 -1
  18. package/locales/it-IT/auth.json +114 -1
  19. package/locales/ja-JP/auth.json +114 -1
  20. package/locales/ko-KR/auth.json +114 -1
  21. package/locales/nl-NL/auth.json +114 -1
  22. package/locales/pl-PL/auth.json +114 -1
  23. package/locales/pt-BR/auth.json +114 -1
  24. package/locales/ru-RU/auth.json +114 -1
  25. package/locales/tr-TR/auth.json +114 -1
  26. package/locales/vi-VN/auth.json +114 -1
  27. package/locales/zh-CN/auth.json +36 -29
  28. package/locales/zh-TW/auth.json +114 -1
  29. package/package.json +4 -1
  30. package/packages/database/migrations/0050_thread_and_user_id.sql +18 -0
  31. package/packages/database/migrations/meta/0050_snapshot.json +8792 -0
  32. package/packages/database/migrations/meta/_journal.json +7 -0
  33. package/packages/database/src/client/db.ts +21 -21
  34. package/packages/database/src/core/migrations.json +51 -10
  35. package/packages/database/src/repositories/dataImporter/deprecated/index.ts +5 -5
  36. package/packages/database/src/repositories/dataImporter/index.ts +59 -59
  37. package/packages/database/src/repositories/knowledge/index.test.ts +17 -5
  38. package/packages/database/src/repositories/knowledge/index.ts +6 -6
  39. package/packages/database/src/schemas/generation.ts +16 -16
  40. package/packages/database/src/schemas/nextauth.ts +3 -3
  41. package/packages/database/src/schemas/oidc.ts +36 -36
  42. package/packages/database/src/schemas/topic.ts +8 -3
  43. package/packages/model-runtime/src/providers/newapi/index.ts +61 -18
  44. package/packages/model-runtime/src/runtimeMap.ts +1 -0
  45. package/packages/types/src/topic/thread.ts +3 -3
  46. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/SettingModal.tsx +10 -6
  47. package/src/envs/redis.ts +106 -0
  48. package/src/libs/redis/index.ts +5 -0
  49. package/src/libs/redis/manager.test.ts +107 -0
  50. package/src/libs/redis/manager.ts +56 -0
  51. package/src/libs/redis/redis.test.ts +158 -0
  52. package/src/libs/redis/redis.ts +117 -0
  53. package/src/libs/redis/types.ts +71 -0
  54. package/src/libs/redis/upstash.test.ts +154 -0
  55. package/src/libs/redis/upstash.ts +109 -0
  56. package/src/libs/redis/utils.test.ts +46 -0
  57. package/src/libs/redis/utils.ts +53 -0
  58. package/src/store/chat/slices/thread/action.ts +1 -1
  59. package/src/store/chat/slices/thread/initialState.ts +1 -1
  60. package/src/store/chat/slices/thread/selectors/util.ts +1 -1
  61. package/.github/workflows/check-console-log.yml +0 -117
@@ -350,6 +350,13 @@
350
350
  "when": 1764229953081,
351
351
  "tag": "0049_better_auth",
352
352
  "breakpoints": true
353
+ },
354
+ {
355
+ "idx": 50,
356
+ "version": "7",
357
+ "when": 1764303057060,
358
+ "tag": "0050_thread_and_user_id",
359
+ "breakpoints": true
353
360
  }
354
361
  ],
355
362
  "version": "6"
@@ -207,7 +207,7 @@ export class DatabaseManager {
207
207
  return this.db;
208
208
  }
209
209
 
210
- // 初始化数据库
210
+ // Initialize database
211
211
  async initialize(callbacks?: DatabaseLoadingCallbacks): Promise<DrizzleInstance> {
212
212
  if (this.initPromise) return this.initPromise;
213
213
 
@@ -218,13 +218,13 @@ export class DatabaseManager {
218
218
  if (this.dbInstance) return this.dbInstance;
219
219
 
220
220
  const time = Date.now();
221
- // 初始化数据库
221
+ // Initialize database
222
222
  this.callbacks?.onStateChange?.(DatabaseLoadingState.Initializing);
223
223
 
224
- // 加载依赖
224
+ // Load dependencies
225
225
  const { fsBundle, PGlite, MemoryFS, IdbFs, vector } = await this.loadDependencies();
226
226
 
227
- // 加载并编译 WASM 模块
227
+ // Load and compile WASM module
228
228
  const wasmModule = await this.loadWasmModule();
229
229
 
230
230
  const { initPgliteWorker } = await import('./pglite');
@@ -267,10 +267,10 @@ export class DatabaseManager {
267
267
  this.callbacks?.onStateChange?.(DatabaseLoadingState.Error);
268
268
  const error = e as Error;
269
269
 
270
- // 查询迁移表数据
270
+ // Query migration table data
271
271
  let migrationsTableData: MigrationTableItem[] = [];
272
272
  try {
273
- // 尝试查询迁移表
273
+ // Attempt to query migration table
274
274
  const drizzleMigration = new DrizzleMigrationModel(this.db as any);
275
275
  migrationsTableData = await drizzleMigration.getMigrationList();
276
276
  } catch (queryError) {
@@ -295,7 +295,7 @@ export class DatabaseManager {
295
295
  return this.initPromise;
296
296
  }
297
297
 
298
- // 获取数据库实例
298
+ // Get database instance
299
299
  get db(): DrizzleInstance {
300
300
  if (!this.dbInstance) {
301
301
  throw new Error('Database not initialized. Please call initialize() first.');
@@ -303,7 +303,7 @@ export class DatabaseManager {
303
303
  return this.dbInstance;
304
304
  }
305
305
 
306
- // 创建代理对象
306
+ // Create proxy object
307
307
  createProxy(): DrizzleInstance {
308
308
  return new Proxy({} as DrizzleInstance, {
309
309
  get: (target, prop) => {
@@ -313,7 +313,7 @@ export class DatabaseManager {
313
313
  }
314
314
 
315
315
  async resetDatabase(): Promise<void> {
316
- // 1. 关闭现有的 PGlite 连接(如果存在)
316
+ // 1. Close existing PGlite connection (if exists)
317
317
  if (this.dbInstance) {
318
318
  try {
319
319
  // @ts-ignore
@@ -321,31 +321,31 @@ export class DatabaseManager {
321
321
  console.log('PGlite instance closed successfully.');
322
322
  } catch (e) {
323
323
  console.error('Error closing PGlite instance:', e);
324
- // 即使关闭失败,也尝试继续删除,IndexedDB onblocked onerror 会处理后续问题
324
+ // Even if closing fails, continue with deletion attempt; IndexedDB onblocked or onerror will handle subsequent issues
325
325
  }
326
326
  }
327
327
 
328
- // 2. 重置数据库实例和初始化状态
328
+ // 2. Reset database instance and initialization state
329
329
  this.dbInstance = null;
330
330
  this.initPromise = null;
331
- this.isLocalDBSchemaSynced = false; // 重置同步状态
331
+ this.isLocalDBSchemaSynced = false; // Reset sync state
332
332
 
333
- // 3. 删除 IndexedDB 数据库
333
+ // 3. Delete IndexedDB database
334
334
  return new Promise<void>((resolve, reject) => {
335
- // 检查 IndexedDB 是否可用
335
+ // Check if IndexedDB is available
336
336
  if (typeof indexedDB === 'undefined') {
337
337
  console.warn('IndexedDB is not available, cannot delete database');
338
- resolve(); // 在此环境下无法删除,直接解决
338
+ resolve(); // Cannot delete in this environment, resolve directly
339
339
  return;
340
340
  }
341
341
 
342
- const dbName = `/pglite/${DB_NAME}`; // PGlite IdbFs 使用的路径
342
+ const dbName = `/pglite/${DB_NAME}`; // Path used by PGlite IdbFs
343
343
  const request = indexedDB.deleteDatabase(dbName);
344
344
 
345
345
  request.onsuccess = () => {
346
346
  console.log(`✅ Database '${dbName}' reset successfully`);
347
347
 
348
- // 清除本地存储的模式哈希
348
+ // Clear locally stored schema hash
349
349
  if (typeof localStorage !== 'undefined') {
350
350
  localStorage.removeItem(pgliteSchemaHashCache);
351
351
  }
@@ -365,7 +365,7 @@ export class DatabaseManager {
365
365
  };
366
366
 
367
367
  request.onblocked = (event) => {
368
- // 当其他打开的连接阻止数据库删除时,会触发此事件
368
+ // This event is triggered when other open connections block database deletion
369
369
  console.warn(
370
370
  `Deletion of database '${dbName}' is blocked. This usually means other connections (e.g., in other tabs) are still open. Event:`,
371
371
  event,
@@ -380,13 +380,13 @@ export class DatabaseManager {
380
380
  }
381
381
  }
382
382
 
383
- // 导出单例
383
+ // Export singleton
384
384
  const dbManager = DatabaseManager.getInstance();
385
385
 
386
- // 保持原有的 clientDB 导出不变
386
+ // Keep original clientDB export unchanged
387
387
  export const clientDB = dbManager.createProxy();
388
388
 
389
- // 导出初始化方法,供应用启动时使用
389
+ // Export initialization method for application startup
390
390
  export const initializeDB = (callbacks?: DatabaseLoadingCallbacks) =>
391
391
  dbManager.initialize(callbacks);
392
392
 
@@ -223,7 +223,10 @@
223
223
  "hash": "9646161fa041354714f823d726af27247bcd6e60fa3be5698c0d69f337a5700b"
224
224
  },
225
225
  {
226
- "sql": ["DROP TABLE \"user_budgets\";", "\nDROP TABLE \"user_subscriptions\";"],
226
+ "sql": [
227
+ "DROP TABLE \"user_budgets\";",
228
+ "\nDROP TABLE \"user_subscriptions\";"
229
+ ],
227
230
  "bps": true,
228
231
  "folderMillis": 1729699958471,
229
232
  "hash": "7dad43a2a25d1aec82124a4e53f8d82f8505c3073f23606c1dc5d2a4598eacf9"
@@ -295,7 +298,9 @@
295
298
  "hash": "845a692ceabbfc3caf252a97d3e19a213bc0c433df2689900135f9cfded2cf49"
296
299
  },
297
300
  {
298
- "sql": ["ALTER TABLE \"messages\" ADD COLUMN \"reasoning\" jsonb;"],
301
+ "sql": [
302
+ "ALTER TABLE \"messages\" ADD COLUMN \"reasoning\" jsonb;"
303
+ ],
299
304
  "bps": true,
300
305
  "folderMillis": 1737609172353,
301
306
  "hash": "2cb36ae4fcdd7b7064767e04bfbb36ae34518ff4bb1b39006f2dd394d1893868"
@@ -510,7 +515,9 @@
510
515
  "hash": "a7ccf007fd185ff922823148d1eae6fafe652fc98d2fd2793f84a84f29e93cd1"
511
516
  },
512
517
  {
513
- "sql": ["ALTER TABLE \"ai_providers\" ADD COLUMN \"config\" jsonb;"],
518
+ "sql": [
519
+ "ALTER TABLE \"ai_providers\" ADD COLUMN \"config\" jsonb;"
520
+ ],
514
521
  "bps": true,
515
522
  "folderMillis": 1749309388370,
516
523
  "hash": "39cea379f08ee4cb944875c0b67f7791387b508c2d47958bb4cd501ed1ef33eb"
@@ -628,7 +635,9 @@
628
635
  "hash": "1ba9b1f74ea13348da98d6fcdad7867ab4316ed565bf75d84d160c526cdac14b"
629
636
  },
630
637
  {
631
- "sql": ["ALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"virtual\" boolean DEFAULT false;"],
638
+ "sql": [
639
+ "ALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"virtual\" boolean DEFAULT false;"
640
+ ],
632
641
  "bps": true,
633
642
  "folderMillis": 1759116400580,
634
643
  "hash": "433ddae88e785f2db734e49a4c115eee93e60afe389f7919d66e5ba9aa159a37"
@@ -678,13 +687,17 @@
678
687
  "hash": "4bdc6505797d7a33b622498c138cfd47f637239f6905e1c484cd01d9d5f21d6b"
679
688
  },
680
689
  {
681
- "sql": ["ALTER TABLE \"user_settings\" ADD COLUMN IF NOT EXISTS \"image\" jsonb;"],
690
+ "sql": [
691
+ "ALTER TABLE \"user_settings\" ADD COLUMN IF NOT EXISTS \"image\" jsonb;"
692
+ ],
682
693
  "bps": true,
683
694
  "folderMillis": 1760108430562,
684
695
  "hash": "ce09b301abb80f6563abc2f526bdd20b4f69bae430f09ba2179b9e3bfec43067"
685
696
  },
686
697
  {
687
- "sql": ["ALTER TABLE \"documents\" ADD COLUMN IF NOT EXISTS \"editor_data\" jsonb;"],
698
+ "sql": [
699
+ "ALTER TABLE \"documents\" ADD COLUMN IF NOT EXISTS \"editor_data\" jsonb;"
700
+ ],
688
701
  "bps": true,
689
702
  "folderMillis": 1761554153406,
690
703
  "hash": "bf2f21293e90e11cf60a784cf3ec219eafa95f7545d7d2f9d1449c0b0949599a"
@@ -764,13 +777,17 @@
764
777
  "hash": "923ccbdf46c32be9a981dabd348e6923b4a365444241e9b8cc174bf5b914cbc5"
765
778
  },
766
779
  {
767
- "sql": ["ALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"market_identifier\" text;\n"],
780
+ "sql": [
781
+ "ALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"market_identifier\" text;\n"
782
+ ],
768
783
  "bps": true,
769
784
  "folderMillis": 1762870034882,
770
785
  "hash": "4178aacb4b8892b7fd15d29209bbf9b1d1f9d7c406ba796f27542c0bcd919680"
771
786
  },
772
787
  {
773
- "sql": ["ALTER TABLE \"message_plugins\" ADD COLUMN IF NOT EXISTS \"intervention\" jsonb;\n"],
788
+ "sql": [
789
+ "ALTER TABLE \"message_plugins\" ADD COLUMN IF NOT EXISTS \"intervention\" jsonb;\n"
790
+ ],
774
791
  "bps": true,
775
792
  "folderMillis": 1762911968658,
776
793
  "hash": "552a032cc0e595277232e70b5f9338658585bafe9481ae8346a5f322b673a68b"
@@ -799,7 +816,9 @@
799
816
  "hash": "f823b521f4d25e5dc5ab238b372727d2d2d7f0aed27b5eabc8a9608ce4e50568"
800
817
  },
801
818
  {
802
- "sql": ["ALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"editor_data\" jsonb;"],
819
+ "sql": [
820
+ "ALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"editor_data\" jsonb;"
821
+ ],
803
822
  "bps": true,
804
823
  "folderMillis": 1764215503726,
805
824
  "hash": "4188893a9083b3c7baebdbad0dd3f9d9400ede7584ca2394f5c64305dc9ec7b0"
@@ -816,5 +835,27 @@
816
835
  "bps": true,
817
836
  "folderMillis": 1764229953081,
818
837
  "hash": "1532ebceae7b70550bc9c230fb0a65090aaa773bc7b873eefbc2ce2a815997e2"
838
+ },
839
+ {
840
+ "sql": [
841
+ "ALTER TABLE \"nextauth_accounts\" RENAME COLUMN \"userId\" TO \"user_id\";",
842
+ "\nALTER TABLE \"nextauth_authenticators\" RENAME COLUMN \"userId\" TO \"user_id\";",
843
+ "\nALTER TABLE \"nextauth_sessions\" RENAME COLUMN \"userId\" TO \"user_id\";",
844
+ "\nALTER TABLE \"nextauth_accounts\" DROP CONSTRAINT \"nextauth_accounts_userId_users_id_fk\";\n",
845
+ "\nALTER TABLE \"nextauth_authenticators\" DROP CONSTRAINT \"nextauth_authenticators_userId_users_id_fk\";\n",
846
+ "\nALTER TABLE \"nextauth_sessions\" DROP CONSTRAINT \"nextauth_sessions_userId_users_id_fk\";\n",
847
+ "\nALTER TABLE \"nextauth_authenticators\" DROP CONSTRAINT \"nextauth_authenticators_userId_credentialID_pk\";",
848
+ "\nALTER TABLE \"threads\" ALTER COLUMN \"status\" DROP DEFAULT;",
849
+ "\nALTER TABLE \"threads\" ALTER COLUMN \"source_message_id\" DROP NOT NULL;",
850
+ "\nALTER TABLE \"nextauth_authenticators\" ADD CONSTRAINT \"nextauth_authenticators_user_id_credentialID_pk\" PRIMARY KEY(\"user_id\",\"credentialID\");",
851
+ "\nALTER TABLE \"threads\" ADD COLUMN \"content\" text;",
852
+ "\nALTER TABLE \"threads\" ADD COLUMN \"editor_data\" jsonb;",
853
+ "\nALTER TABLE \"nextauth_accounts\" ADD CONSTRAINT \"nextauth_accounts_user_id_users_id_fk\" FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\") ON DELETE cascade ON UPDATE no action;",
854
+ "\nALTER TABLE \"nextauth_authenticators\" ADD CONSTRAINT \"nextauth_authenticators_user_id_users_id_fk\" FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\") ON DELETE cascade ON UPDATE no action;",
855
+ "\nALTER TABLE \"nextauth_sessions\" ADD CONSTRAINT \"nextauth_sessions_user_id_users_id_fk\" FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\") ON DELETE cascade ON UPDATE no action;"
856
+ ],
857
+ "bps": true,
858
+ "folderMillis": 1764303057060,
859
+ "hash": "edcebee8f59971210c1f8b567d3bd0ffa37da286afeead5bdaaa19eeaa4b89cb"
819
860
  }
820
- ]
861
+ ]
@@ -127,7 +127,7 @@ export class DeprecatedDataImporterRepos {
127
127
  // filter out existing session, only insert new ones
128
128
  .filter((s) => query.every((q) => q.clientId !== s.id));
129
129
 
130
- // 只有当需要有新的 session 时,才会插入 agent
130
+ // Only insert agent when new sessions are needed
131
131
  if (shouldInsertSessionAgents.length > 0) {
132
132
  const agentMapArray = await trx
133
133
  .insert(agents)
@@ -221,14 +221,14 @@ export class DeprecatedDataImporterRepos {
221
221
  parentId: null,
222
222
  provider: extra?.fromProvider,
223
223
  sessionId: sessionId ? sessionIdMap[sessionId] : null,
224
- topicId: topicId ? topicIdMap[topicId] : null, // 暂时设为 NULL
224
+ topicId: topicId ? topicIdMap[topicId] : null, // Temporarily set to NULL
225
225
  updatedAt: new Date(updatedAt),
226
226
  userId: this.userId,
227
227
  }),
228
228
  );
229
229
 
230
230
  console.time('insert messages');
231
- const BATCH_SIZE = 100; // 每批次插入的记录数
231
+ const BATCH_SIZE = 100; // Number of records to insert per batch
232
232
 
233
233
  for (let i = 0; i < inertValues.length; i += BATCH_SIZE) {
234
234
  const batch = inertValues.slice(i, i + BATCH_SIZE);
@@ -257,7 +257,7 @@ export class DeprecatedDataImporterRepos {
257
257
  // 3. update parentId for messages
258
258
  console.time('execute updates parentId');
259
259
  const parentIdUpdates = shouldInsertMessages
260
- .filter((msg) => msg.parentId) // 只处理有 parentId 的消息
260
+ .filter((msg) => msg.parentId) // Only process messages with parentId
261
261
  .map((msg) => {
262
262
  if (messageIdMap[msg.parentId as string])
263
263
  return sql`WHEN ${messages.clientId} = ${msg.id} THEN ${messageIdMap[msg.parentId as string]} `;
@@ -315,7 +315,7 @@ export class DeprecatedDataImporterRepos {
315
315
  );
316
316
  }
317
317
 
318
- // TODO: 未来需要处理 TTS 和图片的插入 (目前存在 file 的部分,不方便处理)
318
+ // TODO: Need to handle TTS and image insertion in the future (currently difficult to handle due to file-related parts)
319
319
  }
320
320
 
321
321
  messageResult.added = shouldInsertMessages.length;