@mastra/client-js 0.0.0-tool-call-parts-20250630193309 → 0.0.0-transpile-packages-20250730132657
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 +318 -3
- package/LICENSE.md +11 -42
- package/README.md +1 -0
- package/dist/index.cjs +261 -66
- package/dist/index.d.cts +211 -45
- package/dist/index.d.ts +211 -45
- package/dist/index.js +260 -65
- package/package.json +6 -5
- package/src/client.ts +145 -2
- package/src/example.ts +45 -17
- package/src/index.test.ts +294 -6
- package/src/resources/agent.ts +51 -21
- package/src/resources/base.ts +6 -1
- package/src/resources/memory-thread.ts +18 -0
- package/src/resources/network.ts +4 -3
- package/src/resources/vNextNetwork.ts +22 -5
- package/src/resources/workflow.ts +42 -5
- package/src/types.ts +95 -4
- package/src/utils/process-client-tools.ts +1 -1
- package/.turbo/turbo-build.log +0 -19
package/src/example.ts
CHANGED
|
@@ -14,25 +14,53 @@ import z from 'zod';
|
|
|
14
14
|
const agent = client.getAgent('weatherAgent');
|
|
15
15
|
const response = await agent.stream({
|
|
16
16
|
messages: 'what is the weather in new york?',
|
|
17
|
+
output: z.object({
|
|
18
|
+
weather: z.string(),
|
|
19
|
+
temperature: z.number(),
|
|
20
|
+
humidity: z.number(),
|
|
21
|
+
windSpeed: z.number(),
|
|
22
|
+
windDirection: z.string(),
|
|
23
|
+
windGust: z.number(),
|
|
24
|
+
windChill: z.number(),
|
|
25
|
+
}),
|
|
17
26
|
});
|
|
18
27
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
// Process data stream - unstructured output
|
|
29
|
+
|
|
30
|
+
// response.processDataStream({
|
|
31
|
+
// onTextPart: text => {
|
|
32
|
+
// process.stdout.write(text);
|
|
33
|
+
// },
|
|
34
|
+
// onFilePart: file => {
|
|
35
|
+
// console.log(file);
|
|
36
|
+
// },
|
|
37
|
+
// onDataPart: data => {
|
|
38
|
+
// console.log(data);
|
|
39
|
+
// },
|
|
40
|
+
// onErrorPart: error => {
|
|
41
|
+
// console.error(error);
|
|
42
|
+
// },
|
|
43
|
+
// onToolCallPart(streamPart) {
|
|
44
|
+
// console.log(streamPart);
|
|
45
|
+
// },
|
|
46
|
+
// });
|
|
47
|
+
|
|
48
|
+
// Process text stream - structured output
|
|
49
|
+
|
|
50
|
+
// response.processTextStream({
|
|
51
|
+
// onTextPart: text => {
|
|
52
|
+
// process.stdout.write(text);
|
|
53
|
+
// },
|
|
54
|
+
// });
|
|
55
|
+
|
|
56
|
+
// read the response body directly
|
|
57
|
+
|
|
58
|
+
// const reader = response.body!.getReader();
|
|
59
|
+
// while (true) {
|
|
60
|
+
// const { done, value } = await reader.read();
|
|
61
|
+
// if (done) break;
|
|
62
|
+
// console.log(new TextDecoder().decode(value));
|
|
63
|
+
// }
|
|
36
64
|
} catch (error) {
|
|
37
65
|
console.error(error);
|
|
38
66
|
}
|
package/src/index.test.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { describe, expect, beforeEach, it, vi } from 'vitest';
|
|
2
2
|
import { MastraClient } from './client';
|
|
3
|
-
import type { McpServerListResponse
|
|
3
|
+
import type { McpServerListResponse } from './types';
|
|
4
|
+
import type { ServerDetailInfo } from '@mastra/core/mcp';
|
|
5
|
+
import { ScoringEntityType, ScoringSource } from '@mastra/core/scores';
|
|
4
6
|
|
|
5
7
|
// Mock fetch globally
|
|
6
8
|
global.fetch = vi.fn();
|
|
@@ -27,7 +29,13 @@ describe('MastraClient Resources', () => {
|
|
|
27
29
|
} else {
|
|
28
30
|
responseBody = new ReadableStream({
|
|
29
31
|
start(controller) {
|
|
30
|
-
|
|
32
|
+
if (typeof data === 'string') {
|
|
33
|
+
controller.enqueue(new TextEncoder().encode(data));
|
|
34
|
+
} else if (typeof data === 'object' && data !== null) {
|
|
35
|
+
controller.enqueue(new TextEncoder().encode(JSON.stringify(data)));
|
|
36
|
+
} else {
|
|
37
|
+
controller.enqueue(new TextEncoder().encode(String(data)));
|
|
38
|
+
}
|
|
31
39
|
controller.close();
|
|
32
40
|
},
|
|
33
41
|
});
|
|
@@ -279,7 +287,7 @@ describe('MastraClient Resources', () => {
|
|
|
279
287
|
});
|
|
280
288
|
|
|
281
289
|
it('should stream responses', async () => {
|
|
282
|
-
const mockChunk =
|
|
290
|
+
const mockChunk = `0:"test response"\n`;
|
|
283
291
|
mockFetchResponse(mockChunk, { isStream: true });
|
|
284
292
|
|
|
285
293
|
const response = await agent.stream({
|
|
@@ -298,7 +306,7 @@ describe('MastraClient Resources', () => {
|
|
|
298
306
|
if (reader) {
|
|
299
307
|
const { value, done } = await reader.read();
|
|
300
308
|
expect(done).toBe(false);
|
|
301
|
-
expect(new TextDecoder().decode(value)).toBe(
|
|
309
|
+
expect(new TextDecoder().decode(value)).toBe(mockChunk);
|
|
302
310
|
}
|
|
303
311
|
});
|
|
304
312
|
|
|
@@ -582,6 +590,48 @@ describe('MastraClient Resources', () => {
|
|
|
582
590
|
}),
|
|
583
591
|
);
|
|
584
592
|
});
|
|
593
|
+
|
|
594
|
+
it('should get paginated thread messages', async () => {
|
|
595
|
+
const mockResponse = {
|
|
596
|
+
messages: [
|
|
597
|
+
{
|
|
598
|
+
id: '1',
|
|
599
|
+
content: 'test message',
|
|
600
|
+
threadId,
|
|
601
|
+
role: 'user',
|
|
602
|
+
type: 'text',
|
|
603
|
+
resourceId: 'test-resource',
|
|
604
|
+
createdAt: new Date(),
|
|
605
|
+
},
|
|
606
|
+
],
|
|
607
|
+
total: 5,
|
|
608
|
+
page: 1,
|
|
609
|
+
perPage: 2,
|
|
610
|
+
hasMore: true,
|
|
611
|
+
};
|
|
612
|
+
mockFetchResponse(mockResponse);
|
|
613
|
+
|
|
614
|
+
const selectBy = {
|
|
615
|
+
pagination: {
|
|
616
|
+
page: 1,
|
|
617
|
+
perPage: 2,
|
|
618
|
+
},
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
const result = await memoryThread.getMessagesPaginated({
|
|
622
|
+
resourceId: 'test-resource',
|
|
623
|
+
format: 'v2',
|
|
624
|
+
selectBy,
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
expect(result).toEqual(mockResponse);
|
|
628
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
629
|
+
`${clientOptions.baseUrl}/api/memory/threads/${threadId}/messages/paginated?resourceId=test-resource&format=v2&selectBy=${encodeURIComponent(JSON.stringify(selectBy))}`,
|
|
630
|
+
expect.objectContaining({
|
|
631
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
632
|
+
}),
|
|
633
|
+
);
|
|
634
|
+
});
|
|
585
635
|
});
|
|
586
636
|
|
|
587
637
|
describe('Tool Resource', () => {
|
|
@@ -662,14 +712,14 @@ describe('MastraClient Resources', () => {
|
|
|
662
712
|
};
|
|
663
713
|
mockFetchResponse(mockResponse);
|
|
664
714
|
|
|
665
|
-
const result = await workflow.startAsync({
|
|
715
|
+
const result = await workflow.startAsync({ inputData: { test: 'test' } });
|
|
666
716
|
expect(result).toEqual(mockResponse);
|
|
667
717
|
expect(global.fetch).toHaveBeenCalledWith(
|
|
668
718
|
`${clientOptions.baseUrl}/api/workflows/test-workflow/start-async?`,
|
|
669
719
|
expect.objectContaining({
|
|
670
720
|
method: 'POST',
|
|
671
721
|
headers: expect.objectContaining(clientOptions.headers),
|
|
672
|
-
body: JSON.stringify({ test: 'test' }),
|
|
722
|
+
body: JSON.stringify({ inputData: { test: 'test' } }),
|
|
673
723
|
}),
|
|
674
724
|
);
|
|
675
725
|
});
|
|
@@ -827,4 +877,242 @@ describe('MastraClient Resources', () => {
|
|
|
827
877
|
});
|
|
828
878
|
});
|
|
829
879
|
});
|
|
880
|
+
|
|
881
|
+
describe('Scores Methods', () => {
|
|
882
|
+
describe('getScorers()', () => {
|
|
883
|
+
it('should fetch all available scorers', async () => {
|
|
884
|
+
const mockResponse = {
|
|
885
|
+
scorers: [
|
|
886
|
+
{ id: 'scorer-1', name: 'Test Scorer 1', description: 'A test scorer' },
|
|
887
|
+
{ id: 'scorer-2', name: 'Test Scorer 2', description: 'Another test scorer' },
|
|
888
|
+
],
|
|
889
|
+
};
|
|
890
|
+
mockFetchResponse(mockResponse);
|
|
891
|
+
|
|
892
|
+
const result = await client.getScorers();
|
|
893
|
+
expect(result).toEqual(mockResponse);
|
|
894
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
895
|
+
`${clientOptions.baseUrl}/api/scores/scorers`,
|
|
896
|
+
expect.objectContaining({
|
|
897
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
898
|
+
}),
|
|
899
|
+
);
|
|
900
|
+
});
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
describe('getScoresByRunId()', () => {
|
|
904
|
+
it('should fetch scores by run ID without pagination', async () => {
|
|
905
|
+
const mockResponse = {
|
|
906
|
+
pagination: {
|
|
907
|
+
total: 10,
|
|
908
|
+
page: 0,
|
|
909
|
+
perPage: 10,
|
|
910
|
+
hasMore: false,
|
|
911
|
+
},
|
|
912
|
+
scores: [
|
|
913
|
+
{
|
|
914
|
+
id: 'score-1',
|
|
915
|
+
runId: 'run-123',
|
|
916
|
+
scorer: { name: 'test-scorer' },
|
|
917
|
+
result: { score: 0.8 },
|
|
918
|
+
input: { messages: [] },
|
|
919
|
+
output: { response: 'test' },
|
|
920
|
+
source: 'LIVE',
|
|
921
|
+
createdAt: new Date(),
|
|
922
|
+
updatedAt: new Date(),
|
|
923
|
+
},
|
|
924
|
+
],
|
|
925
|
+
};
|
|
926
|
+
|
|
927
|
+
mockFetchResponse({
|
|
928
|
+
...mockResponse,
|
|
929
|
+
scores: mockResponse.scores.map(score => ({
|
|
930
|
+
...score,
|
|
931
|
+
createdAt: score.createdAt.toISOString(),
|
|
932
|
+
updatedAt: score.updatedAt.toISOString(),
|
|
933
|
+
})),
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
const result = await client.getScoresByRunId({ runId: 'run-123' });
|
|
937
|
+
|
|
938
|
+
expect(result).toEqual({
|
|
939
|
+
...mockResponse,
|
|
940
|
+
scores: mockResponse.scores.map(score => ({
|
|
941
|
+
...score,
|
|
942
|
+
createdAt: score.createdAt.toISOString(),
|
|
943
|
+
updatedAt: score.updatedAt.toISOString(),
|
|
944
|
+
})),
|
|
945
|
+
});
|
|
946
|
+
|
|
947
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
948
|
+
`${clientOptions.baseUrl}/api/scores/run/run-123`,
|
|
949
|
+
expect.objectContaining({
|
|
950
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
951
|
+
}),
|
|
952
|
+
);
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
it('should fetch scores by run ID with pagination', async () => {
|
|
956
|
+
const mockResponse = {
|
|
957
|
+
pagination: {
|
|
958
|
+
total: 20,
|
|
959
|
+
page: 1,
|
|
960
|
+
perPage: 5,
|
|
961
|
+
hasMore: true,
|
|
962
|
+
},
|
|
963
|
+
scores: [],
|
|
964
|
+
};
|
|
965
|
+
mockFetchResponse(mockResponse);
|
|
966
|
+
|
|
967
|
+
const result = await client.getScoresByRunId({
|
|
968
|
+
runId: 'run-123',
|
|
969
|
+
page: 1,
|
|
970
|
+
perPage: 5,
|
|
971
|
+
});
|
|
972
|
+
expect(result).toEqual(mockResponse);
|
|
973
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
974
|
+
`${clientOptions.baseUrl}/api/scores/run/run-123?page=1&perPage=5`,
|
|
975
|
+
expect.objectContaining({
|
|
976
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
977
|
+
}),
|
|
978
|
+
);
|
|
979
|
+
});
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
describe('getScoresByEntityId()', () => {
|
|
983
|
+
it('should fetch scores by entity ID and type without pagination', async () => {
|
|
984
|
+
const mockResponse = {
|
|
985
|
+
pagination: {
|
|
986
|
+
total: 5,
|
|
987
|
+
page: 0,
|
|
988
|
+
perPage: 10,
|
|
989
|
+
hasMore: false,
|
|
990
|
+
},
|
|
991
|
+
scores: [
|
|
992
|
+
{
|
|
993
|
+
id: 'score-1',
|
|
994
|
+
runId: 'run-123',
|
|
995
|
+
entityId: 'agent-456',
|
|
996
|
+
entityType: 'AGENT',
|
|
997
|
+
scorer: { name: 'test-scorer' },
|
|
998
|
+
result: { score: 0.9 },
|
|
999
|
+
input: { messages: [] },
|
|
1000
|
+
output: { response: 'test' },
|
|
1001
|
+
source: 'LIVE',
|
|
1002
|
+
createdAt: new Date(),
|
|
1003
|
+
updatedAt: new Date(),
|
|
1004
|
+
},
|
|
1005
|
+
],
|
|
1006
|
+
};
|
|
1007
|
+
|
|
1008
|
+
const mockResponseWithDates = mockResponse.scores.map(score => ({
|
|
1009
|
+
...score,
|
|
1010
|
+
createdAt: score.createdAt.toISOString(),
|
|
1011
|
+
updatedAt: score.updatedAt.toISOString(),
|
|
1012
|
+
}));
|
|
1013
|
+
|
|
1014
|
+
mockFetchResponse({
|
|
1015
|
+
...mockResponse,
|
|
1016
|
+
scores: mockResponseWithDates,
|
|
1017
|
+
});
|
|
1018
|
+
|
|
1019
|
+
const result = await client.getScoresByEntityId({
|
|
1020
|
+
entityId: 'agent-456',
|
|
1021
|
+
entityType: 'AGENT',
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
expect(result).toEqual({
|
|
1025
|
+
...mockResponse,
|
|
1026
|
+
scores: mockResponseWithDates,
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
1030
|
+
`${clientOptions.baseUrl}/api/scores/entity/AGENT/agent-456`,
|
|
1031
|
+
expect.objectContaining({
|
|
1032
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
1033
|
+
}),
|
|
1034
|
+
);
|
|
1035
|
+
});
|
|
1036
|
+
|
|
1037
|
+
it('should fetch scores by entity ID and type with pagination', async () => {
|
|
1038
|
+
const mockResponse = {
|
|
1039
|
+
pagination: {
|
|
1040
|
+
total: 15,
|
|
1041
|
+
page: 2,
|
|
1042
|
+
perPage: 5,
|
|
1043
|
+
hasMore: true,
|
|
1044
|
+
},
|
|
1045
|
+
scores: [],
|
|
1046
|
+
};
|
|
1047
|
+
mockFetchResponse(mockResponse);
|
|
1048
|
+
|
|
1049
|
+
const result = await client.getScoresByEntityId({
|
|
1050
|
+
entityId: 'workflow-789',
|
|
1051
|
+
entityType: 'WORKFLOW',
|
|
1052
|
+
page: 2,
|
|
1053
|
+
perPage: 5,
|
|
1054
|
+
});
|
|
1055
|
+
expect(result).toEqual(mockResponse);
|
|
1056
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
1057
|
+
`${clientOptions.baseUrl}/api/scores/entity/WORKFLOW/workflow-789?page=2&perPage=5`,
|
|
1058
|
+
expect.objectContaining({
|
|
1059
|
+
body: undefined,
|
|
1060
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
1061
|
+
signal: undefined,
|
|
1062
|
+
}),
|
|
1063
|
+
);
|
|
1064
|
+
});
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
describe('saveScore()', () => {
|
|
1068
|
+
it('should save a score', async () => {
|
|
1069
|
+
const scoreData = {
|
|
1070
|
+
id: 'score-1',
|
|
1071
|
+
scorerId: 'test-scorer',
|
|
1072
|
+
runId: 'run-123',
|
|
1073
|
+
scorer: { name: 'test-scorer' },
|
|
1074
|
+
score: 0.85,
|
|
1075
|
+
input: [],
|
|
1076
|
+
output: { response: 'test response' },
|
|
1077
|
+
source: 'LIVE' as ScoringSource,
|
|
1078
|
+
entityId: 'agent-456',
|
|
1079
|
+
entityType: 'AGENT' as ScoringEntityType,
|
|
1080
|
+
entity: { id: 'agent-456', name: 'test-agent' },
|
|
1081
|
+
createdAt: new Date(),
|
|
1082
|
+
updatedAt: new Date(),
|
|
1083
|
+
runtimeContext: {
|
|
1084
|
+
model: {
|
|
1085
|
+
name: 'test-model',
|
|
1086
|
+
version: '1.0.0',
|
|
1087
|
+
},
|
|
1088
|
+
},
|
|
1089
|
+
};
|
|
1090
|
+
const mockResponse = {
|
|
1091
|
+
score: {
|
|
1092
|
+
...scoreData,
|
|
1093
|
+
createdAt: scoreData.createdAt.toISOString(),
|
|
1094
|
+
updatedAt: scoreData.updatedAt.toISOString(),
|
|
1095
|
+
},
|
|
1096
|
+
};
|
|
1097
|
+
mockFetchResponse(mockResponse);
|
|
1098
|
+
|
|
1099
|
+
const result = await client.saveScore({ score: scoreData });
|
|
1100
|
+
expect(result).toEqual({
|
|
1101
|
+
score: {
|
|
1102
|
+
...scoreData,
|
|
1103
|
+
createdAt: scoreData.createdAt.toISOString(),
|
|
1104
|
+
updatedAt: scoreData.updatedAt.toISOString(),
|
|
1105
|
+
},
|
|
1106
|
+
});
|
|
1107
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
1108
|
+
`${clientOptions.baseUrl}/api/scores`,
|
|
1109
|
+
expect.objectContaining({
|
|
1110
|
+
method: 'POST',
|
|
1111
|
+
headers: expect.objectContaining(clientOptions.headers),
|
|
1112
|
+
body: JSON.stringify({ score: scoreData }),
|
|
1113
|
+
}),
|
|
1114
|
+
);
|
|
1115
|
+
});
|
|
1116
|
+
});
|
|
1117
|
+
});
|
|
830
1118
|
});
|
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({
|
|
@@ -673,6 +685,24 @@ export class Agent extends BaseResource {
|
|
|
673
685
|
toolInvocation.result = result;
|
|
674
686
|
}
|
|
675
687
|
|
|
688
|
+
// write the tool result part to the stream
|
|
689
|
+
const writer = writable.getWriter();
|
|
690
|
+
|
|
691
|
+
try {
|
|
692
|
+
await writer.write(
|
|
693
|
+
new TextEncoder().encode(
|
|
694
|
+
'a:' +
|
|
695
|
+
JSON.stringify({
|
|
696
|
+
toolCallId: toolCall.toolCallId,
|
|
697
|
+
result,
|
|
698
|
+
}) +
|
|
699
|
+
'\n',
|
|
700
|
+
),
|
|
701
|
+
);
|
|
702
|
+
} finally {
|
|
703
|
+
writer.releaseLock();
|
|
704
|
+
}
|
|
705
|
+
|
|
676
706
|
// Convert messages to the correct format for the recursive call
|
|
677
707
|
const originalMessages = processedParams.messages;
|
|
678
708
|
const messageArray = Array.isArray(originalMessages) ? originalMessages : [originalMessages];
|
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
|
});
|
|
@@ -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,20 @@ 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
|
+
}
|
|
63
81
|
}
|
package/src/resources/network.ts
CHANGED
|
@@ -28,9 +28,10 @@ export class Network extends BaseResource {
|
|
|
28
28
|
* @param params - Generation parameters including prompt
|
|
29
29
|
* @returns Promise containing the generated response
|
|
30
30
|
*/
|
|
31
|
-
generate<
|
|
32
|
-
|
|
33
|
-
|
|
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>> {
|
|
34
35
|
const processedParams = {
|
|
35
36
|
...params,
|
|
36
37
|
output: zodToJsonSchema(params.output),
|
|
@@ -10,6 +10,8 @@ import type {
|
|
|
10
10
|
} from '../types';
|
|
11
11
|
|
|
12
12
|
import { BaseResource } from './base';
|
|
13
|
+
import { parseClientRuntimeContext } from '../utils';
|
|
14
|
+
import type { RuntimeContext } from '@mastra/core/runtime-context';
|
|
13
15
|
|
|
14
16
|
const RECORD_SEPARATOR = '\x1E';
|
|
15
17
|
|
|
@@ -37,7 +39,10 @@ export class VNextNetwork extends BaseResource {
|
|
|
37
39
|
generate(params: GenerateOrStreamVNextNetworkParams): Promise<GenerateVNextNetworkResponse> {
|
|
38
40
|
return this.request(`/api/networks/v-next/${this.networkId}/generate`, {
|
|
39
41
|
method: 'POST',
|
|
40
|
-
body:
|
|
42
|
+
body: {
|
|
43
|
+
...params,
|
|
44
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
45
|
+
},
|
|
41
46
|
});
|
|
42
47
|
}
|
|
43
48
|
|
|
@@ -46,10 +51,16 @@ export class VNextNetwork extends BaseResource {
|
|
|
46
51
|
* @param params - Generation parameters including message
|
|
47
52
|
* @returns Promise containing the generated response
|
|
48
53
|
*/
|
|
49
|
-
loop(params: {
|
|
54
|
+
loop(params: {
|
|
55
|
+
message: string;
|
|
56
|
+
runtimeContext?: RuntimeContext | Record<string, any>;
|
|
57
|
+
}): Promise<LoopVNextNetworkResponse> {
|
|
50
58
|
return this.request(`/api/networks/v-next/${this.networkId}/loop`, {
|
|
51
59
|
method: 'POST',
|
|
52
|
-
body:
|
|
60
|
+
body: {
|
|
61
|
+
...params,
|
|
62
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
63
|
+
},
|
|
53
64
|
});
|
|
54
65
|
}
|
|
55
66
|
|
|
@@ -125,7 +136,10 @@ export class VNextNetwork extends BaseResource {
|
|
|
125
136
|
async stream(params: GenerateOrStreamVNextNetworkParams, onRecord: (record: WatchEvent) => void) {
|
|
126
137
|
const response: Response = await this.request(`/api/networks/v-next/${this.networkId}/stream`, {
|
|
127
138
|
method: 'POST',
|
|
128
|
-
body:
|
|
139
|
+
body: {
|
|
140
|
+
...params,
|
|
141
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
142
|
+
},
|
|
129
143
|
stream: true,
|
|
130
144
|
});
|
|
131
145
|
|
|
@@ -154,7 +168,10 @@ export class VNextNetwork extends BaseResource {
|
|
|
154
168
|
async loopStream(params: LoopStreamVNextNetworkParams, onRecord: (record: WatchEvent) => void) {
|
|
155
169
|
const response: Response = await this.request(`/api/networks/v-next/${this.networkId}/loop-stream`, {
|
|
156
170
|
method: 'POST',
|
|
157
|
-
body:
|
|
171
|
+
body: {
|
|
172
|
+
...params,
|
|
173
|
+
runtimeContext: parseClientRuntimeContext(params.runtimeContext),
|
|
174
|
+
},
|
|
158
175
|
stream: true,
|
|
159
176
|
});
|
|
160
177
|
|