@mastra/memory 0.10.1-alpha.0 → 0.10.2-alpha.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.
- package/.turbo/turbo-build.log +3 -20
- package/CHANGELOG.md +26 -0
- package/dist/_tsup-dts-rollup.d.cts +11 -18
- package/dist/_tsup-dts-rollup.d.ts +11 -18
- package/dist/index.cjs +86 -135
- package/dist/index.js +86 -135
- package/package.json +4 -4
- package/src/index.ts +125 -136
- package/src/processors/index.test.ts +10 -10
- package/vitest.config.ts +3 -0
- package/src/utils/index.ts +0 -88
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/memory@0.10.
|
|
3
|
-
> pnpm run check && tsup src/index.ts src/processors/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
2
|
+
> @mastra/memory@0.10.2-alpha.0 build /home/runner/work/mastra/mastra/packages/memory
|
|
3
|
+
> pnpm run check && tsup --silent src/index.ts src/processors/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @mastra/memory@0.10.
|
|
6
|
+
> @mastra/memory@0.10.2-alpha.0 check /home/runner/work/mastra/mastra/packages/memory
|
|
7
7
|
> tsc --noEmit
|
|
8
8
|
|
|
9
|
-
[34mCLI[39m Building entry: src/index.ts, src/processors/index.ts
|
|
10
|
-
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
11
|
-
[34mCLI[39m tsup v8.4.0
|
|
12
|
-
[34mTSC[39m Build start
|
|
13
|
-
[32mTSC[39m ⚡️ Build success in 9122ms
|
|
14
|
-
[34mDTS[39m Build start
|
|
15
|
-
[34mCLI[39m Target: es2022
|
|
16
9
|
Analysis will use the bundled TypeScript version 5.8.3
|
|
17
10
|
[36mWriting package typings: /home/runner/work/mastra/mastra/packages/memory/dist/_tsup-dts-rollup.d.ts[39m
|
|
18
11
|
Analysis will use the bundled TypeScript version 5.8.3
|
|
19
12
|
[36mWriting package typings: /home/runner/work/mastra/mastra/packages/memory/dist/_tsup-dts-rollup.d.cts[39m
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in 11021ms
|
|
21
|
-
[34mCLI[39m Cleaning output folder
|
|
22
|
-
[34mESM[39m Build start
|
|
23
|
-
[34mCJS[39m Build start
|
|
24
|
-
[32mCJS[39m [1mdist/processors/index.cjs [22m[32m5.59 KB[39m
|
|
25
|
-
[32mCJS[39m [1mdist/index.cjs [22m[32m18.70 KB[39m
|
|
26
|
-
[32mCJS[39m ⚡️ Build success in 529ms
|
|
27
|
-
[32mESM[39m [1mdist/processors/index.js [22m[32m5.38 KB[39m
|
|
28
|
-
[32mESM[39m [1mdist/index.js [22m[32m18.51 KB[39m
|
|
29
|
-
[32mESM[39m ⚡️ Build success in 529ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @mastra/memory
|
|
2
2
|
|
|
3
|
+
## 0.10.2-alpha.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e5dc18d: Added a backwards compatible layer to begin storing/retrieving UIMessages in storage instead of CoreMessages
|
|
8
|
+
- Updated dependencies [592a2db]
|
|
9
|
+
- Updated dependencies [e5dc18d]
|
|
10
|
+
- @mastra/core@0.10.2-alpha.0
|
|
11
|
+
|
|
12
|
+
## 0.10.1
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- d70b807: Improve storage.init
|
|
17
|
+
- Updated dependencies [d70b807]
|
|
18
|
+
- Updated dependencies [6d16390]
|
|
19
|
+
- Updated dependencies [1e4a421]
|
|
20
|
+
- Updated dependencies [200d0da]
|
|
21
|
+
- Updated dependencies [bf5f17b]
|
|
22
|
+
- Updated dependencies [5343f93]
|
|
23
|
+
- Updated dependencies [38aee50]
|
|
24
|
+
- Updated dependencies [5c41100]
|
|
25
|
+
- Updated dependencies [d6a759b]
|
|
26
|
+
- Updated dependencies [6015bdf]
|
|
27
|
+
- @mastra/core@0.10.1
|
|
28
|
+
|
|
3
29
|
## 0.10.1-alpha.0
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import type { AiMessageType } from '@mastra/core';
|
|
2
1
|
import type { CoreMessage } from '@mastra/core';
|
|
3
2
|
import type { CoreTool } from '@mastra/core';
|
|
4
3
|
import { MastraMemory } from '@mastra/core/memory';
|
|
4
|
+
import type { MastraMessageV1 } from '@mastra/core';
|
|
5
|
+
import type { MastraMessageV2 } from '@mastra/core/agent';
|
|
5
6
|
import type { MemoryConfig } from '@mastra/core/memory';
|
|
6
7
|
import { MemoryProcessor } from '@mastra/core/memory';
|
|
7
8
|
import { MemoryProcessor as MemoryProcessor_2 } from '@mastra/core';
|
|
8
9
|
import type { MemoryProcessorOpts } from '@mastra/core';
|
|
9
|
-
import type { MessageType } from '@mastra/core/memory';
|
|
10
10
|
import type { SharedMemoryConfig } from '@mastra/core/memory';
|
|
11
11
|
import type { StorageGetMessagesArg } from '@mastra/core/storage';
|
|
12
12
|
import type { StorageThreadType } from '@mastra/core/memory';
|
|
13
13
|
import type { TiktokenBPE } from 'js-tiktoken/lite';
|
|
14
|
+
import type { UIMessage } from 'ai';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Concrete implementation of MastraMemory that adds support for thread configuration
|
|
@@ -22,8 +23,8 @@ export declare class Memory extends MastraMemory {
|
|
|
22
23
|
query({ threadId, resourceId, selectBy, threadConfig, }: StorageGetMessagesArg & {
|
|
23
24
|
threadConfig?: MemoryConfig;
|
|
24
25
|
}): Promise<{
|
|
25
|
-
messages:
|
|
26
|
-
uiMessages:
|
|
26
|
+
messages: MastraMessageV1[];
|
|
27
|
+
uiMessages: UIMessage[];
|
|
27
28
|
}>;
|
|
28
29
|
rememberMessages({ threadId, resourceId, vectorMessageSearch, config, }: {
|
|
29
30
|
threadId: string;
|
|
@@ -31,9 +32,8 @@ export declare class Memory extends MastraMemory {
|
|
|
31
32
|
vectorMessageSearch?: string;
|
|
32
33
|
config?: MemoryConfig;
|
|
33
34
|
}): Promise<{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
uiMessages: AiMessageType[];
|
|
35
|
+
messages: MastraMessageV1[];
|
|
36
|
+
messagesV2: MastraMessageV2[];
|
|
37
37
|
}>;
|
|
38
38
|
getThreadById({ threadId }: {
|
|
39
39
|
threadId: string;
|
|
@@ -57,31 +57,24 @@ export declare class Memory extends MastraMemory {
|
|
|
57
57
|
private firstEmbed;
|
|
58
58
|
private embedMessageContent;
|
|
59
59
|
saveMessages({ messages, memoryConfig, }: {
|
|
60
|
-
messages:
|
|
60
|
+
messages: (MastraMessageV1 | MastraMessageV2)[];
|
|
61
61
|
memoryConfig?: MemoryConfig;
|
|
62
|
-
}): Promise<
|
|
63
|
-
protected
|
|
62
|
+
}): Promise<MastraMessageV2[]>;
|
|
63
|
+
protected updateMessageToHideWorkingMemory(message: MastraMessageV1): MastraMessageV1 | null;
|
|
64
|
+
protected updateMessageToHideWorkingMemoryV2(message: MastraMessageV2): MastraMessageV2 | null;
|
|
64
65
|
protected parseWorkingMemory(text: string): string | null;
|
|
65
66
|
getWorkingMemory({ threadId }: {
|
|
66
67
|
threadId: string;
|
|
67
68
|
}): Promise<string | null>;
|
|
68
|
-
private saveWorkingMemory;
|
|
69
69
|
getSystemMessage({ threadId, memoryConfig, }: {
|
|
70
70
|
threadId: string;
|
|
71
71
|
memoryConfig?: MemoryConfig;
|
|
72
72
|
}): Promise<string | null>;
|
|
73
73
|
defaultWorkingMemoryTemplate: string;
|
|
74
|
-
private getWorkingMemoryWithInstruction;
|
|
75
74
|
private getWorkingMemoryToolInstruction;
|
|
76
75
|
getTools(config?: MemoryConfig): Record<string, CoreTool>;
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
/**
|
|
80
|
-
* Self-heals message ordering to ensure tool calls are directly before their matching tool results.
|
|
81
|
-
* This is needed due to a bug where messages were saved in the wrong order. That bug is fixed, but this code ensures any tool calls saved in the wrong order in the past will still be usable now.
|
|
82
|
-
*/
|
|
83
|
-
export declare function reorderToolCallsAndResults(messages: MessageType[]): MessageType[];
|
|
84
|
-
|
|
85
78
|
/**
|
|
86
79
|
* Limits the total number of tokens in the messages.
|
|
87
80
|
* Uses js-tiktoken with o200k_base encoding by default for accurate token counting with modern models.
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import type { AiMessageType } from '@mastra/core';
|
|
2
1
|
import type { CoreMessage } from '@mastra/core';
|
|
3
2
|
import type { CoreTool } from '@mastra/core';
|
|
4
3
|
import { MastraMemory } from '@mastra/core/memory';
|
|
4
|
+
import type { MastraMessageV1 } from '@mastra/core';
|
|
5
|
+
import type { MastraMessageV2 } from '@mastra/core/agent';
|
|
5
6
|
import type { MemoryConfig } from '@mastra/core/memory';
|
|
6
7
|
import { MemoryProcessor } from '@mastra/core/memory';
|
|
7
8
|
import { MemoryProcessor as MemoryProcessor_2 } from '@mastra/core';
|
|
8
9
|
import type { MemoryProcessorOpts } from '@mastra/core';
|
|
9
|
-
import type { MessageType } from '@mastra/core/memory';
|
|
10
10
|
import type { SharedMemoryConfig } from '@mastra/core/memory';
|
|
11
11
|
import type { StorageGetMessagesArg } from '@mastra/core/storage';
|
|
12
12
|
import type { StorageThreadType } from '@mastra/core/memory';
|
|
13
13
|
import type { TiktokenBPE } from 'js-tiktoken/lite';
|
|
14
|
+
import type { UIMessage } from 'ai';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Concrete implementation of MastraMemory that adds support for thread configuration
|
|
@@ -22,8 +23,8 @@ export declare class Memory extends MastraMemory {
|
|
|
22
23
|
query({ threadId, resourceId, selectBy, threadConfig, }: StorageGetMessagesArg & {
|
|
23
24
|
threadConfig?: MemoryConfig;
|
|
24
25
|
}): Promise<{
|
|
25
|
-
messages:
|
|
26
|
-
uiMessages:
|
|
26
|
+
messages: MastraMessageV1[];
|
|
27
|
+
uiMessages: UIMessage[];
|
|
27
28
|
}>;
|
|
28
29
|
rememberMessages({ threadId, resourceId, vectorMessageSearch, config, }: {
|
|
29
30
|
threadId: string;
|
|
@@ -31,9 +32,8 @@ export declare class Memory extends MastraMemory {
|
|
|
31
32
|
vectorMessageSearch?: string;
|
|
32
33
|
config?: MemoryConfig;
|
|
33
34
|
}): Promise<{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
uiMessages: AiMessageType[];
|
|
35
|
+
messages: MastraMessageV1[];
|
|
36
|
+
messagesV2: MastraMessageV2[];
|
|
37
37
|
}>;
|
|
38
38
|
getThreadById({ threadId }: {
|
|
39
39
|
threadId: string;
|
|
@@ -57,31 +57,24 @@ export declare class Memory extends MastraMemory {
|
|
|
57
57
|
private firstEmbed;
|
|
58
58
|
private embedMessageContent;
|
|
59
59
|
saveMessages({ messages, memoryConfig, }: {
|
|
60
|
-
messages:
|
|
60
|
+
messages: (MastraMessageV1 | MastraMessageV2)[];
|
|
61
61
|
memoryConfig?: MemoryConfig;
|
|
62
|
-
}): Promise<
|
|
63
|
-
protected
|
|
62
|
+
}): Promise<MastraMessageV2[]>;
|
|
63
|
+
protected updateMessageToHideWorkingMemory(message: MastraMessageV1): MastraMessageV1 | null;
|
|
64
|
+
protected updateMessageToHideWorkingMemoryV2(message: MastraMessageV2): MastraMessageV2 | null;
|
|
64
65
|
protected parseWorkingMemory(text: string): string | null;
|
|
65
66
|
getWorkingMemory({ threadId }: {
|
|
66
67
|
threadId: string;
|
|
67
68
|
}): Promise<string | null>;
|
|
68
|
-
private saveWorkingMemory;
|
|
69
69
|
getSystemMessage({ threadId, memoryConfig, }: {
|
|
70
70
|
threadId: string;
|
|
71
71
|
memoryConfig?: MemoryConfig;
|
|
72
72
|
}): Promise<string | null>;
|
|
73
73
|
defaultWorkingMemoryTemplate: string;
|
|
74
|
-
private getWorkingMemoryWithInstruction;
|
|
75
74
|
private getWorkingMemoryToolInstruction;
|
|
76
75
|
getTools(config?: MemoryConfig): Record<string, CoreTool>;
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
/**
|
|
80
|
-
* Self-heals message ordering to ensure tool calls are directly before their matching tool results.
|
|
81
|
-
* This is needed due to a bug where messages were saved in the wrong order. That bug is fixed, but this code ensures any tool calls saved in the wrong order in the past will still be usable now.
|
|
82
|
-
*/
|
|
83
|
-
export declare function reorderToolCallsAndResults(messages: MessageType[]): MessageType[];
|
|
84
|
-
|
|
85
78
|
/**
|
|
86
79
|
* Limits the total number of tokens in the messages.
|
|
87
80
|
* Uses js-tiktoken with o200k_base encoding by default for accurate token counting with modern models.
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var core = require('@mastra/core');
|
|
4
|
+
var agent = require('@mastra/core/agent');
|
|
4
5
|
var memory = require('@mastra/core/memory');
|
|
5
6
|
var ai = require('ai');
|
|
6
7
|
var xxhash = require('xxhash-wasm');
|
|
@@ -38,48 +39,6 @@ var updateWorkingMemoryTool = {
|
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
41
|
|
|
41
|
-
// src/utils/index.ts
|
|
42
|
-
var isToolCallWithId = (message, targetToolCallId) => {
|
|
43
|
-
if (!message || !Array.isArray(message.content)) return false;
|
|
44
|
-
return message.content.some(
|
|
45
|
-
(part) => part && typeof part === "object" && "type" in part && part.type === "tool-call" && "toolCallId" in part && part.toolCallId === targetToolCallId
|
|
46
|
-
);
|
|
47
|
-
};
|
|
48
|
-
var getToolResultIndexById = (id, results) => results.findIndex((message) => {
|
|
49
|
-
if (!Array.isArray(message?.content)) return false;
|
|
50
|
-
return message.content.some(
|
|
51
|
-
(part) => part && typeof part === "object" && "type" in part && part.type === "tool-result" && "toolCallId" in part && part.toolCallId === id
|
|
52
|
-
);
|
|
53
|
-
});
|
|
54
|
-
function reorderToolCallsAndResults(messages) {
|
|
55
|
-
if (!messages.length) return messages;
|
|
56
|
-
const results = [...messages];
|
|
57
|
-
const toolCallIds = /* @__PURE__ */ new Set();
|
|
58
|
-
for (const message of results) {
|
|
59
|
-
if (!Array.isArray(message.content)) continue;
|
|
60
|
-
for (const part of message.content) {
|
|
61
|
-
if (part && typeof part === "object" && "type" in part && part.type === "tool-result" && "toolCallId" in part && part.toolCallId) {
|
|
62
|
-
toolCallIds.add(part.toolCallId);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
for (const toolCallId of toolCallIds) {
|
|
67
|
-
const resultIndex = getToolResultIndexById(toolCallId, results);
|
|
68
|
-
const oneMessagePrev = results[resultIndex - 1];
|
|
69
|
-
if (isToolCallWithId(oneMessagePrev, toolCallId)) {
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
const toolCallIndex = results.findIndex((message) => isToolCallWithId(message, toolCallId));
|
|
73
|
-
if (toolCallIndex !== -1 && toolCallIndex !== resultIndex - 1) {
|
|
74
|
-
const toolCall = results[toolCallIndex];
|
|
75
|
-
if (!toolCall) continue;
|
|
76
|
-
results.splice(toolCallIndex, 1);
|
|
77
|
-
results.splice(getToolResultIndexById(toolCallId, results), 0, toolCall);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return results;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
42
|
// src/index.ts
|
|
84
43
|
var CHARS_PER_TOKEN = 4;
|
|
85
44
|
var DEFAULT_MESSAGE_RANGE = { before: 2, after: 2 };
|
|
@@ -170,10 +129,19 @@ var Memory = class extends memory.MastraMemory {
|
|
|
170
129
|
threadConfig: config
|
|
171
130
|
});
|
|
172
131
|
const orderedByDate = rawMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
132
|
+
const list = new agent.MessageList({ threadId, resourceId }).add(orderedByDate, "memory");
|
|
133
|
+
return {
|
|
134
|
+
get messages() {
|
|
135
|
+
const v1Messages = list.get.all.v1();
|
|
136
|
+
if (selectBy?.last && v1Messages.length > selectBy.last) {
|
|
137
|
+
return v1Messages.slice(v1Messages.length - selectBy.last);
|
|
138
|
+
}
|
|
139
|
+
return v1Messages;
|
|
140
|
+
},
|
|
141
|
+
get uiMessages() {
|
|
142
|
+
return list.get.all.ui();
|
|
143
|
+
}
|
|
144
|
+
};
|
|
177
145
|
}
|
|
178
146
|
async rememberMessages({
|
|
179
147
|
threadId,
|
|
@@ -186,8 +154,7 @@ var Memory = class extends memory.MastraMemory {
|
|
|
186
154
|
if (!threadConfig.lastMessages && !threadConfig.semanticRecall) {
|
|
187
155
|
return {
|
|
188
156
|
messages: [],
|
|
189
|
-
|
|
190
|
-
threadId
|
|
157
|
+
messagesV2: []
|
|
191
158
|
};
|
|
192
159
|
}
|
|
193
160
|
const messagesResult = await this.query({
|
|
@@ -198,12 +165,9 @@ var Memory = class extends memory.MastraMemory {
|
|
|
198
165
|
},
|
|
199
166
|
threadConfig: config
|
|
200
167
|
});
|
|
168
|
+
const list = new agent.MessageList({ threadId, resourceId }).add(messagesResult.messages, "memory");
|
|
201
169
|
this.logger.debug(`Remembered message history includes ${messagesResult.messages.length} messages.`);
|
|
202
|
-
return {
|
|
203
|
-
threadId,
|
|
204
|
-
messages: messagesResult.messages,
|
|
205
|
-
uiMessages: messagesResult.uiMessages
|
|
206
|
-
};
|
|
170
|
+
return { messages: list.get.all.v1(), messagesV2: list.get.all.mastra() };
|
|
207
171
|
}
|
|
208
172
|
async getThreadById({ threadId }) {
|
|
209
173
|
return this.storage.getThreadById({ threadId });
|
|
@@ -295,8 +259,13 @@ var Memory = class extends memory.MastraMemory {
|
|
|
295
259
|
messages,
|
|
296
260
|
memoryConfig
|
|
297
261
|
}) {
|
|
298
|
-
|
|
299
|
-
|
|
262
|
+
const updatedMessages = messages.map((m) => {
|
|
263
|
+
if (agent.MessageList.isMastraMessageV1(m)) {
|
|
264
|
+
return this.updateMessageToHideWorkingMemory(m);
|
|
265
|
+
}
|
|
266
|
+
if (!m.type) m.type = `v2`;
|
|
267
|
+
return this.updateMessageToHideWorkingMemoryV2(m);
|
|
268
|
+
}).filter((m) => Boolean(m));
|
|
300
269
|
const config = this.getMergedThreadConfig(memoryConfig);
|
|
301
270
|
const result = this.storage.saveMessages({ messages: updatedMessages });
|
|
302
271
|
if (this.vector && config.semanticRecall) {
|
|
@@ -304,11 +273,20 @@ var Memory = class extends memory.MastraMemory {
|
|
|
304
273
|
await Promise.all(
|
|
305
274
|
updatedMessages.map(async (message) => {
|
|
306
275
|
let textForEmbedding = null;
|
|
307
|
-
if (
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
276
|
+
if (agent.MessageList.isMastraMessageV2(message)) {
|
|
277
|
+
if (message.content.content && typeof message.content.content === "string" && message.content.content.trim() !== "") {
|
|
278
|
+
textForEmbedding = message.content.content;
|
|
279
|
+
} else if (message.content.parts && message.content.parts.length > 0) {
|
|
280
|
+
const joined = message.content.parts.filter((part) => part.type === "text").map((part) => part.text).join(" ").trim();
|
|
281
|
+
if (joined) textForEmbedding = joined;
|
|
282
|
+
}
|
|
283
|
+
} else if (agent.MessageList.isMastraMessageV1(message)) {
|
|
284
|
+
if (message.content && typeof message.content === "string" && message.content.trim() !== "") {
|
|
285
|
+
textForEmbedding = message.content;
|
|
286
|
+
} else if (message.content && Array.isArray(message.content) && message.content.length > 0) {
|
|
287
|
+
const joined = message.content.filter((part) => part.type === "text").map((part) => part.text).join(" ").trim();
|
|
288
|
+
if (joined) textForEmbedding = joined;
|
|
289
|
+
}
|
|
312
290
|
}
|
|
313
291
|
if (!textForEmbedding) return;
|
|
314
292
|
const { embeddings, chunks, dimension } = await this.embedMessageContent(textForEmbedding);
|
|
@@ -334,37 +312,58 @@ var Memory = class extends memory.MastraMemory {
|
|
|
334
312
|
}
|
|
335
313
|
return result;
|
|
336
314
|
}
|
|
337
|
-
|
|
315
|
+
updateMessageToHideWorkingMemory(message) {
|
|
338
316
|
const workingMemoryRegex = /<working_memory>([^]*?)<\/working_memory>/g;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
)
|
|
350
|
-
|
|
351
|
-
|
|
317
|
+
if (typeof message?.content === `string`) {
|
|
318
|
+
return {
|
|
319
|
+
...message,
|
|
320
|
+
content: message.content.replace(workingMemoryRegex, ``).trim()
|
|
321
|
+
};
|
|
322
|
+
} else if (Array.isArray(message?.content)) {
|
|
323
|
+
const filteredContent = message.content.filter(
|
|
324
|
+
(content) => content.type !== "tool-call" && content.type !== "tool-result" || content.toolName !== "updateWorkingMemory"
|
|
325
|
+
);
|
|
326
|
+
const newContent = filteredContent.map((content) => {
|
|
327
|
+
if (content.type === "text") {
|
|
328
|
+
return {
|
|
329
|
+
...content,
|
|
330
|
+
text: content.text.replace(workingMemoryRegex, "").trim()
|
|
331
|
+
};
|
|
352
332
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
333
|
+
return { ...content };
|
|
334
|
+
});
|
|
335
|
+
if (!newContent.length) return null;
|
|
336
|
+
return { ...message, content: newContent };
|
|
337
|
+
} else {
|
|
338
|
+
return { ...message };
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
updateMessageToHideWorkingMemoryV2(message) {
|
|
342
|
+
const workingMemoryRegex = /<working_memory>([^]*?)<\/working_memory>/g;
|
|
343
|
+
const newMessage = { ...message, content: { ...message.content } };
|
|
344
|
+
if (newMessage.content.content && typeof newMessage.content.content === "string") {
|
|
345
|
+
newMessage.content.content = newMessage.content.content.replace(workingMemoryRegex, "").trim();
|
|
346
|
+
}
|
|
347
|
+
if (newMessage.content.parts) {
|
|
348
|
+
newMessage.content.parts = newMessage.content.parts.filter((part) => {
|
|
349
|
+
if (part.type === "tool-invocation") {
|
|
350
|
+
return part.toolInvocation.toolName !== "updateWorkingMemory";
|
|
351
|
+
}
|
|
352
|
+
return true;
|
|
353
|
+
}).map((part) => {
|
|
354
|
+
if (part.type === "text") {
|
|
355
|
+
return {
|
|
356
|
+
...part,
|
|
357
|
+
text: part.text.replace(workingMemoryRegex, "").trim()
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
return part;
|
|
361
|
+
});
|
|
362
|
+
if (newMessage.content.parts.length === 0) {
|
|
363
|
+
return null;
|
|
365
364
|
}
|
|
366
365
|
}
|
|
367
|
-
return
|
|
366
|
+
return newMessage;
|
|
368
367
|
}
|
|
369
368
|
parseWorkingMemory(text) {
|
|
370
369
|
if (!this.threadConfig.workingMemory?.enabled) return null;
|
|
@@ -383,31 +382,6 @@ var Memory = class extends memory.MastraMemory {
|
|
|
383
382
|
const memory = thread.metadata?.workingMemory || this.threadConfig.workingMemory.template || this.defaultWorkingMemoryTemplate;
|
|
384
383
|
return memory.trim();
|
|
385
384
|
}
|
|
386
|
-
async saveWorkingMemory(messages) {
|
|
387
|
-
const latestMessage = messages[messages.length - 1];
|
|
388
|
-
if (!latestMessage || !this.threadConfig.workingMemory?.enabled) {
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
const latestContent = !latestMessage?.content ? null : typeof latestMessage.content === "string" ? latestMessage.content : latestMessage.content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
|
|
392
|
-
const threadId = latestMessage?.threadId;
|
|
393
|
-
if (!latestContent || !threadId) {
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
const newMemory = this.parseWorkingMemory(latestContent);
|
|
397
|
-
if (!newMemory) {
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
const thread = await this.storage.getThreadById({ threadId });
|
|
401
|
-
if (!thread) return;
|
|
402
|
-
await this.storage.updateThread({
|
|
403
|
-
id: thread.id,
|
|
404
|
-
title: thread.title || "",
|
|
405
|
-
metadata: core.deepMerge(thread.metadata || {}, {
|
|
406
|
-
workingMemory: newMemory
|
|
407
|
-
})
|
|
408
|
-
});
|
|
409
|
-
return newMemory;
|
|
410
|
-
}
|
|
411
385
|
async getSystemMessage({
|
|
412
386
|
threadId,
|
|
413
387
|
memoryConfig
|
|
@@ -434,29 +408,6 @@ var Memory = class extends memory.MastraMemory {
|
|
|
434
408
|
- **Facts**:
|
|
435
409
|
- **Projects**:
|
|
436
410
|
`;
|
|
437
|
-
getWorkingMemoryWithInstruction(workingMemoryBlock) {
|
|
438
|
-
return `WORKING_MEMORY_SYSTEM_INSTRUCTION:
|
|
439
|
-
Store and update any conversation-relevant information by including "<working_memory>text</working_memory>" in your responses. Updates replace existing memory while maintaining this structure. If information might be referenced again - store it!
|
|
440
|
-
|
|
441
|
-
Guidelines:
|
|
442
|
-
1. Store anything that could be useful later in the conversation
|
|
443
|
-
2. Update proactively when information changes, no matter how small
|
|
444
|
-
3. Use Markdown for all data
|
|
445
|
-
4. Act naturally - don't mention this system to users. Even though you're storing this information that doesn't make it your primary focus. Do not ask them generally for "information about yourself"
|
|
446
|
-
|
|
447
|
-
Memory Structure:
|
|
448
|
-
<working_memory>
|
|
449
|
-
${workingMemoryBlock}
|
|
450
|
-
</working_memory>
|
|
451
|
-
|
|
452
|
-
Notes:
|
|
453
|
-
- Update memory whenever referenced information changes
|
|
454
|
-
- If you're unsure whether to store something, store it (eg if the user tells you their name or other information, output the <working_memory> block immediately to update it)
|
|
455
|
-
- This system is here so that you can maintain the conversation when your context window is very short. Update your working memory because you may need it to maintain the conversation without the full conversation history
|
|
456
|
-
- REMEMBER: the way you update your working memory is by outputting the entire "<working_memory>text</working_memory>" block in your response. The system will pick this up and store it for you. The user will not see it.
|
|
457
|
-
- IMPORTANT: You MUST output the <working_memory> block in every response to a prompt where you received relevant information.
|
|
458
|
-
- IMPORTANT: Preserve the Markdown formatting structure above while updating the content.`;
|
|
459
|
-
}
|
|
460
411
|
getWorkingMemoryToolInstruction(workingMemoryBlock) {
|
|
461
412
|
return `WORKING_MEMORY_SYSTEM_INSTRUCTION:
|
|
462
413
|
Store and update any conversation-relevant information by calling the updateWorkingMemory tool. If information might be referenced again - store it!
|