@batonfx/memory 0.3.3 → 0.3.4

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.
@@ -1,5 +1,5 @@
1
1
  $ bun build ./src/index.ts --outdir dist --target bun --format esm
2
- Bundled 176 modules in 529ms
2
+ Bundled 176 modules in 523ms
3
3
 
4
4
  index.js 1.1 MB (entry point)
5
5
 
package/dist/index.js CHANGED
@@ -32662,11 +32662,13 @@ class Memory extends exports_Context.Service()("@batonfx/core/Memory") {
32662
32662
  }
32663
32663
  var noop = {
32664
32664
  recall: () => exports_Effect.succeed([]),
32665
- remember: () => exports_Effect.void
32665
+ remember: () => exports_Effect.void,
32666
+ forget: () => exports_Effect.void
32666
32667
  };
32667
32668
  var merge6 = (first, second) => ({
32668
32669
  recall: (input) => exports_Effect.all([first.recall(input), second.recall(input)]).pipe(exports_Effect.map(([firstItems, secondItems]) => [...firstItems, ...secondItems])),
32669
- remember: (input) => exports_Effect.all([first.remember(input), second.remember(input)], { discard: true })
32670
+ remember: (input) => exports_Effect.all([first.remember(input), second.remember(input)], { discard: true }),
32671
+ forget: (input) => exports_Effect.all([first.forget(input), second.forget(input)], { discard: true })
32670
32672
  });
32671
32673
  var noopLayer = exports_Layer.succeed(Memory, Memory.of(noop));
32672
32674
  var testLayer = (implementation) => exports_Layer.succeed(Memory, Memory.of(implementation));
@@ -32862,7 +32864,8 @@ var make37 = exports_Ref.make(exports_HashMap.empty()).pipe(exports_Effect.map((
32862
32864
  matches.push({ document, score });
32863
32865
  }
32864
32866
  return matches.toSorted((left, right) => right.score - left.score).slice(0, input.limit);
32865
- })
32867
+ }),
32868
+ delete: (input) => exports_Ref.update(documents, (current) => exports_HashMap.filter(current, (document) => !sameKey(document.key, input.key)))
32866
32869
  })));
32867
32870
  var memoryLayer2 = exports_Layer.effect(VectorStore, make37.pipe(exports_Effect.map(VectorStore.of)));
32868
32871
  var testLayer2 = (implementation) => exports_Layer.succeed(VectorStore, VectorStore.of(implementation));
@@ -32939,7 +32942,8 @@ var make38 = (options = {}) => exports_Effect.gen(function* () {
32939
32942
  embedding: embedding.vector
32940
32943
  }
32941
32944
  ])))), exports_Effect.mapError(memoryError));
32942
- }
32945
+ },
32946
+ forget: (input) => store.delete({ key: input.key }).pipe(exports_Effect.mapError(memoryError))
32943
32947
  };
32944
32948
  });
32945
32949
  var makeSemanticRecall = make38;
@@ -33064,7 +33068,8 @@ var make39 = (options = {}) => exports_Ref.make(exports_HashMap.empty()).pipe(ex
33064
33068
  };
33065
33069
  yield* exports_Ref.update(states, exports_HashMap.set(id2, nextState));
33066
33070
  });
33067
- }
33071
+ },
33072
+ forget: (input) => exports_Ref.update(states, exports_HashMap.remove(keyId(input.key)))
33068
33073
  };
33069
33074
  }));
33070
33075
  var makeWorkingMemory = make39;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@batonfx/memory",
4
- "version": "0.3.3",
4
+ "version": "0.3.4",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "exports": {
@@ -14,7 +14,7 @@
14
14
  "typecheck": "bun tsc --noEmit"
15
15
  },
16
16
  "dependencies": {
17
- "@batonfx/core": "0.3.3",
17
+ "@batonfx/core": "0.3.4",
18
18
  "effect": "4.0.0-beta.93"
19
19
  },
20
20
  "devDependencies": {
@@ -109,6 +109,7 @@ export const make = (
109
109
  Effect.mapError(memoryError),
110
110
  )
111
111
  },
112
+ forget: (input) => store.delete({ key: input.key }).pipe(Effect.mapError(memoryError)),
112
113
  }
113
114
  })
114
115
 
@@ -28,6 +28,11 @@ export interface Query {
28
28
  readonly minScore?: number
29
29
  }
