@lobehub/lobehub 2.0.0-next.342 → 2.0.0-next.344

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 (80) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/changelog/v1.json +21 -0
  3. package/package.json +1 -1
  4. package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +161 -12
  5. package/packages/database/src/models/__tests__/userMemories.test.ts +62 -5
  6. package/packages/database/src/models/agentCronJob.ts +9 -9
  7. package/packages/database/src/models/userMemory/__tests__/identity.test.ts +5 -5
  8. package/packages/database/src/models/userMemory/experience.ts +91 -1
  9. package/packages/database/src/models/userMemory/identity.ts +93 -2
  10. package/packages/database/src/models/userMemory/model.ts +27 -8
  11. package/packages/types/src/userMemory/experience.ts +25 -0
  12. package/packages/types/src/userMemory/identity.ts +27 -0
  13. package/packages/types/src/userMemory/index.ts +1 -0
  14. package/packages/types/src/userMemory/shared.ts +30 -0
  15. package/src/app/[variants]/(main)/group/profile/features/Header/index.tsx +3 -4
  16. package/src/app/[variants]/(main)/home/features/InputArea/SkillInstallBanner.tsx +7 -8
  17. package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaDetail.tsx +58 -0
  18. package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaHeader.tsx +22 -0
  19. package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaSummary.tsx +43 -0
  20. package/src/app/[variants]/(main)/memory/(home)/features/Persona/index.tsx +53 -0
  21. package/src/app/[variants]/(main)/memory/(home)/features/RoleTagCloud/index.tsx +2 -2
  22. package/src/app/[variants]/(main)/memory/(home)/index.tsx +15 -3
  23. package/src/app/[variants]/(main)/memory/experiences/features/List/GridView/ExperienceCard.tsx +3 -3
  24. package/src/app/[variants]/(main)/memory/experiences/features/List/GridView/index.tsx +3 -3
  25. package/src/app/[variants]/(main)/memory/experiences/features/List/TimelineView/ExperienceCard.tsx +3 -3
  26. package/src/app/[variants]/(main)/memory/experiences/features/List/TimelineView/index.tsx +3 -3
  27. package/src/app/[variants]/(main)/memory/features/SourceLink.tsx +2 -11
  28. package/src/app/[variants]/(main)/memory/features/TimeLineView/TimeLineCard.tsx +2 -9
  29. package/src/app/[variants]/(main)/memory/identities/features/IdentityRightPanel.tsx +1 -1
  30. package/src/app/[variants]/(main)/memory/identities/features/List/GridView/IdentityCard.tsx +5 -4
  31. package/src/app/[variants]/(main)/memory/identities/features/List/GridView/index.tsx +3 -3
  32. package/src/app/[variants]/(main)/memory/identities/features/List/TimelineView/IdentityCard.tsx +6 -6
  33. package/src/app/[variants]/(main)/memory/identities/features/List/TimelineView/index.tsx +6 -4
  34. package/src/app/[variants]/(main)/settings/profile/index.tsx +8 -8
  35. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +0 -1
  36. package/src/app/[variants]/(main)/settings/skill/features/Actions.tsx +0 -1
  37. package/src/app/[variants]/(main)/settings/skill/features/KlavisSkillItem.tsx +9 -10
  38. package/src/app/[variants]/(main)/settings/skill/features/LobehubSkillItem.tsx +9 -10
  39. package/src/app/[variants]/(main)/settings/skill/features/McpSkillItem.tsx +4 -5
  40. package/src/app/[variants]/(main)/settings/skill/features/SkillList.tsx +4 -5
  41. package/src/app/[variants]/share/t/[id]/SharedMessageList.tsx +1 -4
  42. package/src/app/[variants]/share/t/[id]/_layout/index.tsx +47 -121
  43. package/src/app/[variants]/share/t/[id]/_layout/style.ts +59 -0
  44. package/src/app/[variants]/share/t/[id]/features/Portal/index.tsx +4 -5
  45. package/src/app/[variants]/share/t/[id]/index.tsx +30 -37
  46. package/src/components/404/index.tsx +15 -9
  47. package/src/components/DragUpload/index.tsx +15 -16
  48. package/src/features/EditorCanvas/DocumentIdMode.tsx +1 -2
  49. package/src/features/IntegrationDetailModal/index.tsx +11 -12
  50. package/src/features/ResourceManager/index.tsx +13 -6
  51. package/src/features/ShareModal/ShareImage/Preview.tsx +19 -28
  52. package/src/features/ShareModal/ShareImage/style.ts +4 -2
  53. package/src/features/ShareModal/index.tsx +5 -1
  54. package/src/features/ShareModal/style.ts +1 -0
  55. package/src/features/ShareModal/useContainerStyles.ts +1 -1
  56. package/src/features/SharePopover/index.tsx +16 -9
  57. package/src/features/SharePopover/style.ts +2 -2
  58. package/src/features/SkillStore/CommunityList/Item.tsx +2 -2
  59. package/src/features/SkillStore/LobeHubList/Item.tsx +2 -2
  60. package/src/features/SkillStore/LobeHubList/index.tsx +2 -3
  61. package/src/features/SkillStore/style.ts +4 -4
  62. package/src/layout/GlobalProvider/ServerVersionOutdatedAlert.tsx +28 -20
  63. package/src/server/routers/lambda/userMemories.ts +61 -5
  64. package/src/server/routers/lambda/userMemory.ts +5 -1
  65. package/src/services/chat/index.ts +2 -2
  66. package/src/services/userMemory/index.ts +25 -1
  67. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +0 -1
  68. package/src/store/userMemory/initialState.ts +22 -52
  69. package/src/store/userMemory/slices/context/action.ts +1 -1
  70. package/src/store/userMemory/slices/context/index.ts +1 -0
  71. package/src/store/userMemory/slices/context/initialState.ts +22 -0
  72. package/src/store/userMemory/slices/experience/action.ts +10 -22
  73. package/src/store/userMemory/slices/experience/index.ts +1 -0
  74. package/src/store/userMemory/slices/experience/initialState.ts +22 -0
  75. package/src/store/userMemory/slices/home/action.ts +17 -0
  76. package/src/store/userMemory/slices/identity/action.ts +36 -24
  77. package/src/store/userMemory/slices/identity/initialState.ts +7 -4
  78. package/src/store/userMemory/slices/preference/action.ts +1 -1
  79. package/src/store/userMemory/slices/preference/index.ts +1 -0
  80. package/src/store/userMemory/slices/preference/initialState.ts +22 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,72 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.344](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.343...v2.0.0-next.344)
