@batonfx/memory 0.3.4 → 0.3.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.
@@ -1,5 +1,5 @@
1
1
  $ bun build ./src/index.ts --outdir dist --target bun --format esm
2
- Bundled 176 modules in 523ms
2
+ Bundled 176 modules in 368ms
3
3
 
4
4
  index.js 1.1 MB (entry point)
5
5
 
package/dist/index.js CHANGED
@@ -32678,6 +32678,25 @@ class ModelMiddleware extends exports_Context.Service()("@batonfx/core/ModelMidd
32678
32678
  }
32679
32679
  var identityLayer = exports_Layer.succeed(ModelMiddleware, []);
32680
32680
 
32681
+ // ../core/src/model-registry.ts
32682
+ class LanguageModelNotRegistered extends exports_Schema.TaggedErrorClass()("LanguageModelNotRegistered", {
32683
+ provider: exports_Schema.String,
32684
+ model: exports_Schema.String,
32685
+ registration_key: exports_Schema.optionalKey(exports_Schema.String)
32686
+ }) {
32687
+ }
32688
+
32689
+ class Service2 extends exports_Context.Service()("@batonfx/core/ModelRegistry") {
32690
+ }
32691
+ var register = exports_Effect.fn("ModelRegistry.register.call")(function* (input) {
32692
+ const service3 = yield* Service2;
32693
+ return yield* service3.register(input);
32694
+ });
32695
+ var registrations = exports_Effect.fn("ModelRegistry.registrations.call")(function* () {
32696
+ const service3 = yield* Service2;
32697
+ return yield* service3.registrations;
32698
+ });
32699
+
32681
32700
  // ../core/src/model-resilience.ts
32682
32701
  class ModelResilience extends exports_Context.Service()("@batonfx/core/ModelResilience") {
32683
32702
  }
@@ -32769,24 +32788,6 @@ var activateSkillTool = exports_Tool.make(activateSkillToolName, {
32769
32788
  var defaultParameters = exports_Schema.Struct({ prompt: exports_Schema.String });
32770
32789
  // ../core/src/handoff.ts
32771
32790
  var defaultTransferParameters = exports_Schema.Struct({ prompt: exports_Schema.String });
32772
- // ../core/src/model-registry.ts
32773
- class LanguageModelNotRegistered extends exports_Schema.TaggedErrorClass()("LanguageModelNotRegistered", {
32774
- provider: exports_Schema.String,
32775
- model: exports_Schema.String,
32776
- registration_key: exports_Schema.optionalKey(exports_Schema.String)
32777
- }) {
32778
- }
32779
-
32780
- class Service2 extends exports_Context.Service()("@batonfx/core/ModelRegistry") {
32781
- }
32782
- var register = exports_Effect.fn("ModelRegistry.register.call")(function* (input) {
32783
- const service3 = yield* Service2;
32784
- return yield* service3.register(input);
32785
- });
32786
- var registrations = exports_Effect.fn("ModelRegistry.registrations.call")(function* () {
32787
- const service3 = yield* Service2;
32788
- return yield* service3.registrations;
32789
- });
32790
32791
  // src/semantic-recall.ts
32791
32792
  var exports_semantic_recall = {};
32792
32793
  __export(exports_semantic_recall, {
@@ -32865,7 +32866,11 @@ var make37 = exports_Ref.make(exports_HashMap.empty()).pipe(exports_Effect.map((
32865
32866
  }
32866
32867
  return matches.toSorted((left, right) => right.score - left.score).slice(0, input.limit);
32867
32868
  }),
32868
- delete: (input) => exports_Ref.update(documents, (current) => exports_HashMap.filter(current, (document) => !sameKey(document.key, input.key)))
32869
+ delete: (input) => exports_Ref.update(documents, (current) => exports_HashMap.filter(current, (document) => {
32870
+ if (!sameKey(document.key, input.key))
32871
+ return true;
32872
+ return input.id === undefined ? false : document.id !== input.id;
32873
+ }))
32869
32874
  })));
32870
32875
  var memoryLayer2 = exports_Layer.effect(VectorStore, make37.pipe(exports_Effect.map(VectorStore.of)));
32871
32876
  var testLayer2 = (implementation) => exports_Layer.succeed(VectorStore, VectorStore.of(implementation));
