@mastra/client-js 0.10.15-alpha.1 → 0.10.15-alpha.2

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/src/client.ts CHANGED
@@ -39,6 +39,13 @@ import type {
39
39
  GetNetworkMemoryThreadParams,
40
40
  CreateNetworkMemoryThreadParams,
41
41
  SaveNetworkMessageToMemoryParams,
42
+ GetScorerResponse,
43
+ GetScoresByScorerIdParams,
44
+ GetScoresResponse,
45
+ GetScoresByRunIdParams,
46
+ GetScoresByEntityIdParams,
47
+ SaveScoreParams,
48
+ SaveScoreResponse,
42
49
  } from './types';
43
50
 
44
51
  export class MastraClient extends BaseResource {
@@ -523,4 +530,94 @@ export class MastraClient extends BaseResource {
523
530
  },
524
531
  });
525
532
  }
533
+
534
+ /**
535
+ * Retrieves all available scorers
536
+ * @returns Promise containing list of available scorers
537
+ */
538
+ public getScorers(): Promise<Record<string, GetScorerResponse>> {
539
+ return this.request('/api/scores/scorers');
540
+ }
541
+
542
+ /**
543
+ * Retrieves a scorer by ID
544
+ * @param scorerId - ID of the scorer to retrieve
545
+ * @returns Promise containing the scorer
546
+ */
547
+ public getScorer(scorerId: string): Promise<GetScorerResponse> {
548
+ return this.request(`/api/scores/scorers/${scorerId}`);
549
+ }
550
+
551
+ public getScoresByScorerId(params: GetScoresByScorerIdParams): Promise<GetScoresResponse> {
552
+ const { page, perPage, scorerId, entityId, entityType } = params;
553
+ const searchParams = new URLSearchParams();
554
+
555
+ if (entityId) {
556
+ searchParams.set('entityId', entityId);
557
+ }
558
+ if (entityType) {
559
+ searchParams.set('entityType', entityType);
560
+ }
561
+
562
+ if (page !== undefined) {
563
+ searchParams.set('page', String(page));
564
+ }
565
+ if (perPage !== undefined) {
566
+ searchParams.set('perPage', String(perPage));
567
+ }
568
+ const queryString = searchParams.toString();
569
+ return this.request(`/api/scores/scorer/${scorerId}${queryString ? `?${queryString}` : ''}`);
570
+ }
571
+
572
+ /**
573
+ * Retrieves scores by run ID
574
+ * @param params - Parameters containing run ID and pagination options
575
+ * @returns Promise containing scores and pagination info
576
+ */
577
+ public getScoresByRunId(params: GetScoresByRunIdParams): Promise<GetScoresResponse> {
578
+ const { runId, page, perPage } = params;
579
+ const searchParams = new URLSearchParams();
580
+
581
+ if (page !== undefined) {
582
+ searchParams.set('page', String(page));
583
+ }
584
+ if (perPage !== undefined) {
585
+ searchParams.set('perPage', String(perPage));
586
+ }
587
+
588
+ const queryString = searchParams.toString();
589
+ return this.request(`/api/scores/run/${runId}${queryString ? `?${queryString}` : ''}`);
590
+ }
591
+
592
+ /**
593
+ * Retrieves scores by entity ID and type
594
+ * @param params - Parameters containing entity ID, type, and pagination options
595
+ * @returns Promise containing scores and pagination info
596
+ */
597
+ public getScoresByEntityId(params: GetScoresByEntityIdParams): Promise<GetScoresResponse> {
598
+ const { entityId, entityType, page, perPage } = params;
599
+ const searchParams = new URLSearchParams();
600
+
601
+ if (page !== undefined) {
602
+ searchParams.set('page', String(page));
603
+ }
604
+ if (perPage !== undefined) {
605
+ searchParams.set('perPage', String(perPage));
606
+ }
607
+
608
+ const queryString = searchParams.toString();
609
+ return this.request(`/api/scores/entity/${entityType}/${entityId}${queryString ? `?${queryString}` : ''}`);
610
+ }
611
+
612
+ /**
613
+ * Saves a score
614
+ * @param params - Parameters containing the score data to save
615
+ * @returns Promise containing the saved score
616
+ */
617
+ public saveScore(params: SaveScoreParams): Promise<SaveScoreResponse> {
618
+ return this.request('/api/scores', {
619
+ method: 'POST',
620
+ body: params,
621
+ });
622
+ }
526
623
  }
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, ServerDetailInfo } from './types';
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
- controller.enqueue(new TextEncoder().encode(JSON.stringify(data)));
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 = { content: 'test response' };
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(JSON.stringify(mockChunk));
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({ triggerData: { test: 'test' } });
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
  });