@batonfx/memory 0.4.0 → 0.4.1

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,155 +0,0 @@
1
- import { describe, expect, it } from "@effect/vitest"
2
- import { Effect, Layer, Stream } from "effect"
3
- import { LanguageModel, Prompt } from "effect/unstable/ai"
4
- import { Memory } from "@batonfx/core"
5
- import { WorkingMemory } from "../src/index"
6
-
7
- const key: Memory.Key = { agent: "memory-agent", subject: "subject-a" }
8
- const otherKey: Memory.Key = { agent: "memory-agent", subject: "subject-b" }
9
-
10
- const textPart = (text: string) => Prompt.makePart("text", { text })
11
- const user = (text: string) => Prompt.makeMessage("user", { content: [textPart(text)] })
12
- const assistant = (text: string) => Prompt.makeMessage("assistant", { content: [textPart(text)] })
13
- const prompt = (...messages: ReadonlyArray<Prompt.Message>) => Prompt.fromMessages(messages)
14
-
15
- const itemText = (item: Memory.Item): string =>
16
- item.parts
17
- .filter((part): part is Prompt.TextPart => part.type === "text")
18
- .map((part) => part.text)
19
- .join("")
20
-
21
- describe("WorkingMemory", () => {
22
- it.effect("keeps a bounded recent tail", () =>
23
- Effect.gen(function* () {
24
- const memory = yield* Memory.Memory
25
-
26
- yield* memory.remember({
27
- key,
28
- turn: 0,
29
- terminal: true,
30
- transcript: prompt(user("one"), assistant("two"), user("three")),
31
- })
32
-
33
- const recalled = yield* memory.recall({ key, turn: 0, prompt: prompt(user("current")) })
34
-
35
- expect(recalled.map(itemText)).toEqual(["Assistant: two", "User: three"])
36
- }).pipe(Effect.provide(WorkingMemory.layer({ maxMessages: 2 }))),
37
- )
38
-
39
- it.effect("summarizes overflow once and recalls summary before the recent tail", () => {
40
- let summaryCalls = 0
41
- let summaryPrompt = ""
42
- const summaryModel = Layer.effect(
43
- LanguageModel.LanguageModel,
44
- LanguageModel.make({
45
- generateText: (options) =>
46
- Effect.sync(() => {
47
- summaryCalls += 1
48
- summaryPrompt = JSON.stringify(options.prompt.content)
49
- return [{ type: "text", text: "summary" }]
50
- }),
51
- streamText: () => Stream.empty,
52
- }),
53
- )
54
-
55
- return Effect.gen(function* () {
56
- const memory = yield* Memory.Memory
57
-
58
- yield* memory.remember({
59
- key,
60
- turn: 0,
61
- terminal: true,
62
- transcript: prompt(user("one"), assistant("two"), user("three"), assistant("four")),
63
- })
64
-
65
- const recalled = yield* memory.recall({ key, turn: 0, prompt: prompt(user("current")) })
66
-
67
- expect(summaryCalls).toBe(1)
68
- expect(summaryPrompt).toContain("one")
69
- expect(summaryPrompt).toContain("two")
70
- expect(recalled.map(itemText)).toEqual([
71
- "<working-memory-summary>\nsummary\n</working-memory-summary>",
72
- "User: three",
73
- "Assistant: four",
74
- ])
75
- }).pipe(
76
- Effect.provide(
77
- WorkingMemory.layer({
78
- maxMessages: 2,
79
- summarize: { model: summaryModel },
80
- }),
81
- ),
82
- )
83
- })
84
-
85
- it.effect("isolates state by memory key", () =>
86
- Effect.gen(function* () {
87
- const memory = yield* Memory.Memory
88
-
89
- yield* memory.remember({
90
- key,
91
- turn: 0,
92
- terminal: true,
93
- transcript: prompt(user("one"), assistant("two")),
94
- })
95
-
96
- const recalled = yield* memory.recall({ key: otherKey, turn: 0, prompt: prompt(user("current")) })
97
-
98
- expect(recalled).toEqual([])
99
- }).pipe(Effect.provide(WorkingMemory.layer({ maxMessages: 2 }))),
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
- )
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
- )
155
- })
package/tsconfig.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "rootDir": "."
5
- },
6
- "include": ["src/**/*.ts", "test/**/*.ts"]
7
- }