@mastra/client-js 0.0.0-mcp-changeset-20250707162621 → 0.0.0-memory-system-message-error-20250813233316
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 +527 -2
- package/LICENSE.md +11 -42
- package/README.md +1 -0
- package/dist/adapters/agui.d.ts +23 -0
- package/dist/adapters/agui.d.ts.map +1 -0
- package/dist/client.d.ts +270 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/example.d.ts +2 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/index.cjs +333 -98
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -1164
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +332 -97
- package/dist/index.js.map +1 -0
- package/dist/resources/a2a.d.ts +41 -0
- package/dist/resources/a2a.d.ts.map +1 -0
- package/dist/resources/agent.d.ts +123 -0
- package/dist/resources/agent.d.ts.map +1 -0
- package/dist/resources/base.d.ts +13 -0
- package/dist/resources/base.d.ts.map +1 -0
- package/dist/resources/index.d.ts +11 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/legacy-workflow.d.ts +87 -0
- package/dist/resources/legacy-workflow.d.ts.map +1 -0
- package/dist/resources/mcp-tool.d.ts +27 -0
- package/dist/resources/mcp-tool.d.ts.map +1 -0
- package/dist/resources/memory-thread.d.ts +53 -0
- package/dist/resources/memory-thread.d.ts.map +1 -0
- package/dist/resources/network-memory-thread.d.ts +47 -0
- package/dist/resources/network-memory-thread.d.ts.map +1 -0
- package/dist/resources/network.d.ts +30 -0
- package/dist/resources/network.d.ts.map +1 -0
- package/dist/resources/tool.d.ts +23 -0
- package/dist/resources/tool.d.ts.map +1 -0
- package/dist/resources/vNextNetwork.d.ts +42 -0
- package/dist/resources/vNextNetwork.d.ts.map +1 -0
- package/dist/resources/vector.d.ts +48 -0
- package/dist/resources/vector.d.ts.map +1 -0
- package/dist/resources/workflow.d.ts +154 -0
- package/dist/resources/workflow.d.ts.map +1 -0
- package/dist/types.d.ts +422 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/process-client-tools.d.ts +3 -0
- package/dist/utils/process-client-tools.d.ts.map +1 -0
- package/dist/utils/zod-to-json-schema.d.ts +105 -0
- package/dist/utils/zod-to-json-schema.d.ts.map +1 -0
- package/integration-tests/agui-adapter.test.ts +122 -0
- package/integration-tests/package.json +18 -0
- package/integration-tests/src/mastra/index.ts +35 -0
- package/integration-tests/vitest.config.ts +9 -0
- package/package.json +15 -9
- package/src/adapters/agui.test.ts +145 -3
- package/src/adapters/agui.ts +29 -11
- package/src/client.ts +153 -2
- package/src/example.ts +45 -17
- package/src/index.test.ts +402 -6
- package/src/index.ts +1 -0
- package/src/resources/a2a.ts +35 -25
- package/src/resources/agent.ts +58 -24
- package/src/resources/base.ts +6 -1
- package/src/resources/memory-thread.test.ts +285 -0
- package/src/resources/memory-thread.ts +36 -0
- package/src/resources/network-memory-thread.test.ts +269 -0
- package/src/resources/network-memory-thread.ts +18 -0
- package/src/resources/network.ts +4 -3
- package/src/resources/vNextNetwork.ts +22 -5
- package/src/resources/workflow.ts +17 -3
- package/src/types.ts +90 -10
- package/src/utils/process-client-tools.ts +1 -1
- package/src/v2-messages.test.ts +180 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +1 -1
- package/tsup.config.ts +17 -0
- package/.turbo/turbo-build.log +0 -19
- package/dist/index.d.cts +0 -1164
package/src/resources/agent.ts
CHANGED
|
@@ -9,11 +9,13 @@ import {
|
|
|
9
9
|
type UIMessage,
|
|
10
10
|
type UseChatOptions,
|
|
11
11
|
} from '@ai-sdk/ui-utils';
|
|
12
|
-
import { Tool, type CoreMessage, type
|
|
12
|
+
import { Tool, type CoreMessage, type MastraLanguageModel } from '@mastra/core';
|
|
13
|
+
import { type GenerateReturn } from '@mastra/core/llm';
|
|
13
14
|
import type { JSONSchema7 } from 'json-schema';
|
|
14
15
|
import { ZodSchema } from 'zod';
|
|
15
16
|
import { zodToJsonSchema } from '../utils/zod-to-json-schema';
|
|
16
17
|
import { processClientTools } from '../utils/process-client-tools';
|
|
18
|
+
import { v4 as uuid } from '@lukeed/uuid';
|
|
17
19
|
|
|
18
20
|
import type {
|
|
19
21
|
GenerateParams,
|
|
@@ -116,18 +118,19 @@ export class Agent extends BaseResource {
|
|
|
116
118
|
* @param params - Generation parameters including prompt
|
|
117
119
|
* @returns Promise containing the generated response
|
|
118
120
|
*/
|
|
119
|
-
async generate
|
|
120
|
-
params: GenerateParams<
|
|
121
|
-
): Promise<GenerateReturn<
|
|
122
|
-
async generate<
|
|
123
|
-
params: GenerateParams<
|
|
124
|
-
): Promise<GenerateReturn<
|
|
125
|
-
async generate<
|
|
126
|
-
params: GenerateParams<
|
|
127
|
-
): Promise<GenerateReturn<
|
|
128
|
-
async generate<
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
async generate(
|
|
122
|
+
params: GenerateParams<undefined> & { output?: never; experimental_output?: never },
|
|
123
|
+
): Promise<GenerateReturn<any, undefined, undefined>>;
|
|
124
|
+
async generate<Output extends JSONSchema7 | ZodSchema>(
|
|
125
|
+
params: GenerateParams<Output> & { output: Output; experimental_output?: never },
|
|
126
|
+
): Promise<GenerateReturn<any, Output, undefined>>;
|
|
127
|
+
async generate<StructuredOutput extends JSONSchema7 | ZodSchema>(
|
|
128
|
+
params: GenerateParams<StructuredOutput> & { output?: never; experimental_output: StructuredOutput },
|
|
129
|
+
): Promise<GenerateReturn<any, undefined, StructuredOutput>>;
|
|
130
|
+
async generate<
|
|
131
|
+
Output extends JSONSchema7 | ZodSchema | undefined = undefined,
|
|
132
|
+
StructuredOutput extends JSONSchema7 | ZodSchema | undefined = undefined,
|
|
133
|
+
>(params: GenerateParams<Output>): Promise<GenerateReturn<any, Output, StructuredOutput>> {
|
|
131
134
|
const processedParams = {
|
|
132
135
|
...params,
|
|
133
136
|
output: params.output ? zodToJsonSchema(params.output) : undefined,
|
|
@@ -138,18 +141,27 @@ export class Agent extends BaseResource {
|
|
|
138
141
|
|
|
139
142
|
const { runId, resourceId, threadId, runtimeContext } = processedParams as GenerateParams;
|
|
140
143
|
|
|
141
|
-
const response: GenerateReturn<
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
const response: GenerateReturn<any, Output, StructuredOutput> = await this.request(
|
|
145
|
+
`/api/agents/${this.agentId}/generate`,
|
|
146
|
+
{
|
|
147
|
+
method: 'POST',
|
|
148
|
+
body: processedParams,
|
|
149
|
+
},
|
|
150
|
+
);
|
|
145
151
|
|
|
146
152
|
if (response.finishReason === 'tool-calls') {
|
|
147
|
-
|
|
153
|
+
const toolCalls = (
|
|
148
154
|
response as unknown as {
|
|
149
155
|
toolCalls: { toolName: string; args: any; toolCallId: string }[];
|
|
150
156
|
messages: CoreMessage[];
|
|
151
157
|
}
|
|
152
|
-
).toolCalls
|
|
158
|
+
).toolCalls;
|
|
159
|
+
|
|
160
|
+
if (!toolCalls || !Array.isArray(toolCalls)) {
|
|
161
|
+
return response;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
for (const toolCall of toolCalls) {
|
|
153
165
|
const clientTool = params.clientTools?.[toolCall.toolName] as Tool;
|
|
154
166
|
|
|
155
167
|
if (clientTool && clientTool.execute) {
|
|
@@ -219,7 +231,7 @@ export class Agent extends BaseResource {
|
|
|
219
231
|
const message: UIMessage = replaceLastMessage
|
|
220
232
|
? structuredClone(lastMessage)
|
|
221
233
|
: {
|
|
222
|
-
id:
|
|
234
|
+
id: uuid(),
|
|
223
235
|
createdAt: getCurrentDate(),
|
|
224
236
|
role: 'assistant',
|
|
225
237
|
content: '',
|
|
@@ -279,7 +291,7 @@ export class Agent extends BaseResource {
|
|
|
279
291
|
// changes. This is why we need to add a revision id to ensure that the message
|
|
280
292
|
// is updated with SWR (without it, the changes get stuck in SWR and are not
|
|
281
293
|
// forwarded to rendering):
|
|
282
|
-
revisionId:
|
|
294
|
+
revisionId: uuid(),
|
|
283
295
|
} as UIMessage;
|
|
284
296
|
|
|
285
297
|
update({
|
|
@@ -620,7 +632,13 @@ export class Agent extends BaseResource {
|
|
|
620
632
|
this.processChatResponse({
|
|
621
633
|
stream: streamForProcessing,
|
|
622
634
|
update: ({ message }) => {
|
|
623
|
-
messages.
|
|
635
|
+
const existingIndex = messages.findIndex(m => m.id === message.id);
|
|
636
|
+
|
|
637
|
+
if (existingIndex !== -1) {
|
|
638
|
+
messages[existingIndex] = message;
|
|
639
|
+
} else {
|
|
640
|
+
messages.push(message);
|
|
641
|
+
}
|
|
624
642
|
},
|
|
625
643
|
onFinish: async ({ finishReason, message }) => {
|
|
626
644
|
if (finishReason === 'tool-calls') {
|
|
@@ -699,10 +717,12 @@ export class Agent extends BaseResource {
|
|
|
699
717
|
this.processStreamResponse(
|
|
700
718
|
{
|
|
701
719
|
...processedParams,
|
|
702
|
-
messages: [...messageArray, ...messages, lastMessage],
|
|
720
|
+
messages: [...messageArray, ...messages.filter(m => m.id !== lastMessage.id), lastMessage],
|
|
703
721
|
},
|
|
704
722
|
writable,
|
|
705
|
-
)
|
|
723
|
+
).catch(error => {
|
|
724
|
+
console.error('Error processing stream response:', error);
|
|
725
|
+
});
|
|
706
726
|
}
|
|
707
727
|
}
|
|
708
728
|
} else {
|
|
@@ -712,6 +732,8 @@ export class Agent extends BaseResource {
|
|
|
712
732
|
}
|
|
713
733
|
},
|
|
714
734
|
lastMessage: undefined,
|
|
735
|
+
}).catch(error => {
|
|
736
|
+
console.error('Error processing stream response:', error);
|
|
715
737
|
});
|
|
716
738
|
} catch (error) {
|
|
717
739
|
console.error('Error processing stream response:', error);
|
|
@@ -760,4 +782,16 @@ export class Agent extends BaseResource {
|
|
|
760
782
|
liveEvals(): Promise<GetEvalsByAgentIdResponse> {
|
|
761
783
|
return this.request(`/api/agents/${this.agentId}/evals/live`);
|
|
762
784
|
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Updates the model for the agent
|
|
788
|
+
* @param params - Parameters for updating the model
|
|
789
|
+
* @returns Promise containing the updated model
|
|
790
|
+
*/
|
|
791
|
+
updateModel(params: { model: MastraLanguageModel }): Promise<{ message: string }> {
|
|
792
|
+
return this.request(`/api/agents/${this.agentId}/model`, {
|
|
793
|
+
method: 'POST',
|
|
794
|
+
body: params,
|
|
795
|
+
});
|
|
796
|
+
}
|
|
763
797
|
}
|
package/src/resources/base.ts
CHANGED
|
@@ -24,12 +24,17 @@ export class BaseResource {
|
|
|
24
24
|
const response = await fetch(`${baseUrl.replace(/\/$/, '')}${path}`, {
|
|
25
25
|
...options,
|
|
26
26
|
headers: {
|
|
27
|
-
...(options.
|
|
27
|
+
...(options.body &&
|
|
28
|
+
!(options.body instanceof FormData) &&
|
|
29
|
+
(options.method === 'POST' || options.method === 'PUT')
|
|
30
|
+
? { 'content-type': 'application/json' }
|
|
31
|
+
: {}),
|
|
28
32
|
...headers,
|
|
29
33
|
...options.headers,
|
|
30
34
|
// TODO: Bring this back once we figure out what we/users need to do to make this work with cross-origin requests
|
|
31
35
|
// 'x-mastra-client-type': 'js',
|
|
32
36
|
},
|
|
37
|
+
signal: this.options.abortSignal,
|
|
33
38
|
body:
|
|
34
39
|
options.body instanceof FormData ? options.body : options.body ? JSON.stringify(options.body) : undefined,
|
|
35
40
|
});
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { describe, expect, beforeEach, it, vi } from 'vitest';
|
|
2
|
+
import { MemoryThread } from './memory-thread';
|
|
3
|
+
import type { ClientOptions } from '../types';
|
|
4
|
+
|
|
5
|
+
// Mock fetch globally
|
|
6
|
+
global.fetch = vi.fn();
|
|
7
|
+
|
|
8
|
+
describe('MemoryThread', () => {
|
|
9
|
+
let thread: MemoryThread;
|
|
10
|
+
const clientOptions: ClientOptions = {
|
|
11
|
+
baseUrl: 'http://localhost:4111',
|
|
12
|
+
headers: {
|
|
13
|
+
Authorization: 'Bearer test-key',
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
const threadId = 'test-thread-id';
|
|
17
|
+
const agentId = 'test-agent-id';
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.clearAllMocks();
|
|
21
|
+
thread = new MemoryThread(clientOptions, threadId, agentId);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const mockFetchResponse = (data: any) => {
|
|
25
|
+
(global.fetch as any).mockResolvedValueOnce({
|
|
26
|
+
ok: true,
|
|
27
|
+
status: 200,
|
|
28
|
+
json: async () => data,
|
|
29
|
+
headers: new Headers({
|
|
30
|
+
'content-type': 'application/json',
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
describe('get', () => {
|
|
36
|
+
it('should retrieve thread details', async () => {
|
|
37
|
+
const mockThread = {
|
|
38
|
+
id: threadId,
|
|
39
|
+
title: 'Test Thread',
|
|
40
|
+
metadata: { test: true },
|
|
41
|
+
createdAt: new Date().toISOString(),
|
|
42
|
+
updatedAt: new Date().toISOString(),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
mockFetchResponse(mockThread);
|
|
46
|
+
|
|
47
|
+
const result = await thread.get();
|
|
48
|
+
|
|
49
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
50
|
+
`http://localhost:4111/api/memory/threads/${threadId}?agentId=${agentId}`,
|
|
51
|
+
expect.objectContaining({
|
|
52
|
+
headers: expect.objectContaining({
|
|
53
|
+
Authorization: 'Bearer test-key',
|
|
54
|
+
}),
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
expect(result).toEqual(mockThread);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('update', () => {
|
|
62
|
+
it('should update thread properties', async () => {
|
|
63
|
+
const updateParams = {
|
|
64
|
+
title: 'Updated Title',
|
|
65
|
+
metadata: { updated: true },
|
|
66
|
+
resourceid: 'resource-1',
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const mockUpdatedThread = {
|
|
70
|
+
id: threadId,
|
|
71
|
+
...updateParams,
|
|
72
|
+
createdAt: new Date().toISOString(),
|
|
73
|
+
updatedAt: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
mockFetchResponse(mockUpdatedThread);
|
|
77
|
+
|
|
78
|
+
const result = await thread.update(updateParams);
|
|
79
|
+
|
|
80
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
81
|
+
`http://localhost:4111/api/memory/threads/${threadId}?agentId=${agentId}`,
|
|
82
|
+
expect.objectContaining({
|
|
83
|
+
method: 'PATCH',
|
|
84
|
+
headers: expect.objectContaining({
|
|
85
|
+
Authorization: 'Bearer test-key',
|
|
86
|
+
}),
|
|
87
|
+
body: JSON.stringify(updateParams),
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
expect(result).toEqual(mockUpdatedThread);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('delete', () => {
|
|
95
|
+
it('should delete the thread', async () => {
|
|
96
|
+
const mockResponse = { result: 'Thread deleted' };
|
|
97
|
+
mockFetchResponse(mockResponse);
|
|
98
|
+
|
|
99
|
+
const result = await thread.delete();
|
|
100
|
+
|
|
101
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
102
|
+
`http://localhost:4111/api/memory/threads/${threadId}?agentId=${agentId}`,
|
|
103
|
+
expect.objectContaining({
|
|
104
|
+
method: 'DELETE',
|
|
105
|
+
headers: expect.objectContaining({
|
|
106
|
+
Authorization: 'Bearer test-key',
|
|
107
|
+
}),
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
110
|
+
expect(result).toEqual(mockResponse);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe('getMessages', () => {
|
|
115
|
+
it('should retrieve thread messages', async () => {
|
|
116
|
+
const mockMessages = {
|
|
117
|
+
messages: [
|
|
118
|
+
{ id: 'msg-1', content: 'Hello', role: 'user' },
|
|
119
|
+
{ id: 'msg-2', content: 'Hi there', role: 'assistant' },
|
|
120
|
+
],
|
|
121
|
+
uiMessages: [
|
|
122
|
+
{ id: 'msg-1', content: 'Hello', role: 'user' },
|
|
123
|
+
{ id: 'msg-2', content: 'Hi there', role: 'assistant' },
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
mockFetchResponse(mockMessages);
|
|
128
|
+
|
|
129
|
+
const result = await thread.getMessages();
|
|
130
|
+
|
|
131
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
132
|
+
`http://localhost:4111/api/memory/threads/${threadId}/messages?agentId=${agentId}`,
|
|
133
|
+
expect.objectContaining({
|
|
134
|
+
headers: expect.objectContaining({
|
|
135
|
+
Authorization: 'Bearer test-key',
|
|
136
|
+
}),
|
|
137
|
+
}),
|
|
138
|
+
);
|
|
139
|
+
expect(result).toEqual(mockMessages);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('should retrieve thread messages with limit', async () => {
|
|
143
|
+
const mockMessages = {
|
|
144
|
+
messages: [{ id: 'msg-1', content: 'Hello', role: 'user' }],
|
|
145
|
+
uiMessages: [{ id: 'msg-1', content: 'Hello', role: 'user' }],
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
mockFetchResponse(mockMessages);
|
|
149
|
+
|
|
150
|
+
const result = await thread.getMessages({ limit: 5 });
|
|
151
|
+
|
|
152
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
153
|
+
`http://localhost:4111/api/memory/threads/${threadId}/messages?agentId=${agentId}&limit=5`,
|
|
154
|
+
expect.objectContaining({
|
|
155
|
+
headers: expect.objectContaining({
|
|
156
|
+
Authorization: 'Bearer test-key',
|
|
157
|
+
}),
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
expect(result).toEqual(mockMessages);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
describe('deleteMessages', () => {
|
|
165
|
+
it('should delete a single message by string ID', async () => {
|
|
166
|
+
const messageId = 'test-message-id';
|
|
167
|
+
const mockResponse = { success: true, message: '1 message deleted successfully' };
|
|
168
|
+
|
|
169
|
+
mockFetchResponse(mockResponse);
|
|
170
|
+
|
|
171
|
+
const result = await thread.deleteMessages(messageId);
|
|
172
|
+
|
|
173
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
174
|
+
`http://localhost:4111/api/memory/messages/delete?agentId=${agentId}`,
|
|
175
|
+
expect.objectContaining({
|
|
176
|
+
method: 'POST',
|
|
177
|
+
headers: expect.objectContaining({
|
|
178
|
+
'content-type': 'application/json',
|
|
179
|
+
Authorization: 'Bearer test-key',
|
|
180
|
+
}),
|
|
181
|
+
body: JSON.stringify({ messageIds: messageId }),
|
|
182
|
+
}),
|
|
183
|
+
);
|
|
184
|
+
expect(result).toEqual(mockResponse);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should delete multiple messages by array of string IDs', async () => {
|
|
188
|
+
const messageIds = ['msg-1', 'msg-2', 'msg-3'];
|
|
189
|
+
const mockResponse = { success: true, message: '3 messages deleted successfully' };
|
|
190
|
+
|
|
191
|
+
mockFetchResponse(mockResponse);
|
|
192
|
+
|
|
193
|
+
const result = await thread.deleteMessages(messageIds);
|
|
194
|
+
|
|
195
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
196
|
+
`http://localhost:4111/api/memory/messages/delete?agentId=${agentId}`,
|
|
197
|
+
expect.objectContaining({
|
|
198
|
+
method: 'POST',
|
|
199
|
+
headers: expect.objectContaining({
|
|
200
|
+
'content-type': 'application/json',
|
|
201
|
+
Authorization: 'Bearer test-key',
|
|
202
|
+
}),
|
|
203
|
+
body: JSON.stringify({ messageIds }),
|
|
204
|
+
}),
|
|
205
|
+
);
|
|
206
|
+
expect(result).toEqual(mockResponse);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('should delete a message by object with id property', async () => {
|
|
210
|
+
const messageObj = { id: 'test-message-id' };
|
|
211
|
+
const mockResponse = { success: true, message: '1 message deleted successfully' };
|
|
212
|
+
|
|
213
|
+
mockFetchResponse(mockResponse);
|
|
214
|
+
|
|
215
|
+
const result = await thread.deleteMessages(messageObj);
|
|
216
|
+
|
|
217
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
218
|
+
`http://localhost:4111/api/memory/messages/delete?agentId=${agentId}`,
|
|
219
|
+
expect.objectContaining({
|
|
220
|
+
method: 'POST',
|
|
221
|
+
headers: expect.objectContaining({
|
|
222
|
+
'content-type': 'application/json',
|
|
223
|
+
Authorization: 'Bearer test-key',
|
|
224
|
+
}),
|
|
225
|
+
body: JSON.stringify({ messageIds: messageObj }),
|
|
226
|
+
}),
|
|
227
|
+
);
|
|
228
|
+
expect(result).toEqual(mockResponse);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should delete messages by array of objects', async () => {
|
|
232
|
+
const messageObjs = [{ id: 'msg-1' }, { id: 'msg-2' }];
|
|
233
|
+
const mockResponse = { success: true, message: '2 messages deleted successfully' };
|
|
234
|
+
|
|
235
|
+
mockFetchResponse(mockResponse);
|
|
236
|
+
|
|
237
|
+
const result = await thread.deleteMessages(messageObjs);
|
|
238
|
+
|
|
239
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
240
|
+
`http://localhost:4111/api/memory/messages/delete?agentId=${agentId}`,
|
|
241
|
+
expect.objectContaining({
|
|
242
|
+
method: 'POST',
|
|
243
|
+
headers: expect.objectContaining({
|
|
244
|
+
'content-type': 'application/json',
|
|
245
|
+
Authorization: 'Bearer test-key',
|
|
246
|
+
}),
|
|
247
|
+
body: JSON.stringify({ messageIds: messageObjs }),
|
|
248
|
+
}),
|
|
249
|
+
);
|
|
250
|
+
expect(result).toEqual(mockResponse);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('should handle empty array', async () => {
|
|
254
|
+
const messageIds: string[] = [];
|
|
255
|
+
|
|
256
|
+
(global.fetch as any).mockResolvedValueOnce({
|
|
257
|
+
ok: false,
|
|
258
|
+
status: 400,
|
|
259
|
+
statusText: 'Bad Request',
|
|
260
|
+
json: async () => ({ error: 'messageIds array cannot be empty' }),
|
|
261
|
+
headers: new Headers({
|
|
262
|
+
'content-type': 'application/json',
|
|
263
|
+
}),
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
await expect(thread.deleteMessages(messageIds)).rejects.toThrow();
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('should handle bulk delete errors', async () => {
|
|
270
|
+
const messageIds = ['msg-1', 'msg-2'];
|
|
271
|
+
|
|
272
|
+
(global.fetch as any).mockResolvedValueOnce({
|
|
273
|
+
ok: false,
|
|
274
|
+
status: 500,
|
|
275
|
+
statusText: 'Internal Server Error',
|
|
276
|
+
json: async () => ({ error: 'Database error' }),
|
|
277
|
+
headers: new Headers({
|
|
278
|
+
'content-type': 'application/json',
|
|
279
|
+
}),
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
await expect(thread.deleteMessages(messageIds)).rejects.toThrow();
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
});
|
|
@@ -5,6 +5,8 @@ import type {
|
|
|
5
5
|
ClientOptions,
|
|
6
6
|
UpdateMemoryThreadParams,
|
|
7
7
|
GetMemoryThreadMessagesParams,
|
|
8
|
+
GetMemoryThreadMessagesPaginatedParams,
|
|
9
|
+
GetMemoryThreadMessagesPaginatedResponse,
|
|
8
10
|
} from '../types';
|
|
9
11
|
|
|
10
12
|
import { BaseResource } from './base';
|
|
@@ -60,4 +62,38 @@ export class MemoryThread extends BaseResource {
|
|
|
60
62
|
});
|
|
61
63
|
return this.request(`/api/memory/threads/${this.threadId}/messages?${query.toString()}`);
|
|
62
64
|
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Retrieves paginated messages associated with the thread with advanced filtering and selection options
|
|
68
|
+
* @param params - Pagination parameters including selectBy criteria, page, perPage, date ranges, and message inclusion options
|
|
69
|
+
* @returns Promise containing paginated thread messages with pagination metadata (total, page, perPage, hasMore)
|
|
70
|
+
*/
|
|
71
|
+
getMessagesPaginated({
|
|
72
|
+
selectBy,
|
|
73
|
+
...rest
|
|
74
|
+
}: GetMemoryThreadMessagesPaginatedParams): Promise<GetMemoryThreadMessagesPaginatedResponse> {
|
|
75
|
+
const query = new URLSearchParams({
|
|
76
|
+
...rest,
|
|
77
|
+
...(selectBy ? { selectBy: JSON.stringify(selectBy) } : {}),
|
|
78
|
+
});
|
|
79
|
+
return this.request(`/api/memory/threads/${this.threadId}/messages/paginated?${query.toString()}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Deletes one or more messages from the thread
|
|
84
|
+
* @param messageIds - Can be a single message ID (string), array of message IDs,
|
|
85
|
+
* message object with id property, or array of message objects
|
|
86
|
+
* @returns Promise containing deletion result
|
|
87
|
+
*/
|
|
88
|
+
deleteMessages(
|
|
89
|
+
messageIds: string | string[] | { id: string } | { id: string }[],
|
|
90
|
+
): Promise<{ success: boolean; message: string }> {
|
|
91
|
+
const query = new URLSearchParams({
|
|
92
|
+
agentId: this.agentId,
|
|
93
|
+
});
|
|
94
|
+
return this.request(`/api/memory/messages/delete?${query.toString()}`, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
body: { messageIds },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
63
99
|
}
|