@smithers-orchestrator/memory 0.16.0

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/LICENSE +21 -0
  2. package/package.json +46 -0
  3. package/src/MemoryFact.ts +9 -0
  4. package/src/MemoryLayerConfig.ts +5 -0
  5. package/src/MemoryMessage.ts +9 -0
  6. package/src/MemoryNamespace.ts +6 -0
  7. package/src/MemoryNamespaceKind.ts +1 -0
  8. package/src/MemoryProcessor.js +5 -0
  9. package/src/MemoryProcessor.ts +9 -0
  10. package/src/MemoryProcessorConfig.ts +3 -0
  11. package/src/MemoryService.js +10 -0
  12. package/src/MemoryServiceApi.js +5 -0
  13. package/src/MemoryServiceApi.ts +49 -0
  14. package/src/MemoryThread.ts +8 -0
  15. package/src/MessageHistoryConfig.ts +4 -0
  16. package/src/SemanticRecallConfig.ts +7 -0
  17. package/src/Summarizer.js +26 -0
  18. package/src/TaskMemoryConfig.ts +15 -0
  19. package/src/TokenLimiter.js +29 -0
  20. package/src/TtlGarbageCollector.js +23 -0
  21. package/src/WorkingMemoryConfig.ts +10 -0
  22. package/src/createMemoryLayer.js +30 -0
  23. package/src/index.d.ts +616 -0
  24. package/src/index.js +39 -0
  25. package/src/memoryFactReads.js +2 -0
  26. package/src/memoryFactWrites.js +2 -0
  27. package/src/memoryMessageSaves.js +2 -0
  28. package/src/memoryRecallDuration.js +7 -0
  29. package/src/memoryRecallQueries.js +2 -0
  30. package/src/metrics.js +5 -0
  31. package/src/namespaceToString.js +9 -0
  32. package/src/parseNamespace.js +18 -0
  33. package/src/processors.js +7 -0
  34. package/src/react-types.ts +1 -0
  35. package/src/schema.js +38 -0
  36. package/src/service.js +7 -0
  37. package/src/store/MemoryStore.js +5 -0
  38. package/src/store/MemoryStore.ts +68 -0
  39. package/src/store/MemoryStoreDb.js +6 -0
  40. package/src/store/MemoryStoreLive.js +306 -0
  41. package/src/store/MemoryStoreService.js +10 -0
  42. package/src/store/createMemoryStore.js +13 -0
  43. package/src/store/createMemoryStoreLayer.js +13 -0
  44. package/src/store/index.js +9 -0
  45. package/src/types.js +21 -0
