@aigne/afs-history 1.2.0-beta.4 → 1.2.0-beta.6

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 (45) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/lib/cjs/index.d.ts +9 -3
  3. package/lib/cjs/index.js +217 -22
  4. package/lib/cjs/storage/index.d.ts +10 -6
  5. package/lib/cjs/storage/index.js +67 -21
  6. package/lib/cjs/storage/migrate.d.ts +1 -1
  7. package/lib/cjs/storage/migrate.js +14 -5
  8. package/lib/cjs/storage/migrations/003-add-compact-table.d.ts +2 -0
  9. package/lib/cjs/storage/migrations/003-add-compact-table.js +23 -0
  10. package/lib/cjs/storage/migrations/004-add-memory-table.d.ts +2 -0
  11. package/lib/cjs/storage/migrations/004-add-memory-table.js +23 -0
  12. package/lib/cjs/storage/migrations/005-add-indexes.d.ts +2 -0
  13. package/lib/cjs/storage/migrations/005-add-indexes.js +31 -0
  14. package/lib/cjs/storage/models/compact.d.ts +183 -0
  15. package/lib/cjs/storage/models/compact.js +27 -0
  16. package/lib/cjs/storage/models/memory.d.ts +182 -0
  17. package/lib/cjs/storage/models/memory.js +27 -0
  18. package/lib/cjs/storage/type.d.ts +31 -4
  19. package/lib/dts/index.d.ts +9 -3
  20. package/lib/dts/storage/index.d.ts +10 -6
  21. package/lib/dts/storage/migrate.d.ts +1 -1
  22. package/lib/dts/storage/migrations/003-add-compact-table.d.ts +2 -0
  23. package/lib/dts/storage/migrations/004-add-memory-table.d.ts +2 -0
  24. package/lib/dts/storage/migrations/005-add-indexes.d.ts +2 -0
  25. package/lib/dts/storage/models/compact.d.ts +183 -0
  26. package/lib/dts/storage/models/memory.d.ts +182 -0
  27. package/lib/dts/storage/type.d.ts +31 -4
  28. package/lib/esm/index.d.ts +9 -3
  29. package/lib/esm/index.js +217 -22
  30. package/lib/esm/storage/index.d.ts +10 -6
  31. package/lib/esm/storage/index.js +68 -22
  32. package/lib/esm/storage/migrate.d.ts +1 -1
  33. package/lib/esm/storage/migrate.js +14 -5
  34. package/lib/esm/storage/migrations/003-add-compact-table.d.ts +2 -0
  35. package/lib/esm/storage/migrations/003-add-compact-table.js +20 -0
  36. package/lib/esm/storage/migrations/004-add-memory-table.d.ts +2 -0
  37. package/lib/esm/storage/migrations/004-add-memory-table.js +20 -0
  38. package/lib/esm/storage/migrations/005-add-indexes.d.ts +2 -0
  39. package/lib/esm/storage/migrations/005-add-indexes.js +28 -0
  40. package/lib/esm/storage/models/compact.d.ts +183 -0
  41. package/lib/esm/storage/models/compact.js +22 -0
  42. package/lib/esm/storage/models/memory.d.ts +182 -0
  43. package/lib/esm/storage/models/memory.js +22 -0
  44. package/lib/esm/storage/type.d.ts +31 -4
  45. package/package.json +3 -2
