@mastra/memory 0.2.10 → 0.2.11-alpha.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.
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +16 -0
- package/dist/_tsup-dts-rollup.d.cts +6 -0
- package/dist/_tsup-dts-rollup.d.ts +6 -0
- package/dist/index.cjs +46 -2
- package/dist/index.js +46 -2
- package/package.json +2 -2
- package/src/index.ts +8 -2
- package/src/utils/index.ts +88 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/memory@0.2.
|
|
2
|
+
> @mastra/memory@0.2.11-alpha.1 build /home/runner/work/mastra/mastra/packages/memory
|
|
3
3
|
> pnpm run check && tsup src/index.ts src/processors/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @mastra/memory@0.2.
|
|
6
|
+
> @mastra/memory@0.2.11-alpha.1 check /home/runner/work/mastra/mastra/packages/memory
|
|
7
7
|
> tsc --noEmit
|
|
8
8
|
|
|
9
9
|
[34mCLI[39m Building entry: src/index.ts, src/processors/index.ts
|
|
10
10
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
11
11
|
[34mCLI[39m tsup v8.4.0
|
|
12
12
|
[34mTSC[39m Build start
|
|
13
|
-
[32mTSC[39m ⚡️ Build success in
|
|
13
|
+
[32mTSC[39m ⚡️ Build success in 9818ms
|
|
14
14
|
[34mDTS[39m Build start
|
|
15
15
|
[34mCLI[39m Target: es2022
|
|
16
16
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
17
17
|
[36mWriting package typings: /home/runner/work/mastra/mastra/packages/memory/dist/_tsup-dts-rollup.d.ts[39m
|
|
18
18
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
19
19
|
[36mWriting package typings: /home/runner/work/mastra/mastra/packages/memory/dist/_tsup-dts-rollup.d.cts[39m
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 11869ms
|
|
21
21
|
[34mCLI[39m Cleaning output folder
|
|
22
22
|
[34mESM[39m Build start
|
|
23
23
|
[34mCJS[39m Build start
|
|
24
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
24
|
+
[32mESM[39m [1mdist/index.js [22m[32m17.39 KB[39m
|
|
25
25
|
[32mESM[39m [1mdist/processors/index.js [22m[32m5.33 KB[39m
|
|
26
|
-
[32mESM[39m ⚡️ Build success in
|
|
27
|
-
[32mCJS[39m [1mdist/index.cjs [22m[
|
|
26
|
+
[32mESM[39m ⚡️ Build success in 1099ms
|
|
27
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m17.66 KB[39m
|
|
28
28
|
[32mCJS[39m [1mdist/processors/index.cjs [22m[32m5.54 KB[39m
|
|
29
|
-
[32mCJS[39m ⚡️ Build success in
|
|
29
|
+
[32mCJS[39m ⚡️ Build success in 1103ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @mastra/memory
|
|
2
2
|
|
|
3
|
+
## 0.2.11-alpha.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6f92295: Fixed an issue where some user messages and llm messages would have the exact same createdAt date, leading to incorrect message ordering. Added a fix for new messages as well as any that were saved before the fix in the wrong order
|
|
8
|
+
- Updated dependencies [8a8a73b]
|
|
9
|
+
- Updated dependencies [6f92295]
|
|
10
|
+
- @mastra/core@0.8.4-alpha.1
|
|
11
|
+
|
|
12
|
+
## 0.2.11-alpha.0
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [03f3cd0]
|
|
17
|
+
- @mastra/core@0.8.4-alpha.0
|
|
18
|
+
|
|
3
19
|
## 0.2.10
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -76,6 +76,12 @@ export declare class Memory extends MastraMemory {
|
|
|
76
76
|
getTools(config?: MemoryConfig): Record<string, CoreTool>;
|
|
77
77
|
}
|
|
78
78
|
|
|
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
|
+
|
|
79
85
|
/**
|
|
80
86
|
* Limits the total number of tokens in the messages.
|
|
81
87
|
* Uses js-tiktoken with o200k_base encoding by default for accurate token counting with modern models.
|
|
@@ -76,6 +76,12 @@ export declare class Memory extends MastraMemory {
|
|
|
76
76
|
getTools(config?: MemoryConfig): Record<string, CoreTool>;
|
|
77
77
|
}
|
|
78
78
|
|
|
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
|
+
|
|
79
85
|
/**
|
|
80
86
|
* Limits the total number of tokens in the messages.
|
|
81
87
|
* Uses js-tiktoken with o200k_base encoding by default for accurate token counting with modern models.
|
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,48 @@ var updateWorkingMemoryTool = {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
+
// src/utils/index.ts
|
|
45
|
+
var isToolCallWithId = (message, targetToolCallId) => {
|
|
46
|
+
if (!message || !Array.isArray(message.content)) return false;
|
|
47
|
+
return message.content.some(
|
|
48
|
+
(part) => part && typeof part === "object" && "type" in part && part.type === "tool-call" && "toolCallId" in part && part.toolCallId === targetToolCallId
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
var getToolResultIndexById = (id, results) => results.findIndex((message) => {
|
|
52
|
+
if (!Array.isArray(message?.content)) return false;
|
|
53
|
+
return message.content.some(
|
|
54
|
+
(part) => part && typeof part === "object" && "type" in part && part.type === "tool-result" && "toolCallId" in part && part.toolCallId === id
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
function reorderToolCallsAndResults(messages) {
|
|
58
|
+
if (!messages.length) return messages;
|
|
59
|
+
const results = [...messages];
|
|
60
|
+
const toolCallIds = /* @__PURE__ */ new Set();
|
|
61
|
+
for (const message of results) {
|
|
62
|
+
if (!Array.isArray(message.content)) continue;
|
|
63
|
+
for (const part of message.content) {
|
|
64
|
+
if (part && typeof part === "object" && "type" in part && part.type === "tool-result" && "toolCallId" in part && part.toolCallId) {
|
|
65
|
+
toolCallIds.add(part.toolCallId);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const toolCallId of toolCallIds) {
|
|
70
|
+
const resultIndex = getToolResultIndexById(toolCallId, results);
|
|
71
|
+
const oneMessagePrev = results[resultIndex - 1];
|
|
72
|
+
if (isToolCallWithId(oneMessagePrev, toolCallId)) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const toolCallIndex = results.findIndex((message) => isToolCallWithId(message, toolCallId));
|
|
76
|
+
if (toolCallIndex !== -1 && toolCallIndex !== resultIndex - 1) {
|
|
77
|
+
const toolCall = results[toolCallIndex];
|
|
78
|
+
if (!toolCall) continue;
|
|
79
|
+
results.splice(toolCallIndex, 1);
|
|
80
|
+
results.splice(getToolResultIndexById(toolCallId, results), 0, toolCall);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return results;
|
|
84
|
+
}
|
|
85
|
+
|
|
44
86
|
// src/index.ts
|
|
45
87
|
var encoder = new lite.Tiktoken(o200k_base__default.default);
|
|
46
88
|
var Memory = class extends memory.MastraMemory {
|
|
@@ -123,8 +165,10 @@ var Memory = class extends memory.MastraMemory {
|
|
|
123
165
|
},
|
|
124
166
|
threadConfig: config
|
|
125
167
|
});
|
|
126
|
-
const
|
|
127
|
-
const
|
|
168
|
+
const orderedByDate = rawMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
169
|
+
const reorderedToolCalls = reorderToolCallsAndResults(orderedByDate);
|
|
170
|
+
const messages = this.parseMessages(reorderedToolCalls);
|
|
171
|
+
const uiMessages = this.convertToUIMessages(reorderedToolCalls);
|
|
128
172
|
return { messages, uiMessages };
|
|
129
173
|
}
|
|
130
174
|
async rememberMessages({
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,48 @@ var updateWorkingMemoryTool = {
|
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
// src/utils/index.ts
|
|
38
|
+
var isToolCallWithId = (message, targetToolCallId) => {
|
|
39
|
+
if (!message || !Array.isArray(message.content)) return false;
|
|
40
|
+
return message.content.some(
|
|
41
|
+
(part) => part && typeof part === "object" && "type" in part && part.type === "tool-call" && "toolCallId" in part && part.toolCallId === targetToolCallId
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
var getToolResultIndexById = (id, results) => results.findIndex((message) => {
|
|
45
|
+
if (!Array.isArray(message?.content)) return false;
|
|
46
|
+
return message.content.some(
|
|
47
|
+
(part) => part && typeof part === "object" && "type" in part && part.type === "tool-result" && "toolCallId" in part && part.toolCallId === id
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
function reorderToolCallsAndResults(messages) {
|
|
51
|
+
if (!messages.length) return messages;
|
|
52
|
+
const results = [...messages];
|
|
53
|
+
const toolCallIds = /* @__PURE__ */ new Set();
|
|
54
|
+
for (const message of results) {
|
|
55
|
+
if (!Array.isArray(message.content)) continue;
|
|
56
|
+
for (const part of message.content) {
|
|
57
|
+
if (part && typeof part === "object" && "type" in part && part.type === "tool-result" && "toolCallId" in part && part.toolCallId) {
|
|
58
|
+
toolCallIds.add(part.toolCallId);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
for (const toolCallId of toolCallIds) {
|
|
63
|
+
const resultIndex = getToolResultIndexById(toolCallId, results);
|
|
64
|
+
const oneMessagePrev = results[resultIndex - 1];
|
|
65
|
+
if (isToolCallWithId(oneMessagePrev, toolCallId)) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const toolCallIndex = results.findIndex((message) => isToolCallWithId(message, toolCallId));
|
|
69
|
+
if (toolCallIndex !== -1 && toolCallIndex !== resultIndex - 1) {
|
|
70
|
+
const toolCall = results[toolCallIndex];
|
|
71
|
+
if (!toolCall) continue;
|
|
72
|
+
results.splice(toolCallIndex, 1);
|
|
73
|
+
results.splice(getToolResultIndexById(toolCallId, results), 0, toolCall);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return results;
|
|
77
|
+
}
|
|
78
|
+
|
|
37
79
|
// src/index.ts
|
|
38
80
|
var encoder = new Tiktoken(o200k_base);
|
|
39
81
|
var Memory = class extends MastraMemory {
|
|
@@ -116,8 +158,10 @@ var Memory = class extends MastraMemory {
|
|
|
116
158
|
},
|
|
117
159
|
threadConfig: config
|
|
118
160
|
});
|
|
119
|
-
const
|
|
120
|
-
const
|
|
161
|
+
const orderedByDate = rawMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
162
|
+
const reorderedToolCalls = reorderToolCallsAndResults(orderedByDate);
|
|
163
|
+
const messages = this.parseMessages(reorderedToolCalls);
|
|
164
|
+
const uiMessages = this.convertToUIMessages(reorderedToolCalls);
|
|
121
165
|
return { messages, uiMessages };
|
|
122
166
|
}
|
|
123
167
|
async rememberMessages({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/memory",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11-alpha.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"redis": "^4.7.0",
|
|
42
42
|
"xxhash-wasm": "^1.1.0",
|
|
43
43
|
"zod": "^3.24.2",
|
|
44
|
-
"@mastra/core": "^0.8.
|
|
44
|
+
"@mastra/core": "^0.8.4-alpha.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@ai-sdk/openai": "^1.3.3",
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { Tiktoken } from 'js-tiktoken/lite';
|
|
|
8
8
|
import o200k_base from 'js-tiktoken/ranks/o200k_base';
|
|
9
9
|
import xxhash from 'xxhash-wasm';
|
|
10
10
|
import { updateWorkingMemoryTool } from './tools/working-memory';
|
|
11
|
+
import { reorderToolCallsAndResults } from './utils';
|
|
11
12
|
|
|
12
13
|
const encoder = new Tiktoken(o200k_base);
|
|
13
14
|
|
|
@@ -126,9 +127,14 @@ export class Memory extends MastraMemory {
|
|
|
126
127
|
threadConfig: config,
|
|
127
128
|
});
|
|
128
129
|
|
|
130
|
+
// First sort messages by date
|
|
131
|
+
const orderedByDate = rawMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
132
|
+
// Then reorder tool calls to be directly before their results
|
|
133
|
+
const reorderedToolCalls = reorderToolCallsAndResults(orderedByDate);
|
|
134
|
+
|
|
129
135
|
// Parse and convert messages
|
|
130
|
-
const messages = this.parseMessages(
|
|
131
|
-
const uiMessages = this.convertToUIMessages(
|
|
136
|
+
const messages = this.parseMessages(reorderedToolCalls);
|
|
137
|
+
const uiMessages = this.convertToUIMessages(reorderedToolCalls);
|
|
132
138
|
|
|
133
139
|
return { messages, uiMessages };
|
|
134
140
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { MessageType } from '@mastra/core/memory';
|
|
2
|
+
|
|
3
|
+
const isToolCallWithId = (message: MessageType | undefined, targetToolCallId: string): boolean => {
|
|
4
|
+
if (!message || !Array.isArray(message.content)) return false;
|
|
5
|
+
return message.content.some(
|
|
6
|
+
part =>
|
|
7
|
+
part &&
|
|
8
|
+
typeof part === 'object' &&
|
|
9
|
+
'type' in part &&
|
|
10
|
+
part.type === 'tool-call' &&
|
|
11
|
+
'toolCallId' in part &&
|
|
12
|
+
part.toolCallId === targetToolCallId,
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const getToolResultIndexById = (id: string, results: MessageType[]) =>
|
|
17
|
+
results.findIndex(message => {
|
|
18
|
+
if (!Array.isArray(message?.content)) return false;
|
|
19
|
+
return message.content.some(
|
|
20
|
+
part =>
|
|
21
|
+
part &&
|
|
22
|
+
typeof part === 'object' &&
|
|
23
|
+
'type' in part &&
|
|
24
|
+
part.type === 'tool-result' &&
|
|
25
|
+
'toolCallId' in part &&
|
|
26
|
+
part.toolCallId === id,
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Self-heals message ordering to ensure tool calls are directly before their matching tool results.
|
|
32
|
+
* 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.
|
|
33
|
+
*/
|
|
34
|
+
export function reorderToolCallsAndResults(messages: MessageType[]): MessageType[] {
|
|
35
|
+
if (!messages.length) return messages;
|
|
36
|
+
|
|
37
|
+
// Create a copy of messages to avoid modifying the original
|
|
38
|
+
const results = [...messages];
|
|
39
|
+
|
|
40
|
+
const toolCallIds = new Set<string>();
|
|
41
|
+
|
|
42
|
+
// First loop: collect all tool result IDs in a set
|
|
43
|
+
for (const message of results) {
|
|
44
|
+
if (!Array.isArray(message.content)) continue;
|
|
45
|
+
|
|
46
|
+
for (const part of message.content) {
|
|
47
|
+
if (
|
|
48
|
+
part &&
|
|
49
|
+
typeof part === 'object' &&
|
|
50
|
+
'type' in part &&
|
|
51
|
+
part.type === 'tool-result' &&
|
|
52
|
+
'toolCallId' in part &&
|
|
53
|
+
part.toolCallId
|
|
54
|
+
) {
|
|
55
|
+
toolCallIds.add(part.toolCallId);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Second loop: for each tool ID, ensure tool calls come before tool results
|
|
61
|
+
for (const toolCallId of toolCallIds) {
|
|
62
|
+
// Find tool result index
|
|
63
|
+
const resultIndex = getToolResultIndexById(toolCallId, results);
|
|
64
|
+
|
|
65
|
+
// Check if tool call is at resultIndex - 1
|
|
66
|
+
const oneMessagePrev = results[resultIndex - 1];
|
|
67
|
+
if (isToolCallWithId(oneMessagePrev, toolCallId)) {
|
|
68
|
+
continue; // Tool call is already in the correct position
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Find the tool call anywhere in the array
|
|
72
|
+
const toolCallIndex = results.findIndex(message => isToolCallWithId(message, toolCallId));
|
|
73
|
+
|
|
74
|
+
if (toolCallIndex !== -1 && toolCallIndex !== resultIndex - 1) {
|
|
75
|
+
// Store the tool call message
|
|
76
|
+
const toolCall = results[toolCallIndex];
|
|
77
|
+
if (!toolCall) continue;
|
|
78
|
+
|
|
79
|
+
// Remove the tool call from its current position
|
|
80
|
+
results.splice(toolCallIndex, 1);
|
|
81
|
+
|
|
82
|
+
// Insert right before the tool result
|
|
83
|
+
results.splice(getToolResultIndexById(toolCallId, results), 0, toolCall);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return results;
|
|
88
|
+
}
|