30
30
 
31
+ /** @experimental */
32
+ export interface DeleteInput {
33
+ readonly key: Memory.Key
34
+ }
35
+
31
36
  /** @experimental */
32
37
  export class VectorStoreError extends Schema.TaggedErrorClass<VectorStoreError>()("@batonfx/memory/VectorStoreError", {
33
38
  message: Schema.String,
@@ -37,6 +42,7 @@ export class VectorStoreError extends Schema.TaggedErrorClass<VectorStoreError>(
37
42
  export interface Interface {
38
43
  readonly upsert: (documents: ReadonlyArray<Embedded>) => Effect.Effect<void, VectorStoreError>
39
44
  readonly query: (query: Query) => Effect.Effect<ReadonlyArray<Match>, VectorStoreError>
45
+ readonly delete: (input: DeleteInput) => Effect.Effect<void, VectorStoreError>
40
46
  }
41
47
 
42
48
  /** @experimental */
@@ -106,6 +112,8 @@ const make = Ref.make(HashMap.empty<string, Embedded>()).pipe(
106
112
  }
107
113
  return matches.toSorted((left, right) => right.score - left.score).slice(0, input.limit)
108
114
  }),
115
+ delete: (input) =>
116
+ Ref.update(documents, (current) => HashMap.filter(current, (document) => !sameKey(document.key, input.key))),
109
117
  }),
110
118
  ),
111
119
  )
@@ -180,6 +180,7 @@ export const make = (options: Options = {}): Effect.Effect<Memory.Interface> =>
180
180
  yield* Ref.update(states, HashMap.set(id, nextState))
181
181
  })
182
182
  },
183
+ forget: (input) => Ref.update(states, HashMap.remove(keyId(input.key))),
183
184
  }
184
185
  }),
185
186
  )
@@ -79,4 +79,23 @@ describe("VectorStore", () => {
79
79
  expect(failure.message).toContain("dimension")
80
80
  }).pipe(Effect.provide(VectorStore.memoryLayer)),
81
81
  )
82
+
83
+ it.effect("deletes documents for the exact memory key", () =>
84
+ Effect.gen(function* () {
85
+ const store = yield* VectorStore.VectorStore
86
+
87
+ yield* store.upsert([
88
+ document("same-id", key, "visible", [1, 0]),
89
+ document("same-id", otherSubject, "other subject", [1, 0]),
90
+ ])
91
+
92
+ yield* store.delete({ key })
93
+
94
+ const deletedMatches = yield* store.query({ key, embedding: [1, 0], limit: 10 })
95
+ const remainingMatches = yield* store.query({ key: otherSubject, embedding: [1, 0], limit: 10 })
96
+
97
+ expect(deletedMatches).toEqual([])
98
+ expect(remainingMatches.map((match) => match.document.text)).toEqual(["other subject"])
99
+ }).pipe(Effect.provide(VectorStore.memoryLayer)),
100
+ )
82
101
  })
@@ -98,4 +98,31 @@ describe("WorkingMemory", () => {
98
98
  expect(recalled).toEqual([])
99
99
  }).pipe(Effect.provide(WorkingMemory.layer({ maxMessages: 2 }))),
100
100
  )
101
+
102
+ it.effect("forgets the exact memory key", () =>
103
+ Effect.gen(function* () {
104
+ const memory = yield* Memory.Memory
105
+
106
+ yield* memory.remember({
107
+ key,
108
+ turn: 0,
109
+ terminal: true,
110
+ transcript: prompt(user("one"), assistant("two")),
111
+ })
112
+ yield* memory.remember({
113
+ key: otherKey,
114
+ turn: 0,
115
+ terminal: true,
116
+ transcript: prompt(user("three"), assistant("four")),
117
+ })
118
+
119
+ yield* memory.forget({ key })
120
+
121
+ const forgotten = yield* memory.recall({ key, turn: 0, prompt: prompt(user("current")) })
122
+ const retained = yield* memory.recall({ key: otherKey, turn: 0, prompt: prompt(user("current")) })
123
+
124
+ expect(forgotten).toEqual([])
125
+ expect(retained.map(itemText)).toEqual(["User: three", "Assistant: four"])
126
+ }).pipe(Effect.provide(WorkingMemory.layer({ maxMessages: 2 }))),
127
+ )
101
128
  })