@mastra/memory 0.0.2-alpha.8 → 0.1.0-alpha.65

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/package.json CHANGED
@@ -1,22 +1,29 @@
1
1
  {
2
2
  "name": "@mastra/memory",
3
- "version": "0.0.2-alpha.8",
3
+ "version": "0.1.0-alpha.65",
4
4
  "description": "",
5
5
  "type": "module",
6
- "main": "dist/index.js",
7
- "module": "dist/memory.esm.js",
8
- "types": "dist/index.d.ts",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
9
8
  "exports": {
10
9
  ".": {
11
10
  "import": {
12
- "types": "./dist/index.d.ts",
13
- "default": "./dist/memory.esm.js"
14
- },
15
- "require": {
16
11
  "types": "./dist/index.d.ts",
17
12
  "default": "./dist/index.js"
18
13
  }
19
14
  },
15
+ "./kv-upstash": {
16
+ "import": {
17
+ "types": "./dist/kv/upstash.d.ts",
18
+ "default": "./dist/kv/upstash.js"
19
+ }
20
+ },
21
+ "./postgres": {
22
+ "import": {
23
+ "types": "./dist/postgres/index.d.ts",
24
+ "default": "./dist/postgres/index.js"
25
+ }
26
+ },
20
27
  "./package.json": "./package.json"
21
28
  },
22
29
  "keywords": [],
@@ -29,7 +36,7 @@
29
36
  "pg-pool": "^3.7.0",
30
37
  "postgres": "^3.4.5",
31
38
  "redis": "^4.7.0",
32
- "@mastra/core": "0.1.27-alpha.29"
39
+ "@mastra/core": "0.2.0-alpha.83"
33
40
  },
34
41
  "devDependencies": {
35
42
  "@babel/preset-env": "^7.26.0",
@@ -37,13 +44,13 @@
37
44
  "@tsconfig/recommended": "^1.0.7",
38
45
  "@types/node": "^22.9.0",
39
46
  "@types/pg": "^8.11.10",
40
- "dts-cli": "^2.0.5",
41
- "jest": "^29.7.0",
42
- "ts-jest": "^29.2.5"
47
+ "tsup": "^8.0.1",
48
+ "vitest": "^3.0.4"
43
49
  },
44
50
  "scripts": {
45
- "build": "dts build",
46
- "build:dev": "dts watch",
47
- "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
51
+ "build": "tsup src/index.ts src/postgres/index.ts src/kv/upstash.ts --format esm --dts --clean --treeshake",
52
+ "dev": "tsup src/index.ts src/postgres/index.ts src/kv/upstash.ts --format esm --dts --clean --watch",
53
+ "test": "vitest",
54
+ "test:watch": "vitest watch"
48
55
  }
49
56
  }