@@ -32943,7 +32948,7 @@ var make38 = (options = {}) => exports_Effect.gen(function* () {
32943
32948
  }
32944
32949
  ])))), exports_Effect.mapError(memoryError));
32945
32950
  },
32946
- forget: (input) => store.delete({ key: input.key }).pipe(exports_Effect.mapError(memoryError))
32951
+ forget: (input) => store.delete(input).pipe(exports_Effect.mapError(memoryError))
32947
32952
  };
32948
32953
  });
32949
32954
  var makeSemanticRecall = make38;
@@ -33069,7 +33074,24 @@ var make39 = (options = {}) => exports_Ref.make(exports_HashMap.empty()).pipe(ex
33069
33074
  yield* exports_Ref.update(states, exports_HashMap.set(id2, nextState));
33070
33075
  });
33071
33076
  },
33072
- forget: (input) => exports_Ref.update(states, exports_HashMap.remove(keyId(input.key)))
33077
+ forget: (input) => exports_Ref.update(states, (current) => {
33078
+ const id2 = keyId(input.key);
33079
+ if (input.id === undefined)
33080
+ return exports_HashMap.remove(current, id2);
33081
+ const existing = exports_HashMap.get(current, id2);
33082
+ if (existing._tag === "None")
33083
+ return current;
33084
+ const summary = input.id === "working-summary" ? undefined : existing.value.summary;
33085
+ const recent = existing.value.recent.filter((item) => item.id !== input.id);
33086
+ if (summary === undefined && recent.length === 0)
33087
+ return exports_HashMap.remove(current, id2);
33088
+ const nextState = {
33089
+ recent,
33090
+ counter: existing.value.counter,
33091
+ ...summary === undefined ? {} : { summary }
33092
+ };
33093
+ return exports_HashMap.set(current, id2, nextState);
33094
+ })
33073
33095
  };
33074
33096
  }));
33075
33097
  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.4",
4
+ "version": "0.3.6",
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.4",
17
+ "@batonfx/core": "0.3.6",
18
18
  "effect": "4.0.0-beta.93"
19
19
  },
20
20
  "devDependencies": {
@@ -109,7 +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
+ forget: (input) => store.delete(input).pipe(Effect.mapError(memoryError)),
113
113
  }
114
114
  })
115
115
 
@@ -31,6 +31,7 @@ export interface Query {
31
31
  /** @experimental */
32
32
  export interface DeleteInput {
33
33
  readonly key: Memory.Key
34
+ readonly id?: string | undefined
34
35
  }
35
36
 
36
37
  /** @experimental */
@@ -113,7 +114,12 @@ const make = Ref.make(HashMap.empty<string, Embedded>()).pipe(
113
114
  return matches.toSorted((left, right) => right.score - left.score).slice(0, input.limit)
114
115
  }),
115
116
  delete: (input) =>
116
- Ref.update(documents, (current) => HashMap.filter(current, (document) => !sameKey(document.key, input.key))),
117
+ Ref.update(documents, (current) =>
118
+ HashMap.filter(current, (document) => {
119
+ if (!sameKey(document.key, input.key)) return true
120
+ return input.id === undefined ? false : document.id !== input.id
121
+ }),
122
+ ),
117
123
  }),
118
124
  ),
119
125
  )
@@ -180,7 +180,22 @@ 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
+ forget: (input) =>
184
+ Ref.update(states, (current) => {
185
+ const id = keyId(input.key)
186
+ if (input.id === undefined) return HashMap.remove(current, id)
187
+ const existing = HashMap.get(current, id)
188
+ if (existing._tag === "None") return current
189
+ const summary = input.id === "working-summary" ? undefined : existing.value.summary
190
+ const recent = existing.value.recent.filter((item) => item.id !== input.id)
191
+ if (summary === undefined && recent.length === 0) return HashMap.remove(current, id)
192
+ const nextState: KeyState = {
193
+ recent,
194
+ counter: existing.value.counter,
195
+ ...(summary === undefined ? {} : { summary }),
196
+ }
197
+ return HashMap.set(current, id, nextState)
198
+ }),
184
199
  }
185
200
  }),
186
201
  )
@@ -91,6 +91,39 @@ describe("SemanticRecall", () => {
91
91
  }).pipe(Effect.provide(memoryLayer)),
92
92
  )
93
93
 