6
+
7
+ <sup>Released on **2026-01-23**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fixed the sandbox tools call when error should use right callback.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fixed the sandbox tools call when error should use right callback, closes [#11721](https://github.com/lobehub/lobe-chat/issues/11721) ([e8fce68](https://github.com/lobehub/lobe-chat/commit/e8fce68))
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.343](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.342...v2.0.0-next.343)
31
+
32
+ <sup>Released on **2026-01-23**</sup>
33
+
34
+ #### ♻ Code Refactoring
35
+
36
+ - **misc**: Improve memory data with experience and identity.
37
+
38
+ #### 🐛 Bug Fixes
39
+
40
+ - **misc**: Fix scope issue.
41
+
42
+ #### 💄 Styles
43
+
44
+ - **misc**: Update share style.
45
+
46
+ <br/>
47
+
48
+ <details>
49
+ <summary><kbd>Improvements and Fixes</kbd></summary>
50
+
51
+ #### Code refactoring
52
+
53
+ - **misc**: Improve memory data with experience and identity, closes [#11717](https://github.com/lobehub/lobe-chat/issues/11717) ([bdb3eb4](https://github.com/lobehub/lobe-chat/commit/bdb3eb4))
54
+
55
+ #### What's fixed
56
+
57
+ - **misc**: Fix scope issue, closes [#11719](https://github.com/lobehub/lobe-chat/issues/11719) ([17adde8](https://github.com/lobehub/lobe-chat/commit/17adde8))
58
+
59
+ #### Styles
60
+
61
+ - **misc**: Update share style, closes [#11716](https://github.com/lobehub/lobe-chat/issues/11716) ([3c70dfa](https://github.com/lobehub/lobe-chat/commit/3c70dfa))
62
+
63
+ </details>
64
+
65
+ <div align="right">
66
+
67
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
68
+
69
+ </div>
70
+
5
71
  ## [Version 2.0.0-next.342](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.341...v2.0.0-next.342)
6
72
 
7
73
  <sup>Released on **2026-01-22**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,25 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Fixed the sandbox tools call when error should use right callback."
6
+ ]
7
+ },
8
+ "date": "2026-01-23",
9
+ "version": "2.0.0-next.344"
10
+ },
11
+ {
12
+ "children": {
13
+ "improvements": [
14
+ "Update share style."
15
+ ],
16
+ "fixes": [
17
+ "Fix scope issue."
18
+ ]
19
+ },
20
+ "date": "2026-01-23",
21
+ "version": "2.0.0-next.343"
22
+ },
2
23
  {
3
24
  "children": {},
4
25
  "date": "2026-01-22",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.342",
3
+ "version": "2.0.0-next.344",
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",
@@ -65,6 +65,14 @@ export class CloudSandboxExecutionRuntime {
65
65
  try {
66
66
  const result = await this.callTool('listLocalFiles', args);
67
67
 
68
+ if (!result.success) {
69
+ return {
70
+ content: result.error?.message || JSON.stringify(result.error),
71
+ state: { files: [] },
72
+ success: true,
73
+ };
74
+ }
75
+
68
76
  const files = result.result?.files || [];
69
77
  const state: ListLocalFilesState = { files };
70
78
 
@@ -90,6 +98,19 @@ export class CloudSandboxExecutionRuntime {
90
98
  try {
91
99
  const result = await this.callTool('readLocalFile', args);
92
100
 
101
+ if (!result.success) {
102
+ return {
103
+ content: result.error?.message || JSON.stringify(result.error),
104
+ state: {
105
+ content: '',
106
+ endLine: args.endLine,
107
+ path: args.path,
108
+ startLine: args.startLine,
109
+ },
110
+ success: true,
111
+ };
112
+ }
113
+
93
114
  const state: ReadLocalFileState = {
94
115
  content: result.result?.content || '',
95
116
  endLine: args.endLine,
@@ -123,6 +144,17 @@ export class CloudSandboxExecutionRuntime {
123
144
  try {
124
145
  const result = await this.callTool('writeLocalFile', args);
125
146
 
147
+ if (!result.success) {
148
+ return {
149
+ content: result.error?.message || JSON.stringify(result.error),
150
+ state: {
151
+ path: args.path,
152
+ success: false,
153
+ },
154
+ success: true,
155
+ };
156
+ }
157
+
126
158
  const state: WriteLocalFileState = {
127
159
  bytesWritten: result.result?.bytesWritten,
128
160
  path: args.path,
@@ -148,6 +180,17 @@ export class CloudSandboxExecutionRuntime {
148
180
  try {
149
181
  const result = await this.callTool('editLocalFile', args);
150
182
 
183
+ if (!result.success) {
184
+ return {
185
+ content: result.error?.message || JSON.stringify(result.error),
186
+ state: {
187
+ path: args.path,
188
+ replacements: 0,
189
+ },
190
+ success: true,
191
+ };
192
+ }
193
+
151
194
  const state: EditLocalFileState = {
152
195
  diffText: result.result?.diffText,
153
196
  linesAdded: result.result?.linesAdded,
@@ -177,6 +220,17 @@ export class CloudSandboxExecutionRuntime {
177
220
  try {
178
221
  const result = await this.callTool('searchLocalFiles', args);
179
222
 
223
+ if (!result.success) {
224
+ return {
225
+ content: result.error?.message || JSON.stringify(result.error),
226
+ state: {
227
+ results: [],
228
+ totalCount: 0,
229
+ },
230
+ success: true,
231
+ };
232
+ }
233
+
180
234
  const results = result.result?.results || [];
181
235
  const state: SearchLocalFilesState = {
182
236
  results,
@@ -201,6 +255,18 @@ export class CloudSandboxExecutionRuntime {
201
255
  try {
202
256
  const result = await this.callTool('moveLocalFiles', args);
203
257
 
258
+ if (!result.success) {
259
+ return {
260
+ content: result.error?.message || JSON.stringify(result.error),
261
+ state: {
262
+ results: [],
263
+ successCount: 0,
264
+ totalCount: args.operations.length,
265
+ },
266
+ success: true,
267
+ };
268
+ }
269
+
204
270
  const results = result.result?.results || [];
205
271
  const state: MoveLocalFilesState = {
206
272
  results,
@@ -224,6 +290,19 @@ export class CloudSandboxExecutionRuntime {
224
290
  try {
225
291
  const result = await this.callTool('renameLocalFile', args);
226
292
 
293
+ if (!result.success) {
294
+ return {
295
+ content: result.error?.message || JSON.stringify(result.error),
296
+ state: {
297
+ error: result.error?.message,
298
+ newPath: '',
299
+ oldPath: args.oldPath,
300
+ success: false,
301
+ },
302
+ success: true,
303
+ };
304
+ }
305
+
227
306
  const state: RenameLocalFileState = {
228
307
  error: result.result?.error,
229
308
  newPath: result.result?.newPath || '',
@@ -241,7 +320,7 @@ export class CloudSandboxExecutionRuntime {
241
320
  return {
242
321
  content,
243
322
  state,
244
- success: result.success,
323
+ success: true,
245
324
  };
246
325
  } catch (error) {
247
326
  return this.handleError(error);
@@ -264,15 +343,24 @@ export class CloudSandboxExecutionRuntime {
264
343
  language,
265
344
  output: result.result?.output,
266
345
  stderr: result.result?.stderr,
267
- success: result.success,
346
+ success: result.success || false,
268
347
  };
269
348
 
349
+ if (!result.success) {
350
+ return {
351
+ content: result.error?.message || JSON.stringify(result.error),
352
+ state,
353
+ success: true,
354
+ };
355
+ }
356
+
270
357
  return {
271
358
  content: JSON.stringify(result.result),
272
359
  state,
273
- success: result.success,
360
+ success: true,
274
361
  };
275
362
  } catch (error) {
363
+ console.log('executeCode error', error);
276
364
  return this.handleError(error);
277
365
  }
278
366
  }
@@ -283,6 +371,18 @@ export class CloudSandboxExecutionRuntime {
283
371
  try {
284
372
  const result = await this.callTool('runCommand', args);
285
373
 
374
+ if (!result.success) {
375
+ return {
376
+ content: result.error?.message || JSON.stringify(result.error),
377
+ state: {
378
+ error: result.error?.message,
379
+ isBackground: args.background || false,
380
+ success: false,
381
+ },
382
+ success: true,
383
+ };
384
+ }
385
+
286
386
  const state: RunCommandState = {
287
387
  commandId: result.result?.commandId,
288
388
  error: result.result?.error,
@@ -296,7 +396,7 @@ export class CloudSandboxExecutionRuntime {
296
396
  return {
297
397
  content: JSON.stringify(result.result),
298
398
  state,
299
- success: result.success,
399
+ success: true,
300
400
  };
301
401
  } catch (error) {
302
402
  return this.handleError(error);
@@ -307,6 +407,18 @@ export class CloudSandboxExecutionRuntime {
307
407
  try {
308
408
  const result = await this.callTool('getCommandOutput', args);
309
409
 
410
+ if (!result.success) {
411
+ return {
412
+ content: result.error?.message || JSON.stringify(result.error),
413
+ state: {
414
+ error: result.error?.message,
415
+ running: false,
416
+ success: false,
417
+ },
418
+ success: true,
419
+ };
420
+ }
421
+
310
422
  const state: GetCommandOutputState = {
311
423
  error: result.result?.error,
312
424
  newOutput: result.result?.newOutput,
@@ -317,7 +429,7 @@ export class CloudSandboxExecutionRuntime {
317
429
  return {
318
430
  content: JSON.stringify(result.result),
319
431
  state,
320
- success: result.success,
432
+ success: true,
321
433
  };
322
434
  } catch (error) {
323
435
  return this.handleError(error);
@@ -328,6 +440,18 @@ export class CloudSandboxExecutionRuntime {
328
440
  try {
329
441
  const result = await this.callTool('killCommand', args);
330
442
 
443
+ if (!result.success) {
444
+ return {
445
+ content: result.error?.message || JSON.stringify(result.error),
446
+ state: {
447
+ commandId: args.commandId,
448
+ error: result.error?.message,
449
+ success: false,
450
+ },
451
+ success: true,
452
+ };
453
+ }
454
+
331
455
  const state: KillCommandState = {
332
456
  commandId: args.commandId,
333
457
  error: result.result?.error,
@@ -340,7 +464,7 @@ export class CloudSandboxExecutionRuntime {
340
464
  success: true,
341
465
  }),
342
466
  state,
343
- success: result.success,
467
+ success: true,
344
468
  };
345
469
  } catch (error) {
346
470
  return this.handleError(error);
@@ -353,6 +477,18 @@ export class CloudSandboxExecutionRuntime {
353
477
  try {
354
478
  const result = await this.callTool('grepContent', args);
355
479
 
480
+ if (!result.success) {
481
+ return {
482
+ content: result.error?.message || JSON.stringify(result.error),
483
+ state: {
484
+ matches: [],
485
+ pattern: args.pattern,
486
+ totalMatches: 0,
487
+ },
488
+ success: true,
489
+ };
490
+ }
491
+
356
492
  const state: GrepContentState = {
357
493
  matches: result.result?.matches || [],
358
494
  pattern: args.pattern,
@@ -373,6 +509,18 @@ export class CloudSandboxExecutionRuntime {
373
509
  try {
374
510
  const result = await this.callTool('globLocalFiles', args);
375
511
 
512
+ if (!result.success) {
513
+ return {
514
+ content: result.error?.message || JSON.stringify(result.error),
515
+ state: {
516
+ files: [],
517
+ pattern: args.pattern,
518
+ totalCount: 0,
519
+ },
520
+ success: true,
521
+ };
522
+ }
523
+
376
524
  const files = result.result?.files || [];
377
525
  const totalCount = result.result?.totalCount || 0;
378
526
 
@@ -433,7 +581,7 @@ export class CloudSandboxExecutionRuntime {
433
581
  success: false,
434
582
  }),
435
583
  state,
436
- success: false,
584
+ success: true,
437
585
  };
438
586
  }
439
587
 
@@ -455,13 +603,14 @@ export class CloudSandboxExecutionRuntime {
455
603
  private async callTool(
456
604
  toolName: string,
457
605
  params: Record<string, any>,
458
- ): Promise<{ result: any; sessionExpiredAndRecreated?: boolean; success: boolean }> {
606
+ ): Promise<{
607
+ error?: { message: string; name?: string };
608
+ result: any;
609
+ sessionExpiredAndRecreated?: boolean;
610
+ success: boolean;
611
+ }> {
459
612
  const result = await this.sandboxService.callTool(toolName, params);
460
613
 
461
- if (!result.success) {
462
- throw new Error(result.error?.message || `Cloud Sandbox tool ${toolName} failed`);
463
- }
464
-
465
614
  return result;
466
615
  }
467
616
 
@@ -6,6 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
6
6
 
7
7
  import { idGenerator } from '@/database/utils/idGenerator';
8
8
 
9
+ import { getTestDB } from '../../core/getTestDB';
9
10
  import {
10
11
  topics,
11
12
  userMemories,
@@ -24,7 +25,6 @@ import {
24
25
  CreateUserMemoryPreferenceParams,
25
26
  UserMemoryModel,
26
27
  } from '../userMemory';
27
- import { getTestDB } from '../../core/getTestDB';
28
28
 
29
29
  const serverDB: LobeChatDatabase = await getTestDB();
30
30
 
@@ -753,20 +753,27 @@ describe('UserMemoryModel', () => {
753
753
 
754
754
  await userMemoryModel.addIdentityEntry({
755
755
  base: { lastAccessedAt: now, tags: [] },
756
- identity: { role: 'engineer', tags: ['alpha', 'beta'] },
756
+ identity: { relationship: 'self', role: 'engineer', tags: ['alpha', 'beta'] },
757
757
  });
758
758
  await userMemoryModel.addIdentityEntry({
759
759
  base: { lastAccessedAt: now, tags: [] },
760
- identity: { role: 'engineer', tags: ['alpha'] },
760
+ identity: { relationship: 'self', role: 'engineer', tags: ['alpha'] },
761
761
  });
762
762
  await userMemoryModel.addIdentityEntry({
763
763
  base: { lastAccessedAt: now, tags: [] },
764
- identity: { role: 'manager', tags: [] },
764
+ identity: { relationship: 'self', role: 'manager', tags: [] },
765
765
  });
766
766
 
767
+ // This should not be counted (different user)
767
768
  await anotherUserModel.addIdentityEntry({
768
769
  base: { lastAccessedAt: now, tags: [] },
769
- identity: { role: 'engineer', tags: ['alpha'] },
770
+ identity: { relationship: 'self', role: 'engineer', tags: ['alpha'] },
771
+ });
772
+
773
+ // This should not be counted (relationship is not 'self')
774
+ await userMemoryModel.addIdentityEntry({
775
+ base: { lastAccessedAt: now, tags: [] },
776
+ identity: { relationship: 'friend', role: 'designer', tags: ['gamma'] },
770
777
  });
771
778
 
772
779
  const result = await userMemoryModel.queryIdentityRoles({ size: 5 });
@@ -1062,6 +1069,56 @@ describe('UserMemoryModel', () => {
1062
1069
  expect(identityItem.identity.userMemoryId).toBe(identityMemoryId);
1063
1070
  expect(identityItem.identity.type).toBe(identity?.type);
1064
1071
  });
1072
+
1073
+ it('should order identity memories by capturedAt desc and include capturedAt and title in response', async () => {
1074
+ const olderCapturedAt = new Date('2024-01-01T10:00:00Z');
1075
+ const newerCapturedAt = new Date('2024-01-15T10:00:00Z');
1076
+
1077
+ await userMemoryModel.addIdentityEntry({
1078
+ base: { summary: 'older identity', title: 'Older Title' },
1079
+ identity: {
1080
+ capturedAt: olderCapturedAt,
1081
+ description: 'Older identity description',
1082
+ relationship: 'friend',
1083
+ type: 'personal',
1084
+ },
1085
+ });
1086
+
1087
+ await userMemoryModel.addIdentityEntry({
1088
+ base: { summary: 'newer identity', title: 'Newer Title' },
1089
+ identity: {
1090
+ capturedAt: newerCapturedAt,
1091
+ description: 'Newer identity description',
1092
+ relationship: 'self',
1093
+ type: 'personal',
1094
+ },
1095
+ });
1096
+
1097
+ const result = await userMemoryModel.queryMemories({
1098
+ layer: LayersEnum.Identity,
1099
+ });
1100
+
1101
+ expect(result.total).toBe(2);
1102
+ expect(result.items).toHaveLength(2);
1103
+
1104
+ const firstItem = result.items[0] as any;
1105
+ const secondItem = result.items[1] as any;
1106
+
1107
+ // Verify order by capturedAt desc
1108
+ expect(firstItem.identity.capturedAt).toEqual(newerCapturedAt);
1109
+ expect(secondItem.identity.capturedAt).toEqual(olderCapturedAt);
1110
+
1111
+ expect(firstItem.identity.description).toBe('Newer identity description');
1112
+ expect(secondItem.identity.description).toBe('Older identity description');
1113
+
1114
+ // Verify title comes from memory schema
1115
+ expect(firstItem.identity.title).toBe('Newer Title');
1116
+ expect(secondItem.identity.title).toBe('Older Title');
1117
+
1118
+ // Verify relationship is included
1119
+ expect(firstItem.identity.relationship).toBe('self');
1120
+ expect(secondItem.identity.relationship).toBe('friend');
1121
+ });
1065
1122
  });
1066
1123
 
1067
1124
  describe('findById', () => {
@@ -1,4 +1,4 @@
1
- import { and, desc, eq, gt, isNull, or, sql } from 'drizzle-orm';
1
+ import { and, desc, eq, gt, inArray, isNull, or, sql } from 'drizzle-orm';
2
2
 
3
3
  import {
4
4
  type AgentCronJob,
@@ -25,8 +25,8 @@ export class AgentCronJobModel {
25
25
  .values({
26
26
  ...data,
27
27
  // Initialize remaining executions to match max executions
28
- remainingExecutions: data.maxExecutions,
29
-
28
+ remainingExecutions: data.maxExecutions,
29
+
30
30
  userId: this.userId,
31
31
  } as NewAgentCronJob)
32
32
  .returning();
@@ -149,11 +149,11 @@ remainingExecutions: data.maxExecutions,
149
149
  .set({
150
150
  enabled: true,
151
151
  // Re-enable job when resetting
152
- lastExecutedAt: null,
153
-
154
- maxExecutions: newMaxExecutions,
155
-
156
- remainingExecutions: newMaxExecutions,
152
+ lastExecutedAt: null,
153
+
154
+ maxExecutions: newMaxExecutions,
155
+
156
+ remainingExecutions: newMaxExecutions,
157
157
  totalExecutions: 0,
158
158
  updatedAt: new Date(),
159
159
  })
@@ -227,7 +227,7 @@ remainingExecutions: newMaxExecutions,
227
227
  enabled,
228
228
  updatedAt: new Date(),
229
229
  })
230
- .where(and(sql`${agentCronJobs.id} = ANY(${ids})`, eq(agentCronJobs.userId, this.userId)))
230
+ .where(and(inArray(agentCronJobs.id, ids), eq(agentCronJobs.userId, this.userId)))
231
231
  .returning();
232
232
 
233
233
  return result.length;
@@ -2,6 +2,7 @@
2
2
  import { RelationshipEnum } from '@lobechat/types';
3
3
  import { beforeEach, describe, expect, it } from 'vitest';
4
4
 
5
+ import { getTestDB } from '../../../core/getTestDB';
5
6
  import {
6
7
  NewUserMemoryIdentity,
7
8
  userMemories,
@@ -9,7 +10,6 @@ import {
9
10
  users,
10
11
  } from '../../../schemas';
11
12
  import { LobeChatDatabase } from '../../../type';
12
- import { getTestDB } from '../../../core/getTestDB';
13
13
  import { UserMemoryIdentityModel } from '../identity';
14
14
 
15
15
  const userId = 'identity-test-user';
@@ -68,21 +68,21 @@ describe('UserMemoryIdentityModel', () => {
68
68
  userId,
69
69
  type: 'personal',
70
70
  description: 'Identity 1',
71
- createdAt: new Date('2024-01-01T10:00:00Z'),
71
+ capturedAt: new Date('2024-01-01T10:00:00Z'),
72
72
  },
73
73
  {
74
74
  id: 'identity-2',
75
75
  userId,
76
76
  type: 'professional',
77
77
  description: 'Identity 2',
78
- createdAt: new Date('2024-01-02T10:00:00Z'),
78
+ capturedAt: new Date('2024-01-02T10:00:00Z'),
79
79
  },
80
80
  {
81
81
  id: 'other-identity',
82
82
  userId: otherUserId,
83
83
  type: 'personal',
84
84
  description: 'Other Identity',
85
- createdAt: new Date('2024-01-03T10:00:00Z'),
85
+ capturedAt: new Date('2024-01-03T10:00:00Z'),
86
86
  },
87
87
  ]);
88
88
  });
@@ -94,7 +94,7 @@ describe('UserMemoryIdentityModel', () => {
94
94
  expect(result.every((i) => i.userId === userId)).toBe(true);
95
95
  });
96
96
 
97
- it('should order by createdAt desc', async () => {
97
+ it('should order by capturedAt desc', async () => {
98
98
  const result = await identityModel.query();
99
99
 
100
100
  expect(result[0].id).toBe('identity-2'); // Most recent first