@mastra/client-js 0.0.0-storage-20250225005900 → 0.0.0-trigger-playground-ui-package-20250506151043
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 +983 -3
- package/{LICENSE → LICENSE.md} +3 -1
- package/README.md +6 -3
- package/dist/index.cjs +1146 -0
- package/dist/index.d.cts +730 -0
- package/dist/index.d.ts +730 -0
- package/dist/index.js +1144 -0
- package/package.json +30 -19
- package/src/adapters/agui.test.ts +167 -0
- package/src/adapters/agui.ts +219 -0
- package/src/client.ts +65 -11
- package/src/example.ts +65 -43
- package/src/index.test.ts +173 -60
- package/src/resources/agent.ts +92 -4
- package/src/resources/base.ts +5 -3
- package/src/resources/index.ts +2 -0
- package/src/resources/memory-thread.ts +1 -8
- package/src/resources/network.ts +92 -0
- package/src/resources/tool.ts +9 -3
- package/src/resources/vnext-workflow.ts +257 -0
- package/src/resources/workflow.ts +192 -9
- package/src/types.ts +116 -17
- package/.turbo/turbo-build.log +0 -16
- package/dist/index.d.mts +0 -405
- package/dist/index.mjs +0 -487
package/src/index.test.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { MessageType } from '@mastra/core';
|
|
2
1
|
import { describe, expect, beforeEach, it, vi } from 'vitest';
|
|
3
2
|
|
|
4
3
|
import { MastraClient } from './client';
|
|
@@ -12,33 +11,51 @@ describe('MastraClient Resources', () => {
|
|
|
12
11
|
baseUrl: 'http://localhost:4111',
|
|
13
12
|
headers: {
|
|
14
13
|
Authorization: 'Bearer test-key',
|
|
14
|
+
'x-mastra-client-type': 'js',
|
|
15
15
|
},
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
// Helper to mock successful API responses
|
|
19
19
|
const mockFetchResponse = (data: any, options: { isStream?: boolean } = {}) => {
|
|
20
20
|
if (options.isStream) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
let contentType = 'text/event-stream';
|
|
22
|
+
let responseBody: ReadableStream;
|
|
23
|
+
|
|
24
|
+
if (data instanceof ReadableStream) {
|
|
25
|
+
responseBody = data;
|
|
26
|
+
contentType = 'audio/mp3';
|
|
27
|
+
} else {
|
|
28
|
+
responseBody = new ReadableStream({
|
|
29
|
+
start(controller) {
|
|
30
|
+
controller.enqueue(new TextEncoder().encode(JSON.stringify(data)));
|
|
31
|
+
controller.close();
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const headers = new Headers();
|
|
37
|
+
if (contentType === 'audio/mp3') {
|
|
38
|
+
headers.set('Transfer-Encoding', 'chunked');
|
|
39
|
+
}
|
|
40
|
+
headers.set('Content-Type', contentType);
|
|
41
|
+
|
|
42
|
+
(global.fetch as any).mockResolvedValueOnce(
|
|
43
|
+
new Response(responseBody, {
|
|
44
|
+
status: 200,
|
|
45
|
+
statusText: 'OK',
|
|
46
|
+
headers,
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
34
49
|
} else {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
50
|
+
const response = new Response(undefined, {
|
|
51
|
+
status: 200,
|
|
52
|
+
statusText: 'OK',
|
|
53
|
+
headers: new Headers({
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
}),
|
|
41
56
|
});
|
|
57
|
+
response.json = () => Promise.resolve(data);
|
|
58
|
+
(global.fetch as any).mockResolvedValueOnce(response);
|
|
42
59
|
}
|
|
43
60
|
};
|
|
44
61
|
|
|
@@ -241,7 +258,7 @@ describe('MastraClient Resources', () => {
|
|
|
241
258
|
const result = await agent.generate({
|
|
242
259
|
messages: [],
|
|
243
260
|
threadId: 'test-thread',
|
|
244
|
-
|
|
261
|
+
resourceId: 'test-resource',
|
|
245
262
|
output: {},
|
|
246
263
|
});
|
|
247
264
|
expect(result).toEqual(mockResponse);
|
|
@@ -253,7 +270,7 @@ describe('MastraClient Resources', () => {
|
|
|
253
270
|
body: JSON.stringify({
|
|
254
271
|
messages: [],
|
|
255
272
|
threadId: 'test-thread',
|
|
256
|
-
|
|
273
|
+
resourceId: 'test-resource',
|
|
257
274
|
output: {},
|
|
258
275
|
}),
|
|
259
276
|
}),
|
|
@@ -301,19 +318,18 @@ describe('MastraClient Resources', () => {
|
|
|
301
318
|
});
|
|
302
319
|
|
|
303
320
|
it('should get agent evals', async () => {
|
|
304
|
-
const mockResponse = {
|
|
305
|
-
name: 'Test Agent',
|
|
306
|
-
evals: [{ id: 'eval1' }],
|
|
307
|
-
};
|
|
321
|
+
const mockResponse = { data: 'test' };
|
|
308
322
|
mockFetchResponse(mockResponse);
|
|
309
323
|
const result = await agent.evals();
|
|
310
324
|
expect(result).toEqual(mockResponse);
|
|
311
|
-
expect(global.fetch).toHaveBeenCalledWith(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
325
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
326
|
+
`${clientOptions.baseUrl}/api/agents/test-agent/evals/ci`,
|
|
327
|
+
expect.objectContaining({
|
|
328
|
+
headers: expect.objectContaining({
|
|
329
|
+
Authorization: 'Bearer test-key',
|
|
330
|
+
}),
|
|
331
|
+
}),
|
|
332
|
+
);
|
|
317
333
|
});
|
|
318
334
|
|
|
319
335
|
it('should get live evals', async () => {
|
|
@@ -333,6 +349,106 @@ describe('MastraClient Resources', () => {
|
|
|
333
349
|
});
|
|
334
350
|
});
|
|
335
351
|
|
|
352
|
+
describe('Agent Voice Resource', () => {
|
|
353
|
+
const agentId = 'test-agent';
|
|
354
|
+
let agent: ReturnType<typeof client.getAgent>;
|
|
355
|
+
beforeEach(() => {
|
|
356
|
+
agent = client.getAgent(agentId);
|
|
357
|
+
});
|
|
358
|
+
it('should get available speakers', async () => {
|
|
359
|
+
const mockResponse = [{ voiceId: 'speaker1' }];
|
|
360
|
+
mockFetchResponse(mockResponse);
|
|
361
|
+
|
|
362
|
+
const result = await agent.voice.getSpeakers();
|
|
363
|
+
|
|
364
|
+
expect(result).toEqual(mockResponse);
|
|
365
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
366
|
+
`${clientOptions.baseUrl}/api/agents/test-agent/voice/speakers`,
|
|
367
|
+
expect.objectContaining({
|
|
368
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
369
|
+
}),
|
|
370
|
+
);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it(`should call speak without options`, async () => {
|
|
374
|
+
const mockAudioStream = new ReadableStream();
|
|
375
|
+
mockFetchResponse(mockAudioStream, { isStream: true });
|
|
376
|
+
|
|
377
|
+
const result = await agent.voice.speak('test');
|
|
378
|
+
|
|
379
|
+
expect(result).toBeInstanceOf(Response);
|
|
380
|
+
expect(result.body).toBeInstanceOf(ReadableStream);
|
|
381
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
382
|
+
`${clientOptions.baseUrl}/api/agents/test-agent/voice/speak`,
|
|
383
|
+
expect.objectContaining({
|
|
384
|
+
method: 'POST',
|
|
385
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
386
|
+
}),
|
|
387
|
+
);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it(`should call speak with options`, async () => {
|
|
391
|
+
const mockAudioStream = new ReadableStream();
|
|
392
|
+
mockFetchResponse(mockAudioStream, { isStream: true });
|
|
393
|
+
|
|
394
|
+
const result = await agent.voice.speak('test', { speaker: 'speaker1' });
|
|
395
|
+
expect(result).toBeInstanceOf(Response);
|
|
396
|
+
expect(result.body).toBeInstanceOf(ReadableStream);
|
|
397
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
398
|
+
`${clientOptions.baseUrl}/api/agents/test-agent/voice/speak`,
|
|
399
|
+
expect.objectContaining({
|
|
400
|
+
method: 'POST',
|
|
401
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
402
|
+
}),
|
|
403
|
+
);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it(`should call listen with audio file`, async () => {
|
|
407
|
+
const transcriptionResponse = { text: 'Hello world' };
|
|
408
|
+
mockFetchResponse(transcriptionResponse);
|
|
409
|
+
|
|
410
|
+
const audioBlob = new Blob(['test audio data'], { type: 'audio/wav' });
|
|
411
|
+
|
|
412
|
+
const result = await agent.voice.listen(audioBlob, { filetype: 'wav' });
|
|
413
|
+
expect(result).toEqual(transcriptionResponse);
|
|
414
|
+
|
|
415
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
416
|
+
const [url, config] = (global.fetch as any).mock.calls[0];
|
|
417
|
+
expect(url).toBe(`${clientOptions.baseUrl}/api/agents/test-agent/voice/listen`);
|
|
418
|
+
expect(config.method).toBe('POST');
|
|
419
|
+
expect(config.headers).toMatchObject(clientOptions.headers);
|
|
420
|
+
|
|
421
|
+
const formData = config.body;
|
|
422
|
+
expect(formData).toBeInstanceOf(FormData);
|
|
423
|
+
const audioContent = formData.get('audio');
|
|
424
|
+
expect(audioContent).toBeInstanceOf(Blob);
|
|
425
|
+
expect(audioContent.type).toBe('audio/wav');
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it(`should call listen with audio blob and options`, async () => {
|
|
429
|
+
const transcriptionResponse = { text: 'Hello world' };
|
|
430
|
+
mockFetchResponse(transcriptionResponse);
|
|
431
|
+
|
|
432
|
+
const audioBlob = new Blob(['test audio data'], { type: 'audio/mp3' });
|
|
433
|
+
|
|
434
|
+
const result = await agent.voice.listen(audioBlob, { filetype: 'mp3' });
|
|
435
|
+
|
|
436
|
+
expect(result).toEqual(transcriptionResponse);
|
|
437
|
+
|
|
438
|
+
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
439
|
+
const [url, config] = (global.fetch as any).mock.calls[0];
|
|
440
|
+
expect(url).toBe(`${clientOptions.baseUrl}/api/agents/test-agent/voice/listen`);
|
|
441
|
+
expect(config.method).toBe('POST');
|
|
442
|
+
expect(config.headers).toMatchObject(clientOptions.headers);
|
|
443
|
+
|
|
444
|
+
const formData = config.body as FormData;
|
|
445
|
+
expect(formData).toBeInstanceOf(FormData);
|
|
446
|
+
const audioContent = formData.get('audio');
|
|
447
|
+
expect(audioContent).toBeInstanceOf(Blob);
|
|
448
|
+
expect(formData.get('options')).toBe(JSON.stringify({ filetype: 'mp3' }));
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
|
|
336
452
|
const agentId = 'test-agent';
|
|
337
453
|
|
|
338
454
|
describe('Memory Thread Resource', () => {
|
|
@@ -372,7 +488,7 @@ describe('MastraClient Resources', () => {
|
|
|
372
488
|
const result = await memoryThread.update({
|
|
373
489
|
title: 'Updated Thread',
|
|
374
490
|
metadata: { updated: true },
|
|
375
|
-
|
|
491
|
+
resourceId: 'test-resource',
|
|
376
492
|
});
|
|
377
493
|
expect(result).toEqual(mockResponse);
|
|
378
494
|
expect(global.fetch).toHaveBeenCalledWith(
|
|
@@ -412,29 +528,28 @@ describe('MastraClient Resources', () => {
|
|
|
412
528
|
});
|
|
413
529
|
|
|
414
530
|
it('should save messages to memory', async () => {
|
|
415
|
-
const messages
|
|
531
|
+
const messages = [
|
|
416
532
|
{
|
|
417
533
|
id: '1',
|
|
418
|
-
type: 'text',
|
|
534
|
+
type: 'text' as const,
|
|
419
535
|
content: 'test',
|
|
420
|
-
role: 'user',
|
|
536
|
+
role: 'user' as const,
|
|
421
537
|
threadId: 'test-thread',
|
|
422
|
-
|
|
538
|
+
resourceId: 'test-resource',
|
|
539
|
+
createdAt: new Date('2025-03-26T10:40:55.116Z'),
|
|
423
540
|
},
|
|
424
541
|
];
|
|
425
542
|
mockFetchResponse(messages);
|
|
426
|
-
const result = await client.saveMessageToMemory({
|
|
543
|
+
const result = await client.saveMessageToMemory({ agentId, messages });
|
|
427
544
|
expect(result).toEqual(messages);
|
|
428
545
|
expect(global.fetch).toHaveBeenCalledWith(
|
|
429
546
|
`${clientOptions.baseUrl}/api/memory/save-messages?agentId=${agentId}`,
|
|
430
|
-
{
|
|
547
|
+
expect.objectContaining({
|
|
431
548
|
method: 'POST',
|
|
432
|
-
headers: {
|
|
549
|
+
headers: expect.objectContaining({
|
|
433
550
|
Authorization: 'Bearer test-key',
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
body: JSON.stringify({ messages, agentId }),
|
|
437
|
-
},
|
|
551
|
+
}),
|
|
552
|
+
}),
|
|
438
553
|
);
|
|
439
554
|
});
|
|
440
555
|
});
|
|
@@ -467,21 +582,19 @@ describe('MastraClient Resources', () => {
|
|
|
467
582
|
});
|
|
468
583
|
|
|
469
584
|
it('should execute tool', async () => {
|
|
470
|
-
const mockResponse = {
|
|
471
|
-
result: 'Tool execution result',
|
|
472
|
-
};
|
|
585
|
+
const mockResponse = { data: 'test' };
|
|
473
586
|
mockFetchResponse(mockResponse);
|
|
474
|
-
|
|
475
|
-
const result = await tool.execute({ data: '' });
|
|
587
|
+
const result = await tool.execute({ data: '', runId: 'test-run-id' });
|
|
476
588
|
expect(result).toEqual(mockResponse);
|
|
477
|
-
expect(global.fetch).toHaveBeenCalledWith(
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
589
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
590
|
+
`${clientOptions.baseUrl}/api/tools/test-tool/execute?runId=test-run-id`,
|
|
591
|
+
expect.objectContaining({
|
|
592
|
+
method: 'POST',
|
|
593
|
+
headers: expect.objectContaining({
|
|
594
|
+
Authorization: 'Bearer test-key',
|
|
595
|
+
}),
|
|
596
|
+
}),
|
|
597
|
+
);
|
|
485
598
|
});
|
|
486
599
|
});
|
|
487
600
|
|
|
@@ -519,14 +632,14 @@ describe('MastraClient Resources', () => {
|
|
|
519
632
|
};
|
|
520
633
|
mockFetchResponse(mockResponse);
|
|
521
634
|
|
|
522
|
-
const result = await workflow.
|
|
635
|
+
const result = await workflow.startAsync({ triggerData: { test: 'test' } });
|
|
523
636
|
expect(result).toEqual(mockResponse);
|
|
524
637
|
expect(global.fetch).toHaveBeenCalledWith(
|
|
525
|
-
`${clientOptions.baseUrl}/api/workflows/test-workflow/
|
|
638
|
+
`${clientOptions.baseUrl}/api/workflows/test-workflow/start-async?`,
|
|
526
639
|
expect.objectContaining({
|
|
527
640
|
method: 'POST',
|
|
528
641
|
headers: expect.objectContaining(clientOptions.headers),
|
|
529
|
-
body: JSON.stringify({
|
|
642
|
+
body: JSON.stringify({ test: 'test' }),
|
|
530
643
|
}),
|
|
531
644
|
);
|
|
532
645
|
});
|
package/src/resources/agent.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { processDataStream } from '@ai-sdk/ui-utils';
|
|
2
|
+
import type { GenerateReturn } from '@mastra/core';
|
|
2
3
|
import type { JSONSchema7 } from 'json-schema';
|
|
3
4
|
import { ZodSchema } from 'zod';
|
|
4
5
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
@@ -36,12 +37,70 @@ export class AgentTool extends BaseResource {
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
|
|
40
|
+
export class AgentVoice extends BaseResource {
|
|
41
|
+
constructor(
|
|
42
|
+
options: ClientOptions,
|
|
43
|
+
private agentId: string,
|
|
44
|
+
) {
|
|
45
|
+
super(options);
|
|
46
|
+
this.agentId = agentId;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Convert text to speech using the agent's voice provider
|
|
51
|
+
* @param text - Text to convert to speech
|
|
52
|
+
* @param options - Optional provider-specific options for speech generation
|
|
53
|
+
* @returns Promise containing the audio data
|
|
54
|
+
*/
|
|
55
|
+
async speak(text: string, options?: { speaker?: string; [key: string]: any }): Promise<Response> {
|
|
56
|
+
return this.request<Response>(`/api/agents/${this.agentId}/voice/speak`, {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
headers: {
|
|
59
|
+
'Content-Type': 'application/json',
|
|
60
|
+
},
|
|
61
|
+
body: { input: text, options },
|
|
62
|
+
stream: true,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Convert speech to text using the agent's voice provider
|
|
68
|
+
* @param audio - Audio data to transcribe
|
|
69
|
+
* @param options - Optional provider-specific options
|
|
70
|
+
* @returns Promise containing the transcribed text
|
|
71
|
+
*/
|
|
72
|
+
listen(audio: Blob, options?: Record<string, any>): Promise<Response> {
|
|
73
|
+
const formData = new FormData();
|
|
74
|
+
formData.append('audio', audio);
|
|
75
|
+
|
|
76
|
+
if (options) {
|
|
77
|
+
formData.append('options', JSON.stringify(options));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return this.request(`/api/agents/${this.agentId}/voice/listen`, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
body: formData,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get available speakers for the agent's voice provider
|
|
88
|
+
* @returns Promise containing list of available speakers
|
|
89
|
+
*/
|
|
90
|
+
getSpeakers(): Promise<Array<{ voiceId: string; [key: string]: any }>> {
|
|
91
|
+
return this.request(`/api/agents/${this.agentId}/voice/speakers`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
39
95
|
export class Agent extends BaseResource {
|
|
96
|
+
public readonly voice: AgentVoice;
|
|
97
|
+
|
|
40
98
|
constructor(
|
|
41
99
|
options: ClientOptions,
|
|
42
100
|
private agentId: string,
|
|
43
101
|
) {
|
|
44
102
|
super(options);
|
|
103
|
+
this.voice = new AgentVoice(options, this.agentId);
|
|
45
104
|
}
|
|
46
105
|
|
|
47
106
|
/**
|
|
@@ -63,6 +122,10 @@ export class Agent extends BaseResource {
|
|
|
63
122
|
const processedParams = {
|
|
64
123
|
...params,
|
|
65
124
|
output: params.output instanceof ZodSchema ? zodToJsonSchema(params.output) : params.output,
|
|
125
|
+
experimental_output:
|
|
126
|
+
params.experimental_output instanceof ZodSchema
|
|
127
|
+
? zodToJsonSchema(params.experimental_output)
|
|
128
|
+
: params.experimental_output,
|
|
66
129
|
};
|
|
67
130
|
|
|
68
131
|
return this.request(`/api/agents/${this.agentId}/generate`, {
|
|
@@ -74,19 +137,44 @@ export class Agent extends BaseResource {
|
|
|
74
137
|
/**
|
|
75
138
|
* Streams a response from the agent
|
|
76
139
|
* @param params - Stream parameters including prompt
|
|
77
|
-
* @returns Promise containing the
|
|
140
|
+
* @returns Promise containing the enhanced Response object with processDataStream method
|
|
78
141
|
*/
|
|
79
|
-
stream<T extends JSONSchema7 | ZodSchema | undefined = undefined>(
|
|
142
|
+
async stream<T extends JSONSchema7 | ZodSchema | undefined = undefined>(
|
|
143
|
+
params: StreamParams<T>,
|
|
144
|
+
): Promise<
|
|
145
|
+
Response & {
|
|
146
|
+
processDataStream: (options?: Omit<Parameters<typeof processDataStream>[0], 'stream'>) => Promise<void>;
|
|
147
|
+
}
|
|
148
|
+
> {
|
|
80
149
|
const processedParams = {
|
|
81
150
|
...params,
|
|
82
151
|
output: params.output instanceof ZodSchema ? zodToJsonSchema(params.output) : params.output,
|
|
152
|
+
experimental_output:
|
|
153
|
+
params.experimental_output instanceof ZodSchema
|
|
154
|
+
? zodToJsonSchema(params.experimental_output)
|
|
155
|
+
: params.experimental_output,
|
|
83
156
|
};
|
|
84
157
|
|
|
85
|
-
|
|
158
|
+
const response: Response & {
|
|
159
|
+
processDataStream: (options?: Omit<Parameters<typeof processDataStream>[0], 'stream'>) => Promise<void>;
|
|
160
|
+
} = await this.request(`/api/agents/${this.agentId}/stream`, {
|
|
86
161
|
method: 'POST',
|
|
87
162
|
body: processedParams,
|
|
88
163
|
stream: true,
|
|
89
164
|
});
|
|
165
|
+
|
|
166
|
+
if (!response.body) {
|
|
167
|
+
throw new Error('No response body');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
response.processDataStream = async (options = {}) => {
|
|
171
|
+
await processDataStream({
|
|
172
|
+
stream: response.body as ReadableStream<Uint8Array>,
|
|
173
|
+
...options,
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
return response;
|
|
90
178
|
}
|
|
91
179
|
|
|
92
180
|
/**
|
package/src/resources/base.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestOptions, ClientOptions } from '../types';
|
|
2
2
|
|
|
3
3
|
export class BaseResource {
|
|
4
4
|
readonly options: ClientOptions;
|
|
@@ -24,11 +24,13 @@ export class BaseResource {
|
|
|
24
24
|
const response = await fetch(`${baseUrl}${path}`, {
|
|
25
25
|
...options,
|
|
26
26
|
headers: {
|
|
27
|
-
'Content-Type': 'application/json',
|
|
28
27
|
...headers,
|
|
29
28
|
...options.headers,
|
|
29
|
+
// TODO: Bring this back once we figure out what we/users need to do to make this work with cross-origin requests
|
|
30
|
+
// 'x-mastra-client-type': 'js',
|
|
30
31
|
},
|
|
31
|
-
body:
|
|
32
|
+
body:
|
|
33
|
+
options.body instanceof FormData ? options.body : options.body ? JSON.stringify(options.body) : undefined,
|
|
32
34
|
});
|
|
33
35
|
|
|
34
36
|
if (!response.ok) {
|
package/src/resources/index.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import type { StorageThreadType } from '@mastra/core';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
CreateMemoryThreadParams,
|
|
5
|
-
GetMemoryThreadMessagesResponse,
|
|
6
|
-
GetMemoryThreadResponse,
|
|
7
|
-
ClientOptions,
|
|
8
|
-
SaveMessageToMemoryParams,
|
|
9
|
-
UpdateMemoryThreadParams,
|
|
10
|
-
} from '../types';
|
|
3
|
+
import type { GetMemoryThreadMessagesResponse, ClientOptions, UpdateMemoryThreadParams } from '../types';
|
|
11
4
|
|
|
12
5
|
import { BaseResource } from './base';
|
|
13
6
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { processDataStream } from '@ai-sdk/ui-utils';
|
|
2
|
+
import type { GenerateReturn } from '@mastra/core';
|
|
3
|
+
import type { JSONSchema7 } from 'json-schema';
|
|
4
|
+
import { ZodSchema } from 'zod';
|
|
5
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
6
|
+
|
|
7
|
+
import type { GenerateParams, ClientOptions, StreamParams, GetNetworkResponse } from '../types';
|
|
8
|
+
|
|
9
|
+
import { BaseResource } from './base';
|
|
10
|
+
|
|
11
|
+
export class Network extends BaseResource {
|
|
12
|
+
constructor(
|
|
13
|
+
options: ClientOptions,
|
|
14
|
+
private networkId: string,
|
|
15
|
+
) {
|
|
16
|
+
super(options);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves details about the network
|
|
21
|
+
* @returns Promise containing network details
|
|
22
|
+
*/
|
|
23
|
+
details(): Promise<GetNetworkResponse> {
|
|
24
|
+
return this.request(`/api/networks/${this.networkId}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generates a response from the agent
|
|
29
|
+
* @param params - Generation parameters including prompt
|
|
30
|
+
* @returns Promise containing the generated response
|
|
31
|
+
*/
|
|
32
|
+
generate<T extends JSONSchema7 | ZodSchema | undefined = undefined>(
|
|
33
|
+
params: GenerateParams<T>,
|
|
34
|
+
): Promise<GenerateReturn<T>> {
|
|
35
|
+
const processedParams = {
|
|
36
|
+
...params,
|
|
37
|
+
output: params.output instanceof ZodSchema ? zodToJsonSchema(params.output) : params.output,
|
|
38
|
+
experimental_output:
|
|
39
|
+
params.experimental_output instanceof ZodSchema
|
|
40
|
+
? zodToJsonSchema(params.experimental_output)
|
|
41
|
+
: params.experimental_output,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return this.request(`/api/networks/${this.networkId}/generate`, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
body: processedParams,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Streams a response from the agent
|
|
52
|
+
* @param params - Stream parameters including prompt
|
|
53
|
+
* @returns Promise containing the enhanced Response object with processDataStream method
|
|
54
|
+
*/
|
|
55
|
+
async stream<T extends JSONSchema7 | ZodSchema | undefined = undefined>(
|
|
56
|
+
params: StreamParams<T>,
|
|
57
|
+
): Promise<
|
|
58
|
+
Response & {
|
|
59
|
+
processDataStream: (options?: Omit<Parameters<typeof processDataStream>[0], 'stream'>) => Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
> {
|
|
62
|
+
const processedParams = {
|
|
63
|
+
...params,
|
|
64
|
+
output: params.output instanceof ZodSchema ? zodToJsonSchema(params.output) : params.output,
|
|
65
|
+
experimental_output:
|
|
66
|
+
params.experimental_output instanceof ZodSchema
|
|
67
|
+
? zodToJsonSchema(params.experimental_output)
|
|
68
|
+
: params.experimental_output,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const response: Response & {
|
|
72
|
+
processDataStream: (options?: Omit<Parameters<typeof processDataStream>[0], 'stream'>) => Promise<void>;
|
|
73
|
+
} = await this.request(`/api/networks/${this.networkId}/stream`, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
body: processedParams,
|
|
76
|
+
stream: true,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
if (!response.body) {
|
|
80
|
+
throw new Error('No response body');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
response.processDataStream = async (options = {}) => {
|
|
84
|
+
await processDataStream({
|
|
85
|
+
stream: response.body as ReadableStream<Uint8Array>,
|
|
86
|
+
...options,
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return response;
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/resources/tool.ts
CHANGED
|
@@ -23,10 +23,16 @@ export class Tool extends BaseResource {
|
|
|
23
23
|
* @param params - Parameters required for tool execution
|
|
24
24
|
* @returns Promise containing the tool execution results
|
|
25
25
|
*/
|
|
26
|
-
execute(params: { data: any }): Promise<any> {
|
|
27
|
-
|
|
26
|
+
execute(params: { data: any; runId?: string }): Promise<any> {
|
|
27
|
+
const url = new URLSearchParams();
|
|
28
|
+
|
|
29
|
+
if (params.runId) {
|
|
30
|
+
url.set('runId', params.runId);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return this.request(`/api/tools/${this.toolId}/execute?${url.toString()}`, {
|
|
28
34
|
method: 'POST',
|
|
29
|
-
body: params,
|
|
35
|
+
body: params.data,
|
|
30
36
|
});
|
|
31
37
|
}
|
|
32
38
|
}
|