@@ -0,0 +1,183 @@
1
+ import type { AFSModule } from "@aigne/afs";
2
+ export declare const compactTableName: (module: AFSModule) => string;
3
+ export declare const compactTable: (module: AFSModule) => import("@aigne/sqlite").SQLiteTableWithColumns<{
4
+ name: string;
5
+ schema: undefined;
6
+ columns: {
7
+ id: import("@aigne/sqlite").SQLiteColumn<{
8
+ name: "id";
9
+ tableName: string;
10
+ dataType: "string";
11
+ columnType: "SQLiteText";
12
+ data: string;
13
+ driverParam: string;
14
+ notNull: true;
15
+ hasDefault: true;
16
+ isPrimaryKey: true;
17
+ isAutoincrement: false;
18
+ hasRuntimeDefault: true;
19
+ enumValues: [string, ...string[]];
20
+ baseColumn: never;
21
+ identity: undefined;
22
+ generated: undefined;
23
+ }, {}, {
24
+ length: number | undefined;
25
+ }>;
26
+ createdAt: import("@aigne/sqlite").SQLiteColumn<{
27
+ name: "createdAt";
28
+ tableName: string;
29
+ dataType: "custom";
30
+ columnType: "SQLiteCustomColumn";
31
+ data: Date;
32
+ driverParam: string;
33
+ notNull: true;
34
+ hasDefault: true;
35
+ isPrimaryKey: false;
36
+ isAutoincrement: false;
37
+ hasRuntimeDefault: true;
38
+ enumValues: undefined;
39
+ baseColumn: never;
40
+ identity: undefined;
41
+ generated: undefined;
42
+ }, {}, {
43
+ sqliteColumnBuilderBrand: "SQLiteCustomColumnBuilderBrand";
44
+ }>;
45
+ updatedAt: import("@aigne/sqlite").SQLiteColumn<{
46
+ name: "updatedAt";
47
+ tableName: string;
48
+ dataType: "custom";
49
+ columnType: "SQLiteCustomColumn";
50
+ data: Date;
51
+ driverParam: string;
52
+ notNull: true;
53
+ hasDefault: true;
54
+ isPrimaryKey: false;
55
+ isAutoincrement: false;
56
+ hasRuntimeDefault: true;
57
+ enumValues: undefined;
58
+ baseColumn: never;
59
+ identity: undefined;
60
+ generated: undefined;
61
+ }, {}, {
62
+ sqliteColumnBuilderBrand: "SQLiteCustomColumnBuilderBrand";
63
+ }>;
64
+ path: import("@aigne/sqlite").SQLiteColumn<{
65
+ name: "path";
66
+ tableName: string;
67
+ dataType: "string";
68
+ columnType: "SQLiteText";
69
+ data: string;
70
+ driverParam: string;
71
+ notNull: true;
72
+ hasDefault: false;
73
+ isPrimaryKey: false;
74
+ isAutoincrement: false;
75
+ hasRuntimeDefault: false;
76
+ enumValues: [string, ...string[]];
77
+ baseColumn: never;
78
+ identity: undefined;
79
+ generated: undefined;
80
+ }, {}, {
81
+ length: number | undefined;
82
+ }>;
83
+ userId: import("@aigne/sqlite").SQLiteColumn<{
84
+ name: "userId";
85
+ tableName: string;
86
+ dataType: "string";
87
+ columnType: "SQLiteText";
88
+ data: string;
89
+ driverParam: string;
90
+ notNull: false;
91
+ hasDefault: false;
92
+ isPrimaryKey: false;
93
+ isAutoincrement: false;
94
+ hasRuntimeDefault: false;
95
+ enumValues: [string, ...string[]];
96
+ baseColumn: never;
97
+ identity: undefined;
98
+ generated: undefined;
99
+ }, {}, {
100
+ length: number | undefined;
101
+ }>;
102
+ sessionId: import("@aigne/sqlite").SQLiteColumn<{
103
+ name: "sessionId";
104
+ tableName: string;
105
+ dataType: "string";
106
+ columnType: "SQLiteText";
107
+ data: string;
108
+ driverParam: string;
109
+ notNull: false;
110
+ hasDefault: false;
111
+ isPrimaryKey: false;
112
+ isAutoincrement: false;
113
+ hasRuntimeDefault: false;
114
+ enumValues: [string, ...string[]];
115
+ baseColumn: never;
116
+ identity: undefined;
117
+ generated: undefined;
118
+ }, {}, {
119
+ length: number | undefined;
120
+ }>;
121
+ agentId: import("@aigne/sqlite").SQLiteColumn<{
122
+ name: "agentId";
123
+ tableName: string;
124
+ dataType: "string";
125
+ columnType: "SQLiteText";
126
+ data: string;
127
+ driverParam: string;
128
+ notNull: false;
129
+ hasDefault: false;
130
+ isPrimaryKey: false;
131
+ isAutoincrement: false;
132
+ hasRuntimeDefault: false;
133
+ enumValues: [string, ...string[]];
134
+ baseColumn: never;
135
+ identity: undefined;
136
+ generated: undefined;
137
+ }, {}, {
138
+ length: number | undefined;
139
+ }>;
140
+ metadata: import("@aigne/sqlite").SQLiteColumn<{
141
+ name: string;
142
+ tableName: string;
143
+ dataType: "custom";
144
+ columnType: "SQLiteCustomColumn";
145
+ data: {
146
+ scope?: string;
147
+ latestEntryId?: string;
148
+ } & Record<string, unknown>;
149
+ driverParam: string;
150
+ notNull: false;
151
+ hasDefault: false;
152
+ isPrimaryKey: false;
153
+ isAutoincrement: false;
154
+ hasRuntimeDefault: false;
155
+ enumValues: undefined;
156
+ baseColumn: never;
157
+ identity: undefined;
158
+ generated: undefined;
159
+ }, {}, {
160
+ sqliteColumnBuilderBrand: "SQLiteCustomColumnBuilderBrand";
161
+ }>;
162
+ content: import("@aigne/sqlite").SQLiteColumn<{
163
+ name: string;
164
+ tableName: string;
165
+ dataType: "custom";
166
+ columnType: "SQLiteCustomColumn";
167
+ data: unknown;
168
+ driverParam: string;
169
+ notNull: false;
170
+ hasDefault: false;
171
+ isPrimaryKey: false;
172
+ isAutoincrement: false;
173
+ hasRuntimeDefault: false;
174
+ enumValues: undefined;
175
+ baseColumn: never;
176
+ identity: undefined;
177
+ generated: undefined;
178
+ }, {}, {
179
+ sqliteColumnBuilderBrand: "SQLiteCustomColumnBuilderBrand";
180
+ }>;
181
+ };
182
+ dialect: "sqlite";
183
+ }>;
@@ -0,0 +1,182 @@
1
+ import type { AFSModule } from "@aigne/afs";
2
+ export declare const memoryTableName: (module: AFSModule) => string;
3
+ export declare const memoryTable: (module: AFSModule) => import("@aigne/sqlite").SQLiteTableWithColumns<{
4
+ name: string;
5
+ schema: undefined;
6
+ columns: {
7
+ id: import("@aigne/sqlite").SQLiteColumn<{
8
+ name: "id";
9
+ tableName: string;
10
+ dataType: "string";
11
+ columnType: "SQLiteText";
12
+ data: string;
13
+ driverParam: string;
14
+ notNull: true;
15
+ hasDefault: true;
16
+ isPrimaryKey: true;
17
+ isAutoincrement: false;
18
+ hasRuntimeDefault: true;
19
+ enumValues: [string, ...string[]];
20
+ baseColumn: never;
21
+ identity: undefined;
22
+ generated: undefined;
23
+ }, {}, {
24
+ length: number | undefined;
25
+ }>;
26
+ createdAt: import("@aigne/sqlite").SQLiteColumn<{
27
+ name: "createdAt";
28
+ tableName: string;
29
+ dataType: "custom";
30
+ columnType: "SQLiteCustomColumn";
31
+ data: Date;
32
+ driverParam: string;
33
+ notNull: true;
34
+ hasDefault: true;
35
+ isPrimaryKey: false;
36
+ isAutoincrement: false;
37
+ hasRuntimeDefault: true;
38
+ enumValues: undefined;
39
+ baseColumn: never;
40
+ identity: undefined;
41
+ generated: undefined;
42
+ }, {}, {
43
+ sqliteColumnBuilderBrand: "SQLiteCustomColumnBuilderBrand";
44
+ }>;
45
+ updatedAt: import("@aigne/sqlite").SQLiteColumn<{
46
+ name: "updatedAt";
47
+ tableName: string;
48
+ dataType: "custom";
49
+ columnType: "SQLiteCustomColumn";
50
+ data: Date;
51
+ driverParam: string;
52
+ notNull: true;
53
+ hasDefault: true;
54
+ isPrimaryKey: false;
55
+ isAutoincrement: false;
56
+ hasRuntimeDefault: true;
57
+ enumValues: undefined;
58
+ baseColumn: never;
59
+ identity: undefined;
60
+ generated: undefined;
61
+ }, {}, {
62
+ sqliteColumnBuilderBrand: "SQLiteCustomColumnBuilderBrand";
63
+ }>;
64
+ path: import("@aigne/sqlite").SQLiteColumn<{
65
+ name: "path";
66
+ tableName: string;
67
+ dataType: "string";
68
+ columnType: "SQLiteText";
69
+ data: string;
70
+ driverParam: string;
71
+ notNull: true;
72
+ hasDefault: false;
73
+ isPrimaryKey: false;
74
+ isAutoincrement: false;
75
+ hasRuntimeDefault: false;
76
+ enumValues: [string, ...string[]];
77
+ baseColumn: never;
78
+ identity: undefined;
79
+ generated: undefined;
80
+ }, {}, {
81
+ length: number | undefined;
82
+ }>;
83
+ userId: import("@aigne/sqlite").SQLiteColumn<{
84
+ name: "userId";
85
+ tableName: string;
86
+ dataType: "string";
87
+ columnType: "SQLiteText";
88
+ data: string;
89
+ driverParam: string;
90
+ notNull: false;
91
+ hasDefault: false;
92
+ isPrimaryKey: false;
93
+ isAutoincrement: false;
94
+ hasRuntimeDefault: false;
95
+ enumValues: [string, ...string[]];
96
+ baseColumn: never;
97
+ identity: undefined;
98
+ generated: undefined;
99
+ }, {}, {
100
+ length: number | undefined;
101
+ }>;
102
+ sessionId: import("@aigne/sqlite").SQLiteColumn<{
103
+ name: "sessionId";
104
+ tableName: string;
105
+ dataType: "string";
106
+ columnType: "SQLiteText";
107
+ data: string;
108
+ driverParam: string;
109
+ notNull: false;
110
+ hasDefault: false;
111
+ isPrimaryKey: false;
112
+ isAutoincrement: false;
113
+ hasRuntimeDefault: false;
114
+ enumValues: [string, ...string[]];
115
+ baseColumn: never;
116
+ identity: undefined;
117
+ generated: undefined;
118
+ }, {}, {
119
+ length: number | undefined;
120
+ }>;
121
+ agentId: import("@aigne/sqlite").SQLiteColumn<{
122
+ name: "agentId";
123
+ tableName: string;
124
+ dataType: "string";
125
+ columnType: "SQLiteText";
126
+ data: string;
127
+ driverParam: string;
128
+ notNull: false;
129
+ hasDefault: false;
130
+ isPrimaryKey: false;
131
+ isAutoincrement: false;
132
+ hasRuntimeDefault: false;
133
+ enumValues: [string, ...string[]];
134
+ baseColumn: never;
135
+ identity: undefined;
136
+ generated: undefined;
137
+ }, {}, {
138
+ length: number | undefined;
139
+ }>;
140
+ metadata: import("@aigne/sqlite").SQLiteColumn<{
141
+ name: string;
142
+ tableName: string;
143
+ dataType: "custom";
144
+ columnType: "SQLiteCustomColumn";
145
+ data: {
146
+ scope?: string;
147
+ } & Record<string, unknown>;
148
+ driverParam: string;
149
+ notNull: false;
150
+ hasDefault: false;
151
+ isPrimaryKey: false;
152
+ isAutoincrement: false;
153
+ hasRuntimeDefault: false;
154
+ enumValues: undefined;
155
+ baseColumn: never;
156
+ identity: undefined;
157
+ generated: undefined;
158
+ }, {}, {
159
+ sqliteColumnBuilderBrand: "SQLiteCustomColumnBuilderBrand";
160
+ }>;
161
+ content: import("@aigne/sqlite").SQLiteColumn<{
162
+ name: string;
163
+ tableName: string;
164
+ dataType: "custom";
165
+ columnType: "SQLiteCustomColumn";
166
+ data: unknown;
167
+ driverParam: string;
168
+ notNull: false;
169
+ hasDefault: false;
170
+ isPrimaryKey: false;
171
+ isAutoincrement: false;
172
+ hasRuntimeDefault: false;
173
+ enumValues: undefined;
174
+ baseColumn: never;
175
+ identity: undefined;
176
+ generated: undefined;
177
+ }, {}, {
178
+ sqliteColumnBuilderBrand: "SQLiteCustomColumnBuilderBrand";
179
+ }>;
180
+ };
181
+ dialect: "sqlite";
182
+ }>;
@@ -1,22 +1,49 @@
1
1
  import type { AFSEntry, AFSModule } from "@aigne/afs";
