@lobehub/lobehub 2.0.0-next.342 → 2.0.0-next.343
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/CHANGELOG.md +41 -0
- package/changelog/v1.json +12 -0
- package/package.json +1 -1
- package/packages/database/src/models/__tests__/userMemories.test.ts +62 -5
- package/packages/database/src/models/agentCronJob.ts +9 -9
- package/packages/database/src/models/userMemory/__tests__/identity.test.ts +5 -5
- package/packages/database/src/models/userMemory/experience.ts +91 -1
- package/packages/database/src/models/userMemory/identity.ts +93 -2
- package/packages/database/src/models/userMemory/model.ts +27 -8
- package/packages/types/src/userMemory/experience.ts +25 -0
- package/packages/types/src/userMemory/identity.ts +27 -0
- package/packages/types/src/userMemory/index.ts +1 -0
- package/packages/types/src/userMemory/shared.ts +30 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/index.tsx +3 -4
- package/src/app/[variants]/(main)/home/features/InputArea/SkillInstallBanner.tsx +7 -8
- package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaDetail.tsx +58 -0
- package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaHeader.tsx +22 -0
- package/src/app/[variants]/(main)/memory/(home)/features/Persona/PersonaSummary.tsx +43 -0
- package/src/app/[variants]/(main)/memory/(home)/features/Persona/index.tsx +53 -0
- package/src/app/[variants]/(main)/memory/(home)/features/RoleTagCloud/index.tsx +2 -2
- package/src/app/[variants]/(main)/memory/(home)/index.tsx +15 -3
- package/src/app/[variants]/(main)/memory/experiences/features/List/GridView/ExperienceCard.tsx +3 -3
- package/src/app/[variants]/(main)/memory/experiences/features/List/GridView/index.tsx +3 -3
- package/src/app/[variants]/(main)/memory/experiences/features/List/TimelineView/ExperienceCard.tsx +3 -3
- package/src/app/[variants]/(main)/memory/experiences/features/List/TimelineView/index.tsx +3 -3
- package/src/app/[variants]/(main)/memory/features/SourceLink.tsx +2 -11
- package/src/app/[variants]/(main)/memory/features/TimeLineView/TimeLineCard.tsx +2 -9
- package/src/app/[variants]/(main)/memory/identities/features/IdentityRightPanel.tsx +1 -1
- package/src/app/[variants]/(main)/memory/identities/features/List/GridView/IdentityCard.tsx +5 -4
- package/src/app/[variants]/(main)/memory/identities/features/List/GridView/index.tsx +3 -3
- package/src/app/[variants]/(main)/memory/identities/features/List/TimelineView/IdentityCard.tsx +6 -6
- package/src/app/[variants]/(main)/memory/identities/features/List/TimelineView/index.tsx +6 -4
- package/src/app/[variants]/(main)/settings/profile/index.tsx +8 -8
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +0 -1
- package/src/app/[variants]/(main)/settings/skill/features/Actions.tsx +0 -1
- package/src/app/[variants]/(main)/settings/skill/features/KlavisSkillItem.tsx +9 -10
- package/src/app/[variants]/(main)/settings/skill/features/LobehubSkillItem.tsx +9 -10
- package/src/app/[variants]/(main)/settings/skill/features/McpSkillItem.tsx +4 -5
- package/src/app/[variants]/(main)/settings/skill/features/SkillList.tsx +4 -5
- package/src/app/[variants]/share/t/[id]/SharedMessageList.tsx +1 -4
- package/src/app/[variants]/share/t/[id]/_layout/index.tsx +47 -121
- package/src/app/[variants]/share/t/[id]/_layout/style.ts +59 -0
- package/src/app/[variants]/share/t/[id]/features/Portal/index.tsx +4 -5
- package/src/app/[variants]/share/t/[id]/index.tsx +30 -37
- package/src/components/404/index.tsx +15 -9
- package/src/components/DragUpload/index.tsx +15 -16
- package/src/features/EditorCanvas/DocumentIdMode.tsx +1 -2
- package/src/features/IntegrationDetailModal/index.tsx +11 -12
- package/src/features/ResourceManager/index.tsx +13 -6
- package/src/features/ShareModal/ShareImage/Preview.tsx +19 -28
- package/src/features/ShareModal/ShareImage/style.ts +4 -2
- package/src/features/ShareModal/index.tsx +5 -1
- package/src/features/ShareModal/style.ts +1 -0
- package/src/features/ShareModal/useContainerStyles.ts +1 -1
- package/src/features/SharePopover/index.tsx +16 -9
- package/src/features/SharePopover/style.ts +2 -2
- package/src/features/SkillStore/CommunityList/Item.tsx +2 -2
- package/src/features/SkillStore/LobeHubList/Item.tsx +2 -2
- package/src/features/SkillStore/LobeHubList/index.tsx +2 -3
- package/src/features/SkillStore/style.ts +4 -4
- package/src/layout/GlobalProvider/ServerVersionOutdatedAlert.tsx +28 -20
- package/src/server/routers/lambda/userMemories.ts +61 -5
- package/src/server/routers/lambda/userMemory.ts +5 -1
- package/src/services/chat/index.ts +2 -2
- package/src/services/userMemory/index.ts +25 -1
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +0 -1
- package/src/store/userMemory/initialState.ts +22 -52
- package/src/store/userMemory/slices/context/action.ts +1 -1
- package/src/store/userMemory/slices/context/index.ts +1 -0
- package/src/store/userMemory/slices/context/initialState.ts +22 -0
- package/src/store/userMemory/slices/experience/action.ts +10 -22
- package/src/store/userMemory/slices/experience/index.ts +1 -0
- package/src/store/userMemory/slices/experience/initialState.ts +22 -0
- package/src/store/userMemory/slices/home/action.ts +17 -0
- package/src/store/userMemory/slices/identity/action.ts +36 -24
- package/src/store/userMemory/slices/identity/initialState.ts +7 -4
- package/src/store/userMemory/slices/preference/action.ts +1 -1
- package/src/store/userMemory/slices/preference/index.ts +1 -0
- package/src/store/userMemory/slices/preference/initialState.ts +22 -0
|
@@ -8,7 +8,7 @@ import { Loader2, MoreVerticalIcon, Plus, Unplug } from 'lucide-react';
|
|
|
8
8
|
import React, { memo } from 'react';
|
|
9
9
|
import { useTranslation } from 'react-i18next';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { itemStyles } from '../style';
|
|
12
12
|
import { useSkillConnect } from './useSkillConnect';
|
|
13
13
|
|
|
14
14
|
interface ItemProps {
|
|
@@ -25,7 +25,7 @@ interface ItemProps {
|
|
|
25
25
|
const Item = memo<ItemProps>(
|
|
26
26
|
({ description, icon, identifier, label, onOpenDetail, serverName, type }) => {
|
|
27
27
|
const { t } = useTranslation('setting');
|
|
28
|
-
const
|
|
28
|
+
const styles = itemStyles;
|
|
29
29
|
const { modal } = App.useApp();
|
|
30
30
|
|
|
31
31
|
const { handleConnect, handleDisconnect, isConnected, isConnecting } = useSkillConnect({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { KLAVIS_SERVER_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const';
|
|
4
|
-
import {
|
|
4
|
+
import { createStaticStyles } from 'antd-style';
|
|
5
5
|
import isEqual from 'fast-deep-equal';
|
|
6
6
|
import type { Klavis } from 'klavis';
|
|
7
7
|
import { memo, useMemo, useState } from 'react';
|
|
@@ -17,7 +17,7 @@ import Empty from '../Empty';
|
|
|
17
17
|
import Item from './Item';
|
|
18
18
|
import { useSkillConnect } from './useSkillConnect';
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const styles = createStaticStyles(({ css }) => ({
|
|
21
21
|
grid: css`
|
|
22
22
|
display: grid;
|
|
23
23
|
grid-template-columns: repeat(2, 1fr);
|
|
@@ -69,7 +69,6 @@ const DetailModalWithConnect = memo<DetailModalWithConnectProps>(({ detailState,
|
|
|
69
69
|
DetailModalWithConnect.displayName = 'DetailModalWithConnect';
|
|
70
70
|
|
|
71
71
|
export const LobeHubList = memo<LobeHubListProps>(({ keywords }) => {
|
|
72
|
-
const { styles } = useStyles();
|
|
73
72
|
const [detailState, setDetailState] = useState<DetailState | null>(null);
|
|
74
73
|
|
|
75
74
|
const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createStaticStyles } from 'antd-style';
|
|
2
2
|
|
|
3
|
-
export const
|
|
3
|
+
export const itemStyles = createStaticStyles(({ css, cssVar }) => ({
|
|
4
4
|
container: css`
|
|
5
5
|
position: relative;
|
|
6
6
|
overflow: hidden;
|
|
@@ -11,7 +11,7 @@ export const useItemStyles = createStyles(({ css, token }) => ({
|
|
|
11
11
|
overflow: hidden;
|
|
12
12
|
|
|
13
13
|
font-size: 12px;
|
|
14
|
-
color: ${
|
|
14
|
+
color: ${cssVar.colorTextSecondary};
|
|
15
15
|
text-overflow: ellipsis;
|
|
16
16
|
white-space: nowrap;
|
|
17
17
|
`,
|
|
@@ -20,7 +20,7 @@ export const useItemStyles = createStyles(({ css, token }) => ({
|
|
|
20
20
|
|
|
21
21
|
font-size: 14px;
|
|
22
22
|
font-weight: 500;
|
|
23
|
-
color: ${
|
|
23
|
+
color: ${cssVar.colorText};
|
|
24
24
|
text-overflow: ellipsis;
|
|
25
25
|
white-space: nowrap;
|
|
26
26
|
`,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { Button, Flexbox, Icon } from '@lobehub/ui';
|
|
4
|
-
import {
|
|
4
|
+
import { createStaticStyles, useTheme } from 'antd-style';
|
|
5
5
|
import { TriangleAlert, X } from 'lucide-react';
|
|
6
|
-
import { useState } from 'react';
|
|
6
|
+
import { useMemo, useState } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
|
|
9
9
|
import { MANUAL_UPGRADE_URL } from '@/const/url';
|
|
@@ -12,7 +12,7 @@ import { useElectronStore } from '@/store/electron';
|
|
|
12
12
|
import { electronSyncSelectors } from '@/store/electron/selectors';
|
|
13
13
|
import { useGlobalStore } from '@/store/global';
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
16
16
|
closeButton: css`
|
|
17
17
|
cursor: pointer;
|
|
18
18
|
|
|
@@ -26,15 +26,15 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
26
26
|
|
|
27
27
|
width: 28px;
|
|
28
28
|
height: 28px;
|
|
29
|
-
border-radius: ${
|
|
29
|
+
border-radius: ${cssVar.borderRadius};
|
|
30
30
|
|
|
31
|
-
color: ${
|
|
31
|
+
color: ${cssVar.colorTextSecondary};
|
|
32
32
|
|
|
33
33
|
transition: all 0.2s;
|
|
34
34
|
|
|
35
35
|
&:hover {
|
|
36
|
-
color: ${
|
|
37
|
-
background: ${
|
|
36
|
+
color: ${cssVar.colorText};
|
|
37
|
+
background: ${cssVar.colorFillSecondary};
|
|
38
38
|
}
|
|
39
39
|
`,
|
|
40
40
|
container: css`
|
|
@@ -46,7 +46,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
46
46
|
align-items: center;
|
|
47
47
|
justify-content: center;
|
|
48
48
|
|
|
49
|
-
background: ${
|
|
49
|
+
background: ${cssVar.colorBgMask};
|
|
50
50
|
`,
|
|
51
51
|
content: css`
|
|
52
52
|
position: relative;
|
|
@@ -55,47 +55,55 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
55
55
|
|
|
56
56
|
max-width: 480px;
|
|
57
57
|
padding: 24px;
|
|
58
|
-
border: 1px solid ${
|
|
59
|
-
border-radius: ${
|
|
58
|
+
border: 1px solid var(--content-yellow-border, ${cssVar.colorWarningBorder});
|
|
59
|
+
border-radius: ${cssVar.borderRadiusLG};
|
|
60
60
|
|
|
61
|
-
background: ${
|
|
62
|
-
box-shadow: ${
|
|
61
|
+
background: ${cssVar.colorBgContainer};
|
|
62
|
+
box-shadow: ${cssVar.boxShadowSecondary};
|
|
63
63
|
`,
|
|
64
64
|
desc: css`
|
|
65
65
|
line-height: 1.6;
|
|
66
|
-
color: ${
|
|
66
|
+
color: ${cssVar.colorTextSecondary};
|
|
67
67
|
`,
|
|
68
68
|
title: css`
|
|
69
69
|
font-size: 16px;
|
|
70
70
|
font-weight: bold;
|
|
71
|
-
color: ${
|
|
71
|
+
color: ${cssVar.colorWarningText};
|
|
72
72
|
`,
|
|
73
73
|
titleIcon: css`
|
|
74
74
|
flex-shrink: 0;
|
|
75
|
-
color: ${
|
|
75
|
+
color: ${cssVar.colorWarning};
|
|
76
76
|
`,
|
|
77
77
|
warning: css`
|
|
78
78
|
padding: 12px;
|
|
79
|
-
border-radius: ${
|
|
80
|
-
color: ${
|
|
81
|
-
background: ${
|
|
79
|
+
border-radius: ${cssVar.borderRadius};
|
|
80
|
+
color: ${cssVar.colorWarningText};
|
|
81
|
+
background: var(--warning-yellow-bg, ${cssVar.colorWarningBg});
|
|
82
82
|
`,
|
|
83
83
|
}));
|
|
84
84
|
|
|
85
85
|
const ServerVersionOutdatedAlert = () => {
|
|
86
|
-
const
|
|
86
|
+
const theme = useTheme();
|
|
87
87
|
const { t } = useTranslation('common');
|
|
88
88
|
const [dismissed, setDismissed] = useState(false);
|
|
89
89
|
const isServerVersionOutdated = useGlobalStore((s) => s.isServerVersionOutdated);
|
|
90
90
|
const storageMode = useElectronStore(electronSyncSelectors.storageMode);
|
|
91
91
|
|
|
92
|
+
const cssVariables = useMemo<Record<string, string>>(
|
|
93
|
+
() => ({
|
|
94
|
+
'--content-yellow-border': theme.yellowBorder,
|
|
95
|
+
'--warning-yellow-bg': theme.yellowBg,
|
|
96
|
+
}),
|
|
97
|
+
[theme.yellowBorder, theme.yellowBg],
|
|
98
|
+
);
|
|
99
|
+
|
|
92
100
|
// Only show alert when using self-hosted server, not cloud
|
|
93
101
|
if (storageMode !== 'selfHost') return null;
|
|
94
102
|
if (!isServerVersionOutdated || dismissed) return null;
|
|
95
103
|
|
|
96
104
|
return (
|
|
97
105
|
<div className={styles.container}>
|
|
98
|
-
<div className={styles.content}>
|
|
106
|
+
<div className={styles.content} style={cssVariables}>
|
|
99
107
|
<div className={styles.closeButton} onClick={() => setDismissed(true)}>
|
|
100
108
|
<Icon icon={X} />
|
|
101
109
|
</div>
|
|
@@ -21,6 +21,7 @@ import { z } from 'zod';
|
|
|
21
21
|
import {
|
|
22
22
|
type IdentityEntryBasePayload,
|
|
23
23
|
type IdentityEntryPayload,
|
|
24
|
+
UserMemoryExperienceModel,
|
|
24
25
|
UserMemoryIdentityModel,
|
|
25
26
|
UserMemoryModel,
|
|
26
27
|
} from '@/database/models/userMemory';
|
|
@@ -203,6 +204,8 @@ const memoryProcedure = authedProcedure.use(serverDatabase).use(async (opts) =>
|
|
|
203
204
|
const { ctx } = opts;
|
|
204
205
|
return opts.next({
|
|
205
206
|
ctx: {
|
|
207
|
+
experienceModel: new UserMemoryExperienceModel(ctx.serverDB, ctx.userId),
|
|
208
|
+
identityModel: new UserMemoryIdentityModel(ctx.serverDB, ctx.userId),
|
|
206
209
|
memoryModel: new UserMemoryModel(ctx.serverDB, ctx.userId),
|
|
207
210
|
},
|
|
208
211
|
});
|
|
@@ -220,13 +223,66 @@ export const userMemoriesRouter = router({
|
|
|
220
223
|
}
|
|
221
224
|
}),
|
|
222
225
|
|
|
223
|
-
|
|
224
|
-
.
|
|
226
|
+
queryExperiences: memoryProcedure
|
|
227
|
+
.input(
|
|
228
|
+
z
|
|
229
|
+
.object({
|
|
230
|
+
order: z.enum(['asc', 'desc']).optional(),
|
|
231
|
+
page: z.coerce.number().int().min(1).optional(),
|
|
232
|
+
pageSize: z.coerce.number().int().min(1).max(100).optional(),
|
|
233
|
+
q: z.string().optional(),
|
|
234
|
+
sort: z.enum(['capturedAt', 'scoreConfidence']).optional(),
|
|
235
|
+
tags: z.array(z.string()).optional(),
|
|
236
|
+
types: z.array(z.string()).optional(),
|
|
237
|
+
})
|
|
238
|
+
.optional(),
|
|
239
|
+
)
|
|
240
|
+
.query(async ({ ctx, input }) => {
|
|
241
|
+
const params = input ?? {};
|
|
242
|
+
const fallbackPage = params.page ?? 1;
|
|
243
|
+
const fallbackPageSize = params.pageSize ?? 20;
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
return await ctx.experienceModel.queryList(params);
|
|
247
|
+
} catch (error) {
|
|
248
|
+
console.error('Failed to query experiences:', error);
|
|
249
|
+
return { items: [], page: fallbackPage, pageSize: fallbackPageSize, total: 0 };
|
|
250
|
+
}
|
|
251
|
+
}),
|
|
252
|
+
|
|
253
|
+
queryIdentities: memoryProcedure
|
|
254
|
+
.input(
|
|
255
|
+
z
|
|
256
|
+
.object({
|
|
257
|
+
order: z.enum(['asc', 'desc']).optional(),
|
|
258
|
+
page: z.coerce.number().int().min(1).optional(),
|
|
259
|
+
pageSize: z.coerce.number().int().min(1).max(100).optional(),
|
|
260
|
+
q: z.string().optional(),
|
|
261
|
+
relationships: z.array(z.string()).optional(),
|
|
262
|
+
sort: z.enum(['capturedAt', 'type']).optional(),
|
|
263
|
+
tags: z.array(z.string()).optional(),
|
|
264
|
+
types: z.array(z.string()).optional(),
|
|
265
|
+
})
|
|
266
|
+
.optional(),
|
|
267
|
+
)
|
|
268
|
+
.query(async ({ ctx, input }) => {
|
|
269
|
+
const params = input ?? {};
|
|
270
|
+
const fallbackPage = params.page ?? 1;
|
|
271
|
+
const fallbackPageSize = params.pageSize ?? 20;
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
return await ctx.identityModel.queryList(params);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.error('Failed to query identities:', error);
|
|
277
|
+
return { items: [], page: fallbackPage, pageSize: fallbackPageSize, total: 0 };
|
|
278
|
+
}
|
|
279
|
+
}),
|
|
280
|
+
|
|
281
|
+
queryIdentitiesForInjection: memoryProcedure
|
|
225
282
|
.input(z.object({ limit: z.coerce.number().int().min(1).max(100).optional() }).optional())
|
|
226
283
|
.query(async ({ ctx, input }) => {
|
|
227
284
|
try {
|
|
228
|
-
|
|
229
|
-
return await identityModel.queryForInjection(input?.limit ?? 50);
|
|
285
|
+
return await ctx.identityModel.queryForInjection(input?.limit ?? 50);
|
|
230
286
|
} catch (error) {
|
|
231
287
|
console.error('Failed to query identities for injection:', error);
|
|
232
288
|
return [];
|
|
@@ -262,7 +318,7 @@ export const userMemoriesRouter = router({
|
|
|
262
318
|
pageSize: z.coerce.number().int().min(1).max(100).optional(),
|
|
263
319
|
q: z.string().optional(),
|
|
264
320
|
sort: z
|
|
265
|
-
.enum(['scoreConfidence', 'scoreImpact', 'scorePriority', 'scoreUrgency'])
|
|
321
|
+
.enum(['capturedAt', 'scoreConfidence', 'scoreImpact', 'scorePriority', 'scoreUrgency'])
|
|
266
322
|
.optional(),
|
|
267
323
|
tags: z.array(z.string()).optional(),
|
|
268
324
|
types: z.array(z.string()).optional(),
|
|
@@ -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
|
|
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
|
-
|
|
37
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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,
|
|
@@ -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<
|
|
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
|
-
|
|
85
|
-
|
|
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:
|
|
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,
|
|
@@ -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,
|