@mastra/client-js 0.0.0-custom-instrumentation-20250626084921 → 0.0.0-declaration-maps-20250729202623
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 -10
- package/CHANGELOG.md +452 -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 +265 -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 +305 -69
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -1126
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +304 -68
- package/dist/index.js.map +1 -0
- package/dist/resources/a2a.d.ts +44 -0
- package/dist/resources/a2a.d.ts.map +1 -0
- package/dist/resources/agent.d.ts +112 -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/package.json +8 -7
- package/src/client.ts +145 -2
- package/src/example.ts +45 -17
- package/src/index.test.ts +402 -6
- package/src/index.ts +1 -0
- package/src/resources/agent.ts +64 -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 +43 -6
- package/src/types.ts +105 -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/dist/index.d.cts +0 -1126
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
|
|
12
|
+
import { Tool, type CoreMessage } 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') {
|
|
@@ -673,6 +691,24 @@ export class Agent extends BaseResource {
|
|
|
673
691
|
toolInvocation.result = result;
|
|
674
692
|
}
|
|
675
693
|
|
|
694
|
+
// write the tool result part to the stream
|
|
695
|
+
const writer = writable.getWriter();
|
|
696
|
+
|
|
697
|
+
try {
|
|
698
|
+
await writer.write(
|
|
699
|
+
new TextEncoder().encode(
|
|
700
|
+
'a:' +
|
|
701
|
+
JSON.stringify({
|
|
702
|
+
toolCallId: toolCall.toolCallId,
|
|
703
|
+
result,
|
|
704
|
+
}) +
|
|
705
|
+
'\n',
|
|
706
|
+
),
|
|
707
|
+
);
|
|
708
|
+
} finally {
|
|
709
|
+
writer.releaseLock();
|
|
710
|
+
}
|
|
711
|
+
|
|
676
712
|
// Convert messages to the correct format for the recursive call
|
|
677
713
|
const originalMessages = processedParams.messages;
|
|
678
714
|
const messageArray = Array.isArray(originalMessages) ? originalMessages : [originalMessages];
|
|
@@ -681,10 +717,12 @@ export class Agent extends BaseResource {
|
|
|
681
717
|
this.processStreamResponse(
|
|
682
718
|
{
|
|
683
719
|
...processedParams,
|
|
684
|
-
messages: [...messageArray, ...messages, lastMessage],
|
|
720
|
+
messages: [...messageArray, ...messages.filter(m => m.id !== lastMessage.id), lastMessage],
|
|
685
721
|
},
|
|
686
722
|
writable,
|
|
687
|
-
)
|
|
723
|
+
).catch(error => {
|
|
724
|
+
console.error('Error processing stream response:', error);
|
|
725
|
+
});
|
|
688
726
|
}
|
|
689
727
|
}
|
|
690
728
|
} else {
|
|
@@ -694,6 +732,8 @@ export class Agent extends BaseResource {
|
|
|
694
732
|
}
|
|
695
733
|
},
|
|
696
734
|
lastMessage: undefined,
|
|
735
|
+
}).catch(error => {
|
|
736
|
+
console.error('Error processing stream response:', error);
|
|
697
737
|
});
|
|
698
738
|
} catch (error) {
|
|
699
739
|
console.error('Error processing stream response:', error);
|
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
|
}
|