@aigne/afs-user-profile-memory 1.3.0-beta.2 → 1.3.0-beta.21

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 CHANGED
@@ -1,5 +1,222 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.0-beta.21](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.20...afs-user-profile-memory-v1.3.0-beta.21) (2026-01-15)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * dependencies
10
+ * @aigne/core bumped to 1.72.0-beta.21
11
+ * devDependencies
12
+ * @aigne/test-utils bumped to 0.5.69-beta.21
13
+
14
+ ## [1.3.0-beta.20](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.19...afs-user-profile-memory-v1.3.0-beta.20) (2026-01-15)
15
+
16
+
17
+ ### Dependencies
18
+
19
+ * The following workspace dependencies were updated
20
+ * dependencies
21
+ * @aigne/core bumped to 1.72.0-beta.20
22
+ * devDependencies
23
+ * @aigne/test-utils bumped to 0.5.69-beta.20
24
+
25
+ ## [1.3.0-beta.19](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.18...afs-user-profile-memory-v1.3.0-beta.19) (2026-01-14)
26
+
27
+
28
+ ### Features
29
+
30
+ * **afs:** add module access control and schema validation support ([#904](https://github.com/AIGNE-io/aigne-framework/issues/904)) ([d0b279a](https://github.com/AIGNE-io/aigne-framework/commit/d0b279aac07ebe2bcc1fd4148498fc3f6bbcd561))
31
+
32
+
33
+ ### Bug Fixes
34
+
35
+ * improve test coverage tracking and reporting ([#903](https://github.com/AIGNE-io/aigne-framework/issues/903)) ([031144e](https://github.com/AIGNE-io/aigne-framework/commit/031144e74f29e882cffe52ffda8f7a18c76ace7f))
36
+
37
+
38
+ ### Dependencies
39
+
40
+ * The following workspace dependencies were updated
41
+ * dependencies
42
+ * @aigne/afs bumped to 1.4.0-beta.9
43
+ * @aigne/afs-history bumped to 1.2.0-beta.10
44
+ * @aigne/core bumped to 1.72.0-beta.19
45
+ * devDependencies
46
+ * @aigne/test-utils bumped to 0.5.69-beta.19
47
+
48
+ ## [1.3.0-beta.18](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.17...afs-user-profile-memory-v1.3.0-beta.18) (2026-01-13)
49
+
50
+
51
+ ### Dependencies
52
+
53
+ * The following workspace dependencies were updated
54
+ * dependencies
55
+ * @aigne/core bumped to 1.72.0-beta.18
56
+
57
+ ## [1.3.0-beta.17](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.16...afs-user-profile-memory-v1.3.0-beta.17) (2026-01-12)
58
+
59
+
60
+ ### Dependencies
61
+
62
+ * The following workspace dependencies were updated
63
+ * dependencies
64
+ * @aigne/core bumped to 1.72.0-beta.17
65
+
66
+ ## [1.3.0-beta.16](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.15...afs-user-profile-memory-v1.3.0-beta.16) (2026-01-12)
67
+
68
+
69
+ ### Dependencies
70
+
71
+ * The following workspace dependencies were updated
72
+ * dependencies
73
+ * @aigne/afs bumped to 1.4.0-beta.8
74
+ * @aigne/afs-history bumped to 1.2.0-beta.9
75
+ * @aigne/core bumped to 1.72.0-beta.16
76
+
77
+ ## [1.3.0-beta.15](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.14...afs-user-profile-memory-v1.3.0-beta.15) (2026-01-10)
78
+
79
+
80
+ ### Dependencies
81
+
82
+ * The following workspace dependencies were updated
83
+ * dependencies
84
+ * @aigne/core bumped to 1.72.0-beta.15
85
+
86
+ ## [1.3.0-beta.14](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.13...afs-user-profile-memory-v1.3.0-beta.14) (2026-01-09)
87
+
88
+
89
+ ### Dependencies
90
+
91
+ * The following workspace dependencies were updated
92
+ * dependencies
93
+ * @aigne/core bumped to 1.72.0-beta.14
94
+
95
+ ## [1.3.0-beta.13](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.12...afs-user-profile-memory-v1.3.0-beta.13) (2026-01-08)
96
+
97
+
98
+ ### Bug Fixes
99
+
100
+ * bump version ([696560f](https://github.com/AIGNE-io/aigne-framework/commit/696560fa2673eddcb4d00ac0523fbbbde7273cb3))
101
+
102
+
103
+ ### Dependencies
104
+
105
+ * The following workspace dependencies were updated
106
+ * dependencies
107
+ * @aigne/afs bumped to 1.4.0-beta.7
108
+ * @aigne/afs-history bumped to 1.2.0-beta.8
109
+ * @aigne/core bumped to 1.72.0-beta.13
110
+
111
+ ## [1.3.0-beta.12](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.11...afs-user-profile-memory-v1.3.0-beta.12) (2026-01-07)
112
+
113
+
114
+ ### Dependencies
115
+
116
+ * The following workspace dependencies were updated
117
+ * dependencies
118
+ * @aigne/core bumped to 1.72.0-beta.12
119
+
120
+ ## [1.3.0-beta.11](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.10...afs-user-profile-memory-v1.3.0-beta.11) (2026-01-06)
121
+
122
+
123
+ ### Dependencies
124
+
125
+ * The following workspace dependencies were updated
126
+ * dependencies
127
+ * @aigne/afs bumped to 1.4.0-beta.6
128
+ * @aigne/afs-history bumped to 1.2.0-beta.7
129
+ * @aigne/core bumped to 1.72.0-beta.11
130
+
131
+ ## [1.3.0-beta.10](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.9...afs-user-profile-memory-v1.3.0-beta.10) (2026-01-06)
132
+
133
+
134
+ ### Features
135
+
136
+ * **core:** add cross session user memory support ([#873](https://github.com/AIGNE-io/aigne-framework/issues/873)) ([f377aa1](https://github.com/AIGNE-io/aigne-framework/commit/f377aa17f2cf8004fd3225ade4a37fd90af1292f))
137
+
138
+
139
+ ### Dependencies
140
+
141
+ * The following workspace dependencies were updated
142
+ * dependencies
143
+ * @aigne/afs-history bumped to 1.2.0-beta.6
144
+ * @aigne/core bumped to 1.72.0-beta.10
145
+
146
+ ## [1.3.0-beta.9](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.8...afs-user-profile-memory-v1.3.0-beta.9) (2026-01-02)
147
+
148
+
149
+ ### Dependencies
150
+
151
+ * The following workspace dependencies were updated
152
+ * dependencies
153
+ * @aigne/core bumped to 1.72.0-beta.9
154
+
155
+ ## [1.3.0-beta.8](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.7...afs-user-profile-memory-v1.3.0-beta.8) (2025-12-31)
156
+
157
+
158
+ ### Features
159
+
160
+ * add session compact support for AIAgent ([#863](https://github.com/AIGNE-io/aigne-framework/issues/863)) ([9010918](https://github.com/AIGNE-io/aigne-framework/commit/9010918cd3f18b02b5c60ddc9ed5c34b568d0b28))
161
+
162
+
163
+ ### Dependencies
164
+
165
+ * The following workspace dependencies were updated
166
+ * dependencies
167
+ * @aigne/afs bumped to 1.4.0-beta.5
168
+ * @aigne/afs-history bumped to 1.2.0-beta.5
169
+ * @aigne/core bumped to 1.72.0-beta.8
170
+
171
+ ## [1.3.0-beta.7](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.6...afs-user-profile-memory-v1.3.0-beta.7) (2025-12-26)
172
+
173
+
174
+ ### Dependencies
175
+
176
+ * The following workspace dependencies were updated
177
+ * dependencies
178
+ * @aigne/afs bumped to 1.4.0-beta.4
179
+ * @aigne/afs-history bumped to 1.2.0-beta.4
180
+ * @aigne/core bumped to 1.72.0-beta.7
181
+
182
+ ## [1.3.0-beta.6](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.5...afs-user-profile-memory-v1.3.0-beta.6) (2025-12-25)
183
+
184
+
185
+ ### Dependencies
186
+
187
+ * The following workspace dependencies were updated
188
+ * dependencies
189
+ * @aigne/core bumped to 1.72.0-beta.6
190
+
191
+ ## [1.3.0-beta.5](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.4...afs-user-profile-memory-v1.3.0-beta.5) (2025-12-25)
192
+
193
+
194
+ ### Dependencies
195
+
196
+ * The following workspace dependencies were updated
197
+ * dependencies
198
+ * @aigne/core bumped to 1.72.0-beta.5
199
+
200
+ ## [1.3.0-beta.4](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.3...afs-user-profile-memory-v1.3.0-beta.4) (2025-12-24)
201
+
202
+
203
+ ### Dependencies
204
+
205
+ * The following workspace dependencies were updated
206
+ * dependencies
207
+ * @aigne/afs bumped to 1.4.0-beta.3
208
+ * @aigne/afs-history bumped to 1.2.0-beta.3
209
+ * @aigne/core bumped to 1.72.0-beta.4
210
+
211
+ ## [1.3.0-beta.3](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.2...afs-user-profile-memory-v1.3.0-beta.3) (2025-12-19)
212
+
213
+
214
+ ### Dependencies
215
+
216
+ * The following workspace dependencies were updated
217
+ * dependencies
218
+ * @aigne/core bumped to 1.72.0-beta.3
219
+
3
220
  ## [1.3.0-beta.2](https://github.com/AIGNE-io/aigne-framework/compare/afs-user-profile-memory-v1.3.0-beta.1...afs-user-profile-memory-v1.3.0-beta.2) (2025-12-19)
4
221
 
5
222
 
@@ -1,18 +1,34 @@
1
- import type { AFSEntry, AFSListOptions, AFSListResult, AFSModule, AFSReadResult, AFSRoot, AFSSearchOptions, AFSSearchResult, AFSWriteEntryPayload, AFSWriteResult } from "@aigne/afs";
1
+ import type { AFSAccessMode, AFSEntry, AFSListOptions, AFSListResult, AFSModule, AFSModuleLoadParams, AFSOperationOptions, AFSReadResult, AFSRoot, AFSSearchOptions, AFSSearchResult, AFSWriteEntryPayload, AFSWriteResult } from "@aigne/afs";
2
2
  import { SharedAFSStorage, type SharedAFSStorageOptions } from "@aigne/afs-history";
3
- import { AIAgent, type Context } from "@aigne/core";
4
- import type { z } from "zod";
3
+ import { AIAgent } from "@aigne/core";
4
+ import { z } from "zod";
5
5
  import { userProfileJsonPathSchema } from "./schema.js";
6
6
  export interface UserProfileMemoryOptions {
7
- context: Context;
8
7
  storage?: SharedAFSStorage | SharedAFSStorageOptions;
9
8
  description?: string;
9
+ /**
10
+ * Access mode for this module.
11
+ * @default "readwrite"
12
+ */
13
+ accessMode?: AFSAccessMode;
10
14
  }
11
15
  export declare class UserProfileMemory implements AFSModule {
12
16
  options: UserProfileMemoryOptions;
17
+ static schema(): z.ZodObject<{
18
+ description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
19
+ accessMode: z.ZodType<"readonly" | "readwrite" | undefined, z.ZodTypeDef, "readonly" | "readwrite" | undefined>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ description?: string | undefined;
22
+ accessMode?: "readonly" | "readwrite" | undefined;
23
+ }, {
24
+ description?: string | undefined;
25
+ accessMode?: "readonly" | "readwrite" | undefined;
26
+ }>;
27
+ static load({ parsed }: AFSModuleLoadParams): Promise<UserProfileMemory>;
13
28
  constructor(options: UserProfileMemoryOptions);
14
29
  private storage;
15
30
  readonly name: string;
31
+ readonly accessMode: AFSAccessMode;
16
32
  description?: string | undefined;
17
33
  extractor: AIAgent<{
18
34
  schema: any;
@@ -20,7 +36,7 @@ export declare class UserProfileMemory implements AFSModule {
20
36
  entry: AFSEntry;
21
37
  }, z.infer<typeof userProfileJsonPathSchema>>;
22
38
  onMount(afs: AFSRoot): void;
23
- updateProfile(entry: AFSEntry): Promise<AFSWriteResult>;
39
+ updateProfile(entry: AFSEntry, options?: AFSOperationOptions): Promise<AFSWriteResult>;
24
40
  list(_path: string, _options?: AFSListOptions): Promise<AFSListResult>;
25
41
  read(path: string): Promise<AFSReadResult>;
26
42
  write(path: string, entry: AFSWriteEntryPayload): Promise<AFSWriteResult>;
package/lib/cjs/index.js CHANGED
@@ -3,11 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UserProfileMemory = void 0;
4
4
  const afs_history_1 = require("@aigne/afs-history");
5
5
  const core_1 = require("@aigne/core");
6
+ const schema_js_1 = require("@aigne/core/loader/schema.js");
6
7
  const logger_js_1 = require("@aigne/core/utils/logger.js");
8
+ const uuid_1 = require("@aigne/uuid");
7
9
  const fast_json_patch_1 = require("fast-json-patch");
10
+ const zod_1 = require("zod");
8
11
  const zod_to_json_schema_1 = require("zod-to-json-schema");
9
12
  const prompt_js_1 = require("./prompt.js");
10
- const schema_js_1 = require("./schema.js");
13
+ const schema_js_2 = require("./schema.js");
11
14
  const DEFAULT_DESCRIPTION = `\
12
15
  User Profile Memory: This contains structured information about the user that has been \
13
16
  automatically extracted from previous conversations. It includes personal details such as name, \
@@ -15,8 +18,19 @@ location, interests, family members, projects, and other relevant information th
15
18
  Use this memory to personalize responses and maintain context about the user across conversations. \
16
19
  The profile is continuously updated as new information is learned.
17
20
  `;
21
+ const userProfileMemoryOptionsSchema = (0, schema_js_1.camelizeSchema)(zod_1.z.object({
22
+ description: (0, schema_js_1.optionalize)(zod_1.z.string().describe("Description of the user profile memory")),
23
+ accessMode: (0, schema_js_1.optionalize)(zod_1.z.enum(["readonly", "readwrite"]).describe("Access mode for this module")),
24
+ }));
18
25
  class UserProfileMemory {
19
26
  options;
27
+ static schema() {
28
+ return userProfileMemoryOptionsSchema;
29
+ }
30
+ static async load({ parsed }) {
31
+ const valid = await UserProfileMemory.schema().parseAsync(parsed);
32
+ return new UserProfileMemory(valid);
33
+ }
20
34
  constructor(options) {
21
35
  this.options = options;
22
36
  this.storage =
@@ -24,28 +38,35 @@ class UserProfileMemory {
24
38
  ? options.storage.withModule(this)
25
39
  : new afs_history_1.SharedAFSStorage(options?.storage).withModule(this);
26
40
  this.description = options.description || DEFAULT_DESCRIPTION;
41
+ this.accessMode = options.accessMode ?? "readwrite";
27
42
  }
28
43
  storage;
29
44
  name = "user-profile-memory";
45
+ accessMode;
30
46
  description;
31
47
  extractor = core_1.AIAgent.from({
32
48
  instructions: prompt_js_1.USER_PROFILE_MEMORY_EXTRACTOR_PROMPT,
33
- outputSchema: schema_js_1.userProfileJsonPathSchema,
49
+ outputSchema: schema_js_2.userProfileJsonPathSchema,
34
50
  });
35
51
  onMount(afs) {
36
- afs.on("historyCreated", async ({ entry }) => {
52
+ afs.on("historyCreated", async ({ entry }, options) => {
37
53
  try {
38
- await this.updateProfile(entry);
54
+ await this.updateProfile(entry, options);
39
55
  }
40
56
  catch (error) {
41
57
  logger_js_1.logger.error("Failed to update user profile memory", error);
42
58
  }
43
59
  });
44
60
  }
45
- async updateProfile(entry) {
61
+ async updateProfile(entry, options) {
46
62
  const { data: previous } = await this.read("/");
47
- const { ops } = await this.options.context.newContext({ reset: true }).invoke(this.extractor, {
48
- schema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_js_1.userProfileSchema),
63
+ if (typeof options?.context?.newContext !== "function") {
64
+ throw new Error("Context is not valid for user profile extraction");
65
+ }
66
+ const { ops } = await (options?.context)
67
+ .newContext({ reset: true })
68
+ .invoke(this.extractor, {
69
+ schema: (0, zod_to_json_schema_1.zodToJsonSchema)(schema_js_2.userProfileSchema),
49
70
  profile: previous?.content,
50
71
  entry,
51
72
  });
@@ -60,13 +81,24 @@ class UserProfileMemory {
60
81
  return { data: profile ? [profile] : [] };
61
82
  }
62
83
  async read(path) {
63
- const data = await this.storage.read(path);
84
+ if (path !== "/")
85
+ return {};
86
+ const data = (await this.storage.list({
87
+ orderBy: [["createdAt", "desc"]],
88
+ limit: 1,
89
+ })).data.at(0);
64
90
  if (data)
65
91
  data.description = this.description;
66
92
  return { data };
67
93
  }
68
94
  async write(path, entry) {
69
- const data = await this.storage.create({ ...entry, path });
95
+ const { data: previous } = await this.read("/");
96
+ const data = await this.storage.create({
97
+ ...previous,
98
+ ...entry,
99
+ id: previous?.id || (0, uuid_1.v7)(),
100
+ path,
101
+ });
70
102
  if (data)
71
103
  data.description = this.description;
72
104
  return { data };
@@ -1,18 +1,34 @@
1
- import type { AFSEntry, AFSListOptions, AFSListResult, AFSModule, AFSReadResult, AFSRoot, AFSSearchOptions, AFSSearchResult, AFSWriteEntryPayload, AFSWriteResult } from "@aigne/afs";
1
+ import type { AFSAccessMode, AFSEntry, AFSListOptions, AFSListResult, AFSModule, AFSModuleLoadParams, AFSOperationOptions, AFSReadResult, AFSRoot, AFSSearchOptions, AFSSearchResult, AFSWriteEntryPayload, AFSWriteResult } from "@aigne/afs";
2
2
  import { SharedAFSStorage, type SharedAFSStorageOptions } from "@aigne/afs-history";
3
- import { AIAgent, type Context } from "@aigne/core";
4
- import type { z } from "zod";
3
+ import { AIAgent } from "@aigne/core";
4
+ import { z } from "zod";
5
5
  import { userProfileJsonPathSchema } from "./schema.js";
6
6
  export interface UserProfileMemoryOptions {
7
- context: Context;
8
7
  storage?: SharedAFSStorage | SharedAFSStorageOptions;
9
8
  description?: string;
9
+ /**
10
+ * Access mode for this module.
11
+ * @default "readwrite"
12
+ */
13
+ accessMode?: AFSAccessMode;
10
14
  }
11
15
  export declare class UserProfileMemory implements AFSModule {
12
16
  options: UserProfileMemoryOptions;
17
+ static schema(): z.ZodObject<{
18
+ description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
19
+ accessMode: z.ZodType<"readonly" | "readwrite" | undefined, z.ZodTypeDef, "readonly" | "readwrite" | undefined>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ description?: string | undefined;
22
+ accessMode?: "readonly" | "readwrite" | undefined;
23
+ }, {
24
+ description?: string | undefined;
25
+ accessMode?: "readonly" | "readwrite" | undefined;
26
+ }>;
27
+ static load({ parsed }: AFSModuleLoadParams): Promise<UserProfileMemory>;
13
28
  constructor(options: UserProfileMemoryOptions);
14
29
  private storage;
15
30
  readonly name: string;
31
+ readonly accessMode: AFSAccessMode;
16
32
  description?: string | undefined;
17
33
  extractor: AIAgent<{
18
34
  schema: any;
@@ -20,7 +36,7 @@ export declare class UserProfileMemory implements AFSModule {
20
36
  entry: AFSEntry;
21
37
  }, z.infer<typeof userProfileJsonPathSchema>>;
22
38
  onMount(afs: AFSRoot): void;
23
- updateProfile(entry: AFSEntry): Promise<AFSWriteResult>;
39
+ updateProfile(entry: AFSEntry, options?: AFSOperationOptions): Promise<AFSWriteResult>;
24
40
  list(_path: string, _options?: AFSListOptions): Promise<AFSListResult>;
25
41
  read(path: string): Promise<AFSReadResult>;
26
42
  write(path: string, entry: AFSWriteEntryPayload): Promise<AFSWriteResult>;
@@ -1,18 +1,34 @@
1
- import type { AFSEntry, AFSListOptions, AFSListResult, AFSModule, AFSReadResult, AFSRoot, AFSSearchOptions, AFSSearchResult, AFSWriteEntryPayload, AFSWriteResult } from "@aigne/afs";
1
+ import type { AFSAccessMode, AFSEntry, AFSListOptions, AFSListResult, AFSModule, AFSModuleLoadParams, AFSOperationOptions, AFSReadResult, AFSRoot, AFSSearchOptions, AFSSearchResult, AFSWriteEntryPayload, AFSWriteResult } from "@aigne/afs";
2
2
  import { SharedAFSStorage, type SharedAFSStorageOptions } from "@aigne/afs-history";
3
- import { AIAgent, type Context } from "@aigne/core";
4
- import type { z } from "zod";
3
+ import { AIAgent } from "@aigne/core";
4
+ import { z } from "zod";
5
5
  import { userProfileJsonPathSchema } from "./schema.js";
6
6
  export interface UserProfileMemoryOptions {
7
- context: Context;
8
7
  storage?: SharedAFSStorage | SharedAFSStorageOptions;
9
8
  description?: string;
9
+ /**
10
+ * Access mode for this module.
11
+ * @default "readwrite"
12
+ */
13
+ accessMode?: AFSAccessMode;
10
14
  }
11
15
  export declare class UserProfileMemory implements AFSModule {
12
16
  options: UserProfileMemoryOptions;
17
+ static schema(): z.ZodObject<{
18
+ description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
19
+ accessMode: z.ZodType<"readonly" | "readwrite" | undefined, z.ZodTypeDef, "readonly" | "readwrite" | undefined>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ description?: string | undefined;
22
+ accessMode?: "readonly" | "readwrite" | undefined;
23
+ }, {
24
+ description?: string | undefined;
25
+ accessMode?: "readonly" | "readwrite" | undefined;
26
+ }>;
27
+ static load({ parsed }: AFSModuleLoadParams): Promise<UserProfileMemory>;
13
28
  constructor(options: UserProfileMemoryOptions);
14
29
  private storage;
15
30
  readonly name: string;
31
+ readonly accessMode: AFSAccessMode;
16
32
  description?: string | undefined;
17
33
  extractor: AIAgent<{
18
34
  schema: any;
@@ -20,7 +36,7 @@ export declare class UserProfileMemory implements AFSModule {
20
36
  entry: AFSEntry;
21
37
  }, z.infer<typeof userProfileJsonPathSchema>>;
22
38
  onMount(afs: AFSRoot): void;
23
- updateProfile(entry: AFSEntry): Promise<AFSWriteResult>;
39
+ updateProfile(entry: AFSEntry, options?: AFSOperationOptions): Promise<AFSWriteResult>;
24
40
  list(_path: string, _options?: AFSListOptions): Promise<AFSListResult>;
25
41
  read(path: string): Promise<AFSReadResult>;
26
42
  write(path: string, entry: AFSWriteEntryPayload): Promise<AFSWriteResult>;
package/lib/esm/index.js CHANGED
@@ -1,7 +1,10 @@
1
1
  import { SharedAFSStorage, } from "@aigne/afs-history";
2
2
  import { AIAgent } from "@aigne/core";
3
+ import { camelizeSchema, optionalize } from "@aigne/core/loader/schema.js";
3
4
  import { logger } from "@aigne/core/utils/logger.js";
5
+ import { v7 } from "@aigne/uuid";
4
6
  import { applyPatch } from "fast-json-patch";
7
+ import { z } from "zod";
5
8
  import { zodToJsonSchema } from "zod-to-json-schema";
6
9
  import { USER_PROFILE_MEMORY_EXTRACTOR_PROMPT } from "./prompt.js";
7
10
  import { userProfileJsonPathSchema, userProfileSchema } from "./schema.js";
@@ -12,8 +15,19 @@ location, interests, family members, projects, and other relevant information th
12
15
  Use this memory to personalize responses and maintain context about the user across conversations. \
13
16
  The profile is continuously updated as new information is learned.
14
17
  `;
18
+ const userProfileMemoryOptionsSchema = camelizeSchema(z.object({
19
+ description: optionalize(z.string().describe("Description of the user profile memory")),
20
+ accessMode: optionalize(z.enum(["readonly", "readwrite"]).describe("Access mode for this module")),
21
+ }));
15
22
  export class UserProfileMemory {
16
23
  options;
24
+ static schema() {
25
+ return userProfileMemoryOptionsSchema;
26
+ }
27
+ static async load({ parsed }) {
28
+ const valid = await UserProfileMemory.schema().parseAsync(parsed);
29
+ return new UserProfileMemory(valid);
30
+ }
17
31
  constructor(options) {
18
32
  this.options = options;
19
33
  this.storage =
@@ -21,27 +35,34 @@ export class UserProfileMemory {
21
35
  ? options.storage.withModule(this)
22
36
  : new SharedAFSStorage(options?.storage).withModule(this);
23
37
  this.description = options.description || DEFAULT_DESCRIPTION;
38
+ this.accessMode = options.accessMode ?? "readwrite";
24
39
  }
25
40
  storage;
26
41
  name = "user-profile-memory";
42
+ accessMode;
27
43
  description;
28
44
  extractor = AIAgent.from({
29
45
  instructions: USER_PROFILE_MEMORY_EXTRACTOR_PROMPT,
30
46
  outputSchema: userProfileJsonPathSchema,
31
47
  });
32
48
  onMount(afs) {
33
- afs.on("historyCreated", async ({ entry }) => {
49
+ afs.on("historyCreated", async ({ entry }, options) => {
34
50
  try {
35
- await this.updateProfile(entry);
51
+ await this.updateProfile(entry, options);
36
52
  }
37
53
  catch (error) {
38
54
  logger.error("Failed to update user profile memory", error);
39
55
  }
40
56
  });
41
57
  }
42
- async updateProfile(entry) {
58
+ async updateProfile(entry, options) {
43
59
  const { data: previous } = await this.read("/");
44
- const { ops } = await this.options.context.newContext({ reset: true }).invoke(this.extractor, {
60
+ if (typeof options?.context?.newContext !== "function") {
61
+ throw new Error("Context is not valid for user profile extraction");
62
+ }
63
+ const { ops } = await (options?.context)
64
+ .newContext({ reset: true })
65
+ .invoke(this.extractor, {
45
66
  schema: zodToJsonSchema(userProfileSchema),
46
67
  profile: previous?.content,
47
68
  entry,
@@ -57,13 +78,24 @@ export class UserProfileMemory {
57
78
  return { data: profile ? [profile] : [] };
58
79
  }
59
80
  async read(path) {
60
- const data = await this.storage.read(path);
81
+ if (path !== "/")
82
+ return {};
83
+ const data = (await this.storage.list({
84
+ orderBy: [["createdAt", "desc"]],
85
+ limit: 1,
86
+ })).data.at(0);
61
87
  if (data)
62
88
  data.description = this.description;
63
89
  return { data };
64
90
  }
65
91
  async write(path, entry) {
66
- const data = await this.storage.create({ ...entry, path });
92
+ const { data: previous } = await this.read("/");
93
+ const data = await this.storage.create({
94
+ ...previous,
95
+ ...entry,
96
+ id: previous?.id || v7(),
97
+ path,
98
+ });
67
99
  if (data)
68
100
  data.description = this.description;
69
101
  return { data };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/afs-user-profile-memory",
3
- "version": "1.3.0-beta.2",
3
+ "version": "1.3.0-beta.21",
4
4
  "description": "AIGNE AFS module for user profile memory",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -47,18 +47,20 @@
47
47
  }
48
48
  },
49
49
  "dependencies": {
50
+ "@aigne/uuid": "^13.0.1",
50
51
  "fast-json-patch": "^3.1.1",
51
52
  "zod": "^3.25.67",
52
53
  "zod-to-json-schema": "^3.24.6",
53
- "@aigne/afs-history": "^1.2.0-beta.2",
54
- "@aigne/afs": "^1.4.0-beta.2",
55
- "@aigne/core": "^1.72.0-beta.2"
54
+ "@aigne/afs": "^1.4.0-beta.9",
55
+ "@aigne/afs-history": "^1.2.0-beta.10",
56
+ "@aigne/core": "^1.72.0-beta.21"
56
57
  },
57
58
  "devDependencies": {
58
59
  "@types/bun": "^1.2.22",
59
60
  "npm-run-all": "^4.1.5",
60
61
  "rimraf": "^6.0.1",
61
- "typescript": "^5.9.2"
62
+ "typescript": "^5.9.2",
63
+ "@aigne/test-utils": "^0.5.69-beta.21"
62
64
  },
63
65
  "scripts": {
64
66
  "lint": "tsc --noEmit",