@mastra/client-js 0.0.0-switch-to-core-20250424015131 → 0.0.0-taofeeq-fix-tool-call-showing-after-message-20250806162745
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 +18 -0
- package/CHANGELOG.md +1355 -2
- package/LICENSE.md +11 -42
- package/README.md +2 -1
- 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 +1785 -82
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -585
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1785 -86
- 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/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 +32 -19
- package/src/adapters/agui.test.ts +322 -0
- package/src/adapters/agui.ts +257 -0
- package/src/client.ts +414 -5
- package/src/example.ts +59 -29
- package/src/index.test.ts +526 -10
- package/src/index.ts +1 -0
- package/src/resources/a2a.ts +88 -0
- package/src/resources/agent.ts +629 -49
- package/src/resources/base.ts +8 -2
- package/src/resources/index.ts +4 -1
- package/src/resources/legacy-workflow.ts +242 -0
- package/src/resources/mcp-tool.ts +48 -0
- package/src/resources/memory-thread.test.ts +285 -0
- package/src/resources/memory-thread.ts +49 -3
- package/src/resources/network-memory-thread.test.ts +269 -0
- package/src/resources/network-memory-thread.ts +81 -0
- package/src/resources/network.ts +11 -17
- package/src/resources/tool.ts +16 -3
- package/src/resources/vNextNetwork.ts +194 -0
- package/src/resources/workflow.ts +289 -94
- package/src/types.ts +298 -20
- package/src/utils/index.ts +11 -0
- package/src/utils/process-client-tools.ts +32 -0
- package/src/utils/zod-to-json-schema.ts +10 -0
- 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/dist/index.d.cts +0 -585
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { describe, expect, beforeEach, it, vi } from 'vitest';
|
|
2
|
+
import { NetworkMemoryThread } from './network-memory-thread';
|
|
3
|
+
import type { ClientOptions } from '../types';
|
|
4
|
+
|
|
5
|
+
// Mock fetch globally
|
|
6
|
+
global.fetch = vi.fn();
|
|
7
|
+
|
|
8
|
+
describe('NetworkMemoryThread', () => {
|
|
9
|
+
let thread: NetworkMemoryThread;
|
|
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 networkId = 'test-network-id';
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.clearAllMocks();
|
|
21
|
+
thread = new NetworkMemoryThread(clientOptions, threadId, networkId);
|
|
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/network/threads/${threadId}?networkId=${networkId}`,
|
|
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/network/threads/${threadId}?networkId=${networkId}`,
|
|
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/network/threads/${threadId}?networkId=${networkId}`,
|
|
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/network/threads/${threadId}/messages?networkId=${networkId}`,
|
|
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/network/threads/${threadId}/messages?networkId=${networkId}&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/network/messages/delete?networkId=${networkId}`,
|
|
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/network/messages/delete?networkId=${networkId}`,
|
|
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/network/messages/delete?networkId=${networkId}`,
|
|
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/network/messages/delete?networkId=${networkId}`,
|
|
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 delete messages errors', async () => {
|
|
254
|
+
const messageId = 'non-existent-id';
|
|
255
|
+
|
|
256
|
+
(global.fetch as any).mockResolvedValueOnce({
|
|
257
|
+
ok: false,
|
|
258
|
+
status: 404,
|
|
259
|
+
statusText: 'Not Found',
|
|
260
|
+
json: async () => ({ error: 'Message not found' }),
|
|
261
|
+
headers: new Headers({
|
|
262
|
+
'content-type': 'application/json',
|
|
263
|
+
}),
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
await expect(thread.deleteMessages(messageId)).rejects.toThrow();
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { StorageThreadType } from '@mastra/core';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
GetMemoryThreadMessagesResponse,
|
|
5
|
+
ClientOptions,
|
|
6
|
+
UpdateMemoryThreadParams,
|
|
7
|
+
GetMemoryThreadMessagesParams,
|
|
8
|
+
} from '../types';
|
|
9
|
+
|
|
10
|
+
import { BaseResource } from './base';
|
|
11
|
+
|
|
12
|
+
export class NetworkMemoryThread extends BaseResource {
|
|
13
|
+
constructor(
|
|
14
|
+
options: ClientOptions,
|
|
15
|
+
private threadId: string,
|
|
16
|
+
private networkId: string,
|
|
17
|
+
) {
|
|
18
|
+
super(options);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Retrieves the memory thread details
|
|
23
|
+
* @returns Promise containing thread details including title and metadata
|
|
24
|
+
*/
|
|
25
|
+
get(): Promise<StorageThreadType> {
|
|
26
|
+
return this.request(`/api/memory/network/threads/${this.threadId}?networkId=${this.networkId}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Updates the memory thread properties
|
|
31
|
+
* @param params - Update parameters including title and metadata
|
|
32
|
+
* @returns Promise containing updated thread details
|
|
33
|
+
*/
|
|
34
|
+
update(params: UpdateMemoryThreadParams): Promise<StorageThreadType> {
|
|
35
|
+
return this.request(`/api/memory/network/threads/${this.threadId}?networkId=${this.networkId}`, {
|
|
36
|
+
method: 'PATCH',
|
|
37
|
+
body: params,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Deletes the memory thread
|
|
43
|
+
* @returns Promise containing deletion result
|
|
44
|
+
*/
|
|
45
|
+
delete(): Promise<{ result: string }> {
|
|
46
|
+
return this.request(`/api/memory/network/threads/${this.threadId}?networkId=${this.networkId}`, {
|
|
47
|
+
method: 'DELETE',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Retrieves messages associated with the thread
|
|
53
|
+
* @param params - Optional parameters including limit for number of messages to retrieve
|
|
54
|
+
* @returns Promise containing thread messages and UI messages
|
|
55
|
+
*/
|
|
56
|
+
getMessages(params?: GetMemoryThreadMessagesParams): Promise<GetMemoryThreadMessagesResponse> {
|
|
57
|
+
const query = new URLSearchParams({
|
|
58
|
+
networkId: this.networkId,
|
|
59
|
+
...(params?.limit ? { limit: params.limit.toString() } : {}),
|
|
60
|
+
});
|
|
61
|
+
return this.request(`/api/memory/network/threads/${this.threadId}/messages?${query.toString()}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Deletes one or more messages from the thread
|
|
66
|
+
* @param messageIds - Can be a single message ID (string), array of message IDs,
|
|
67
|
+
* message object with id property, or array of message objects
|
|
68
|
+
* @returns Promise containing deletion result
|
|
69
|
+
*/
|
|
70
|
+
deleteMessages(
|
|
71
|
+
messageIds: string | string[] | { id: string } | { id: string }[],
|
|
72
|
+
): Promise<{ success: boolean; message: string }> {
|
|
73
|
+
const query = new URLSearchParams({
|
|
74
|
+
networkId: this.networkId,
|
|
75
|
+
});
|
|
76
|
+
return this.request(`/api/memory/network/messages/delete?${query.toString()}`, {
|
|
77
|
+
method: 'POST',
|
|
78
|
+
body: { messageIds },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
package/src/resources/network.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
import { processDataStream } from '@ai-sdk/ui-utils';
|
|
1
2
|
import type { GenerateReturn } from '@mastra/core';
|
|
2
3
|
import type { JSONSchema7 } from 'json-schema';
|
|
3
|
-
import { ZodSchema } from 'zod';
|
|
4
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
5
|
-
|
|
4
|
+
import type { ZodSchema } from 'zod';
|
|
6
5
|
import type { GenerateParams, ClientOptions, StreamParams, GetNetworkResponse } from '../types';
|
|
6
|
+
import { zodToJsonSchema } from '../utils/zod-to-json-schema';
|
|
7
7
|
|
|
8
8
|
import { BaseResource } from './base';
|
|
9
|
-
import { processDataStream } from '@ai-sdk/ui-utils';
|
|
10
9
|
|
|
11
10
|
export class Network extends BaseResource {
|
|
12
11
|
constructor(
|
|
@@ -29,16 +28,14 @@ export class Network extends BaseResource {
|
|
|
29
28
|
* @param params - Generation parameters including prompt
|
|
30
29
|
* @returns Promise containing the generated response
|
|
31
30
|
*/
|
|
32
|
-
generate<
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
generate<
|
|
32
|
+
Output extends JSONSchema7 | ZodSchema | undefined = undefined,
|
|
33
|
+
StructuredOutput extends JSONSchema7 | ZodSchema | undefined = undefined,
|
|
34
|
+
>(params: GenerateParams<Output>): Promise<GenerateReturn<any, Output, StructuredOutput>> {
|
|
35
35
|
const processedParams = {
|
|
36
36
|
...params,
|
|
37
|
-
output:
|
|
38
|
-
experimental_output:
|
|
39
|
-
params.experimental_output instanceof ZodSchema
|
|
40
|
-
? zodToJsonSchema(params.experimental_output)
|
|
41
|
-
: params.experimental_output,
|
|
37
|
+
output: zodToJsonSchema(params.output),
|
|
38
|
+
experimental_output: zodToJsonSchema(params.experimental_output),
|
|
42
39
|
};
|
|
43
40
|
|
|
44
41
|
return this.request(`/api/networks/${this.networkId}/generate`, {
|
|
@@ -61,11 +58,8 @@ export class Network extends BaseResource {
|
|
|
61
58
|
> {
|
|
62
59
|
const processedParams = {
|
|
63
60
|
...params,
|
|
64
|
-
output:
|
|
65
|
-
experimental_output:
|
|
66
|
-
params.experimental_output instanceof ZodSchema
|
|
67
|
-
? zodToJsonSchema(params.experimental_output)
|
|
68
|
-
: params.experimental_output,
|
|
61
|
+
output: zodToJsonSchema(params.output),
|
|
62
|
+
experimental_output: zodToJsonSchema(params.experimental_output),
|
|
69
63
|
};
|
|
70
64
|
|
|
71
65
|
const response: Response & {
|
package/src/resources/tool.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { RuntimeContext } from '@mastra/core/runtime-context';
|
|
1
2
|
import type { GetToolResponse, ClientOptions } from '../types';
|
|
2
3
|
|
|
3
4
|
import { BaseResource } from './base';
|
|
5
|
+
import { parseClientRuntimeContext } from '../utils';
|
|
4
6
|
|
|
5
7
|
export class Tool extends BaseResource {
|
|
6
8
|
constructor(
|
|
@@ -23,10 +25,21 @@ export class Tool extends BaseResource {
|
|
|
23
25
|
* @param params - Parameters required for tool execution
|
|
24
26
|
* @returns Promise containing the tool execution results
|
|
25
27
|
*/
|
|
26
|
-
execute(params: { data: any }): Promise<any> {
|
|
27
|
-
|
|
28
|
+
execute(params: { data: any; runId?: string; runtimeContext?: RuntimeContext | Record<string, any> }): Promise<any> {
|
|
29
|
+
const url = new URLSearchParams();
|
|
30
|
+
|
|
31
|
+
if (params.runId) {
|
|
32
|
+
url.set('runId', params.runId);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const body = {
|
|
36
|
+
data: params.data,
|
|
37
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return this.request(`/api/tools/${this.toolId}/execute?${url.toString()}`, {
|
|
28
41
|
method: 'POST',
|
|
29
|
-
body
|
|
42
|
+
body,
|
|
30
43
|
});
|
|
31
44
|
}
|
|
32
45
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import type { WatchEvent } from '@mastra/core/workflows';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
ClientOptions,
|
|
5
|
+
GetVNextNetworkResponse,
|
|
6
|
+
GenerateVNextNetworkResponse,
|
|
7
|
+
LoopVNextNetworkResponse,
|
|
8
|
+
GenerateOrStreamVNextNetworkParams,
|
|
9
|
+
LoopStreamVNextNetworkParams,
|
|
10
|
+
} from '../types';
|
|
11
|
+
|
|
12
|
+
import { BaseResource } from './base';
|
|
13
|
+
import { parseClientRuntimeContext } from '../utils';
|
|
14
|
+
import type { RuntimeContext } from '@mastra/core/runtime-context';
|
|
15
|
+
|
|
16
|
+
const RECORD_SEPARATOR = '\x1E';
|
|
17
|
+
|
|
18
|
+
export class VNextNetwork extends BaseResource {
|
|
19
|
+
constructor(
|
|
20
|
+
options: ClientOptions,
|
|
21
|
+
private networkId: string,
|
|
22
|
+
) {
|
|
23
|
+
super(options);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Retrieves details about the network
|
|
28
|
+
* @returns Promise containing vNext network details
|
|
29
|
+
*/
|
|
30
|
+
details(): Promise<GetVNextNetworkResponse> {
|
|
31
|
+
return this.request(`/api/networks/v-next/${this.networkId}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Generates a response from the v-next network
|
|
36
|
+
* @param params - Generation parameters including message
|
|
37
|
+
* @returns Promise containing the generated response
|
|
38
|
+
*/
|
|
39
|
+
generate(params: GenerateOrStreamVNextNetworkParams): Promise<GenerateVNextNetworkResponse> {
|
|
40
|
+
return this.request(`/api/networks/v-next/${this.networkId}/generate`, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
body: {
|
|
43
|
+
...params,
|
|
44
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Generates a response from the v-next network using multiple primitives
|
|
51
|
+
* @param params - Generation parameters including message
|
|
52
|
+
* @returns Promise containing the generated response
|
|
53
|
+
*/
|
|
54
|
+
loop(params: {
|
|
55
|
+
message: string;
|
|
56
|
+
runtimeContext?: RuntimeContext | Record<string, any>;
|
|
57
|
+
}): Promise<LoopVNextNetworkResponse> {
|
|
58
|
+
return this.request(`/api/networks/v-next/${this.networkId}/loop`, {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
body: {
|
|
61
|
+
...params,
|
|
62
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private async *streamProcessor(stream: ReadableStream): AsyncGenerator<WatchEvent, void, unknown> {
|
|
68
|
+
const reader = stream.getReader();
|
|
69
|
+
|
|
70
|
+
// Track if we've finished reading from the stream
|
|
71
|
+
let doneReading = false;
|
|
72
|
+
// Buffer to accumulate partial chunks
|
|
73
|
+
let buffer = '';
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
while (!doneReading) {
|
|
77
|
+
// Read the next chunk from the stream
|
|
78
|
+
const { done, value } = await reader.read();
|
|
79
|
+
doneReading = done;
|
|
80
|
+
|
|
81
|
+
// Skip processing if we're done and there's no value
|
|
82
|
+
if (done && !value) continue;
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
// Decode binary data to text
|
|
86
|
+
const decoded = value ? new TextDecoder().decode(value) : '';
|
|
87
|
+
|
|
88
|
+
// Split the combined buffer and new data by record separator
|
|
89
|
+
const chunks = (buffer + decoded).split(RECORD_SEPARATOR);
|
|
90
|
+
|
|
91
|
+
// The last chunk might be incomplete, so save it for the next iteration
|
|
92
|
+
buffer = chunks.pop() || '';
|
|
93
|
+
|
|
94
|
+
// Process complete chunks
|
|
95
|
+
for (const chunk of chunks) {
|
|
96
|
+
if (chunk) {
|
|
97
|
+
// Only process non-empty chunks
|
|
98
|
+
if (typeof chunk === 'string') {
|
|
99
|
+
try {
|
|
100
|
+
const parsedChunk = JSON.parse(chunk);
|
|
101
|
+
yield parsedChunk;
|
|
102
|
+
} catch {
|
|
103
|
+
// Silently ignore parsing errors to maintain stream processing
|
|
104
|
+
// This allows the stream to continue even if one record is malformed
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} catch {
|
|
110
|
+
// Silently ignore parsing errors to maintain stream processing
|
|
111
|
+
// This allows the stream to continue even if one record is malformed
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Process any remaining data in the buffer after stream is done
|
|
116
|
+
if (buffer) {
|
|
117
|
+
try {
|
|
118
|
+
yield JSON.parse(buffer);
|
|
119
|
+
} catch {
|
|
120
|
+
// Ignore parsing error for final chunk
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} finally {
|
|
124
|
+
// Always ensure we clean up the reader
|
|
125
|
+
reader.cancel().catch(() => {
|
|
126
|
+
// Ignore cancel errors
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Streams a response from the v-next network
|
|
133
|
+
* @param params - Stream parameters including message
|
|
134
|
+
* @returns Promise containing the results
|
|
135
|
+
*/
|
|
136
|
+
async stream(params: GenerateOrStreamVNextNetworkParams, onRecord: (record: WatchEvent) => void) {
|
|
137
|
+
const response: Response = await this.request(`/api/networks/v-next/${this.networkId}/stream`, {
|
|
138
|
+
method: 'POST',
|
|
139
|
+
body: {
|
|
140
|
+
...params,
|
|
141
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
142
|
+
},
|
|
143
|
+
stream: true,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
if (!response.ok) {
|
|
147
|
+
throw new Error(`Failed to stream vNext network: ${response.statusText}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!response.body) {
|
|
151
|
+
throw new Error('Response body is null');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
for await (const record of this.streamProcessor(response.body)) {
|
|
155
|
+
if (typeof record === 'string') {
|
|
156
|
+
onRecord(JSON.parse(record));
|
|
157
|
+
} else {
|
|
158
|
+
onRecord(record);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Streams a response from the v-next network loop
|
|
165
|
+
* @param params - Stream parameters including message
|
|
166
|
+
* @returns Promise containing the results
|
|
167
|
+
*/
|
|
168
|
+
async loopStream(params: LoopStreamVNextNetworkParams, onRecord: (record: WatchEvent) => void) {
|
|
169
|
+
const response: Response = await this.request(`/api/networks/v-next/${this.networkId}/loop-stream`, {
|
|
170
|
+
method: 'POST',
|
|
171
|
+
body: {
|
|
172
|
+
...params,
|
|
173
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
174
|
+
},
|
|
175
|
+
stream: true,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
throw new Error(`Failed to stream vNext network loop: ${response.statusText}`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!response.body) {
|
|
183
|
+
throw new Error('Response body is null');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
for await (const record of this.streamProcessor(response.body)) {
|
|
187
|
+
if (typeof record === 'string') {
|
|
188
|
+
onRecord(JSON.parse(record));
|
|
189
|
+
} else {
|
|
190
|
+
onRecord(record);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|