@aigne/afs-history 1.2.0-beta.3 → 1.2.0-beta.5

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 (40) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/lib/cjs/index.d.ts +8 -3
  3. package/lib/cjs/index.js +193 -21
  4. package/lib/cjs/storage/index.d.ts +11 -5
  5. package/lib/cjs/storage/index.js +67 -18
  6. package/lib/cjs/storage/migrate.d.ts +1 -1
  7. package/lib/cjs/storage/migrate.js +7 -5
  8. package/lib/cjs/storage/migrations/002-add-agent-id.d.ts +2 -0
  9. package/lib/cjs/storage/migrations/002-add-agent-id.js +13 -0
  10. package/lib/cjs/storage/migrations/003-add-compact-table.d.ts +2 -0
  11. package/lib/cjs/storage/migrations/003-add-compact-table.js +23 -0
  12. package/lib/cjs/storage/models/compact.d.ts +183 -0
  13. package/lib/cjs/storage/models/compact.js +27 -0
  14. package/lib/cjs/storage/models/entries.d.ts +19 -0
  15. package/lib/cjs/storage/models/entries.js +1 -0
  16. package/lib/cjs/storage/type.d.ts +18 -2
  17. package/lib/dts/index.d.ts +8 -3
  18. package/lib/dts/storage/index.d.ts +11 -5
  19. package/lib/dts/storage/migrate.d.ts +1 -1
  20. package/lib/dts/storage/migrations/002-add-agent-id.d.ts +2 -0
  21. package/lib/dts/storage/migrations/003-add-compact-table.d.ts +2 -0
  22. package/lib/dts/storage/models/compact.d.ts +183 -0
  23. package/lib/dts/storage/models/entries.d.ts +19 -0
  24. package/lib/dts/storage/type.d.ts +18 -2
  25. package/lib/esm/index.d.ts +8 -3
  26. package/lib/esm/index.js +193 -21
  27. package/lib/esm/storage/index.d.ts +11 -5
  28. package/lib/esm/storage/index.js +68 -19
  29. package/lib/esm/storage/migrate.d.ts +1 -1
  30. package/lib/esm/storage/migrate.js +7 -5
  31. package/lib/esm/storage/migrations/002-add-agent-id.d.ts +2 -0
  32. package/lib/esm/storage/migrations/002-add-agent-id.js +10 -0
  33. package/lib/esm/storage/migrations/003-add-compact-table.d.ts +2 -0
  34. package/lib/esm/storage/migrations/003-add-compact-table.js +20 -0
  35. package/lib/esm/storage/models/compact.d.ts +183 -0
  36. package/lib/esm/storage/models/compact.js +22 -0
  37. package/lib/esm/storage/models/entries.d.ts +19 -0
  38. package/lib/esm/storage/models/entries.js +1 -0
  39. package/lib/esm/storage/type.d.ts +18 -2
  40. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -6,6 +6,34 @@
6
6
  * dependencies
7
7
  * @aigne/afs bumped to 1.2.0
8
8
 