2
2
  import type { SQL } from "@aigne/sqlite";
3
- export interface AFSStorageCreatePayload extends Omit<AFSEntry, "id"> {
3
+ export interface AFSStorageCreatePayload extends AFSEntry {
4
4
  }
5
- export interface AFSStorageListOptions {
5
+ export interface AFSStorageTypeOptions {
6
+ type?: EntryType;
7
+ scope?: Scope;
8
+ }
9
+ export interface AFSStorageListOptions extends AFSStorageTypeOptions {
6
10
  filter?: {
7
11
  agentId?: string;
8
12
  userId?: string;
9
13
  sessionId?: string;
14
+ before?: Date | string;
15
+ after?: Date | string;
10
16
  };
11
17
  limit?: number;
12
18
  orderBy?: [string, "asc" | "desc"][];
13
19
  }
20
+ export interface AFSStorageReadOptions extends AFSStorageTypeOptions {
21
+ filter?: {
22
+ agentId?: string;
23
+ userId?: string;
24
+ sessionId?: string;
25
+ };
26
+ }
27
+ export interface AFSStorageDeleteOptions extends AFSStorageTypeOptions {
28
+ filter?: {
29
+ agentId?: string;
30
+ userId?: string;
31
+ sessionId?: string;
32
+ };
33
+ }
34
+ export type EntryType = "history" | "compact" | "memory";
35
+ export type Scope = "session" | "user" | "agent";
36
+ export interface AFSStorageCreateOptions extends AFSStorageTypeOptions {
37
+ }
14
38
  export interface AFSStorage {
15
- create(entry: AFSStorageCreatePayload): Promise<AFSEntry>;
39
+ create(entry: AFSStorageCreatePayload, options?: AFSStorageCreateOptions): Promise<AFSEntry>;
16
40
  list(options?: AFSStorageListOptions): Promise<{
17
41
  data: AFSEntry[];
18
42
  }>;
19
- read(path: string): Promise<AFSEntry | undefined>;
43
+ read(id: string, options?: AFSStorageReadOptions): Promise<AFSEntry | undefined>;
44
+ delete(id: string, options?: AFSStorageDeleteOptions): Promise<{
45
+ deletedCount: number;
46
+ }>;
20
47
  }
21
48
  export type AFSStorageMigrations = {
22
49
  hash: string;
@@ -1,4 +1,4 @@
1
- import type { AFSListOptions, AFSListResult, AFSModule, AFSReadResult, AFSRoot } from "@aigne/afs";
1
+ import type { AFSDeleteOptions, AFSDeleteResult, AFSListOptions, AFSListResult, AFSModule, AFSReadOptions, AFSReadResult, AFSRoot, AFSWriteEntryPayload, AFSWriteResult } from "@aigne/afs";
2
2
  import { SharedAFSStorage, type SharedAFSStorageOptions } from "./storage/index.js";
3
3
  export * from "./storage/index.js";
4
4
  export interface AFSHistoryOptions {
@@ -6,9 +6,15 @@ export interface AFSHistoryOptions {
6
6
  }
7
7
  export declare class AFSHistory implements AFSModule {
8
8
  constructor(options?: AFSHistoryOptions);
9
- private storage;
10
9
  readonly name: string;
10
+ private storage;
11
+ private afs?;
12
+ private router;
13
+ private rootEntries;
11
14
  onMount(afs: AFSRoot): void;
12
15
  list(path: string, options?: AFSListOptions): Promise<AFSListResult>;
13
- read(path: string): Promise<AFSReadResult>;
16
+ read(path: string, options?: AFSReadOptions): Promise<AFSReadResult>;
17
+ write(path: string, content: AFSWriteEntryPayload): Promise<AFSWriteResult>;
18
+ delete(path: string, _options?: AFSDeleteOptions): Promise<AFSDeleteResult>;
19
+ private normalizePath;
14
20
  }
package/lib/esm/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { v7 } from "@aigne/uuid";
2
+ import { createRouter } from "radix3";
2
3
  import { joinURL } from "ufo";
3
4
  import { SharedAFSStorage, } from "./storage/index.js";
4
5
  export * from "./storage/index.js";
@@ -9,33 +10,227 @@ export class AFSHistory {
9
10
  ? options.storage.withModule(this)
10
11
  : new SharedAFSStorage(options?.storage).withModule(this);
11
12
  }
12
- storage;
13
13
  name = "history";
14
+ storage;
15
+ afs;
16
+ router = createRouter({
17
+ routes: {
18
+ "/by-session": { action: "list", type: "history", scope: "session" },
19
+ "/by-session/:sessionId": { action: "list", type: "history", scope: "session" },
20
+ "/by-session/:sessionId/new": { action: "create", type: "history", scope: "session" },
21
+ "/by-session/:sessionId/@metadata/compact": {
22
+ action: "list",
23
+ type: "compact",
24
+ scope: "session",
25
+ },
26
+ "/by-session/:sessionId/@metadata/compact/new": {
27
+ action: "create",
28
+ type: "compact",
29
+ scope: "session",
30
+ },
31
+ "/by-session/:sessionId/@metadata/compact/:compactId": {
32
+ action: "read",
33
+ type: "compact",
34
+ scope: "session",
35
+ },
36
+ "/by-session/:sessionId/@metadata/memory": {
37
+ action: "list",
38
+ type: "memory",
39
+ scope: "session",
40
+ },
41
+ "/by-session/:sessionId/@metadata/memory/new": {
42
+ action: "create",
43
+ type: "memory",
44
+ scope: "session",
45
+ },
46
+ "/by-session/:sessionId/@metadata/memory/:memoryId": {
47
+ action: "read",
48
+ type: "memory",
49
+ scope: "session",
50
+ },
51
+ "/by-session/:sessionId/:entryId": { action: "read", type: "history", scope: "session" },
52
+ "/by-user": { action: "list", type: "history", scope: "user" },
53
+ "/by-user/:userId": { action: "list", type: "history", scope: "user" },
54
+ "/by-user/:userId/new": { action: "create", type: "history", scope: "user" },
55
+ "/by-user/:userId/@metadata/compact": { action: "list", type: "compact", scope: "user" },
56
+ "/by-user/:userId/@metadata/compact/new": {
57
+ action: "create",
58
+ type: "compact",
59
+ scope: "user",
60
+ },
61
+ "/by-user/:userId/@metadata/compact/:compactId": {
62
+ action: "read",
63
+ type: "compact",
64
+ scope: "user",
65
+ },
66
+ "/by-user/:userId/@metadata/memory": { action: "list", type: "memory", scope: "user" },
67
+ "/by-user/:userId/@metadata/memory/new": { action: "create", type: "memory", scope: "user" },
68
+ "/by-user/:userId/@metadata/memory/:memoryId": {
69
+ action: "read",
70
+ type: "memory",
71
+ scope: "user",
72
+ },
73
+ "/by-user/:userId/:entryId": { action: "read", type: "history", scope: "user" },
74
+ "/by-agent": { action: "list", type: "history", scope: "agent" },
75
+ "/by-agent/:agentId": { action: "list", type: "history", scope: "agent" },
76
+ "/by-agent/:agentId/new": { action: "create", type: "history", scope: "agent" },
77
+ "/by-agent/:agentId/@metadata/compact": { action: "list", type: "compact", scope: "agent" },
78
+ "/by-agent/:agentId/@metadata/compact/new": {
79
+ action: "create",
80
+ type: "compact",
81
+ scope: "agent",
82
+ },
83
+ "/by-agent/:agentId/@metadata/compact/:compactId": {
84
+ action: "read",
85
+ type: "compact",
86
+ scope: "agent",
87
+ },
88
+ "/by-agent/:agentId/:entryId": { action: "read", type: "history", scope: "agent" },
89
+ },
90
+ });
91
+ rootEntries = [
92
+ {
93
+ id: "by-session",
94
+ path: "/by-session",
95
+ description: "Retrieve history entries by session ID.",
96
+ },
97
+ {
98
+ id: "by-user",
99
+ path: "/by-user",
100
+ description: "Retrieve history entries by user ID.",
101
+ },
102
+ {
103
+ id: "by-agent",
104
+ path: "/by-agent",
105
+ description: "Retrieve history entries by agent ID.",
106
+ },
107
+ ];
14
108
  onMount(afs) {
15
- afs.on("agentSucceed", ({ agentId, userId, sessionId, input, output, messages }) => {
16
- this.storage
17
- .create({
18
- path: joinURL("/", v7()),
19
- agentId,
20
- userId,
21
- sessionId,
22
- content: { input, output, messages },
23
- })
24
- .then((entry) => {
25
- afs.emit("historyCreated", { entry });
26
- })
27
- .catch((error) => {
28
- console.error("Failed to store history entry", error);
29
- });
30
- });
109
+ this.afs = afs;
31
110
  }
32
111
  async list(path, options) {
33
- if (path !== "/")
112
+ if (path === "/")
113
+ return { data: this.rootEntries };
114
+ const match = this.router.lookup(path);
115
+ if (!match || match.action !== "list") {
34
116
  return { data: [] };
35
- return await this.storage.list(options);
117
+ }
118
+ const { type, scope } = match;
119
+ const mergedFilter = {
120
+ ...options?.filter,
121
+ ...match.params,
122
+ };
123
+ const result = await this.storage.list({
124
+ ...options,
125
+ type,
126
+ scope,
127
+ filter: mergedFilter,
128
+ });
129
+ return {
130
+ ...result,
131
+ data: result.data.map((entry) => ({
132
+ ...entry,
133
+ path: this.normalizePath(entry, scope, type),
134
+ })),
135
+ };
136
+ }
137
+ async read(path, options) {
138
+ const match = this.router.lookup(path);
139
+ if (!match || match.action !== "read")
140
+ return {};
141
+ const { type, scope } = match;
142
+ const entryId = match.params?.entryId ?? match.params?.compactId ?? match.params?.memoryId;
143
+ if (!entryId)
144
+ throw new Error(`Entry ID is required in the path to read ${type}.`);
145
+ const mergedFilter = {
146
+ ...options?.filter,
147
+ ...match.params,
148
+ };
149
+ const data = await this.storage.read(entryId, {
150
+ type,
151
+ scope,
152
+ filter: mergedFilter,
153
+ });
154
+ // Add virtual path prefix for entries
155
+ return {
156
+ data: data && {
157
+ ...data,
158
+ path: this.normalizePath(data, scope, type),
159
+ },
160
+ };
161
+ }
162
+ async write(path, content) {
163
+ const id = v7();
164
+ const match = this.router.lookup(path);
165
+ if (!match || match.action !== "create") {
166
+ throw new Error("Can only write to paths with 'new' suffix: /by-{scope}/{scopeId}/new or /by-{scope}/{scopeId}/@metadata/{type}/new");
167
+ }
168
+ const { type, scope } = match;
169
+ // Validate that scope ID is provided in path params
170
+ const scopeIdField = `${scope}Id`;
171
+ const scopeIdValue = match.params?.[scopeIdField];
172
+ if (!scopeIdValue) {
173
+ throw new Error(`${scopeIdField} is required in the path to create ${type} entry.`);
174
+ }
175
+ const entry = await this.storage.create({
176
+ ...match.params,
177
+ ...content,
178
+ id,
179
+ path: joinURL("/", type, id),
180
+ }, { type, scope });
181
+ // Emit event for history entries
182
+ if (type === "history") {
183
+ this.afs?.emit("historyCreated", { entry });
184
+ }
185
+ return {
186
+ data: {
187
+ ...entry,
188
+ path: this.normalizePath(entry, scope, type),
189
+ },
190
+ };
191
+ }
192
+ async delete(path, _options) {
193
+ const match = this.router.lookup(path);
194
+ if (!match || match.action !== "read") {
195
+ throw new Error(`Cannot delete: path not found or not a valid entry path`);
196
+ }
197
+ const { type, scope } = match;
198
+ const entryId = match.params?.entryId ?? match.params?.compactId ?? match.params?.memoryId;
199
+ if (!entryId)
200
+ throw new Error(`Entry ID is required in the path to delete ${type}.`);
201
+ const result = await this.storage.delete(entryId, {
202
+ type,
203
+ scope,
204
+ filter: match.params,
205
+ });
206
+ if (result.deletedCount === 0) {
207
+ return {
208
+ message: `No ${type} entry found with id ${entryId}`,
209
+ };
210
+ }
211
+ return {
212
+ message: `Deleted ${result.deletedCount} ${type} entry`,
213
+ };
36
214
  }
37
- async read(path) {
38
- const data = await this.storage.read(path);
39
- return { data };
215
+ normalizePath(entry, scope, entryType) {
216
+ const scopeIdMap = {
217
+ session: entry.sessionId,
218
+ user: entry.userId,
219
+ agent: entry.agentId,
220
+ };
221
+ const scopeId = scopeIdMap[scope];
222
+ if (!scopeId) {
223
+ throw new Error(`Cannot reset path for entry without ${scope} info.`);
224
+ }
225
+ const prefix = `by-${scope}`;
226
+ // Build path based on entry type
227
+ if (entryType === "compact") {
228
+ return joinURL("/", prefix, scopeId, "@metadata/compact", entry.id);
229
+ }
230
+ if (entryType === "memory") {
231
+ return joinURL("/", prefix, scopeId, "@metadata/memory", entry.id);
232
+ }
233
+ // Default: history entry
234
+ return joinURL("/", prefix, scopeId, entry.id);
40
235
  }
41
236
  }