@mastra/memory 0.0.0-a2a-20250421213654
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/CHANGELOG.md +1842 -0
- package/LICENSE.md +46 -0
- package/README.md +7 -0
- package/dist/_tsup-dts-rollup.d.cts +138 -0
- package/dist/_tsup-dts-rollup.d.ts +138 -0
- package/dist/index.cjs +482 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +476 -0
- package/dist/processors/index.cjs +161 -0
- package/dist/processors/index.d.cts +2 -0
- package/dist/processors/index.d.ts +2 -0
- package/dist/processors/index.js +154 -0
- package/eslint.config.js +12 -0
- package/package.json +67 -0
- package/src/index.ts +565 -0
- package/src/processors/index.test.ts +238 -0
- package/src/processors/index.ts +2 -0
- package/src/processors/token-limiter.ts +150 -0
- package/src/processors/tool-call-filter.ts +77 -0
- package/src/tools/working-memory.ts +33 -0
- package/src/utils/index.ts +88 -0
- package/tsconfig.json +5 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { MemoryProcessor } from '@mastra/core/memory';
|
|
2
|
+
import { Tiktoken } from 'js-tiktoken/lite';
|
|
3
|
+
import o200k_base from 'js-tiktoken/ranks/o200k_base';
|
|
4
|
+
import { MemoryProcessor as MemoryProcessor$1 } from '@mastra/core';
|
|
5
|
+
|
|
6
|
+
// src/processors/token-limiter.ts
|
|
7
|
+
var TokenLimiter = class extends MemoryProcessor {
|
|
8
|
+
encoder;
|
|
9
|
+
maxTokens;
|
|
10
|
+
// Token overheads per OpenAI's documentation
|
|
11
|
+
// See: https://cookbook.openai.com/examples/how_to_count_tokens_with_tiktoken#6-counting-tokens-for-chat-completions-api-calls
|
|
12
|
+
// Every message follows <|start|>{role/name}\n{content}<|end|>
|
|
13
|
+
TOKENS_PER_MESSAGE = 3;
|
|
14
|
+
// tokens added for each message (start & end tokens)
|
|
15
|
+
TOKENS_PER_TOOL = 2;
|
|
16
|
+
// empirical adjustment for tool calls
|
|
17
|
+
TOKENS_PER_CONVERSATION = 25;
|
|
18
|
+
// fixed overhead for the conversation
|
|
19
|
+
/**
|
|
20
|
+
* Create a token limiter for messages.
|
|
21
|
+
* @param options Either a number (token limit) or a configuration object
|
|
22
|
+
*/
|
|
23
|
+
constructor(options) {
|
|
24
|
+
super({
|
|
25
|
+
name: "TokenLimiter"
|
|
26
|
+
});
|
|
27
|
+
if (typeof options === "number") {
|
|
28
|
+
this.maxTokens = options;
|
|
29
|
+
this.encoder = new Tiktoken(o200k_base);
|
|
30
|
+
} else {
|
|
31
|
+
this.maxTokens = options.limit;
|
|
32
|
+
this.encoder = new Tiktoken(options.encoding || o200k_base);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
process(messages, { systemMessage, memorySystemMessage, newMessages } = {}) {
|
|
36
|
+
let totalTokens = 0;
|
|
37
|
+
totalTokens += this.TOKENS_PER_CONVERSATION;
|
|
38
|
+
if (systemMessage) {
|
|
39
|
+
totalTokens += this.countTokens(systemMessage);
|
|
40
|
+
totalTokens += this.TOKENS_PER_MESSAGE;
|
|
41
|
+
}
|
|
42
|
+
if (memorySystemMessage) {
|
|
43
|
+
totalTokens += this.countTokens(memorySystemMessage);
|
|
44
|
+
totalTokens += this.TOKENS_PER_MESSAGE;
|
|
45
|
+
}
|
|
46
|
+
const allMessages = [...messages, ...newMessages || []];
|
|
47
|
+
const result = [];
|
|
48
|
+
for (let i = allMessages.length - 1; i >= 0; i--) {
|
|
49
|
+
const message = allMessages[i];
|
|
50
|
+
if (!message) continue;
|
|
51
|
+
const messageTokens = this.countTokens(message);
|
|
52
|
+
if (totalTokens + messageTokens <= this.maxTokens) {
|
|
53
|
+
result.unshift(message);
|
|
54
|
+
totalTokens += messageTokens;
|
|
55
|
+
} else {
|
|
56
|
+
this.logger.info(
|
|
57
|
+
`filtering ${allMessages.length - result.length}/${allMessages.length} messages, token limit of ${this.maxTokens} exceeded`
|
|
58
|
+
);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
countTokens(message) {
|
|
65
|
+
if (typeof message === `string`) {
|
|
66
|
+
return this.encoder.encode(message).length;
|
|
67
|
+
}
|
|
68
|
+
let tokenString = message.role;
|
|
69
|
+
if (typeof message.content === "string") {
|
|
70
|
+
tokenString += message.content;
|
|
71
|
+
} else if (Array.isArray(message.content)) {
|
|
72
|
+
for (const part of message.content) {
|
|
73
|
+
tokenString += part.type;
|
|
74
|
+
if (part.type === "text") {
|
|
75
|
+
tokenString += part.text;
|
|
76
|
+
} else if (part.type === "tool-call") {
|
|
77
|
+
tokenString += part.toolName;
|
|
78
|
+
if (part.args) {
|
|
79
|
+
tokenString += typeof part.args === "string" ? part.args : JSON.stringify(part.args);
|
|
80
|
+
}
|
|
81
|
+
} else if (part.type === "tool-result") {
|
|
82
|
+
if (part.result !== void 0) {
|
|
83
|
+
tokenString += typeof part.result === "string" ? part.result : JSON.stringify(part.result);
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
tokenString += JSON.stringify(part);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const messageOverhead = this.TOKENS_PER_MESSAGE;
|
|
91
|
+
let toolOverhead = 0;
|
|
92
|
+
if (Array.isArray(message.content)) {
|
|
93
|
+
for (const part of message.content) {
|
|
94
|
+
if (part.type === "tool-call" || part.type === "tool-result") {
|
|
95
|
+
toolOverhead += this.TOKENS_PER_TOOL;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const totalMessageOverhead = messageOverhead + toolOverhead;
|
|
100
|
+
return this.encoder.encode(tokenString).length + totalMessageOverhead;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
var ToolCallFilter = class extends MemoryProcessor$1 {
|
|
104
|
+
exclude;
|
|
105
|
+
/**
|
|
106
|
+
* Create a filter for tool calls and results.
|
|
107
|
+
* @param options Configuration options
|
|
108
|
+
* @param options.exclude List of specific tool names to exclude. If not provided, all tool calls are excluded.
|
|
109
|
+
*/
|
|
110
|
+
constructor(options = {}) {
|
|
111
|
+
super({ name: "ToolCallFilter" });
|
|
112
|
+
if (!options || !options.exclude) {
|
|
113
|
+
this.exclude = "all";
|
|
114
|
+
} else {
|
|
115
|
+
this.exclude = Array.isArray(options.exclude) ? options.exclude : [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
process(messages) {
|
|
119
|
+
if (this.exclude === "all") {
|
|
120
|
+
return messages.filter((message) => {
|
|
121
|
+
if (Array.isArray(message.content)) {
|
|
122
|
+
return !message.content.some((part) => part.type === "tool-call" || part.type === "tool-result");
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (this.exclude.length > 0) {
|
|
128
|
+
const excludedToolCallIds = /* @__PURE__ */ new Set();
|
|
129
|
+
return messages.filter((message) => {
|
|
130
|
+
if (!Array.isArray(message.content)) return true;
|
|
131
|
+
if (message.role === "assistant") {
|
|
132
|
+
let shouldExclude = false;
|
|
133
|
+
for (const part of message.content) {
|
|
134
|
+
if (part.type === "tool-call" && this.exclude.includes(part.toolName)) {
|
|
135
|
+
excludedToolCallIds.add(part.toolCallId);
|
|
136
|
+
shouldExclude = true;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return !shouldExclude;
|
|
140
|
+
}
|
|
141
|
+
if (message.role === "tool") {
|
|
142
|
+
const shouldExclude = message.content.some(
|
|
143
|
+
(part) => part.type === "tool-result" && excludedToolCallIds.has(part.toolCallId)
|
|
144
|
+
);
|
|
145
|
+
return !shouldExclude;
|
|
146
|
+
}
|
|
147
|
+
return true;
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return messages;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export { TokenLimiter, ToolCallFilter };
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createConfig } from '@internal/lint/eslint';
|
|
2
|
+
|
|
3
|
+
const config = await createConfig();
|
|
4
|
+
|
|
5
|
+
/** @type {import("eslint").Linter.Config[]} */
|
|
6
|
+
export default [
|
|
7
|
+
...config,
|
|
8
|
+
{
|
|
9
|
+
files: ['integration-tests/**/*'],
|
|
10
|
+
...(await import('typescript-eslint')).configs.disableTypeChecked,
|
|
11
|
+
},
|
|
12
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mastra/memory",
|
|
3
|
+
"version": "0.0.0-a2a-20250421213654",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.cts",
|
|
16
|
+
"default": "./dist/index.cjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"./processors": {
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/processors/index.d.ts",
|
|
22
|
+
"default": "./dist/processors/index.js"
|
|
23
|
+
},
|
|
24
|
+
"require": {
|
|
25
|
+
"types": "./dist/processors/index.d.cts",
|
|
26
|
+
"default": "./dist/processors/index.cjs"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [],
|
|
32
|
+
"author": "",
|
|
33
|
+
"license": "Elastic-2.0",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@upstash/redis": "^1.34.5",
|
|
36
|
+
"ai": "^4.2.2",
|
|
37
|
+
"js-tiktoken": "^1.0.19",
|
|
38
|
+
"pg": "^8.13.3",
|
|
39
|
+
"pg-pool": "^3.7.1",
|
|
40
|
+
"postgres": "^3.4.5",
|
|
41
|
+
"redis": "^4.7.0",
|
|
42
|
+
"xxhash-wasm": "^1.1.0",
|
|
43
|
+
"zod": "^3.24.2",
|
|
44
|
+
"@mastra/core": "0.0.0-a2a-20250421213654"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@ai-sdk/openai": "^1.3.3",
|
|
48
|
+
"@microsoft/api-extractor": "^7.52.1",
|
|
49
|
+
"@types/node": "^20.17.27",
|
|
50
|
+
"@types/pg": "^8.11.11",
|
|
51
|
+
"eslint": "^9.23.0",
|
|
52
|
+
"tsup": "^8.4.0",
|
|
53
|
+
"typescript": "^5.8.2",
|
|
54
|
+
"typescript-eslint": "^8.26.1",
|
|
55
|
+
"vitest": "^3.0.9",
|
|
56
|
+
"@internal/lint": "0.0.2"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"check": "tsc --noEmit",
|
|
60
|
+
"build": "pnpm run check && tsup src/index.ts src/processors/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
|
|
61
|
+
"build:watch": "pnpm build --watch",
|
|
62
|
+
"test:integration": "cd integration-tests && pnpm run test",
|
|
63
|
+
"test:unit": "pnpm vitest run ./src/*",
|
|
64
|
+
"test": "pnpm test:integration && pnpm test:unit",
|
|
65
|
+
"lint": "eslint ."
|
|
66
|
+
}
|
|
67
|
+
}
|