@@ -0,0 +1,9 @@
1
+
2
+ /** @typedef {import("./MemoryNamespace.ts").MemoryNamespace} MemoryNamespace */
3
+ /**
4
+ * @param {MemoryNamespace} ns
5
+ * @returns {string}
6
+ */
7
+ export function namespaceToString(ns) {
8
+ return `${ns.kind}:${ns.id}`;
9
+ }
@@ -0,0 +1,18 @@
1
+
2
+ /** @typedef {import("./MemoryNamespace.ts").MemoryNamespace} MemoryNamespace */
3
+ /**
4
+ * @param {string} str
5
+ * @returns {MemoryNamespace}
6
+ */
7
+ export function parseNamespace(str) {
8
+ const idx = str.indexOf(":");
9
+ if (idx < 0) {
10
+ return { kind: "global", id: str };
11
+ }
12
+ const kind = str.slice(0, idx);
13
+ const id = str.slice(idx + 1);
14
+ if (!["workflow", "agent", "user", "global"].includes(kind)) {
15
+ return { kind: "global", id: str };
16
+ }
17
+ return { kind, id };
18
+ }
@@ -0,0 +1,7 @@
1
+ // @smithers-type-exports-begin
2
+ /** @typedef {import("./MemoryProcessor.ts").MemoryProcessor} MemoryProcessor */
3
+ // @smithers-type-exports-end
4
+
5
+ export { TtlGarbageCollector } from "./TtlGarbageCollector.js";
6
+ export { TokenLimiter } from "./TokenLimiter.js";
7
+ export { Summarizer } from "./Summarizer.js";
@@ -0,0 +1 @@
1
+ export type { TaskMemoryConfig } from "@smithers-orchestrator/graph/types";
package/src/schema.js ADDED
@@ -0,0 +1,38 @@
1
+ import { integer, sqliteTable, text, primaryKey, } from "drizzle-orm/sqlite-core";
2
+ // ---------------------------------------------------------------------------
3
+ // Memory Facts -- (namespace, key) primary key
4
+ // ---------------------------------------------------------------------------
5
+ export const smithersMemoryFacts = sqliteTable("_smithers_memory_facts", {
6
+ namespace: text("namespace").notNull(),
7
+ key: text("key").notNull(),
8
+ valueJson: text("value_json").notNull(),
9
+ schemaSig: text("schema_sig"),
10
+ createdAtMs: integer("created_at_ms").notNull(),
11
+ updatedAtMs: integer("updated_at_ms").notNull(),
12
+ ttlMs: integer("ttl_ms"),
13
+ }, (t) => ({
14
+ pk: primaryKey({ columns: [t.namespace, t.key] }),
15
+ }));
16
+ // ---------------------------------------------------------------------------
17
+ // Memory Threads
18
+ // ---------------------------------------------------------------------------
19
+ export const smithersMemoryThreads = sqliteTable("_smithers_memory_threads", {
20
+ threadId: text("thread_id").primaryKey(),
21
+ namespace: text("namespace").notNull(),
22
+ title: text("title"),
23
+ metadataJson: text("metadata_json"),
24
+ createdAtMs: integer("created_at_ms").notNull(),
25
+ updatedAtMs: integer("updated_at_ms").notNull(),
26
+ });
27
+ // ---------------------------------------------------------------------------
28
+ // Memory Messages
29
+ // ---------------------------------------------------------------------------
30
+ export const smithersMemoryMessages = sqliteTable("_smithers_memory_messages", {
31
+ id: text("id").primaryKey(),
32
+ threadId: text("thread_id").notNull(),
33
+ role: text("role").notNull(),
34
+ contentJson: text("content_json").notNull(),
35
+ runId: text("run_id"),
36
+ nodeId: text("node_id"),
37
+ createdAtMs: integer("created_at_ms").notNull(),
38
+ });
package/src/service.js ADDED
@@ -0,0 +1,7 @@
1
+ // @smithers-type-exports-begin
2
+ /** @typedef {import("./MemoryLayerConfig.ts").MemoryLayerConfig} MemoryLayerConfig */
3
+ /** @typedef {import("./MemoryServiceApi.ts").MemoryServiceApi} MemoryServiceApi */
4
+ // @smithers-type-exports-end
5
+
6
+ export { MemoryService } from "./MemoryService.js";
7
+ export { createMemoryLayer } from "./createMemoryLayer.js";
@@ -0,0 +1,5 @@
1
+ // @smithers-type-exports-begin
2
+ /** @typedef {import("./MemoryStore.ts").MemoryStore} MemoryStore */
3
+ // @smithers-type-exports-end
4
+
5
+ import { Effect } from "effect";
@@ -0,0 +1,68 @@
1
+ import type { Effect } from "effect";
2
+ import type { SmithersError } from "@smithers-orchestrator/errors";
3
+ import type { MemoryNamespace } from "../MemoryNamespace";
4
+ import type { MemoryFact } from "../MemoryFact";
5
+ import type { MemoryThread } from "../MemoryThread";
6
+ import type { MemoryMessage } from "../MemoryMessage";
7
+
8
+ export type MemoryStore = {
9
+ getFact: (
10
+ ns: MemoryNamespace,
11
+ key: string,
12
+ ) => Promise<MemoryFact | undefined>;
13
+ setFact: (
14
+ ns: MemoryNamespace,
15
+ key: string,
16
+ value: unknown,
17
+ ttlMs?: number,
18
+ ) => Promise<void>;
19
+ deleteFact: (ns: MemoryNamespace, key: string) => Promise<void>;
20
+ listFacts: (ns: MemoryNamespace) => Promise<MemoryFact[]>;
21
+ createThread: (ns: MemoryNamespace, title?: string) => Promise<MemoryThread>;
22
+ getThread: (threadId: string) => Promise<MemoryThread | undefined>;
23
+ deleteThread: (threadId: string) => Promise<void>;
24
+ saveMessage: (
25
+ msg: Omit<MemoryMessage, "createdAtMs"> & { createdAtMs?: number },
26
+ ) => Promise<void>;
27
+ listMessages: (threadId: string, limit?: number) => Promise<MemoryMessage[]>;
28
+ countMessages: (threadId: string) => Promise<number>;
29
+ deleteExpiredFacts: () => Promise<number>;
30
+ getFactEffect: (
31
+ ns: MemoryNamespace,
32
+ key: string,
33
+ ) => Effect.Effect<MemoryFact | undefined, SmithersError>;
34
+ setFactEffect: (
35
+ ns: MemoryNamespace,
36
+ key: string,
37
+ value: unknown,
38
+ ttlMs?: number,
39
+ ) => Effect.Effect<void, SmithersError>;
40
+ deleteFactEffect: (
41
+ ns: MemoryNamespace,
42
+ key: string,
43
+ ) => Effect.Effect<void, SmithersError>;
44
+ listFactsEffect: (
45
+ ns: MemoryNamespace,
46
+ ) => Effect.Effect<MemoryFact[], SmithersError>;
47
+ createThreadEffect: (
48
+ ns: MemoryNamespace,
49
+ title?: string,
50
+ ) => Effect.Effect<MemoryThread, SmithersError>;
51
+ getThreadEffect: (
52
+ threadId: string,
53
+ ) => Effect.Effect<MemoryThread | undefined, SmithersError>;
54
+ deleteThreadEffect: (
55
+ threadId: string,
56
+ ) => Effect.Effect<void, SmithersError>;
57
+ saveMessageEffect: (
58
+ msg: Omit<MemoryMessage, "createdAtMs"> & { createdAtMs?: number },
59
+ ) => Effect.Effect<void, SmithersError>;
60
+ listMessagesEffect: (
61
+ threadId: string,
62
+ limit?: number,
63
+ ) => Effect.Effect<MemoryMessage[], SmithersError>;
64
+ countMessagesEffect: (
65
+ threadId: string,
66
+ ) => Effect.Effect<number, SmithersError>;
67
+ deleteExpiredFactsEffect: () => Effect.Effect<number, SmithersError>;
68
+ };
@@ -0,0 +1,6 @@
1
+ import { Context } from "effect";
2
+ /** @typedef {import("drizzle-orm/bun-sqlite").BunSQLiteDatabase<any>} BunSQLiteDatabaseAny */
3
+
4
+ /** @type {Context.Tag<BunSQLiteDatabaseAny, BunSQLiteDatabaseAny>} */
5
+ export const MemoryStoreDb =
6
+ Context.GenericTag("MemoryStoreDb");
@@ -0,0 +1,306 @@
1
+ import { and, desc, eq, sql } from "drizzle-orm";
2
+ import { Effect, Layer, Metric } from "effect";
3
+ import { toSmithersError } from "@smithers-orchestrator/errors/toSmithersError";
4
+ import { dbQueryDuration } from "@smithers-orchestrator/observability/metrics";
5
+ import { nowMs } from "@smithers-orchestrator/scheduler/nowMs";
6
+ import { namespaceToString } from "../namespaceToString.js";
7
+ import { smithersMemoryFacts, smithersMemoryThreads, smithersMemoryMessages, } from "../schema.js";
8
+ import { memoryFactReads } from "../memoryFactReads.js";
9
+ import { memoryFactWrites } from "../memoryFactWrites.js";
10
+ import { memoryMessageSaves } from "../memoryMessageSaves.js";
11
+ import { MemoryStoreDb } from "./MemoryStoreDb.js";
12
+ import { MemoryStoreService } from "./MemoryStoreService.js";
13
+ /** @typedef {import("./MemoryStore.ts").MemoryStore} MemoryStore */
14
+ /** @typedef {import("../MemoryNamespace.ts").MemoryNamespace} MemoryNamespace */
15
+ /** @typedef {import("../MemoryFact.ts").MemoryFact} MemoryFact */
16
+ /** @typedef {import("../MemoryMessage.ts").MemoryMessage} MemoryMessage */
17
+ /** @typedef {import("../MemoryThread.ts").MemoryThread} MemoryThread */
18
+ /** @typedef {import("@smithers-orchestrator/errors/SmithersError").SmithersError} SmithersError */
19
+
20
+ /** @typedef {import("drizzle-orm/bun-sqlite").BunSQLiteDatabase} BunSQLiteDatabase */
21
+
22
+ // ---------------------------------------------------------------------------
23
+ // Helpers
24
+ // ---------------------------------------------------------------------------
25
+ /**
26
+ * @template A
27
+ * @param {string} label
28
+ * @param {() => PromiseLike<A>} operation
29
+ * @returns {Effect.Effect<A, SmithersError>}
30
+ */
31
+ function readEffect(label, operation) {
32
+ return Effect.gen(function* () {
33
+ const start = performance.now();
34
+ const result = yield* Effect.tryPromise({
35
+ try: () => operation(),
36
+ catch: (cause) => toSmithersError(cause, label, {
37
+ code: "DB_QUERY_FAILED",
38
+ details: { operation: label },
39
+ }),
40
+ });
41
+ yield* Metric.update(dbQueryDuration, performance.now() - start);
42
+ return result;
43
+ }).pipe(Effect.annotateLogs({ dbOperation: label }), Effect.withLogSpan(`memory:${label}`));
44
+ }
45
+ /**
46
+ * @template A
47
+ * @param {string} label
48
+ * @param {() => PromiseLike<A>} operation
49
+ * @returns {Effect.Effect<A, SmithersError>}
50
+ */
51
+ function writeEffect(label, operation) {
52
+ return Effect.gen(function* () {
53
+ const start = performance.now();
54
+ const result = yield* Effect.tryPromise({
55
+ try: () => operation(),
56
+ catch: (cause) => toSmithersError(cause, label, {
57
+ code: "DB_WRITE_FAILED",
58
+ details: { operation: label },
59
+ }),
60
+ });
61
+ yield* Metric.update(dbQueryDuration, performance.now() - start);
62
+ return result;
63
+ }).pipe(Effect.annotateLogs({ dbOperation: label }), Effect.withLogSpan(`memory:${label}`));
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // Factory
67
+ // ---------------------------------------------------------------------------
68
+ /**
69
+ * @param {BunSQLiteDatabase<any>} db
70
+ * @returns {MemoryStore}
71
+ */
72
+ function makeMemoryStore(db) {
73
+ // --- Working Memory Effects ---
74
+ /**
75
+ * @param {MemoryNamespace} ns
76
+ * @param {string} key
77
+ * @returns {Effect.Effect<MemoryFact | undefined, SmithersError>}
78
+ */
79
+ function getFactEffect(ns, key) {
80
+ const nsStr = namespaceToString(ns);
81
+ return Effect.gen(function* () {
82
+ yield* Metric.increment(memoryFactReads);
83
+ const rows = yield* readEffect("memory getFact", () => db
84
+ .select()
85
+ .from(smithersMemoryFacts)
86
+ .where(and(eq(smithersMemoryFacts.namespace, nsStr), eq(smithersMemoryFacts.key, key)))
87
+ .limit(1));
88
+ const row = rows[0];
89
+ if (!row)
90
+ return undefined;
91
+ return {
92
+ namespace: row.namespace,
93
+ key: row.key,
94
+ valueJson: row.valueJson,
95
+ schemaSig: row.schemaSig,
96
+ createdAtMs: row.createdAtMs,
97
+ updatedAtMs: row.updatedAtMs,
98
+ ttlMs: row.ttlMs,
99
+ };
100
+ });
101
+ }
102
+ /**
103
+ * @param {MemoryNamespace} ns
104
+ * @param {string} key
105
+ * @param {unknown} value
106
+ * @param {number} [ttlMs]
107
+ * @returns {Effect.Effect<void, SmithersError>}
108
+ */
109
+ function setFactEffect(ns, key, value, ttlMs) {
110
+ const nsStr = namespaceToString(ns);
111
+ const now = nowMs();
112
+ return Effect.gen(function* () {
113
+ yield* Metric.increment(memoryFactWrites);
114
+ yield* writeEffect("memory setFact", () => db
115
+ .insert(smithersMemoryFacts)
116
+ .values({
117
+ namespace: nsStr,
118
+ key,
119
+ valueJson: JSON.stringify(value),
120
+ createdAtMs: now,
121
+ updatedAtMs: now,
122
+ ttlMs: ttlMs ?? null,
123
+ })
124
+ .onConflictDoUpdate({
125
+ target: [smithersMemoryFacts.namespace, smithersMemoryFacts.key],
126
+ set: {
127
+ valueJson: JSON.stringify(value),
128
+ updatedAtMs: now,
129
+ ttlMs: ttlMs ?? null,
130
+ },
131
+ }));
132
+ });
133
+ }
134
+ /**
135
+ * @param {MemoryNamespace} ns
136
+ * @param {string} key
137
+ * @returns {Effect.Effect<void, SmithersError>}
138
+ */
139
+ function deleteFactEffect(ns, key) {
140
+ const nsStr = namespaceToString(ns);
141
+ return writeEffect("memory deleteFact", () => db
142
+ .delete(smithersMemoryFacts)
143
+ .where(and(eq(smithersMemoryFacts.namespace, nsStr), eq(smithersMemoryFacts.key, key)))).pipe(Effect.asVoid);
144
+ }
145
+ /**
146
+ * @param {MemoryNamespace} ns
147
+ * @returns {Effect.Effect<MemoryFact[], SmithersError>}
148
+ */
149
+ function listFactsEffect(ns) {
150
+ const nsStr = namespaceToString(ns);
151
+ return readEffect("memory listFacts", () => db
152
+ .select()
153
+ .from(smithersMemoryFacts)
154
+ .where(eq(smithersMemoryFacts.namespace, nsStr))
155
+ .orderBy(smithersMemoryFacts.key)).pipe(Effect.map((rows) => rows.map((row) => ({
156
+ namespace: row.namespace,
157
+ key: row.key,
158
+ valueJson: row.valueJson,
159
+ schemaSig: row.schemaSig,
160
+ createdAtMs: row.createdAtMs,
161
+ updatedAtMs: row.updatedAtMs,
162
+ ttlMs: row.ttlMs,
163
+ }))));
164
+ }
165
+ // --- Thread Effects ---
166
+ /**
167
+ * @param {MemoryNamespace} ns
168
+ * @param {string} [title]
169
+ * @returns {Effect.Effect<MemoryThread, SmithersError>}
170
+ */
171
+ function createThreadEffect(ns, title) {
172
+ const nsStr = namespaceToString(ns);
173
+ const now = nowMs();
174
+ const threadId = crypto.randomUUID();
175
+ const thread = {
176
+ threadId,
177
+ namespace: nsStr,
178
+ title: title ?? null,
179
+ metadataJson: null,
180
+ createdAtMs: now,
181
+ updatedAtMs: now,
182
+ };
183
+ return writeEffect("memory createThread", () => db.insert(smithersMemoryThreads).values(thread)).pipe(Effect.map(() => thread));
184
+ }
185
+ /**
186
+ * @param {string} threadId
187
+ * @returns {Effect.Effect<MemoryThread | undefined, SmithersError>}
188
+ */
189
+ function getThreadEffect(threadId) {
190
+ return readEffect("memory getThread", () => db
191
+ .select()
192
+ .from(smithersMemoryThreads)
193
+ .where(eq(smithersMemoryThreads.threadId, threadId))
194
+ .limit(1)).pipe(Effect.map((rows) => rows[0]));
195
+ }
196
+ /**
197
+ * @param {string} threadId
198
+ * @returns {Effect.Effect<void, SmithersError>}
199
+ */
200
+ function deleteThreadEffect(threadId) {
201
+ return Effect.gen(function* () {
202
+ // Delete messages first
203
+ yield* writeEffect("memory deleteThreadMessages", () => db
204
+ .delete(smithersMemoryMessages)
205
+ .where(eq(smithersMemoryMessages.threadId, threadId)));
206
+ // Delete the thread
207
+ yield* writeEffect("memory deleteThread", () => db
208
+ .delete(smithersMemoryThreads)
209
+ .where(eq(smithersMemoryThreads.threadId, threadId)));
210
+ });
211
+ }
212
+ // --- Message Effects ---
213
+ /**
214
+ * @param {Omit<MemoryMessage, "createdAtMs"> & { createdAtMs?: number }} msg
215
+ * @returns {Effect.Effect<void, SmithersError>}
216
+ */
217
+ function saveMessageEffect(msg) {
218
+ return Effect.gen(function* () {
219
+ yield* Metric.increment(memoryMessageSaves);
220
+ yield* writeEffect("memory saveMessage", () => db.insert(smithersMemoryMessages).values({
221
+ id: msg.id,
222
+ threadId: msg.threadId,
223
+ role: msg.role,
224
+ contentJson: msg.contentJson,
225
+ runId: msg.runId ?? null,
226
+ nodeId: msg.nodeId ?? null,
227
+ createdAtMs: msg.createdAtMs ?? nowMs(),
228
+ }));
229
+ });
230
+ }
231
+ /**
232
+ * @param {string} threadId
233
+ * @param {number} [limit]
234
+ * @returns {Effect.Effect<MemoryMessage[], SmithersError>}
235
+ */
236
+ function listMessagesEffect(threadId, limit) {
237
+ return readEffect("memory listMessages", () => {
238
+ let query = db
239
+ .select()
240
+ .from(smithersMemoryMessages)
241
+ .where(eq(smithersMemoryMessages.threadId, threadId))
242
+ .orderBy(smithersMemoryMessages.createdAtMs);
243
+ if (limit) {
244
+ query = query.limit(limit);
245
+ }
246
+ return query;
247
+ }).pipe(Effect.map((rows) => rows.map((row) => ({
248
+ id: row.id,
249
+ threadId: row.threadId,
250
+ role: row.role,
251
+ contentJson: row.contentJson,
252
+ runId: row.runId,
253
+ nodeId: row.nodeId,
254
+ createdAtMs: row.createdAtMs,
255
+ }))));
256
+ }
257
+ /**
258
+ * @param {string} threadId
259
+ * @returns {Effect.Effect<number, SmithersError>}
260
+ */
261
+ function countMessagesEffect(threadId) {
262
+ return readEffect("memory countMessages", () => db
263
+ .select({ count: sql `count(*)` })
264
+ .from(smithersMemoryMessages)
265
+ .where(eq(smithersMemoryMessages.threadId, threadId))).pipe(Effect.map((rows) => rows[0]?.count ?? 0));
266
+ }
267
+ // --- Maintenance ---
268
+ /**
269
+ * @returns {Effect.Effect<number, SmithersError>}
270
+ */
271
+ function deleteExpiredFactsEffect() {
272
+ const now = nowMs();
273
+ return writeEffect("memory deleteExpiredFacts", () => db
274
+ .delete(smithersMemoryFacts)
275
+ .where(and(sql `${smithersMemoryFacts.ttlMs} IS NOT NULL`, sql `${smithersMemoryFacts.updatedAtMs} + ${smithersMemoryFacts.ttlMs} < ${now}`))).pipe(Effect.map((result) => result?.changes ?? result?.rowsAffected ?? 0));
276
+ }
277
+ // --- Build the store ---
278
+ return {
279
+ // Promise variants (delegate to Effect)
280
+ getFact: (ns, key) => Effect.runPromise(getFactEffect(ns, key)),
281
+ setFact: (ns, key, value, ttlMs) => Effect.runPromise(setFactEffect(ns, key, value, ttlMs)),
282
+ deleteFact: (ns, key) => Effect.runPromise(deleteFactEffect(ns, key)),
283
+ listFacts: (ns) => Effect.runPromise(listFactsEffect(ns)),
284
+ createThread: (ns, title) => Effect.runPromise(createThreadEffect(ns, title)),
285
+ getThread: (threadId) => Effect.runPromise(getThreadEffect(threadId)),
286
+ deleteThread: (threadId) => Effect.runPromise(deleteThreadEffect(threadId)),
287
+ saveMessage: (msg) => Effect.runPromise(saveMessageEffect(msg)),
288
+ listMessages: (threadId, limit) => Effect.runPromise(listMessagesEffect(threadId, limit)),
289
+ countMessages: (threadId) => Effect.runPromise(countMessagesEffect(threadId)),
290
+ deleteExpiredFacts: () => Effect.runPromise(deleteExpiredFactsEffect()),
291
+ // Effect variants
292
+ getFactEffect,
293
+ setFactEffect,
294
+ deleteFactEffect,
295
+ listFactsEffect,
296
+ createThreadEffect,
297
+ getThreadEffect,
298
+ deleteThreadEffect,
299
+ saveMessageEffect,
300
+ listMessagesEffect,
301
+ countMessagesEffect,
302
+ deleteExpiredFactsEffect,
303
+ };
304
+ }
305
+ /** @type {Layer.Layer<MemoryStoreService, never, BunSQLiteDatabase<any>>} */
306
+ export const MemoryStoreLive = Layer.effect(MemoryStoreService, Effect.map(MemoryStoreDb, (db) => makeMemoryStore(db)));
@@ -0,0 +1,10 @@
1
+ import { Context } from "effect";
2
+ /** @typedef {import("./MemoryStore.ts").MemoryStore} MemoryStore */
3
+
4
+ const MemoryStoreServiceBase =
5
+ /** @type {Context.TagClass<MemoryStoreService, "MemoryStoreService", MemoryStore>} */ (
6
+ /** @type {unknown} */ (Context.Tag("MemoryStoreService")())
7
+ );
8
+
9
+ export class MemoryStoreService extends MemoryStoreServiceBase {
10
+ }
@@ -0,0 +1,13 @@
1
+ import { Effect } from "effect";
2
+ import { MemoryStoreService } from "./MemoryStoreService.js";
3
+ import { createMemoryStoreLayer } from "./createMemoryStoreLayer.js";
4
+ /** @typedef {import("drizzle-orm/bun-sqlite").BunSQLiteDatabase} BunSQLiteDatabase */
5
+ /** @typedef {import("./MemoryStore.ts").MemoryStore} MemoryStore */
6
+
7
+ /**
8
+ * @param {BunSQLiteDatabase<any>} db
9
+ * @returns {MemoryStore}
10
+ */
11
+ export function createMemoryStore(db) {
12
+ return Effect.runSync(MemoryStoreService.pipe(Effect.provide(createMemoryStoreLayer(db))));
13
+ }
@@ -0,0 +1,13 @@
1
+ import { Layer } from "effect";
2
+ import { MemoryStoreDb } from "./MemoryStoreDb.js";
3
+ import { MemoryStoreLive } from "./MemoryStoreLive.js";
4
+ import { MemoryStoreService } from "./MemoryStoreService.js";
5
+ /** @typedef {import("drizzle-orm/bun-sqlite").BunSQLiteDatabase} BunSQLiteDatabase */
6
+
7
+ /**
8
+ * @param {BunSQLiteDatabase<any>} db
9
+ * @returns {Layer.Layer<MemoryStoreService, never, never>}
10
+ */
11
+ export function createMemoryStoreLayer(db) {
12
+ return MemoryStoreLive.pipe(Layer.provide(Layer.succeed(MemoryStoreDb, db)));
13
+ }
@@ -0,0 +1,9 @@
1
+ // @smithers-type-exports-begin
2
+ /** @typedef {import("./MemoryStore.ts").MemoryStore} MemoryStore */
3
+ // @smithers-type-exports-end
4
+
5
+ export { MemoryStoreDb } from "./MemoryStoreDb.js";
6
+ export { MemoryStoreService } from "./MemoryStoreService.js";
7
+ export { MemoryStoreLive } from "./MemoryStoreLive.js";
8
+ export { createMemoryStoreLayer } from "./createMemoryStoreLayer.js";
9
+ export { createMemoryStore } from "./createMemoryStore.js";
package/src/types.js ADDED
@@ -0,0 +1,21 @@
1
+ // @smithers-type-exports-begin
2
+ /** @typedef {import("./MemoryFact.ts").MemoryFact} MemoryFact */
3
+ /** @typedef {import("./MemoryLayerConfig.ts").MemoryLayerConfig} MemoryLayerConfig */
4
+ /** @typedef {import("./MemoryMessage.ts").MemoryMessage} MemoryMessage */
5
+ /** @typedef {import("./MemoryNamespace.ts").MemoryNamespace} MemoryNamespace */
6
+ /** @typedef {import("./MemoryNamespaceKind.ts").MemoryNamespaceKind} MemoryNamespaceKind */
7
+ /** @typedef {import("./MemoryProcessor.ts").MemoryProcessor} MemoryProcessor */
8
+ /** @typedef {import("./MemoryProcessorConfig.ts").MemoryProcessorConfig} MemoryProcessorConfig */
9
+ /** @typedef {import("./MemoryServiceApi.ts").MemoryServiceApi} MemoryServiceApi */
10
+ /** @typedef {import("./MemoryThread.ts").MemoryThread} MemoryThread */
11
+ /** @typedef {import("./MessageHistoryConfig.ts").MessageHistoryConfig} MessageHistoryConfig */
12
+ /** @typedef {import("./SemanticRecallConfig.ts").SemanticRecallConfig} SemanticRecallConfig */
13
+ /** @typedef {import("./TaskMemoryConfig.ts").TaskMemoryConfig} TaskMemoryConfig */
14
+ /**
15
+ * @template {import("zod").z.ZodObject<any>} [T=import("zod").z.ZodObject<any>]
16
+ * @typedef {import("./WorkingMemoryConfig.ts").WorkingMemoryConfig<T>} WorkingMemoryConfig
17
+ */
18
+ // @smithers-type-exports-end
19
+
20
+ export { namespaceToString } from "./namespaceToString.js";
21
+ export { parseNamespace } from "./parseNamespace.js";