@mastra/memory 0.12.1 → 0.12.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 +2 -2
- package/CHANGELOG.md +11 -0
- package/dist/index.cjs +88 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +90 -82
- package/dist/index.js.map +1 -1
- package/dist/tools/working-memory.d.ts +40 -3
- package/dist/tools/working-memory.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +2 -2
- package/src/tools/working-memory.ts +132 -126
|
@@ -1,133 +1,139 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MemoryConfig } from '@mastra/core';
|
|
2
|
+
import { createTool } from '@mastra/core';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
|
|
4
|
-
export const updateWorkingMemoryTool = (memoryConfig?: MemoryConfig)
|
|
5
|
-
|
|
6
|
-
'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
5
|
+
export const updateWorkingMemoryTool = (memoryConfig?: MemoryConfig) => {
|
|
6
|
+
return createTool({
|
|
7
|
+
id: 'update-working-memory',
|
|
8
|
+
description:
|
|
9
|
+
'Update the working memory with new information. Always pass data as string to the memory field. Never pass an object.',
|
|
10
|
+
inputSchema: z.object({
|
|
11
|
+
memory: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe(
|
|
14
|
+
`The ${!!memoryConfig?.workingMemory?.schema ? 'JSON' : 'Markdown'} formatted working memory content to store. This MUST be a string. Never pass an object.`,
|
|
15
|
+
),
|
|
16
|
+
}),
|
|
17
|
+
execute: async params => {
|
|
18
|
+
const { context, threadId, memory, resourceId } = params;
|
|
19
|
+
if (!threadId || !memory || !resourceId) {
|
|
20
|
+
throw new Error('Thread ID, Memory instance, and resourceId are required for working memory updates');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let thread = await memory.getThreadById({ threadId });
|
|
24
|
+
|
|
25
|
+
if (!thread) {
|
|
26
|
+
thread = await memory.createThread({
|
|
27
|
+
threadId,
|
|
28
|
+
resourceId,
|
|
29
|
+
memoryConfig,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (thread.resourceId && thread.resourceId !== resourceId) {
|
|
34
|
+
throw new Error(`Thread with id ${threadId} resourceId does not match the current resourceId ${resourceId}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const workingMemory = context.memory;
|
|
38
|
+
|
|
39
|
+
// Use the new updateWorkingMemory method which handles both thread and resource scope
|
|
40
|
+
await memory.updateWorkingMemory({
|
|
24
41
|
threadId,
|
|
25
|
-
resourceId
|
|
42
|
+
resourceId,
|
|
43
|
+
workingMemory: workingMemory,
|
|
26
44
|
memoryConfig,
|
|
27
45
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
46
|
+
|
|
47
|
+
return { success: true };
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const __experimental_updateWorkingMemoryToolVNext = (config: MemoryConfig) => {
|
|
53
|
+
return createTool({
|
|
54
|
+
id: 'update-working-memory',
|
|
55
|
+
description: 'Update the working memory with new information.',
|
|
56
|
+
inputSchema: z.object({
|
|
57
|
+
newMemory: z
|
|
58
|
+
.string()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe(
|
|
61
|
+
`The ${config.workingMemory?.schema ? 'JSON' : 'Markdown'} formatted working memory content to store`,
|
|
62
|
+
),
|
|
63
|
+
searchString: z
|
|
64
|
+
.string()
|
|
65
|
+
.optional()
|
|
66
|
+
.describe(
|
|
67
|
+
"The working memory string to find. Will be replaced with the newMemory string. If this is omitted or doesn't exist, the newMemory string will be appended to the end of your working memory. Replacing single lines at a time is encouraged for greater accuracy. If updateReason is not 'append-new-memory', this search string must be provided or the tool call will be rejected.",
|
|
68
|
+
),
|
|
69
|
+
updateReason: z
|
|
70
|
+
.enum(['append-new-memory', 'clarify-existing-memory', 'replace-irrelevant-memory'])
|
|
71
|
+
.optional()
|
|
72
|
+
.describe(
|
|
73
|
+
"The reason you're updating working memory. Passing any value other than 'append-new-memory' requires a searchString to be provided. Defaults to append-new-memory",
|
|
74
|
+
),
|
|
75
|
+
}),
|
|
76
|
+
execute: async params => {
|
|
77
|
+
const { context, threadId, memory, resourceId } = params;
|
|
78
|
+
if (!threadId || !memory || !resourceId) {
|
|
79
|
+
throw new Error('Thread ID, Memory instance, and resourceId are required for working memory updates');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let thread = await memory.getThreadById({ threadId });
|
|
83
|
+
|
|
84
|
+
if (!thread) {
|
|
85
|
+
thread = await memory.createThread({
|
|
86
|
+
threadId,
|
|
87
|
+
resourceId,
|
|
88
|
+
memoryConfig: config,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (thread.resourceId && thread.resourceId !== resourceId) {
|
|
93
|
+
throw new Error(`Thread with id ${threadId} resourceId does not match the current resourceId ${resourceId}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const workingMemory = context.newMemory || '';
|
|
97
|
+
if (!context.updateReason) context.updateReason = `append-new-memory`;
|
|
98
|
+
|
|
99
|
+
if (
|
|
100
|
+
context.searchString &&
|
|
101
|
+
config.workingMemory?.scope === `resource` &&
|
|
102
|
+
context.updateReason === `replace-irrelevant-memory`
|
|
103
|
+
) {
|
|
104
|
+
// don't allow replacements due to something not being relevant to the current conversation
|
|
105
|
+
// if there's no searchString, then we will append.
|
|
106
|
+
context.searchString = undefined;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (context.updateReason === `append-new-memory` && context.searchString) {
|
|
110
|
+
// do not find/replace when append-new-memory is selected
|
|
111
|
+
// some models get confused and pass a search string even when they don't want to replace it.
|
|
112
|
+
// TODO: maybe they're trying to add new info after the search string?
|
|
113
|
+
context.searchString = undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (context.updateReason !== `append-new-memory` && !context.searchString) {
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
reason: `updateReason was ${context.updateReason} but no searchString was provided. Unable to replace undefined with "${context.newMemory}"`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Use the new updateWorkingMemory method which handles both thread and resource scope
|
|
124
|
+
const result = await memory.__experimental_updateWorkingMemoryVNext({
|
|
81
125
|
threadId,
|
|
82
|
-
resourceId
|
|
83
|
-
|
|
126
|
+
resourceId,
|
|
127
|
+
workingMemory: workingMemory,
|
|
128
|
+
searchString: context.searchString,
|
|
129
|
+
memoryConfig: config,
|
|
84
130
|
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
context.searchString &&
|
|
96
|
-
config.workingMemory?.scope === `resource` &&
|
|
97
|
-
context.updateReason === `replace-irrelevant-memory`
|
|
98
|
-
) {
|
|
99
|
-
// don't allow replacements due to something not being relevant to the current conversation
|
|
100
|
-
// if there's no searchString, then we will append.
|
|
101
|
-
context.searchString = undefined;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (context.updateReason === `append-new-memory` && context.searchString) {
|
|
105
|
-
// do not find/replace when append-new-memory is selected
|
|
106
|
-
// some models get confused and pass a search string even when they don't want to replace it.
|
|
107
|
-
// TODO: maybe they're trying to add new info after the search string?
|
|
108
|
-
context.searchString = undefined;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (context.updateReason !== `append-new-memory` && !context.searchString) {
|
|
112
|
-
return {
|
|
113
|
-
success: false,
|
|
114
|
-
reason: `updateReason was ${context.updateReason} but no searchString was provided. Unable to replace undefined with "${context.newMemory}"`,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Use the new updateWorkingMemory method which handles both thread and resource scope
|
|
119
|
-
const result = await memory.__experimental_updateWorkingMemoryVNext({
|
|
120
|
-
threadId,
|
|
121
|
-
resourceId: resourceId || thread.resourceId,
|
|
122
|
-
workingMemory: workingMemory,
|
|
123
|
-
searchString: context.searchString,
|
|
124
|
-
memoryConfig: config,
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
if (result) {
|
|
128
|
-
return result;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return { success: true };
|
|
132
|
-
},
|
|
133
|
-
});
|
|
131
|
+
|
|
132
|
+
if (result) {
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { success: true };
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
};
|