@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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/index.js +43 -21
- package/package.json +2 -2
- package/src/semantic-recall.ts +1 -1
- package/src/vector-store.ts +7 -1
- package/src/working-memory.ts +16 -1
- package/test/semantic-recall.test.ts +33 -0
- package/test/vector-store.test.ts +20 -0
- package/test/working-memory.test.ts +27 -0
package/.turbo/turbo-build.log
CHANGED
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) =>
|
|
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(
|
|
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,
|
|
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
|
+
"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.
|
|
17
|
+
"@batonfx/core": "0.3.6",
|
|
18
18
|
"effect": "4.0.0-beta.93"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
package/src/semantic-recall.ts
CHANGED
|
@@ -109,7 +109,7 @@ export const make = (
|
|
|
109
109
|
Effect.mapError(memoryError),
|
|
110
110
|
)
|
|
111
111
|
},
|
|
112
|
-
forget: (input) => store.delete(
|
|
112
|
+
forget: (input) => store.delete(input).pipe(Effect.mapError(memoryError)),
|
|
113
113
|
}
|
|
114
114
|
})
|
|
115
115
|
|
package/src/vector-store.ts
CHANGED
|
@@ -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) =>
|
|
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
|
)
|
package/src/working-memory.ts
CHANGED
|
@@ -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) =>
|
|
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
|
})
|