@@ -0,0 +1,7 @@
1
+ import { describe, it, expect } from 'vitest';
2
+
3
+ describe('temp', () => {
4
+ it(`temp`, () => {
5
+ expect(true).toBe(true);
6
+ });
7
+ });
package/src/index.ts CHANGED
@@ -1,2 +1,170 @@
1
- export * from './postgres';
2
- export * from './kv/upstash';
1
+ import { CoreMessage } from '@mastra/core';
2
+ import { MastraMemory, MessageType, MemoryConfig, SharedMemoryConfig, StorageThreadType } from '@mastra/core/memory';
3
+ import { StorageGetMessagesArg } from '@mastra/core/storage';
4
+ import { Message as AiMessage } from 'ai';
5
+
6
+ /**
7
+ * Concrete implementation of MastraMemory that adds support for thread configuration
8
+ * and message injection.
9
+ */
10
+ export class Memory extends MastraMemory {
11
+ constructor(config: SharedMemoryConfig) {
12
+ super({ name: 'Memory', ...config });
13
+ }
14
+
15
+ async getMessages({
16
+ threadId,
17
+ selectBy,
18
+ threadConfig,
19
+ }: StorageGetMessagesArg): Promise<{ messages: CoreMessage[]; uiMessages: AiMessage[] }> {
20
+ let vectorResults:
21
+ | null
22
+ | {
23
+ id: string;
24
+ score: number;
25
+ metadata?: Record<string, any>;
26
+ vector?: number[];
27
+ }[] = null;
28
+
29
+ this.logger.info(`Memory getMessages() with:`, {
30
+ threadId,
31
+ selectBy,
32
+ threadConfig,
33
+ });
34
+
35
+ const config = this.getMergedThreadConfig(threadConfig || {});
36
+
37
+ const vectorConfig =
38
+ typeof config?.injectVectorHistorySearch === `boolean`
39
+ ? {
40
+ includeResults: 2,
41
+ includePrevious: 2,
42
+ includeNext: 2,
43
+ }
44
+ : {
45
+ includeResults: config?.injectVectorHistorySearch?.includeResults || 2,
46
+ includePrevious: config?.injectVectorHistorySearch?.includePrevious || 2,
47
+ includeNext: config?.injectVectorHistorySearch?.includeNext || 2,
48
+ };
49
+
50
+ if (selectBy?.vectorSearchString && this.vector) {
51
+ const { embeddings } = await this.vector.embed(selectBy.vectorSearchString, this.parseEmbeddingOptions());
52
+
53
+ await this.vector.createIndex('memory_messages', 1536);
54
+ vectorResults = await this.vector.query('memory_messages', embeddings[0]!, vectorConfig.includeResults, {
55
+ thread_id: threadId,
56
+ });
57
+ }
58
+
59
+ // Get raw messages from storage
60
+ const rawMessages = await this.storage.__getMessages({
61
+ threadId,
62
+ selectBy: {
63
+ ...selectBy,
64
+ ...(vectorResults?.length
65
+ ? {
66
+ include: vectorResults.map(r => ({
67
+ id: r.metadata?.message_id,
68
+ withNextMessages: vectorConfig.includeNext,
69
+ withPreviousMessages: vectorConfig.includePrevious,
70
+ })),
71
+ }
72
+ : {}),
73
+ },
74
+ threadConfig: config,
75
+ });
76
+
77
+ // Parse and convert messages
78
+ const messages = this.parseMessages(rawMessages);
79
+ const uiMessages = this.convertToUIMessages(rawMessages);
80
+
81
+ return { messages, uiMessages };
82
+ }
83
+
84
+ async rememberMessages({
85
+ threadId,
86
+ vectorMessageSearch,
87
+ config,
88
+ }: {
89
+ threadId: string;
90
+ vectorMessageSearch?: string;
91
+ config?: MemoryConfig;
92
+ }) {
93
+ const threadConfig = this.getMergedThreadConfig(config || {});
94
+
95
+ if (!threadConfig.injectRecentMessages && !threadConfig.injectVectorHistorySearch) {
96
+ return {
97
+ messages: [],
98
+ uiMessages: [],
99
+ } satisfies Awaited<ReturnType<typeof this.getMessages>>;
100
+ }
101
+
102
+ const messages = await this.getMessages({
103
+ threadId,
104
+ selectBy: {
105
+ last: threadConfig.injectRecentMessages,
106
+ vectorSearchString:
107
+ threadConfig.injectVectorHistorySearch && vectorMessageSearch ? vectorMessageSearch : undefined,
108
+ },
109
+ threadConfig: config,
110
+ });
111
+
112
+ this.logger.info(`Remembered message history includes ${messages.messages.length} messages.`);
113
+ return messages;
114
+ }
115
+
116
+ async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {
117
+ return this.storage.__getThreadById({ threadId });
118
+ }
119
+
120
+ async getThreadsByResourceId({ resourceId }: { resourceId: string }): Promise<StorageThreadType[]> {
121
+ return this.storage.__getThreadsByResourceId({ resourceId });
122
+ }
123
+
124
+ async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {
125
+ return this.storage.__saveThread({ thread });
126
+ }
127
+
128
+ async updateThread({
129
+ id,
130
+ title,
131
+ metadata,
132
+ }: {
133
+ id: string;
134
+ title: string;
135
+ metadata: Record<string, unknown>;
136
+ }): Promise<StorageThreadType> {
137
+ return this.storage.__updateThread({
138
+ id,
139
+ title,
140
+ metadata,
141
+ });
142
+ }
143
+
144
+ async saveMessages({ messages }: { messages: MessageType[] }): Promise<MessageType[]> {
145
+ if (this.vector) {
146
+ await this.vector.createIndex('memory_messages', 1536);
147
+ for (const message of messages) {
148
+ if (typeof message.content !== `string`) continue;
149
+ const { embeddings } = await this.vector.embed(message.content, this.parseEmbeddingOptions());
150
+ await this.vector.upsert('memory_messages', embeddings, [
151
+ {
152
+ text: message.content,
153
+ message_id: message.id,
154
+ thread_id: message.threadId,
155
+ },
156
+ ]);
157
+ }
158
+ }
159
+ return this.storage.__saveMessages({ messages });
160
+ }
161
+
162
+ async deleteThread(threadId: string): Promise<void> {
163
+ await this.storage.__deleteThread({ threadId });
164
+
165
+ // TODO: Also clean up vector storage if it exists
166
+ // if (this.vector) {
167
+ // await this.vector.deleteThread(threadId); ?? filter by thread attributes and delete all returned messages?
168
+ // }
169
+ }
170
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: 'node',
6
+ include: ['src/**/*.test.ts'],
7
+ },
8
+ });
@@ -1,71 +0,0 @@
1
- import { MastraMemory, MessageType as BaseMastraMessageType, ThreadType, MessageResponse } from '@mastra/core';
2
- import { Redis } from '@upstash/redis';
3
- import { ToolResultPart, Message as AiMessage } from 'ai';
4
- interface MessageType extends BaseMastraMessageType {
5
- tokens?: number;
6
- }
7
- interface SerializedThreadType extends Omit<ThreadType, 'createdAt' | 'updatedAt'> {
8
- createdAt: string;
9
- updatedAt: string;
10
- }
11
- export declare class UpstashKVMemory extends MastraMemory {
12
- private prefix;
13
- kv: Redis;
14
- constructor(config: {
15
- url: string;
16
- token: string;
17
- prefix?: string;
18
- maxTokens?: number;
19
- });
20
- private getThreadKey;
21
- private getMessagesKey;
22
- private getToolCacheKey;
23
- getThreadById({ threadId }: {
24
- threadId: string;
25
- }): Promise<ThreadType | null>;
26
- getThreadsByResourceId({ resourceid }: {
27
- resourceid: string;
28
- }): Promise<ThreadType[]>;
29
- saveThread({ thread }: {
30
- thread: ThreadType;
31
- }): Promise<ThreadType>;
32
- updateThread(id: string, title: string, metadata: Record<string, unknown>): Promise<ThreadType>;
33
- deleteThread(id: string): Promise<void>;
34
- /**
35
- * Tool Cache
36
- */
37
- validateToolCallArgs({ hashedArgs }: {
38
- hashedArgs: string;
39
- }): Promise<boolean>;
40
- getToolResult({ threadId, toolArgs, toolName, }: {
41
- threadId: string;
42
- toolArgs: Record<string, unknown>;
43
- toolName: string;
44
- }): Promise<ToolResultPart['result'] | null>;
45
- getContextWindow<T extends 'raw' | 'core_message'>({ threadId, startDate, endDate, format, }: {
46
- format?: T;
47
- threadId: string;
48
- startDate?: Date;
49
- endDate?: Date;
50
- }): Promise<MessageResponse<T>>;
51
- /**
52
- * Messages
53
- */
54
- getMessages({ threadId }: {
55
- threadId: string;
56
- }): Promise<{
57
- messages: MessageType[];
58
- uiMessages: AiMessage[];
59
- }>;
60
- saveMessages({ messages }: {
61
- messages: MessageType[];
62
- }): Promise<MessageType[]>;
63
- deleteMessage(id: string): Promise<void>;
64
- /**
65
- * Cleanup
66
- */
67
- drop(): Promise<void>;
68
- parseThread(thread: SerializedThreadType): ThreadType;
69
- parseMessages(messages: MessageType[]): MessageType[];
70
- }
71
- export {};