9
+ ## [1.2.0-beta.5](https://github.com/AIGNE-io/aigne-framework/compare/afs-history-v1.2.0-beta.4...afs-history-v1.2.0-beta.5) (2025-12-31)
10
+
11
+
12
+ ### Features
13
+
14
+ * 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))
15
+
16
+
17
+ ### Dependencies
18
+
19
+ * The following workspace dependencies were updated
20
+ * dependencies
21
+ * @aigne/afs bumped to 1.4.0-beta.5
22
+
23
+ ## [1.2.0-beta.4](https://github.com/AIGNE-io/aigne-framework/compare/afs-history-v1.2.0-beta.3...afs-history-v1.2.0-beta.4) (2025-12-26)
24
+
25
+
26
+ ### Features
27
+
28
+ * **core:** add session history support ([#858](https://github.com/AIGNE-io/aigne-framework/issues/858)) ([28a070e](https://github.com/AIGNE-io/aigne-framework/commit/28a070ed33b821d1fd344b899706d817ca992b9f))
29
+
30
+
31
+ ### Dependencies
32
+
33
+ * The following workspace dependencies were updated
34
+ * dependencies
35
+ * @aigne/afs bumped to 1.4.0-beta.4
36
+
9
37
  ## [1.2.0-beta.3](https://github.com/AIGNE-io/aigne-framework/compare/afs-history-v1.2.0-beta.2...afs-history-v1.2.0-beta.3) (2025-12-24)
10
38
 
11
39
 
@@ -1,4 +1,4 @@
1
- import type { AFSListOptions, AFSListResult, AFSModule, AFSReadResult, AFSRoot, AFSWriteEntryPayload, AFSWriteResult } from "@aigne/afs";
1
+ import type { 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,10 +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>;
14
17
  write(path: string, content: AFSWriteEntryPayload): Promise<AFSWriteResult>;
18
+ private getCompactType;
19
+ private normalizePath;
15
20
  }
package/lib/cjs/index.js CHANGED
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.AFSHistory = void 0;
18
18
  const uuid_1 = require("@aigne/uuid");
19
+ const radix3_1 = require("radix3");
19
20
  const ufo_1 = require("ufo");
20
21
  const index_js_1 = require("./storage/index.js");
21
22
  __exportStar(require("./storage/index.js"), exports);
@@ -26,35 +27,206 @@ class AFSHistory {
26
27
  ? options.storage.withModule(this)
27
28
  : new index_js_1.SharedAFSStorage(options?.storage).withModule(this);
28
29
  }
29
- storage;
30
30
  name = "history";
31
+ storage;
32
+ afs;
33
+ router = (0, radix3_1.createRouter)({
34
+ routes: {
35
+ "/new": { type: "root", id: "new-history" },
36
+ "/by-session": { type: "root", id: "by-session" },
37
+ "/by-session/:sessionId": { type: "list", id: "by-session" },
38
+ "/by-session/:sessionId/@metadata/compact": { type: "compact-list", id: "by-session" },
39
+ "/by-session/:sessionId/@metadata/compact/new": { type: "compact-new", id: "by-session" },
40
+ "/by-session/:sessionId/@metadata/compact/:compactId": {
41
+ type: "compact-detail",
42
+ id: "by-session",
43
+ },
44
+ "/by-session/:sessionId/:entryId": { type: "detail", id: "by-session" },
45
+ "/by-user": { type: "root", id: "by-user" },
46
+ "/by-user/:userId": { type: "list", id: "by-user" },
47
+ "/by-user/:userId/@metadata/compact": { type: "compact-list", id: "by-user" },
48
+ "/by-user/:userId/@metadata/compact/new": { type: "compact-new", id: "by-user" },
49
+ "/by-user/:userId/@metadata/compact/:compactId": { type: "compact-detail", id: "by-user" },
50
+ "/by-user/:userId/:entryId": { type: "detail", id: "by-user" },
51
+ "/by-agent": { type: "root", id: "by-agent" },
52
+ "/by-agent/:agentId": { type: "list", id: "by-agent" },
53
+ "/by-agent/:agentId/@metadata/compact": { type: "compact-list", id: "by-agent" },
54
+ "/by-agent/:agentId/@metadata/compact/new": { type: "compact-new", id: "by-agent" },
55
+ "/by-agent/:agentId/@metadata/compact/:compactId": { type: "compact-detail", id: "by-agent" },
56
+ "/by-agent/:agentId/:entryId": { type: "detail", id: "by-agent" },
57
+ },
58
+ });
59
+ rootEntries = [
60
+ {
61
+ id: "new-history",
62
+ path: "/new",
63
+ description: "Write to this path to create a new history entry, generating a UUID-based path.",
64
+ },
65
+ {
66
+ id: "by-session",
67
+ path: "/by-session",
68
+ description: "Retrieve history entries by session ID.",
69
+ },
70
+ {
71
+ id: "by-user",
72
+ path: "/by-user",
73
+ description: "Retrieve history entries by user ID.",
74
+ },
75
+ {
76
+ id: "by-agent",
77
+ path: "/by-agent",
78
+ description: "Retrieve history entries by agent ID.",
79
+ },
80
+ ];
31
81
  onMount(afs) {
32
- afs.on("agentSucceed", ({ input, output }) => {
33
- this.storage
34
- .create({
35
- path: (0, ufo_1.joinURL)("/", (0, uuid_1.v7)()),
36
- content: { input, output },
37
- })
38
- .then((entry) => {
39
- afs.emit("historyCreated", { entry });
40
- })
41
- .catch((error) => {
42
- console.error("Failed to store history entry", error);
43
- });
44
- });
82
+ this.afs = afs;
45
83
  }
46
84
  async list(path, options) {
47
- if (path !== "/")
85
+ if (path === "/")
86
+ return { data: this.rootEntries };
87
+ // Parse virtual path and extract filter conditions
88
+ const match = this.router.lookup(path);
89
+ // If path doesn't match any virtual path pattern, return empty
90
+ if (!match) {
48
91
  return { data: [] };
49
- return await this.storage.list(options);
92
+ }
93
+ const rootEntry = this.rootEntries.find((entry) => entry.path === `/${match.id}`);
94
+ if (!rootEntry)
95
+ return { data: [] };
96
+ if (match.type === "root") {
97
+ return { data: [rootEntry] };
98
+ }
99
+ const matchId = match.id;
100
+ if (match.type === "list" &&
101
+ (matchId === "by-session" || matchId === "by-user" || matchId === "by-agent")) {
102
+ // Merge virtual path filter with explicit filter options
103
+ const mergedFilter = {
104
+ ...options?.filter,
105
+ ...match.params,
106
+ };
107
+ const result = await this.storage.list({
108
+ ...options,
109
+ filter: mergedFilter,
110
+ });
111
+ // Add virtual path prefix to each entry's path
112
+ return {
113
+ ...result,
114
+ data: result.data.map((entry) => ({
115
+ ...entry,
116
+ path: this.normalizePath(entry, matchId),
117
+ })),
118
+ };
119
+ }
120
+ if (match.type === "compact-list" &&
121
+ (matchId === "by-session" || matchId === "by-user" || matchId === "by-agent")) {
122
+ const compactType = this.getCompactType(matchId);
123
+ const mergedFilter = {
124
+ ...options?.filter,
125
+ ...match.params,
126
+ };
127
+ const result = await this.storage.listCompact(compactType, {
128
+ ...options,
129
+ filter: mergedFilter,
130
+ });
131
+ return { data: result.data };
132
+ }
133
+ return { data: [] };
50
134
  }
51
- async read(path) {
52
- const data = await this.storage.read(path);
53
- return { data };
135
+ async read(path, options) {
136
+ // Parse virtual path and extract filter conditions
137
+ const match = this.router.lookup(path);
138
+ if (!match)
139
+ return {};
140
+ const rootEntry = this.rootEntries.find((entry) => entry.path === `/${match.id}`);
141
+ if (!rootEntry)
142
+ return {};
143
+ if (match.type === "root") {
144
+ return { data: rootEntry };
145
+ }
146
+ if (match.type === "detail" &&
147
+ (match.id === "by-session" || match.id === "by-user" || match.id === "by-agent")) {
148
+ const entryId = match.params?.entryId;
149
+ if (!entryId)
150
+ throw new Error("Entry ID is required in the path to read detail.");
151
+ const data = await this.storage.read(entryId, {
152
+ filter: match.params,
153
+ });
154
+ return {
155
+ data: data && {
156
+ ...data,
157
+ path: this.normalizePath(data, match.id),
158
+ },
159
+ };
160
+ }
161
+ if (match.type === "compact-detail" &&
162
+ (match.id === "by-session" || match.id === "by-user" || match.id === "by-agent")) {
163
+ const compactId = match.params?.compactId;
164
+ if (!compactId)
165
+ throw new Error("Compact ID is required in the path to read compact detail.");
166
+ const compactType = this.getCompactType(match.id);
167
+ const mergedFilter = {
168
+ ...options?.filter,
169
+ ...match.params,
170
+ };
171
+ const data = await this.storage.readCompact(compactType, compactId, {
172
+ filter: mergedFilter,
173
+ });
174
+ return { data };
175
+ }
176
+ return {};
54
177
  }
55
178
  async write(path, content) {
56
- const data = await this.storage.create({ ...content, path });
57
- return { data };
179
+ const id = (0, uuid_1.v7)();
180
+ const match = this.router.lookup(path);
181
+ if (match?.type === "compact-new") {
182
+ const compactType = this.getCompactType(match.id);
183
+ const entry = await this.storage.createCompact(compactType, {
184
+ ...match.params,
185
+ ...content,
186
+ id,
187
+ path: (0, ufo_1.joinURL)("/", compactType, id),
188
+ });
189
+ return { data: entry };
190
+ }
191
+ if (match?.id !== "new-history") {
192
+ throw new Error("Can only write to /new or @metadata/compact/new paths.");
193
+ }
194
+ if (!content.sessionId)
195
+ throw new Error("sessionId is required to create a history entry.");
196
+ const entry = await this.storage.create({
197
+ ...content,
198
+ id,
199
+ path: (0, ufo_1.joinURL)("/", id),
200
+ });
201
+ this.afs?.emit("historyCreated", { entry });
202
+ return {
203
+ data: {
204
+ ...entry,
205
+ path: this.normalizePath(entry, "by-session"),
206
+ },
207
+ };
208
+ }
209
+ getCompactType(id) {
210
+ const mapping = {
211
+ "by-session": "session",
212
+ "by-user": "user",
213
+ "by-agent": "agent",
214
+ };
215
+ const type = mapping[id];
216
+ if (!type)
217
+ throw new Error(`Invalid compact type for id: ${id}`);
218
+ return type;
219
+ }
220
+ normalizePath(entry, type) {
221
+ const [prefix, scopeId] = {
222
+ "by-session": ["by-session", entry.sessionId],
223
+ "by-user": ["by-user", entry.userId],
224
+ "by-agent": ["by-agent", entry.agentId],
225
+ }[type] || [];
226
+ if (!prefix || !scopeId) {
227
+ throw new Error(`Cannot reset path for entry without ${type} info.`);
228
+ }
229
+ return (0, ufo_1.joinURL)("/", prefix, scopeId, entry.id);
58
230
  }
59
231
  }
60
232
  exports.AFSHistory = AFSHistory;
@@ -1,7 +1,6 @@
1
1
  import type { AFSEntry, AFSModule } from "@aigne/afs";
2
2
  import { initDatabase } from "@aigne/sqlite";
3
- import { entriesTable } from "./models/entries.js";
4
- import type { AFSStorage, AFSStorageCreatePayload, AFSStorageListOptions } from "./type.js";
3
+ import type { AFSStorage, AFSStorageCreatePayload, AFSStorageListOptions, AFSStorageReadOptions, CompactType } from "./type.js";
5
4
  export * from "./type.js";
6
5
  export interface SharedAFSStorageOptions {
7
6
  url?: string;
@@ -15,11 +14,18 @@ export declare class SharedAFSStorage {
15
14
  }
16
15
  export declare class AFSStorageWithModule implements AFSStorage {
17
16
  private db;
18
- private table;
19
- constructor(db: ReturnType<typeof initDatabase>, table: Promise<ReturnType<typeof entriesTable>>);
17
+ private module;
18
+ constructor(db: ReturnType<typeof initDatabase>, module: AFSModule);
19
+ private _tables?;
20
+ private get tables();
20
21
  list(options?: AFSStorageListOptions): Promise<{
21
22
  data: AFSEntry[];
22
23
  }>;
23
- read(path: string): Promise<AFSEntry | undefined>;
24
+ read(id: string, options?: AFSStorageReadOptions): Promise<AFSEntry | undefined>;
24
25
  create(entry: AFSStorageCreatePayload): Promise<AFSEntry>;
26
+ createCompact(type: CompactType, entry: AFSStorageCreatePayload): Promise<AFSEntry>;
27
+ listCompact(type: CompactType, options?: AFSStorageListOptions): Promise<{
28
+ data: AFSEntry[];
29
+ }>;
30
+ readCompact(type: CompactType, id: string, options?: AFSStorageReadOptions): Promise<AFSEntry | undefined>;
25
31
  }
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.AFSStorageWithModule = exports.SharedAFSStorage = void 0;
18
18
  const sqlite_1 = require("@aigne/sqlite");
19
19
  const migrate_js_1 = require("./migrate.js");
20
+ const compact_js_1 = require("./models/compact.js");
20
21
  const entries_js_1 = require("./models/entries.js");
21
22
  __exportStar(require("./type.js"), exports);
22
23
  const DEFAULT_AFS_STORAGE_LIST_LIMIT = 10;
@@ -31,57 +32,105 @@ class SharedAFSStorage {
31
32
  return this._db;
32
33
  }
33
34
  withModule(module) {
34
- return new AFSStorageWithModule(this.db, (0, migrate_js_1.migrate)(this.db, module).then(() => (0, entries_js_1.entriesTable)(module)));
35
+ return new AFSStorageWithModule(this.db, module);
35
36
  }
36
37
  }
37
38
  exports.SharedAFSStorage = SharedAFSStorage;
38
39
  class AFSStorageWithModule {
39
40
  db;
40
- table;
41
- constructor(db, table) {
41
+ module;
42
+ constructor(db, module) {
42
43
  this.db = db;
43
- this.table = table;
44
+ this.module = module;
45
+ }
46
+ _tables;
47
+ get tables() {
48
+ if (!this._tables) {
49
+ this._tables = this.db.then((db) => (0, migrate_js_1.migrate)(db, this.module).then(() => ({
50
+ db,
51
+ entries: (0, entries_js_1.entriesTable)(this.module),
52
+ compact: (0, compact_js_1.compactTable)(this.module),
53
+ })));
54
+ }
55
+ return this._tables;
44
56
  }
45
57
  async list(options = {}) {
46
58
  const { filter, limit = DEFAULT_AFS_STORAGE_LIST_LIMIT } = options;
47
- const db = await this.db;
48
- const table = await this.table;
59
+ const { db, entries } = await this.tables;
49
60
  const data = await db
50
61
  .select()
51
- .from(table)
52
- .where((0, sqlite_1.and)(filter?.userId ? (0, sqlite_1.eq)(table.userId, filter.userId) : undefined, filter?.sessionId ? (0, sqlite_1.eq)(table.sessionId, filter.sessionId) : undefined))
62
+ .from(entries)
63
+ .where((0, sqlite_1.and)(filter?.agentId ? (0, sqlite_1.eq)(entries.agentId, filter.agentId) : undefined, filter?.userId ? (0, sqlite_1.eq)(entries.userId, filter.userId) : undefined, filter?.sessionId ? (0, sqlite_1.eq)(entries.sessionId, filter.sessionId) : undefined, filter?.before ? (0, sqlite_1.lt)(entries.createdAt, new Date(filter.before)) : undefined, filter?.after ? (0, sqlite_1.gt)(entries.createdAt, new Date(filter.after)) : undefined))
53
64
  .orderBy(...(options.orderBy ?? []).map((item) => (item[1] === "asc" ? sqlite_1.asc : sqlite_1.desc)(sqlite_1.sql.identifier(item[0]))))
54
65
  .limit(limit)
55
66
  .execute();
56
67
  return { data };
57
68
  }
58
- async read(path) {
59
- const db = await this.db;
60
- const table = await this.table;
69
+ async read(id, options) {
70
+ const { db, entries } = await this.tables;
61
71
  return db
62
72
  .select()
63
- .from(table)
64
- .where((0, sqlite_1.eq)(table.path, path))
73
+ .from(entries)
74
+ .where((0, sqlite_1.and)((0, sqlite_1.eq)(entries.id, id), options?.filter?.agentId ? (0, sqlite_1.eq)(entries.agentId, options.filter.agentId) : undefined, options?.filter?.userId ? (0, sqlite_1.eq)(entries.userId, options.filter.userId) : undefined, options?.filter?.sessionId ? (0, sqlite_1.eq)(entries.sessionId, options.filter.sessionId) : undefined))
65
75
  .limit(1)
66
76
  .execute()
67
77
  .then((memory) => memory.at(0));
68
78
  }
69
79
  async create(entry) {
70
- const db = await this.db;
71
- const table = await this.table;
80
+ const { db, entries } = await this.tables;
72
81
  let result = await db
73
- .update(table)
82
+ .update(entries)
74
83
  .set(entry)
75
- .where((0, sqlite_1.eq)(table.path, entry.path))
84
+ .where((0, sqlite_1.eq)(entries.id, entry.id))
76
85
  .returning()
77
86
  .execute();
78
87
  if (!result.length) {
79
- result = await db.insert(table).values(entry).returning().execute();
88
+ result = await db.insert(entries).values(entry).returning().execute();
80
89
  }
81
90
  const [res] = result;
82
91
  if (!res)
83
92
  throw new Error("Failed to create AFS entry, no result");
84
93
  return res;
85
94
  }
95
+ async createCompact(type, entry) {
96
+ const { db, compact } = await this.tables;
97
+ const result = await db
98
+ .insert(compact)
99
+ .values({
100
+ ...entry,
101
+ metadata: {
102
+ ...entry.metadata,
103
+ type,
104
+ },
105
+ })
106
+ .returning()
107
+ .execute();
108
+ const [res] = result;
109
+ if (!res)
110
+ throw new Error(`Failed to create ${type} compact entry, no result`);
111
+ return res;
112
+ }
113
+ async listCompact(type, options = {}) {
114
+ const { db, compact } = await this.tables;
115
+ const { filter, limit = DEFAULT_AFS_STORAGE_LIST_LIMIT } = options;
116
+ const data = await db
117
+ .select()
118
+ .from(compact)
119
+ .where((0, sqlite_1.and)((0, sqlite_1.eq)((0, sqlite_1.sql) `json_extract(${compact.metadata}, '$.type')`, type), filter?.agentId ? (0, sqlite_1.eq)(compact.agentId, filter.agentId) : undefined, filter?.userId ? (0, sqlite_1.eq)(compact.userId, filter.userId) : undefined, filter?.sessionId ? (0, sqlite_1.eq)(compact.sessionId, filter.sessionId) : undefined, filter?.before ? (0, sqlite_1.lt)(compact.createdAt, new Date(filter.before)) : undefined, filter?.after ? (0, sqlite_1.gt)(compact.createdAt, new Date(filter.after)) : undefined))
120
+ .orderBy(...(options.orderBy ?? []).map((item) => (item[1] === "asc" ? sqlite_1.asc : sqlite_1.desc)(sqlite_1.sql.identifier(item[0]))))
121
+ .limit(limit)
122
+ .execute();
123
+ return { data };
124
+ }
125
+ async readCompact(type, id, options) {
126
+ const { db, compact } = await this.tables;
127
+ return db
128
+ .select()
129
+ .from(compact)
130
+ .where((0, sqlite_1.and)((0, sqlite_1.eq)((0, sqlite_1.sql) `json_extract(${compact.metadata}, '$.type')`, type), (0, sqlite_1.eq)(compact.id, id), options?.filter?.agentId ? (0, sqlite_1.eq)(compact.agentId, options.filter.agentId) : undefined, options?.filter?.userId ? (0, sqlite_1.eq)(compact.userId, options.filter.userId) : undefined, options?.filter?.sessionId ? (0, sqlite_1.eq)(compact.sessionId, options.filter.sessionId) : undefined))
131
+ .limit(1)
132
+ .execute()
133
+ .then((rows) => rows.at(0));
134
+ }
86
135
  }
87
136
  exports.AFSStorageWithModule = AFSStorageWithModule;
@@ -1,3 +1,3 @@
1
1
  import type { AFSModule } from "@aigne/afs";
2
2
  import { type initDatabase } from "@aigne/sqlite";
3
- export declare function migrate(db: ReturnType<typeof initDatabase>, module: AFSModule): Promise<void>;
3
+ export declare function migrate(db: Awaited<ReturnType<typeof initDatabase>>, module: AFSModule): Promise<void>;
@@ -4,8 +4,10 @@ exports.migrate = migrate;
4
4
  const sqlite_1 = require("@aigne/sqlite");
5
5
  const uuid_1 = require("@aigne/uuid");
6
6
  const _001_init_js_1 = require("./migrations/001-init.js");
7
+ const _002_add_agent_id_js_1 = require("./migrations/002-add-agent-id.js");
8
+ const _003_add_compact_table_js_1 = require("./migrations/003-add-compact-table.js");
7
9
  async function migrate(db, module) {
8
- const migrations = [_001_init_js_1.init];
10
+ const migrations = [_001_init_js_1.init, _002_add_agent_id_js_1.addAgentId, _003_add_compact_table_js_1.addCompactTable];
9
11
  const migrationsTable = "__drizzle_migrations";
10
12
  const migrationTableCreate = (0, sqlite_1.sql) `
11
13
  CREATE TABLE IF NOT EXISTS ${sqlite_1.sql.identifier(migrationsTable)} (
@@ -14,18 +16,18 @@ async function migrate(db, module) {
14
16
  "hash" TEXT NOT NULL
15
17
  )
16
18
  `;
17
- await (await db).run(migrationTableCreate).execute();
18
- const dbMigrations = await (await db)
19
+ await db.run(migrationTableCreate).execute();
20
+ const dbMigrations = await db
19
21
  .values((0, sqlite_1.sql) `SELECT "id", "moduleId", "hash" FROM ${sqlite_1.sql.identifier(migrationsTable)} WHERE "moduleId" = ${sqlite_1.sql.param(module.name)} ORDER BY id DESC LIMIT 1`)
20
22
  .execute();
21
23
  const lastDbMigration = dbMigrations[0];
22
24
  const queriesToRun = [];
23
25
  for (const migration of migrations) {
24
- if (!lastDbMigration || lastDbMigration[1] < migration.hash) {
26
+ if (!lastDbMigration || lastDbMigration[2] < migration.hash) {
25
27
  queriesToRun.push(...migration.sql(module), (0, sqlite_1.sql) `INSERT INTO ${sqlite_1.sql.identifier(migrationsTable)} ("id", "moduleId", "hash") VALUES(${sqlite_1.sql.param((0, uuid_1.v7)())}, ${sqlite_1.sql.param(module.name)}, ${sqlite_1.sql.param(migration.hash)})`);
26
28
  }
27
29
  }
28
30
  for (const query of queriesToRun) {
29
- await (await db).run(query).execute();
31
+ await db.run(query).execute();
30
32
  }
31
33
  }
@@ -0,0 +1,2 @@
1
+ import type { AFSStorageMigrations } from "../type.js";
2
+ export declare const addAgentId: AFSStorageMigrations;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addAgentId = void 0;
4
+ const sqlite_1 = require("@aigne/sqlite");
5
+ const entries_js_1 = require("../models/entries.js");
6
+ exports.addAgentId = {
7
+ hash: "002-add-agent-id",
8
+ sql: (module) => [
9
+ (0, sqlite_1.sql) `\
10
+ ALTER TABLE ${sqlite_1.sql.identifier((0, entries_js_1.entriesTableName)(module))} ADD COLUMN "agentId" TEXT;
11
+ `,
12
+ ],
13
+ };
@@ -0,0 +1,2 @@
1
+ import type { AFSStorageMigrations } from "../type.js";
2
+ export declare const addCompactTable: AFSStorageMigrations;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addCompactTable = void 0;
4
+ const sqlite_1 = require("@aigne/sqlite");
5
+ const compact_js_1 = require("../models/compact.js");
6
+ exports.addCompactTable = {
7
+ hash: "003-add-compact-table",
8
+ sql: (module) => [
9
+ (0, sqlite_1.sql) `\
10
+ CREATE TABLE IF NOT EXISTS ${sqlite_1.sql.identifier((0, compact_js_1.compactTableName)(module))} (
11
+ "id" TEXT NOT NULL PRIMARY KEY,
12
+ "createdAt" DATETIME NOT NULL,
13
+ "updatedAt" DATETIME NOT NULL,
14
+ "path" TEXT NOT NULL,
15
+ "sessionId" TEXT,
16
+ "userId" TEXT,
17
+ "agentId" TEXT,
18
+ "metadata" JSON,
19
+ "content" JSON
20
+ )
21
+ `,
22
+ ],
23
+ };