@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.
- package/CHANGELOG.md +66 -0
- package/changelog/v1.json +21 -0
- package/package.json +1 -1
- package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +161 -12
- 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
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ExperienceListParams, ExperienceListResult } from '@lobechat/types';
|
|
2
|
+
import { type SQL, and, asc, desc, eq, ilike, inArray, or, sql } from 'drizzle-orm';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
NewUserMemoryExperience,
|
|
@@ -64,6 +65,95 @@ export class UserMemoryExperienceModel {
|
|
|
64
65
|
});
|
|
65
66
|
};
|
|
66
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Query experience list with pagination, search, and sorting
|
|
70
|
+
* Returns a flat structure optimized for frontend display
|
|
71
|
+
*/
|
|
72
|
+
queryList = async (params: ExperienceListParams = {}): Promise<ExperienceListResult> => {
|
|
73
|
+
const { order = 'desc', page = 1, pageSize = 20, q, sort, tags, types } = params;
|
|
74
|
+
|
|
75
|
+
const normalizedPage = Math.max(1, page);
|
|
76
|
+
const normalizedPageSize = Math.min(Math.max(pageSize, 1), 100);
|
|
77
|
+
const offset = (normalizedPage - 1) * normalizedPageSize;
|
|
78
|
+
const normalizedQuery = typeof q === 'string' ? q.trim() : '';
|
|
79
|
+
|
|
80
|
+
// Build WHERE conditions
|
|
81
|
+
const conditions: Array<SQL | undefined> = [
|
|
82
|
+
eq(userMemoriesExperiences.userId, this.userId),
|
|
83
|
+
// Full-text search across title, situation, keyLearning, action
|
|
84
|
+
normalizedQuery
|
|
85
|
+
? or(
|
|
86
|
+
ilike(userMemories.title, `%${normalizedQuery}%`),
|
|
87
|
+
ilike(userMemoriesExperiences.situation, `%${normalizedQuery}%`),
|
|
88
|
+
ilike(userMemoriesExperiences.keyLearning, `%${normalizedQuery}%`),
|
|
89
|
+
ilike(userMemoriesExperiences.action, `%${normalizedQuery}%`),
|
|
90
|
+
)
|
|
91
|
+
: undefined,
|
|
92
|
+
types && types.length > 0 ? inArray(userMemoriesExperiences.type, types) : undefined,
|
|
93
|
+
tags && tags.length > 0
|
|
94
|
+
? or(...tags.map((tag) => sql<boolean>`${tag} = ANY(${userMemoriesExperiences.tags})`))
|
|
95
|
+
: undefined,
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
const filters = conditions.filter((condition): condition is SQL => condition !== undefined);
|
|
99
|
+
const whereClause = filters.length > 0 ? and(...filters) : undefined;
|
|
100
|
+
|
|
101
|
+
// Build ORDER BY
|
|
102
|
+
const applyOrder = order === 'asc' ? asc : desc;
|
|
103
|
+
const sortColumn =
|
|
104
|
+
sort === 'scoreConfidence'
|
|
105
|
+
? userMemoriesExperiences.scoreConfidence
|
|
106
|
+
: userMemoriesExperiences.capturedAt;
|
|
107
|
+
|
|
108
|
+
const orderByClauses = [
|
|
109
|
+
applyOrder(sortColumn),
|
|
110
|
+
applyOrder(userMemoriesExperiences.updatedAt),
|
|
111
|
+
applyOrder(userMemoriesExperiences.createdAt),
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
// JOIN condition
|
|
115
|
+
const joinCondition = and(
|
|
116
|
+
eq(userMemories.id, userMemoriesExperiences.userMemoryId),
|
|
117
|
+
eq(userMemories.userId, this.userId),
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Execute queries in parallel
|
|
121
|
+
const [rows, totalResult] = await Promise.all([
|
|
122
|
+
this.db
|
|
123
|
+
.select({
|
|
124
|
+
action: userMemoriesExperiences.action,
|
|
125
|
+
capturedAt: userMemoriesExperiences.capturedAt,
|
|
126
|
+
createdAt: userMemoriesExperiences.createdAt,
|
|
127
|
+
id: userMemoriesExperiences.id,
|
|
128
|
+
keyLearning: userMemoriesExperiences.keyLearning,
|
|
129
|
+
scoreConfidence: userMemoriesExperiences.scoreConfidence,
|
|
130
|
+
situation: userMemoriesExperiences.situation,
|
|
131
|
+
tags: userMemoriesExperiences.tags,
|
|
132
|
+
title: userMemories.title,
|
|
133
|
+
type: userMemoriesExperiences.type,
|
|
134
|
+
updatedAt: userMemoriesExperiences.updatedAt,
|
|
135
|
+
})
|
|
136
|
+
.from(userMemoriesExperiences)
|
|
137
|
+
.innerJoin(userMemories, joinCondition)
|
|
138
|
+
.where(whereClause)
|
|
139
|
+
.orderBy(...orderByClauses)
|
|
140
|
+
.limit(normalizedPageSize)
|
|
141
|
+
.offset(offset),
|
|
142
|
+
this.db
|
|
143
|
+
.select({ count: sql<number>`COUNT(*)::int` })
|
|
144
|
+
.from(userMemoriesExperiences)
|
|
145
|
+
.innerJoin(userMemories, joinCondition)
|
|
146
|
+
.where(whereClause),
|
|
147
|
+
]);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
items: rows,
|
|
151
|
+
page: normalizedPage,
|
|
152
|
+
pageSize: normalizedPageSize,
|
|
153
|
+
total: Number(totalResult[0]?.count ?? 0),
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
|
|
67
157
|
findById = async (id: string) => {
|
|
68
158
|
return this.db.query.userMemoriesExperiences.findFirst({
|
|
69
159
|
where: and(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { IdentityListParams, IdentityListResult } from '@lobechat/types';
|
|
1
2
|
import { RelationshipEnum } from '@lobechat/types';
|
|
2
|
-
import { and, desc, eq, isNull, or } from 'drizzle-orm';
|
|
3
|
+
import { type SQL, and, asc, desc, eq, ilike, inArray, isNull, or, sql } from 'drizzle-orm';
|
|
3
4
|
|
|
4
5
|
import {
|
|
5
6
|
NewUserMemoryIdentity,
|
|
@@ -60,11 +61,101 @@ export class UserMemoryIdentityModel {
|
|
|
60
61
|
query = async (limit = 50) => {
|
|
61
62
|
return this.db.query.userMemoriesIdentities.findMany({
|
|
62
63
|
limit,
|
|
63
|
-
orderBy: [desc(userMemoriesIdentities.
|
|
64
|
+
orderBy: [desc(userMemoriesIdentities.capturedAt)],
|
|
64
65
|
where: eq(userMemoriesIdentities.userId, this.userId),
|
|
65
66
|
});
|
|
66
67
|
};
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Query identity list with pagination, search, and sorting
|
|
71
|
+
* Returns a flat structure optimized for frontend display
|
|
72
|
+
*/
|
|
73
|
+
queryList = async (params: IdentityListParams = {}): Promise<IdentityListResult> => {
|
|
74
|
+
const { order = 'desc', page = 1, pageSize = 20, q, relationships, sort, tags, types } = params;
|
|
75
|
+
|
|
76
|
+
const normalizedPage = Math.max(1, page);
|
|
77
|
+
const normalizedPageSize = Math.min(Math.max(pageSize, 1), 100);
|
|
78
|
+
const offset = (normalizedPage - 1) * normalizedPageSize;
|
|
79
|
+
const normalizedQuery = typeof q === 'string' ? q.trim() : '';
|
|
80
|
+
|
|
81
|
+
// Build WHERE conditions
|
|
82
|
+
const conditions: Array<SQL | undefined> = [
|
|
83
|
+
eq(userMemoriesIdentities.userId, this.userId),
|
|
84
|
+
// Full-text search across title, description, role
|
|
85
|
+
normalizedQuery
|
|
86
|
+
? or(
|
|
87
|
+
ilike(userMemories.title, `%${normalizedQuery}%`),
|
|
88
|
+
ilike(userMemoriesIdentities.description, `%${normalizedQuery}%`),
|
|
89
|
+
ilike(userMemoriesIdentities.role, `%${normalizedQuery}%`),
|
|
90
|
+
)
|
|
91
|
+
: undefined,
|
|
92
|
+
types && types.length > 0 ? inArray(userMemoriesIdentities.type, types) : undefined,
|
|
93
|
+
// Default to 'self' relationship if not specified
|
|
94
|
+
relationships && relationships.length > 0
|
|
95
|
+
? inArray(userMemoriesIdentities.relationship, relationships)
|
|
96
|
+
: eq(userMemoriesIdentities.relationship, RelationshipEnum.Self),
|
|
97
|
+
tags && tags.length > 0
|
|
98
|
+
? or(...tags.map((tag) => sql<boolean>`${tag} = ANY(${userMemoriesIdentities.tags})`))
|
|
99
|
+
: undefined,
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
const filters = conditions.filter((condition): condition is SQL => condition !== undefined);
|
|
103
|
+
const whereClause = filters.length > 0 ? and(...filters) : undefined;
|
|
104
|
+
|
|
105
|
+
// Build ORDER BY
|
|
106
|
+
const applyOrder = order === 'asc' ? asc : desc;
|
|
107
|
+
const sortColumn =
|
|
108
|
+
sort === 'type' ? userMemoriesIdentities.type : userMemoriesIdentities.capturedAt;
|
|
109
|
+
|
|
110
|
+
const orderByClauses = [
|
|
111
|
+
applyOrder(sortColumn),
|
|
112
|
+
applyOrder(userMemoriesIdentities.updatedAt),
|
|
113
|
+
applyOrder(userMemoriesIdentities.createdAt),
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
// JOIN condition
|
|
117
|
+
const joinCondition = and(
|
|
118
|
+
eq(userMemories.id, userMemoriesIdentities.userMemoryId),
|
|
119
|
+
eq(userMemories.userId, this.userId),
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
// Execute queries in parallel
|
|
123
|
+
const [rows, totalResult] = await Promise.all([
|
|
124
|
+
this.db
|
|
125
|
+
.select({
|
|
126
|
+
capturedAt: userMemoriesIdentities.capturedAt,
|
|
127
|
+
createdAt: userMemoriesIdentities.createdAt,
|
|
128
|
+
description: userMemoriesIdentities.description,
|
|
129
|
+
episodicDate: userMemoriesIdentities.episodicDate,
|
|
130
|
+
id: userMemoriesIdentities.id,
|
|
131
|
+
relationship: userMemoriesIdentities.relationship,
|
|
132
|
+
role: userMemoriesIdentities.role,
|
|
133
|
+
tags: userMemoriesIdentities.tags,
|
|
134
|
+
title: userMemories.title,
|
|
135
|
+
type: userMemoriesIdentities.type,
|
|
136
|
+
updatedAt: userMemoriesIdentities.updatedAt,
|
|
137
|
+
})
|
|
138
|
+
.from(userMemoriesIdentities)
|
|
139
|
+
.innerJoin(userMemories, joinCondition)
|
|
140
|
+
.where(whereClause)
|
|
141
|
+
.orderBy(...orderByClauses)
|
|
142
|
+
.limit(normalizedPageSize)
|
|
143
|
+
.offset(offset),
|
|
144
|
+
this.db
|
|
145
|
+
.select({ count: sql<number>`COUNT(*)::int` })
|
|
146
|
+
.from(userMemoriesIdentities)
|
|
147
|
+
.innerJoin(userMemories, joinCondition)
|
|
148
|
+
.where(whereClause),
|
|
149
|
+
]);
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
items: rows,
|
|
153
|
+
page: normalizedPage,
|
|
154
|
+
pageSize: normalizedPageSize,
|
|
155
|
+
total: Number(totalResult[0]?.count ?? 0),
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
|
|
68
159
|
findById = async (id: string) => {
|
|
69
160
|
return this.db.query.userMemoriesIdentities.findFirst({
|
|
70
161
|
where: and(eq(userMemoriesIdentities.id, id), eq(userMemoriesIdentities.userId, this.userId)),
|
|
@@ -311,6 +311,7 @@ export interface QueryIdentityRolesResult {
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
export type QueryUserMemoriesSort =
|
|
314
|
+
| 'capturedAt' // all layers
|
|
314
315
|
| 'scoreConfidence' // user_memories_experiences
|
|
315
316
|
| 'scoreImpact' // user_memories_contexts
|
|
316
317
|
| 'scorePriority' // user_memories_preferences
|
|
@@ -668,7 +669,10 @@ export class UserMemoryModel {
|
|
|
668
669
|
const { page = 1, size = 10 } = params;
|
|
669
670
|
const offset = (page - 1) * size;
|
|
670
671
|
|
|
671
|
-
const identityConditions = [
|
|
672
|
+
const identityConditions = [
|
|
673
|
+
eq(userMemoriesIdentities.userId, this.userId),
|
|
674
|
+
eq(userMemoriesIdentities.relationship, RelationshipEnum.Self),
|
|
675
|
+
];
|
|
672
676
|
|
|
673
677
|
const identityTags = this.db.$with('identity_tags').as(
|
|
674
678
|
this.db
|
|
@@ -792,7 +796,9 @@ export class UserMemoryModel {
|
|
|
792
796
|
const scoreColumn =
|
|
793
797
|
sort === 'scoreUrgency'
|
|
794
798
|
? userMemoriesContexts.scoreUrgency
|
|
795
|
-
:
|
|
799
|
+
: sort === 'scoreImpact'
|
|
800
|
+
? userMemoriesContexts.scoreImpact
|
|
801
|
+
: userMemoriesContexts.capturedAt;
|
|
796
802
|
|
|
797
803
|
const orderByClauses = buildOrderBy(
|
|
798
804
|
scoreColumn,
|
|
@@ -880,8 +886,13 @@ export class UserMemoryModel {
|
|
|
880
886
|
};
|
|
881
887
|
}
|
|
882
888
|
case LayersEnum.Experience: {
|
|
889
|
+
const scoreColumn =
|
|
890
|
+
sort === 'scoreConfidence'
|
|
891
|
+
? userMemoriesExperiences.scoreConfidence
|
|
892
|
+
: userMemoriesExperiences.capturedAt;
|
|
893
|
+
|
|
883
894
|
const orderByClauses = buildOrderBy(
|
|
884
|
-
|
|
895
|
+
scoreColumn,
|
|
885
896
|
userMemoriesExperiences.updatedAt,
|
|
886
897
|
userMemoriesExperiences.createdAt,
|
|
887
898
|
);
|
|
@@ -956,7 +967,7 @@ export class UserMemoryModel {
|
|
|
956
967
|
case LayersEnum.Identity: {
|
|
957
968
|
const orderByClauses = buildOrderBy(
|
|
958
969
|
undefined,
|
|
959
|
-
userMemoriesIdentities.
|
|
970
|
+
userMemoriesIdentities.capturedAt,
|
|
960
971
|
userMemoriesIdentities.createdAt,
|
|
961
972
|
);
|
|
962
973
|
const joinCondition = and(
|
|
@@ -986,6 +997,7 @@ export class UserMemoryModel {
|
|
|
986
997
|
.select({
|
|
987
998
|
identity: {
|
|
988
999
|
accessedAt: userMemoriesIdentities.accessedAt,
|
|
1000
|
+
capturedAt: userMemoriesIdentities.capturedAt,
|
|
989
1001
|
createdAt: userMemoriesIdentities.createdAt,
|
|
990
1002
|
description: userMemoriesIdentities.description,
|
|
991
1003
|
episodicDate: userMemoriesIdentities.episodicDate,
|
|
@@ -994,6 +1006,7 @@ export class UserMemoryModel {
|
|
|
994
1006
|
relationship: userMemoriesIdentities.relationship,
|
|
995
1007
|
role: userMemoriesIdentities.role,
|
|
996
1008
|
tags: userMemoriesIdentities.tags,
|
|
1009
|
+
title: userMemories.title,
|
|
997
1010
|
type: userMemoriesIdentities.type,
|
|
998
1011
|
updatedAt: userMemoriesIdentities.updatedAt,
|
|
999
1012
|
userId: userMemoriesIdentities.userId,
|
|
@@ -1028,8 +1041,13 @@ export class UserMemoryModel {
|
|
|
1028
1041
|
};
|
|
1029
1042
|
}
|
|
1030
1043
|
case LayersEnum.Preference: {
|
|
1044
|
+
const scoreColumn =
|
|
1045
|
+
sort === 'scorePriority'
|
|
1046
|
+
? userMemoriesPreferences.scorePriority
|
|
1047
|
+
: userMemoriesPreferences.capturedAt;
|
|
1048
|
+
|
|
1031
1049
|
const orderByClauses = buildOrderBy(
|
|
1032
|
-
|
|
1050
|
+
scoreColumn,
|
|
1033
1051
|
userMemoriesPreferences.updatedAt,
|
|
1034
1052
|
userMemoriesPreferences.createdAt,
|
|
1035
1053
|
);
|
|
@@ -1226,6 +1244,7 @@ export class UserMemoryModel {
|
|
|
1226
1244
|
const [identity] = await this.db
|
|
1227
1245
|
.select({
|
|
1228
1246
|
accessedAt: userMemoriesIdentities.accessedAt,
|
|
1247
|
+
capturedAt: userMemoriesIdentities.capturedAt,
|
|
1229
1248
|
createdAt: userMemoriesIdentities.createdAt,
|
|
1230
1249
|
description: userMemoriesIdentities.description,
|
|
1231
1250
|
episodicDate: userMemoriesIdentities.episodicDate,
|
|
@@ -1933,7 +1952,7 @@ export class UserMemoryModel {
|
|
|
1933
1952
|
.select(selectNonVectorColumns(userMemoriesIdentities))
|
|
1934
1953
|
.from(userMemoriesIdentities)
|
|
1935
1954
|
.where(eq(userMemoriesIdentities.userId, this.userId))
|
|
1936
|
-
.orderBy(desc(userMemoriesIdentities.
|
|
1955
|
+
.orderBy(desc(userMemoriesIdentities.capturedAt));
|
|
1937
1956
|
|
|
1938
1957
|
return res;
|
|
1939
1958
|
};
|
|
@@ -1947,7 +1966,7 @@ export class UserMemoryModel {
|
|
|
1947
1966
|
.from(userMemoriesIdentities)
|
|
1948
1967
|
.innerJoin(userMemories, eq(userMemories.id, userMemoriesIdentities.userMemoryId))
|
|
1949
1968
|
.where(eq(userMemoriesIdentities.userId, this.userId))
|
|
1950
|
-
.orderBy(desc(userMemoriesIdentities.
|
|
1969
|
+
.orderBy(desc(userMemoriesIdentities.capturedAt));
|
|
1951
1970
|
|
|
1952
1971
|
return res as Array<{
|
|
1953
1972
|
identity: typeof userMemoriesIdentities.$inferSelect;
|
|
@@ -1962,7 +1981,7 @@ export class UserMemoryModel {
|
|
|
1962
1981
|
.where(
|
|
1963
1982
|
and(eq(userMemoriesIdentities.userId, this.userId), eq(userMemoriesIdentities.type, type)),
|
|
1964
1983
|
)
|
|
1965
|
-
.orderBy(desc(userMemoriesIdentities.
|
|
1984
|
+
.orderBy(desc(userMemoriesIdentities.capturedAt));
|
|
1966
1985
|
|
|
1967
1986
|
return res;
|
|
1968
1987
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BaseListItem, BaseListParams, BaseListResult } from './shared';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Experience query types for list display
|
|
5
|
+
* These are flat structures optimized for frontend rendering
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type ExperienceListSort = 'capturedAt' | 'scoreConfidence';
|
|
9
|
+
|
|
10
|
+
export interface ExperienceListParams extends BaseListParams {
|
|
11
|
+
sort?: ExperienceListSort;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Flat structure for experience list items
|
|
16
|
+
* Contains fields needed for card display, excluding detail fields like reasoning/possibleOutcome
|
|
17
|
+
*/
|
|
18
|
+
export interface ExperienceListItem extends BaseListItem {
|
|
19
|
+
action: string | null;
|
|
20
|
+
keyLearning: string | null;
|
|
21
|
+
scoreConfidence: number | null;
|
|
22
|
+
situation: string | null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type ExperienceListResult = BaseListResult<ExperienceListItem>;
|
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
+
import type { BaseListItem, BaseListParams, BaseListResult } from './shared';
|
|
4
|
+
|
|
3
5
|
export type IdentityType = 'personal' | 'professional' | 'demographic';
|
|
4
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Identity query types for list display
|
|
9
|
+
* These are flat structures optimized for frontend rendering
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export type IdentityListSort = 'capturedAt' | 'type';
|
|
13
|
+
|
|
14
|
+
export interface IdentityListParams extends BaseListParams {
|
|
15
|
+
relationships?: string[];
|
|
16
|
+
sort?: IdentityListSort;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Flat structure for identity list items
|
|
21
|
+
* Contains fields needed for card display
|
|
22
|
+
*/
|
|
23
|
+
export interface IdentityListItem extends BaseListItem {
|
|
24
|
+
description: string | null;
|
|
25
|
+
episodicDate: Date | null;
|
|
26
|
+
relationship: string | null;
|
|
27
|
+
role: string | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type IdentityListResult = BaseListResult<IdentityListItem>;
|
|
31
|
+
|
|
5
32
|
export interface UserMemoryIdentity {
|
|
6
33
|
accessedAt: Date;
|
|
7
34
|
createdAt: Date;
|
|
@@ -76,3 +76,33 @@ export enum ContextStatusEnum {
|
|
|
76
76
|
Planned = 'planned',
|
|
77
77
|
}
|
|
78
78
|
export const CONTEXT_STATUS = Object.values(ContextStatusEnum);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Shared types for memory list queries
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
export interface BaseListParams {
|
|
85
|
+
order?: 'asc' | 'desc';
|
|
86
|
+
page?: number;
|
|
87
|
+
pageSize?: number;
|
|
88
|
+
q?: string;
|
|
89
|
+
tags?: string[];
|
|
90
|
+
types?: string[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface BaseListResult<T> {
|
|
94
|
+
items: T[];
|
|
95
|
+
page: number;
|
|
96
|
+
pageSize: number;
|
|
97
|
+
total: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface BaseListItem {
|
|
101
|
+
capturedAt: Date;
|
|
102
|
+
createdAt: Date;
|
|
103
|
+
id: string;
|
|
104
|
+
tags: string[] | null;
|
|
105
|
+
title: string | null;
|
|
106
|
+
type: string | null;
|
|
107
|
+
updatedAt: Date;
|
|
108
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { Flexbox } from '@lobehub/ui';
|
|
4
|
-
import {
|
|
4
|
+
import { createStaticStyles } from 'antd-style';
|
|
5
5
|
import { Crown, Users } from 'lucide-react';
|
|
6
6
|
import { memo, useMemo, useState } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
@@ -17,7 +17,7 @@ import { systemStatusSelectors } from '@/store/global/selectors';
|
|
|
17
17
|
import AgentBuilderToggle from './AgentBuilderToggle';
|
|
18
18
|
import ChromeTabs, { type ChromeTabItem } from './ChromeTabs';
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
21
21
|
header: css`
|
|
22
22
|
overflow: hidden;
|
|
23
23
|
flex: none;
|
|
@@ -26,7 +26,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
26
26
|
height: 44px;
|
|
27
27
|
padding-block: 8px;
|
|
28
28
|
padding-inline: 12px;
|
|
29
|
-
border-block-end: 1px solid ${
|
|
29
|
+
border-block-end: 1px solid ${cssVar.colorBorderSecondary};
|
|
30
30
|
`,
|
|
31
31
|
tabsWrapper: css`
|
|
32
32
|
scrollbar-width: none;
|
|
@@ -42,7 +42,6 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
42
42
|
|
|
43
43
|
const Header = memo(() => {
|
|
44
44
|
const { t } = useTranslation('chat');
|
|
45
|
-
const { styles } = useStyles();
|
|
46
45
|
|
|
47
46
|
const [showAddModal, setShowAddModal] = useState(false);
|
|
48
47
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { getKlavisServerByServerIdentifier, getLobehubSkillProviderById } from '@lobechat/const';
|
|
4
4
|
import { Avatar, Flexbox, Icon } from '@lobehub/ui';
|
|
5
|
-
import {
|
|
5
|
+
import { createStaticStyles } from 'antd-style';
|
|
6
6
|
import { Blocks } from 'lucide-react';
|
|
7
7
|
import { type ReactNode, createElement, memo, useMemo, useState } from 'react';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
@@ -11,7 +11,7 @@ import SkillStore from '@/features/SkillStore';
|
|
|
11
11
|
import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfig';
|
|
12
12
|
import { useToolStore } from '@/store/tool';
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
15
15
|
banner: css`
|
|
16
16
|
cursor: pointer;
|
|
17
17
|
|
|
@@ -28,24 +28,24 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
28
28
|
margin-block-end: 6px;
|
|
29
29
|
padding-block: 42px 10px;
|
|
30
30
|
padding-inline: 16px;
|
|
31
|
-
border: 1px solid ${
|
|
31
|
+
border: 1px solid ${cssVar.colorBorderSecondary};
|
|
32
32
|
border-radius: 20px;
|
|
33
33
|
|
|
34
|
-
background: ${
|
|
34
|
+
background: ${cssVar.colorFillQuaternary};
|
|
35
35
|
box-shadow: 0 12px 32px rgb(0 0 0 / 4%);
|
|
36
36
|
|
|
37
37
|
transition: background 0.2s ease-in-out;
|
|
38
38
|
|
|
39
39
|
&:hover {
|
|
40
|
-
background: ${
|
|
40
|
+
background: ${cssVar.colorFillQuaternary};
|
|
41
41
|
}
|
|
42
42
|
`,
|
|
43
43
|
icon: css`
|
|
44
|
-
color: ${
|
|
44
|
+
color: ${cssVar.colorTextSecondary};
|
|
45
45
|
`,
|
|
46
46
|
text: css`
|
|
47
47
|
font-size: 13px;
|
|
48
|
-
color: ${
|
|
48
|
+
color: ${cssVar.colorTextSecondary};
|
|
49
49
|
`,
|
|
50
50
|
}));
|
|
51
51
|
|
|
@@ -60,7 +60,6 @@ const BANNER_SKILL_IDS = [
|
|
|
60
60
|
] as const;
|
|
61
61
|
|
|
62
62
|
const SkillInstallBanner = memo(() => {
|
|
63
|
-
const { styles } = useStyles();
|
|
64
63
|
const { t } = useTranslation('plugin');
|
|
65
64
|
const [open, setOpen] = useState(false);
|
|
66
65
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Markdown } from '@lobehub/ui';
|
|
2
|
+
import { createStaticStyles } from 'antd-style';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
|
|
5
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
6
|
+
markdown: css`
|
|
7
|
+
h2 {
|
|
8
|
+
margin-block: 24px 12px;
|
|
9
|
+
font-size: 16px;
|
|
10
|
+
font-weight: 600;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
h3 {
|
|
14
|
+
margin-block: 16px 8px;
|
|
15
|
+
font-size: 14px;
|
|
16
|
+
font-weight: 500;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
p {
|
|
20
|
+
margin-block-end: 8px;
|
|
21
|
+
font-size: 14px;
|
|
22
|
+
line-height: 1.6;
|
|
23
|
+
color: ${cssVar.colorTextSecondary};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
ul {
|
|
27
|
+
margin-block: 8px;
|
|
28
|
+
margin-inline: 0;
|
|
29
|
+
padding-inline-start: 20px;
|
|
30
|
+
|
|
31
|
+
li {
|
|
32
|
+
margin-block-end: 4px;
|
|
33
|
+
font-size: 14px;
|
|
34
|
+
line-height: 1.6;
|
|
35
|
+
color: ${cssVar.colorTextSecondary};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
strong {
|
|
40
|
+
font-weight: 500;
|
|
41
|
+
color: ${cssVar.colorText};
|
|
42
|
+
}
|
|
43
|
+
`,
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
interface PersonaDetailProps {
|
|
47
|
+
children: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const PersonaDetail = memo<PersonaDetailProps>(({ children }) => {
|
|
51
|
+
return (
|
|
52
|
+
<Markdown className={styles.markdown} enableImageGallery={false} enableLatex={false}>
|
|
53
|
+
{children}
|
|
54
|
+
</Markdown>
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export default PersonaDetail;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Text } from '@lobehub/ui';
|
|
2
|
+
import { createStaticStyles } from 'antd-style';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
|
|
5
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
6
|
+
title: css`
|
|
7
|
+
font-size: 28px;
|
|
8
|
+
font-weight: 700;
|
|
9
|
+
line-height: 1.4;
|
|
10
|
+
color: ${cssVar.colorText};
|
|
11
|
+
`,
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
const PersonaHeader = memo(() => {
|
|
15
|
+
return (
|
|
16
|
+
<Text as={'h1'} className={styles.title}>
|
|
17
|
+
Persona
|
|
18
|
+
</Text>
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export default PersonaHeader;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createStaticStyles } from 'antd-style';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
|
|
4
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
5
|
+
summary: css`
|
|
6
|
+
position: relative;
|
|
7
|
+
|
|
8
|
+
padding-block: 16px;
|
|
9
|
+
padding-inline: 20px;
|
|
10
|
+
border-radius: 8px;
|
|
11
|
+
|
|
12
|
+
font-size: 15px;
|
|
13
|
+
font-style: italic;
|
|
14
|
+
line-height: 1.6;
|
|
15
|
+
color: ${cssVar.colorText};
|
|
16
|
+
|
|
17
|
+
background: ${cssVar.colorFillQuaternary};
|
|
18
|
+
|
|
19
|
+
&::before {
|
|
20
|
+
content: '"';
|
|
21
|
+
|
|
22
|
+
position: absolute;
|
|
23
|
+
inset-block-start: 8px;
|
|
24
|
+
inset-inline-start: 12px;
|
|
25
|
+
|
|
26
|
+
font-family: Georgia, serif;
|
|
27
|
+
font-size: 28px;
|
|
28
|
+
font-style: normal;
|
|
29
|
+
line-height: 1;
|
|
30
|
+
color: ${cssVar.colorTextQuaternary};
|
|
31
|
+
}
|
|
32
|
+
`,
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
interface PersonaSummaryProps {
|
|
36
|
+
children: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const PersonaSummary = memo<PersonaSummaryProps>(({ children }) => {
|
|
40
|
+
return <div className={styles.summary}>{children}</div>;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export default PersonaSummary;
|