@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.
- package/.env.example +23 -3
- package/.env.example.development +5 -0
- package/CHANGELOG.md +50 -0
- package/README.md +6 -6
- package/README.zh-CN.md +6 -6
- package/changelog/v1.json +18 -0
- package/docker-compose/local/docker-compose.yml +24 -1
- package/docker-compose/local/logto/docker-compose.yml +25 -2
- package/docker-compose.development.yml +6 -0
- package/docs/development/database-schema.dbml +8 -6
- package/locales/ar/auth.json +114 -1
- package/locales/bg-BG/auth.json +114 -1
- package/locales/de-DE/auth.json +114 -1
- package/locales/en-US/auth.json +42 -22
- package/locales/es-ES/auth.json +114 -1
- package/locales/fa-IR/auth.json +114 -1
- package/locales/fr-FR/auth.json +114 -1
- package/locales/it-IT/auth.json +114 -1
- package/locales/ja-JP/auth.json +114 -1
- package/locales/ko-KR/auth.json +114 -1
- package/locales/nl-NL/auth.json +114 -1
- package/locales/pl-PL/auth.json +114 -1
- package/locales/pt-BR/auth.json +114 -1
- package/locales/ru-RU/auth.json +114 -1
- package/locales/tr-TR/auth.json +114 -1
- package/locales/vi-VN/auth.json +114 -1
- package/locales/zh-CN/auth.json +36 -29
- package/locales/zh-TW/auth.json +114 -1
- package/package.json +4 -1
- package/packages/database/migrations/0050_thread_and_user_id.sql +18 -0
- package/packages/database/migrations/meta/0050_snapshot.json +8792 -0
- package/packages/database/migrations/meta/_journal.json +7 -0
- package/packages/database/src/client/db.ts +21 -21
- package/packages/database/src/core/migrations.json +51 -10
- package/packages/database/src/repositories/dataImporter/deprecated/index.ts +5 -5
- package/packages/database/src/repositories/dataImporter/index.ts +59 -59
- package/packages/database/src/repositories/knowledge/index.test.ts +17 -5
- package/packages/database/src/repositories/knowledge/index.ts +6 -6
- package/packages/database/src/schemas/generation.ts +16 -16
- package/packages/database/src/schemas/nextauth.ts +3 -3
- package/packages/database/src/schemas/oidc.ts +36 -36
- package/packages/database/src/schemas/topic.ts +8 -3
- package/packages/model-runtime/src/providers/newapi/index.ts +61 -18
- package/packages/model-runtime/src/runtimeMap.ts +1 -0
- package/packages/types/src/topic/thread.ts +3 -3
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/SettingModal.tsx +10 -6
- package/src/envs/redis.ts +106 -0
- package/src/libs/redis/index.ts +5 -0
- package/src/libs/redis/manager.test.ts +107 -0
- package/src/libs/redis/manager.ts +56 -0
- package/src/libs/redis/redis.test.ts +158 -0
- package/src/libs/redis/redis.ts +117 -0
- package/src/libs/redis/types.ts +71 -0
- package/src/libs/redis/upstash.test.ts +154 -0
- package/src/libs/redis/upstash.ts +109 -0
- package/src/libs/redis/utils.test.ts +46 -0
- package/src/libs/redis/utils.ts +53 -0
- package/src/store/chat/slices/thread/action.ts +1 -1
- package/src/store/chat/slices/thread/initialState.ts +1 -1
- package/src/store/chat/slices/thread/selectors/util.ts +1 -1
- 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
|
-
//
|
|
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.
|
|
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
|
-
//
|
|
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.
|
|
333
|
+
// 3. Delete IndexedDB database
|
|
334
334
|
return new Promise<void>((resolve, reject) => {
|
|
335
|
-
//
|
|
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
|
-
//
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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": [
|
|
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
|
-
//
|
|
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, //
|
|
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) //
|
|
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:
|
|
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;
|