94
+ it.effect("forgets one semantic memory id within the exact memory key", () =>
95
+ Effect.gen(function* () {
96
+ const memory = yield* Memory.Memory
97
+
98
+ yield* memory.remember({
99
+ key,
100
+ turn: 0,
101
+ terminal: true,
102
+ transcript: prompt(user("What color is the sky?"), assistant("blue")),
103
+ })
104
+ yield* memory.remember({
105
+ key,
106
+ turn: 1,
107
+ terminal: true,
108
+ transcript: prompt(user("What color is the ocean?"), assistant("blue")),
109
+ })
110
+ yield* memory.remember({
111
+ key: otherKey,
112
+ turn: 0,
113
+ terminal: true,
114
+ transcript: prompt(user("What color is the door?"), assistant("blue")),
115
+ })
116
+
117
+ yield* memory.forget({ key, id: "semantic-1" })
118
+
119
+ const retained = yield* memory.recall({ key, turn: 0, prompt: prompt(user("color")) })
120
+ const otherRetained = yield* memory.recall({ key: otherKey, turn: 0, prompt: prompt(user("color")) })
121
+
122
+ expect(retained.map(itemText)).toEqual(["User: What color is the ocean?\nAssistant: blue"])
123
+ expect(otherRetained.map(itemText)).toEqual(["User: What color is the door?\nAssistant: blue"])
124
+ }).pipe(Effect.provide(memoryLayer)),
125
+ )
126
+
94
127
  it.effect("maps embedding failures to MemoryError", () => {
95
128
  const embeddingError = AiError.make({
96
129
  module: "SemanticRecallTest",
@@ -98,4 +98,24 @@ describe("VectorStore", () => {
98
98
  expect(remainingMatches.map((match) => match.document.text)).toEqual(["other subject"])
99
99
  }).pipe(Effect.provide(VectorStore.memoryLayer)),
100
100
  )
101
+
102
+ it.effect("deletes one document id within the exact memory key", () =>
103
+ Effect.gen(function* () {
104
+ const store = yield* VectorStore.VectorStore
105
+
106
+ yield* store.upsert([
107
+ document("first", key, "first", [1, 0]),
108
+ document("second", key, "second", [0, 1]),
109
+ document("first", otherSubject, "other subject", [1, 0]),
110
+ ])
111
+
112
+ yield* store.delete({ key, id: "first" })
113
+
114
+ const deletedKeyMatches = yield* store.query({ key, embedding: [1, 0], limit: 10 })
115
+ const otherSubjectMatches = yield* store.query({ key: otherSubject, embedding: [1, 0], limit: 10 })
116
+
117
+ expect(deletedKeyMatches.map((match) => match.document.text)).toEqual(["second"])
118
+ expect(otherSubjectMatches.map((match) => match.document.text)).toEqual(["other subject"])
119
+ }).pipe(Effect.provide(VectorStore.memoryLayer)),
120
+ )
101
121
  })
@@ -125,4 +125,31 @@ describe("WorkingMemory", () => {
125
125
  expect(retained.map(itemText)).toEqual(["User: three", "Assistant: four"])
126
126
  }).pipe(Effect.provide(WorkingMemory.layer({ maxMessages: 2 }))),
127
127
  )
128
+
129
+ it.effect("forgets one recalled item id within the exact memory key", () =>
130
+ Effect.gen(function* () {
131
+ const memory = yield* Memory.Memory
132
+
133
+ yield* memory.remember({
134
+ key,
135
+ turn: 0,
136
+ terminal: true,
137
+ transcript: prompt(user("one"), assistant("two")),
138
+ })
139
+ yield* memory.remember({
140
+ key: otherKey,
141
+ turn: 0,
142
+ terminal: true,
143
+ transcript: prompt(user("three"), assistant("four")),
144
+ })
145
+
146
+ yield* memory.forget({ key, id: "working-1" })
147
+
148
+ const retained = yield* memory.recall({ key, turn: 0, prompt: prompt(user("current")) })
149
+ const otherRetained = yield* memory.recall({ key: otherKey, turn: 0, prompt: prompt(user("current")) })
150
+
151
+ expect(retained.map(itemText)).toEqual(["Assistant: two"])
152
+ expect(otherRetained.map(itemText)).toEqual(["User: three", "Assistant: four"])
153
+ }).pipe(Effect.provide(WorkingMemory.layer({ maxMessages: 2 }))),
154
+ )
128
155
  })