@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
@@ -27,7 +27,6 @@ const userMemoryProcedure = authedProcedure.use(serverDatabase).use(async (opts)
27
27
 
28
28
  export const userMemoryRouter = router({
29
29
  // ============ Identity CRUD ============
30
-
31
30
  createIdentity: userMemoryProcedure
32
31
  .input(CreateUserMemoryIdentitySchema)
33
32
  .mutation(async ({ ctx, input }) => {
@@ -83,6 +82,11 @@ export const userMemoryRouter = router({
83
82
  return ctx.userMemoryModel.getAllIdentities();
84
83
  }),
85
84
 
85
+ // ============ Persona ============
86
+ getPersona: userMemoryProcedure.query(async () => {
87
+ return { content: '', summary: '' };
88
+ }),
89
+
86
90
  getPreferences: userMemoryProcedure.query(async ({ ctx }) => {
87
91
  return ctx.userMemoryModel.searchPreferences({});
88
92
  }),
@@ -10,7 +10,6 @@ import {
10
10
  import { AgentRuntimeError, type ChatCompletionErrorPayload } from '@lobechat/model-runtime';
11
11
  import {
12
12
  ChatErrorType,
13
- type MessageMapScope,
14
13
  type RuntimeInitialContext,
15
14
  type RuntimeStepContext,
16
15
  type TracePayload,
@@ -75,7 +74,6 @@ interface GetChatCompletionPayload extends Partial<Omit<ChatStreamPayload, 'mess
75
74
  * Required to ensure config consistency and proper isSubTask filtering.
76
75
  */
77
76
  resolvedAgentConfig: ResolvedAgentConfig;
78
- scope?: MessageMapScope;
79
77
  topicId?: string;
80
78
  }
81
79
 
@@ -349,6 +347,8 @@ class ChatService {
349
347
  // Get the chat config to check streaming preference
350
348
  const chatConfig = agentChatConfigSelectors.currentChatConfig(getAgentStoreState());
351
349
 
350
+ delete (res as any).scope;
351
+
352
352
  const payload = merge(
353
353
  {
354
354
  model: DEFAULT_AGENT_CONFIG.model,
@@ -11,6 +11,10 @@ import {
11
11
  type AddExperienceMemoryResult,
12
12
  type AddIdentityMemoryResult,
13
13
  type AddPreferenceMemoryResult,
14
+ type ExperienceListParams,
15
+ type ExperienceListResult,
16
+ type IdentityListParams,
17
+ type IdentityListResult,
14
18
  type LayersEnum,
15
19
  type RemoveIdentityMemoryResult,
16
20
  type SearchMemoryParams,
@@ -57,6 +61,26 @@ class UserMemoryService {
57
61
  return lambdaClient.userMemories.getMemoryDetail.query(params);
58
62
  };
59
63
 
64
+ getPersona = async () => {
65
+ return lambdaClient.userMemory.getPersona.query();
66
+ };
67
+
68
+ /**
69
+ * Query experiences with pagination, search, and sorting
70
+ * Returns flat structure optimized for frontend display
71
+ */
72
+ queryExperiences = async (params?: ExperienceListParams): Promise<ExperienceListResult> => {
73
+ return lambdaClient.userMemories.queryExperiences.query(params);
74
+ };
75
+
76
+ /**
77
+ * Query identities with pagination, search, and sorting
78
+ * Returns flat structure optimized for frontend display
79
+ */
80
+ queryIdentities = async (params?: IdentityListParams): Promise<IdentityListResult> => {
81
+ return lambdaClient.userMemories.queryIdentities.query(params);
82
+ };
83
+
60
84
  retrieveMemory = async (params: SearchMemoryParams): Promise<SearchMemoryResult> => {
61
85
  return lambdaClient.userMemories.toolSearchMemory.query(params);
62
86
  };
@@ -96,7 +120,7 @@ class UserMemoryService {
96
120
  page?: number;
97
121
  pageSize?: number;
98
122
  q?: string;
99
- sort?: 'scoreConfidence' | 'scoreImpact' | 'scorePriority' | 'scoreUrgency';
123
+ sort?: 'capturedAt' | 'scoreConfidence' | 'scoreImpact' | 'scorePriority' | 'scoreUrgency';
100
124
  tags?: string[];
101
125
  types?: TypesEnum[];
102
126
  }) => {
@@ -481,7 +481,6 @@ export const streamingExecutor: StateCreator<
481
481
  // Pass pre-resolved config to avoid duplicate resolveAgentConfig calls
482
482
  // This ensures isSubTask filtering and other runtime modifications are preserved
483
483
  resolvedAgentConfig: agentConfig,
484
- scope, // Pass scope to chat service for page-agent injection
485
484
  topicId: topicId ?? undefined, // Pass topicId for GTD context injection
486
485
  ...agentConfigData.params,
487
486
  },
@@ -1,46 +1,32 @@
1
1
  import type { RetrieveMemoryParams, RetrieveMemoryResult } from '@lobechat/types';
2
2
 
3
- import {
4
- type DisplayContextMemory,
5
- type DisplayExperienceMemory,
6
- type DisplayPreferenceMemory,
7
- } from '@/database/repositories/userMemory';
8
-
9
3
  import { type AgentMemorySliceState, agentMemoryInitialState } from './slices/agent';
4
+ import { type ContextSliceState, contextInitialState } from './slices/context';
5
+ import { type ExperienceSliceState, experienceInitialState } from './slices/experience';
10
6
  import { type IdentitySliceState, identityInitialState } from './slices/identity';
7
+ import { type PreferenceSliceState, preferenceInitialState } from './slices/preference';
8
+
9
+ export interface PersonaData {
10
+ content: string;
11
+ summary: string;
12
+ }
11
13
 
12
- export interface UserMemoryStoreState extends AgentMemorySliceState, IdentitySliceState {
14
+ export interface UserMemoryStoreState
15
+ extends
16
+ AgentMemorySliceState,
17
+ ContextSliceState,
18
+ ExperienceSliceState,
19
+ IdentitySliceState,
20
+ PreferenceSliceState {
13
21
  activeParams?: RetrieveMemoryParams;
14
22
  activeParamsKey?: string;
15
- contexts: DisplayContextMemory[];
16
- contextsHasMore: boolean;
17
- contextsInit: boolean;
18
- contextsPage: number;
19
- contextsQuery?: string;
20
- contextsSearchLoading?: boolean;
21
- contextsSort?: 'scoreImpact' | 'scoreUrgency';
22
- contextsTotal: number;
23
23
  editingMemoryContent?: string;
24
24
  editingMemoryId?: string;
25
25
  editingMemoryLayer?: 'context' | 'experience' | 'identity' | 'preference';
26
- experiences: DisplayExperienceMemory[];
27
- experiencesHasMore: boolean;
28
- experiencesInit: boolean;
29
- experiencesPage: number;
30
- experiencesQuery?: string;
31
- experiencesSearchLoading?: boolean;
32
- experiencesSort?: 'scoreConfidence';
33
- experiencesTotal: number;
34
26
  memoryFetchedAtMap: Record<string, number>;
35
27
  memoryMap: Record<string, RetrieveMemoryResult>;
36
- preferences: DisplayPreferenceMemory[];
37
- preferencesHasMore: boolean;
38
- preferencesInit: boolean;
39
- preferencesPage: number;
40
- preferencesQuery?: string;
41
- preferencesSearchLoading?: boolean;
42
- preferencesSort?: 'scorePriority';
43
- preferencesTotal: number;
28
+ persona?: PersonaData;
29
+ personaInit: boolean;
44
30
  roles: { count: number; tag: string }[];
45
31
  tags: { count: number; tag: string }[];
46
32
  tagsInit: boolean;
@@ -48,35 +34,19 @@ export interface UserMemoryStoreState extends AgentMemorySliceState, IdentitySli
48
34
 
49
35
  export const initialState: UserMemoryStoreState = {
50
36
  ...agentMemoryInitialState,
37
+ ...contextInitialState,
38
+ ...experienceInitialState,
51
39
  ...identityInitialState,
40
+ ...preferenceInitialState,
52
41
  activeParams: undefined,
53
42
  activeParamsKey: undefined,
54
- contexts: [],
55
- contextsHasMore: true,
56
- contextsInit: false,
57
- contextsPage: 1,
58
- contextsQuery: undefined,
59
- contextsSort: undefined,
60
- contextsTotal: 0,
61
43
  editingMemoryContent: undefined,
62
44
  editingMemoryId: undefined,
63
45
  editingMemoryLayer: undefined,
64
- experiences: [],
65
- experiencesHasMore: true,
66
- experiencesInit: false,
67
- experiencesPage: 1,
68
- experiencesQuery: undefined,
69
- experiencesSort: undefined,
70
- experiencesTotal: 0,
71
46
  memoryFetchedAtMap: {},
72
47
  memoryMap: {},
73
- preferences: [],
74
- preferencesHasMore: true,
75
- preferencesInit: false,
76
- preferencesPage: 1,
77
- preferencesQuery: undefined,
78
- preferencesSort: undefined,
79
- preferencesTotal: 0,
48
+ persona: undefined,
49
+ personaInit: false,
80
50
  roles: [],
81
51
  tags: [],
82
52
  tagsInit: false,
@@ -16,7 +16,7 @@ export interface ContextQueryParams {
16
16
  page?: number;
17
17
  pageSize?: number;
18
18
  q?: string;
19
- sort?: 'scoreImpact' | 'scoreUrgency';
19
+ sort?: 'capturedAt' | 'scoreImpact' | 'scoreUrgency';
20
20
  }
21
21
 
22
22
  export interface ContextAction {
@@ -1 +1,2 @@
1
1
  export { type ContextAction,createContextSlice } from './action';
2
+ export { contextInitialState, type ContextSliceState } from './initialState';
@@ -0,0 +1,22 @@
1
+ import { type DisplayContextMemory } from '@/database/repositories/userMemory';
2
+
3
+ export interface ContextSliceState {
4
+ contexts: DisplayContextMemory[];
5
+ contextsHasMore: boolean;
6
+ contextsInit: boolean;
7
+ contextsPage: number;
8
+ contextsQuery?: string;
9
+ contextsSearchLoading?: boolean;
10
+ contextsSort?: 'capturedAt' | 'scoreImpact' | 'scoreUrgency';
11
+ contextsTotal: number;
12
+ }
13
+
14
+ export const contextInitialState: ContextSliceState = {
15
+ contexts: [],
16
+ contextsHasMore: true,
17
+ contextsInit: false,
18
+ contextsPage: 1,
19
+ contextsQuery: undefined,
20
+ contextsSort: undefined,
21
+ contextsTotal: 0,
22
+ };
@@ -1,3 +1,4 @@
1
+ import type { ExperienceListResult } from '@lobechat/types';
1
2
  import { uniqBy } from 'es-toolkit/compat';
2
3
  import { produce } from 'immer';
3
4
  import useSWR, { type SWRResponse } from 'swr';
@@ -5,7 +6,6 @@ import { type StateCreator } from 'zustand/vanilla';
5
6
 
6
7
  import { userMemoryService } from '@/services/userMemory';
7
8
  import { memoryCRUDService } from '@/services/userMemory/index';
8
- import { LayersEnum } from '@/types/userMemory';
9
9
  import { setNamespace } from '@/utils/storeDebug';
10
10
 
11
11
  import { type UserMemoryStore } from '../../store';
@@ -16,14 +16,14 @@ export interface ExperienceQueryParams {
16
16
  page?: number;
17
17
  pageSize?: number;
18
18
  q?: string;
19
- sort?: 'scoreConfidence';
19
+ sort?: 'capturedAt' | 'scoreConfidence';
20
20
  }
21
21
 
22
22
  export interface ExperienceAction {
23
23
  deleteExperience: (id: string) => Promise<void>;
24
24
  loadMoreExperiences: () => void;
25
25
  resetExperiencesList: (params?: Omit<ExperienceQueryParams, 'page' | 'pageSize'>) => void;
26
- useFetchExperiences: (params: ExperienceQueryParams) => SWRResponse<any>;
26
+ useFetchExperiences: (params: ExperienceQueryParams) => SWRResponse<ExperienceListResult>;
27
27
  }
28
28
 
29
29
  export const createExperienceSlice: StateCreator<
@@ -81,44 +81,32 @@ export const createExperienceSlice: StateCreator<
81
81
  return useSWR(
82
82
  swrKey,
83
83
  async () => {
84
- const result = await userMemoryService.queryMemories({
85
- layer: LayersEnum.Experience,
84
+ // Use the new dedicated queryExperiences API
85
+ return userMemoryService.queryExperiences({
86
86
  page: params.page,
87
87
  pageSize: params.pageSize,
88
88
  q: params.q,
89
89
  sort: params.sort,
90
90
  });
91
-
92
- return result;
93
91
  },
94
92
  {
95
- onSuccess(data: any) {
93
+ onSuccess(data: ExperienceListResult) {
96
94
  set(
97
95
  produce((draft) => {
98
96
  draft.experiencesSearchLoading = false;
97
+ draft.experiencesTotal = data.total;
99
98
 
100
- // 设置基础信息
101
99
  if (!draft.experiencesInit) {
102
100
  draft.experiencesInit = true;
103
- draft.experiencesTotal = data.total;
104
101
  }
105
102
 
106
- // 转换数据结构
107
- const transformedItems = data.items.map((item: any) => ({
108
- ...item.memory,
109
- ...item.experience,
110
- }));
111
-
112
- // 累积数据逻辑
103
+ // Backend now returns flat structure directly, no transformation needed
113
104
  if (page === 1) {
114
- // 第一页,直接设置
115
- draft.experiences = uniqBy(transformedItems, 'id');
105
+ draft.experiences = uniqBy(data.items, 'id');
116
106
  } else {
117
- // 后续页面,累积数据
118
- draft.experiences = uniqBy([...draft.experiences, ...transformedItems], 'id');
107
+ draft.experiences = uniqBy([...draft.experiences, ...data.items], 'id');
119
108
  }
120
109
 
121
- // 更新 hasMore
122
110
  draft.experiencesHasMore = data.items.length >= (params.pageSize || 20);
123
111
  }),
124
112
  false,
@@ -1 +1,2 @@
1
1
  export { createExperienceSlice, type ExperienceAction } from './action';
2
+ export { experienceInitialState, type ExperienceSliceState } from './initialState';
@@ -0,0 +1,22 @@
1
+ import type { ExperienceListItem } from '@lobechat/types';
2
+
3
+ export interface ExperienceSliceState {
4
+ experiences: ExperienceListItem[];
5
+ experiencesHasMore: boolean;
6
+ experiencesInit: boolean;
7
+ experiencesPage: number;
8
+ experiencesQuery?: string;
9
+ experiencesSearchLoading?: boolean;
10
+ experiencesSort?: 'capturedAt' | 'scoreConfidence';
11
+ experiencesTotal: number;
12
+ }
13
+
14
+ export const experienceInitialState: ExperienceSliceState = {
15
+ experiences: [],
16
+ experiencesHasMore: true,
17
+ experiencesInit: false,
18
+ experiencesPage: 1,
19
+ experiencesQuery: undefined,
20
+ experiencesSort: undefined,
21
+ experiencesTotal: 0,
22
+ };
@@ -5,12 +5,15 @@ import { type QueryIdentityRolesResult } from '@/database/models/userMemory';
5
5
  import { useClientDataSWR } from '@/libs/swr';
6
6
  import { userMemoryService } from '@/services/userMemory';
7
7
 
8
+ import { type PersonaData } from '../../initialState';
8
9
  import type { UserMemoryStore } from '../../store';
9
10
 
10
11
  const FETCH_TAGS_KEY = 'useFetchTags';
12
+ const FETCH_PERSONA_KEY = 'useFetchPersona';
11
13
  const n = (namespace: string) => namespace;
12
14
 
13
15
  export interface HomeAction {
16
+ useFetchPersona: () => SWRResponse<PersonaData>;
14
17
  useFetchTags: () => SWRResponse<QueryIdentityRolesResult>;
15
18
  }
16
19
 
@@ -20,6 +23,20 @@ export const createHomeSlice: StateCreator<
20
23
  [],
21
24
  HomeAction
22
25
  > = (set) => ({
26
+ useFetchPersona: () =>
27
+ useClientDataSWR(FETCH_PERSONA_KEY, () => userMemoryService.getPersona(), {
28
+ onSuccess: (data: PersonaData | undefined) => {
29
+ set(
30
+ {
31
+ persona: data,
32
+ personaInit: true,
33
+ },
34
+ false,
35
+ n('useFetchPersona/onSuccess'),
36
+ );
37
+ },
38
+ }),
39
+
23
40
  useFetchTags: () =>
24
41
  useClientDataSWR(
25
42
  FETCH_TAGS_KEY,
@@ -1,7 +1,6 @@
1
1
  import {
2
- LayersEnum,
2
+ type IdentityListResult,
3
3
  type NewUserMemoryIdentity,
4
- type TypesEnum,
5
4
  type UpdateUserMemoryIdentity,
6
5
  } from '@lobechat/types';
7
6
  import { uniqBy } from 'es-toolkit/compat';
@@ -21,7 +20,9 @@ export interface IdentityQueryParams {
21
20
  page?: number;
22
21
  pageSize?: number;
23
22
  q?: string;
24
- types?: TypesEnum[];
23
+ relationships?: string[];
24
+ sort?: 'capturedAt' | 'type';
25
+ types?: string[];
25
26
  }
26
27
 
27
28
  export interface IdentityAction {
@@ -30,7 +31,7 @@ export interface IdentityAction {
30
31
  loadMoreIdentities: () => void;
31
32
  resetIdentitiesList: (params?: Omit<IdentityQueryParams, 'page' | 'pageSize'>) => void;
32
33
  updateIdentity: (id: string, data: UpdateUserMemoryIdentity) => Promise<boolean>;
33
- useFetchIdentities: (params: IdentityQueryParams) => SWRResponse<any>;
34
+ useFetchIdentities: (params: IdentityQueryParams) => SWRResponse<IdentityListResult>;
34
35
  }
35
36
 
36
37
  export const createIdentitySlice: StateCreator<
@@ -42,14 +43,24 @@ export const createIdentitySlice: StateCreator<
42
43
  createIdentity: async (data) => {
43
44
  const result = await memoryCRUDService.createIdentity(data);
44
45
  // Reset list to refresh
45
- get().resetIdentitiesList({ q: get().identitiesQuery, types: get().identitiesTypes });
46
+ get().resetIdentitiesList({
47
+ q: get().identitiesQuery,
48
+ relationships: get().identitiesRelationships,
49
+ sort: get().identitiesSort,
50
+ types: get().identitiesTypes,
51
+ });
46
52
  return result;
47
53
  },
48
54
 
49
55
  deleteIdentity: async (id) => {
50
56
  await memoryCRUDService.deleteIdentity(id);
51
57
  // Reset list to refresh
52
- get().resetIdentitiesList({ q: get().identitiesQuery, types: get().identitiesTypes });
58
+ get().resetIdentitiesList({
59
+ q: get().identitiesQuery,
60
+ relationships: get().identitiesRelationships,
61
+ sort: get().identitiesSort,
62
+ types: get().identitiesTypes,
63
+ });
53
64
  },
54
65
 
55
66
  loadMoreIdentities: () => {
@@ -71,7 +82,9 @@ export const createIdentitySlice: StateCreator<
71
82
  draft.identities = [];
72
83
  draft.identitiesPage = 1;
73
84
  draft.identitiesQuery = params?.q;
85
+ draft.identitiesRelationships = params?.relationships;
74
86
  draft.identitiesSearchLoading = true;
87
+ draft.identitiesSort = params?.sort;
75
88
  draft.identitiesTypes = params?.types;
76
89
  }),
77
90
  false,
@@ -82,7 +95,12 @@ export const createIdentitySlice: StateCreator<
82
95
  updateIdentity: async (id, data) => {
83
96
  const result = await memoryCRUDService.updateIdentity(id, data);
84
97
  // Reset list to refresh
85
- get().resetIdentitiesList({ q: get().identitiesQuery, types: get().identitiesTypes });
98
+ get().resetIdentitiesList({
99
+ q: get().identitiesQuery,
100
+ relationships: get().identitiesRelationships,
101
+ sort: get().identitiesSort,
102
+ types: get().identitiesTypes,
103
+ });
86
104
  return result;
87
105
  },
88
106
 
@@ -92,6 +110,8 @@ export const createIdentitySlice: StateCreator<
92
110
  params.page,
93
111
  params.pageSize,
94
112
  params.q,
113
+ params.relationships?.join(','),
114
+ params.sort,
95
115
  params.types?.join(','),
96
116
  ];
97
117
  const swrKey = swrKeyParts
@@ -102,42 +122,34 @@ export const createIdentitySlice: StateCreator<
102
122
  return useSWR(
103
123
  swrKey,
104
124
  async () => {
105
- return await userMemoryService.queryMemories({
106
- layer: LayersEnum.Identity,
125
+ // Use the new dedicated queryIdentities API
126
+ return userMemoryService.queryIdentities({
107
127
  page: params.page,
108
128
  pageSize: params.pageSize,
109
129
  q: params.q,
130
+ relationships: params.relationships,
131
+ sort: params.sort,
110
132
  types: params.types,
111
133
  });
112
134
  },
113
135
  {
114
- onSuccess(data: any) {
136
+ onSuccess(data: IdentityListResult) {
115
137
  set(
116
138
  produce((draft) => {
117
139
  draft.identitiesSearchLoading = false;
140
+ draft.identitiesTotal = data.total;
118
141
 
119
- // 设置基础信息
120
142
  if (!draft.identitiesInit) {
121
143
  draft.identitiesInit = true;
122
- draft.identitiesTotal = data.total;
123
144
  }
124
145
 
125
- // 转换数据结构
126
- const transformedItems = data.items.map((item: any) => ({
127
- ...item.memory,
128
- ...item.identity,
129
- }));
130
-
131
- // 累积数据逻辑
146
+ // Backend now returns flat structure directly, no transformation needed
132
147
  if (page === 1) {
133
- // 第一页,直接设置
134
- draft.identities = uniqBy(transformedItems, 'id');
148
+ draft.identities = uniqBy(data.items, 'id');
135
149
  } else {
136
- // 后续页面,累积数据
137
- draft.identities = uniqBy([...draft.identities, ...transformedItems], 'id');
150
+ draft.identities = uniqBy([...draft.identities, ...data.items], 'id');
138
151
  }
139
152
 
140
- // 更新 hasMore
141
153
  draft.identitiesHasMore = data.items.length >= (params.pageSize || 20);
142
154
  }),
143
155
  false,
@@ -1,5 +1,4 @@
1
- import { type DisplayIdentityMemory } from '@/database/repositories/userMemory';
2
- import type { TypesEnum } from '@/types/userMemory';
1
+ import type { IdentityListItem, IdentityListSort } from '@lobechat/types';
3
2
 
4
3
  import type { IdentityForInjection } from '../../types';
5
4
 
@@ -10,14 +9,16 @@ export interface IdentitySliceState {
10
9
  globalIdentitiesFetchedAt?: number;
11
10
  /** Whether global identities have been initialized */
12
11
  globalIdentitiesInit: boolean;
13
- identities: DisplayIdentityMemory[];
12
+ identities: IdentityListItem[];
14
13
  identitiesHasMore: boolean;
15
14
  identitiesInit: boolean;
16
15
  identitiesPage: number;
17
16
  identitiesQuery?: string;
17
+ identitiesRelationships?: string[];
18
18
  identitiesSearchLoading?: boolean;
19
+ identitiesSort?: IdentityListSort;
19
20
  identitiesTotal: number;
20
- identitiesTypes?: TypesEnum[];
21
+ identitiesTypes?: string[];
21
22
  }
22
23
 
23
24
  export const identityInitialState: IdentitySliceState = {
@@ -29,6 +30,8 @@ export const identityInitialState: IdentitySliceState = {
29
30
  identitiesInit: false,
30
31
  identitiesPage: 1,
31
32
  identitiesQuery: undefined,
33
+ identitiesRelationships: undefined,
34
+ identitiesSort: undefined,
32
35
  identitiesTotal: 0,
33
36
  identitiesTypes: undefined,
34
37
  };
@@ -16,7 +16,7 @@ export interface PreferenceQueryParams {
16
16
  page?: number;
17
17
  pageSize?: number;
18
18
  q?: string;
19
- sort?: 'scorePriority';
19
+ sort?: 'capturedAt' | 'scorePriority';
20
20
  }
21
21
 
22
22
  export interface PreferenceAction {
@@ -1 +1,2 @@
1
1
  export { createPreferenceSlice, type PreferenceAction } from './action';
2
+ export { preferenceInitialState, type PreferenceSliceState } from './initialState';
@@ -0,0 +1,22 @@
1
+ import { type DisplayPreferenceMemory } from '@/database/repositories/userMemory';
2
+
3
+ export interface PreferenceSliceState {
4
+ preferences: DisplayPreferenceMemory[];
5
+ preferencesHasMore: boolean;
6
+ preferencesInit: boolean;
7
+ preferencesPage: number;
8
+ preferencesQuery?: string;
9
+ preferencesSearchLoading?: boolean;
10
+ preferencesSort?: 'capturedAt' | 'scorePriority';
11
+ preferencesTotal: number;
12
+ }
13
+
14
+ export const preferenceInitialState: PreferenceSliceState = {
15
+ preferences: [],
16
+ preferencesHasMore: true,
17
+ preferencesInit: false,
18
+ preferencesPage: 1,
19
+ preferencesQuery: undefined,
20
+ preferencesSort: undefined,
21
+ preferencesTotal: 0,
22
+ };