@mastra/client-js 0.10.6-alpha.4 → 0.10.6-alpha.6

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @mastra/client-js@0.10.6-alpha.4 build /home/runner/work/mastra/mastra/client-sdks/client-js
2
+ > @mastra/client-js@0.10.6-alpha.6 build /home/runner/work/mastra/mastra/client-sdks/client-js
3
3
  > tsup src/index.ts --format esm,cjs --dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -9,11 +9,11 @@
9
9
  CLI Cleaning output folder
10
10
  ESM Build start
11
11
  CJS Build start
12
- ESM dist/index.js 66.22 KB
13
- ESM ⚡️ Build success in 2601ms
14
- CJS dist/index.cjs 66.51 KB
15
- CJS ⚡️ Build success in 2613ms
12
+ ESM dist/index.js 66.44 KB
13
+ ESM ⚡️ Build success in 2290ms
14
+ CJS dist/index.cjs 66.73 KB
15
+ CJS ⚡️ Build success in 2290ms
16
16
  DTS Build start
17
- DTS ⚡️ Build success in 19250ms
17
+ DTS ⚡️ Build success in 17954ms
18
18
  DTS dist/index.d.ts 39.17 KB
19
19
  DTS dist/index.d.cts 39.17 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @mastra/client-js
2
2
 
3
+ ## 0.10.6-alpha.6
4
+
5
+ ### Patch Changes
6
+
7
+ - c0d41f6: Fix streaming for agent tool calls
8
+
9
+ ## 0.10.6-alpha.5
10
+
11
+ ### Patch Changes
12
+
13
+ - bee3fe4: Fix client side tool calling
14
+ - @mastra/core@0.10.7-alpha.5
15
+
3
16
  ## 0.10.6-alpha.4
4
17
 
5
18
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -702,7 +702,7 @@ var Agent = class extends BaseResource {
702
702
  });
703
703
  streamResponse.processDataStream = async (options = {}) => {
704
704
  await uiUtils.processDataStream({
705
- stream: readable,
705
+ stream: streamResponse.body,
706
706
  ...options
707
707
  });
708
708
  };
@@ -722,76 +722,77 @@ var Agent = class extends BaseResource {
722
722
  }
723
723
  try {
724
724
  let toolCalls = [];
725
- let finishReasonToolCalls = false;
726
725
  let messages = [];
727
- let hasProcessedToolCalls = false;
728
- response.clone().body.pipeTo(writable, {
726
+ const [streamForWritable, streamForProcessing] = response.body.tee();
727
+ streamForWritable.pipeTo(writable, {
729
728
  preventClose: true
729
+ }).catch((error) => {
730
+ console.error("Error piping to writable stream:", error);
730
731
  });
731
- await this.processChatResponse({
732
- stream: response.clone().body,
732
+ this.processChatResponse({
733
+ stream: streamForProcessing,
733
734
  update: ({ message }) => {
734
735
  messages.push(message);
735
736
  },
736
- onFinish: ({ finishReason, message }) => {
737
+ onFinish: async ({ finishReason, message }) => {
737
738
  if (finishReason === "tool-calls") {
738
- finishReasonToolCalls = true;
739
739
  const toolCall = [...message?.parts ?? []].reverse().find((part) => part.type === "tool-invocation")?.toolInvocation;
740
740
  if (toolCall) {
741
741
  toolCalls.push(toolCall);
742
742
  }
743
+ for (const toolCall2 of toolCalls) {
744
+ const clientTool = processedParams.clientTools?.[toolCall2.toolName];
745
+ if (clientTool && clientTool.execute) {
746
+ const result = await clientTool.execute(
747
+ {
748
+ context: toolCall2?.args,
749
+ runId: processedParams.runId,
750
+ resourceId: processedParams.resourceId,
751
+ threadId: processedParams.threadId,
752
+ runtimeContext: processedParams.runtimeContext
753
+ },
754
+ {
755
+ messages: response.messages,
756
+ toolCallId: toolCall2?.toolCallId
757
+ }
758
+ );
759
+ const lastMessage = JSON.parse(JSON.stringify(messages[messages.length - 1]));
760
+ const toolInvocationPart = lastMessage?.parts?.find(
761
+ (part) => part.type === "tool-invocation" && part.toolInvocation?.toolCallId === toolCall2.toolCallId
762
+ );
763
+ if (toolInvocationPart) {
764
+ toolInvocationPart.toolInvocation = {
765
+ ...toolInvocationPart.toolInvocation,
766
+ state: "result",
767
+ result
768
+ };
769
+ }
770
+ const toolInvocation = lastMessage?.toolInvocations?.find(
771
+ (toolInvocation2) => toolInvocation2.toolCallId === toolCall2.toolCallId
772
+ );
773
+ if (toolInvocation) {
774
+ toolInvocation.state = "result";
775
+ toolInvocation.result = result;
776
+ }
777
+ const originalMessages = processedParams.messages;
778
+ const messageArray = Array.isArray(originalMessages) ? originalMessages : [originalMessages];
779
+ this.processStreamResponse(
780
+ {
781
+ ...processedParams,
782
+ messages: [...messageArray, ...messages, lastMessage]
783
+ },
784
+ writable
785
+ );
786
+ }
787
+ }
788
+ } else {
789
+ setTimeout(() => {
790
+ writable.close();
791
+ }, 0);
743
792
  }
744
793
  },
745
794
  lastMessage: void 0
746
795
  });
747
- if (finishReasonToolCalls && !hasProcessedToolCalls) {
748
- hasProcessedToolCalls = true;
749
- for (const toolCall of toolCalls) {
750
- const clientTool = processedParams.clientTools?.[toolCall.toolName];
751
- if (clientTool && clientTool.execute) {
752
- const result = await clientTool.execute(
753
- {
754
- context: toolCall?.args,
755
- runId: processedParams.runId,
756
- resourceId: processedParams.resourceId,
757
- threadId: processedParams.threadId,
758
- runtimeContext: processedParams.runtimeContext
759
- },
760
- {
761
- messages: response.messages,
762
- toolCallId: toolCall?.toolCallId
763
- }
764
- );
765
- const lastMessage = JSON.parse(JSON.stringify(messages[messages.length - 1]));
766
- const toolInvocationPart = lastMessage?.parts?.find(
767
- (part) => part.type === "tool-invocation" && part.toolInvocation?.toolCallId === toolCall.toolCallId
768
- );
769
- if (toolInvocationPart) {
770
- toolInvocationPart.toolInvocation = {
771
- ...toolInvocationPart.toolInvocation,
772
- state: "result",
773
- result
774
- };
775
- }
776
- const toolInvocation = lastMessage?.toolInvocations?.find(
777
- (toolInvocation2) => toolInvocation2.toolCallId === toolCall.toolCallId
778
- );
779
- if (toolInvocation) {
780
- toolInvocation.state = "result";
781
- toolInvocation.result = result;
782
- }
783
- const originalMessages = processedParams.messages;
784
- const messageArray = Array.isArray(originalMessages) ? originalMessages : [originalMessages];
785
- this.processStreamResponse(
786
- {
787
- ...processedParams,
788
- messages: [...messageArray, ...messages, lastMessage]
789
- },
790
- writable
791
- );
792
- }
793
- }
794
- }
795
796
  } catch (error) {
796
797
  console.error("Error processing stream response:", error);
797
798
  }
package/dist/index.js CHANGED
@@ -696,7 +696,7 @@ var Agent = class extends BaseResource {
696
696
  });
697
697
  streamResponse.processDataStream = async (options = {}) => {
698
698
  await processDataStream({
699
- stream: readable,
699
+ stream: streamResponse.body,
700
700
  ...options
701
701
  });
702
702
  };
@@ -716,76 +716,77 @@ var Agent = class extends BaseResource {
716
716
  }
717
717
  try {
718
718
  let toolCalls = [];
719
- let finishReasonToolCalls = false;
720
719
  let messages = [];
721
- let hasProcessedToolCalls = false;
722
- response.clone().body.pipeTo(writable, {
720
+ const [streamForWritable, streamForProcessing] = response.body.tee();
721
+ streamForWritable.pipeTo(writable, {
723
722
  preventClose: true
723
+ }).catch((error) => {
724
+ console.error("Error piping to writable stream:", error);
724
725
  });
725
- await this.processChatResponse({
726
- stream: response.clone().body,
726
+ this.processChatResponse({
727
+ stream: streamForProcessing,
727
728
  update: ({ message }) => {
728
729
  messages.push(message);
729
730
  },
730
- onFinish: ({ finishReason, message }) => {
731
+ onFinish: async ({ finishReason, message }) => {
731
732
  if (finishReason === "tool-calls") {
732
- finishReasonToolCalls = true;
733
733
  const toolCall = [...message?.parts ?? []].reverse().find((part) => part.type === "tool-invocation")?.toolInvocation;
734
734
  if (toolCall) {
735
735
  toolCalls.push(toolCall);
736
736
  }
737
+ for (const toolCall2 of toolCalls) {
738
+ const clientTool = processedParams.clientTools?.[toolCall2.toolName];
739
+ if (clientTool && clientTool.execute) {
740
+ const result = await clientTool.execute(
741
+ {
742
+ context: toolCall2?.args,
743
+ runId: processedParams.runId,
744
+ resourceId: processedParams.resourceId,
745
+ threadId: processedParams.threadId,
746
+ runtimeContext: processedParams.runtimeContext
747
+ },
748
+ {
749
+ messages: response.messages,
750
+ toolCallId: toolCall2?.toolCallId
751
+ }
752
+ );
753
+ const lastMessage = JSON.parse(JSON.stringify(messages[messages.length - 1]));
754
+ const toolInvocationPart = lastMessage?.parts?.find(
755
+ (part) => part.type === "tool-invocation" && part.toolInvocation?.toolCallId === toolCall2.toolCallId
756
+ );
757
+ if (toolInvocationPart) {
758
+ toolInvocationPart.toolInvocation = {
759
+ ...toolInvocationPart.toolInvocation,
760
+ state: "result",
761
+ result
762
+ };
763
+ }
764
+ const toolInvocation = lastMessage?.toolInvocations?.find(
765
+ (toolInvocation2) => toolInvocation2.toolCallId === toolCall2.toolCallId
766
+ );
767
+ if (toolInvocation) {
768
+ toolInvocation.state = "result";
769
+ toolInvocation.result = result;
770
+ }
771
+ const originalMessages = processedParams.messages;
772
+ const messageArray = Array.isArray(originalMessages) ? originalMessages : [originalMessages];
773
+ this.processStreamResponse(
774
+ {
775
+ ...processedParams,
776
+ messages: [...messageArray, ...messages, lastMessage]
777
+ },
778
+ writable
779
+ );
780
+ }
781
+ }
782
+ } else {
783
+ setTimeout(() => {
784
+ writable.close();
785
+ }, 0);
737
786
  }
738
787
  },
739
788
  lastMessage: void 0
740
789
  });
741
- if (finishReasonToolCalls && !hasProcessedToolCalls) {
742
- hasProcessedToolCalls = true;
743
- for (const toolCall of toolCalls) {
744
- const clientTool = processedParams.clientTools?.[toolCall.toolName];
745
- if (clientTool && clientTool.execute) {
746
- const result = await clientTool.execute(
747
- {
748
- context: toolCall?.args,
749
- runId: processedParams.runId,
750
- resourceId: processedParams.resourceId,
751
- threadId: processedParams.threadId,
752
- runtimeContext: processedParams.runtimeContext
753
- },
754
- {
755
- messages: response.messages,
756
- toolCallId: toolCall?.toolCallId
757
- }
758
- );
759
- const lastMessage = JSON.parse(JSON.stringify(messages[messages.length - 1]));
760
- const toolInvocationPart = lastMessage?.parts?.find(
761
- (part) => part.type === "tool-invocation" && part.toolInvocation?.toolCallId === toolCall.toolCallId
762
- );
763
- if (toolInvocationPart) {
764
- toolInvocationPart.toolInvocation = {
765
- ...toolInvocationPart.toolInvocation,
766
- state: "result",
767
- result
768
- };
769
- }
770
- const toolInvocation = lastMessage?.toolInvocations?.find(
771
- (toolInvocation2) => toolInvocation2.toolCallId === toolCall.toolCallId
772
- );
773
- if (toolInvocation) {
774
- toolInvocation.state = "result";
775
- toolInvocation.result = result;
776
- }
777
- const originalMessages = processedParams.messages;
778
- const messageArray = Array.isArray(originalMessages) ? originalMessages : [originalMessages];
779
- this.processStreamResponse(
780
- {
781
- ...processedParams,
782
- messages: [...messageArray, ...messages, lastMessage]
783
- },
784
- writable
785
- );
786
- }
787
- }
788
- }
789
790
  } catch (error) {
790
791
  console.error("Error processing stream response:", error);
791
792
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/client-js",
3
- "version": "0.10.6-alpha.4",
3
+ "version": "0.10.6-alpha.6",
4
4
  "description": "The official TypeScript library for the Mastra Client API",
5
5
  "author": "",
6
6
  "type": "module",
@@ -33,7 +33,7 @@
33
33
  "rxjs": "7.8.1",
34
34
  "zod": "^3.25.67",
35
35
  "zod-to-json-schema": "^3.24.5",
36
- "@mastra/core": "0.10.7-alpha.4"
36
+ "@mastra/core": "0.10.7-alpha.5"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "zod": "^3.0.0"
@@ -574,7 +574,7 @@ export class Agent extends BaseResource {
574
574
  // Add the processDataStream method to the response
575
575
  streamResponse.processDataStream = async (options = {}) => {
576
576
  await processDataStream({
577
- stream: readable as ReadableStream<Uint8Array>,
577
+ stream: streamResponse.body as ReadableStream<Uint8Array>,
578
578
  ...options,
579
579
  });
580
580
  };
@@ -604,90 +604,97 @@ export class Agent extends BaseResource {
604
604
  let messages: UIMessage[] = [];
605
605
  let hasProcessedToolCalls = false;
606
606
 
607
- // If no tool calls or they've been processed, pipe the original response
608
- response.clone().body!.pipeTo(writable, {
609
- preventClose: true,
610
- });
607
+ // Use tee() to split the stream into two branches
608
+ const [streamForWritable, streamForProcessing] = response.body.tee();
609
+
610
+ // Pipe one branch to the writable stream
611
+ streamForWritable
612
+ .pipeTo(writable, {
613
+ preventClose: true,
614
+ })
615
+ .catch(error => {
616
+ console.error('Error piping to writable stream:', error);
617
+ });
611
618
 
612
- await this.processChatResponse({
613
- stream: response.clone().body!,
619
+ // Process the other branch for chat response handling
620
+ this.processChatResponse({
621
+ stream: streamForProcessing,
614
622
  update: ({ message }) => {
615
623
  messages.push(message);
616
624
  },
617
- onFinish: ({ finishReason, message }) => {
625
+ onFinish: async ({ finishReason, message }) => {
618
626
  if (finishReason === 'tool-calls') {
619
- finishReasonToolCalls = true;
620
627
  const toolCall = [...(message?.parts ?? [])]
621
628
  .reverse()
622
629
  .find(part => part.type === 'tool-invocation')?.toolInvocation;
623
630
  if (toolCall) {
624
631
  toolCalls.push(toolCall);
625
632
  }
633
+
634
+ // Handle tool calls if needed
635
+ for (const toolCall of toolCalls) {
636
+ const clientTool = processedParams.clientTools?.[toolCall.toolName] as Tool;
637
+ if (clientTool && clientTool.execute) {
638
+ const result = await clientTool.execute(
639
+ {
640
+ context: toolCall?.args,
641
+ runId: processedParams.runId,
642
+ resourceId: processedParams.resourceId,
643
+ threadId: processedParams.threadId,
644
+ runtimeContext: processedParams.runtimeContext as RuntimeContext,
645
+ },
646
+ {
647
+ messages: (response as unknown as { messages: CoreMessage[] }).messages,
648
+ toolCallId: toolCall?.toolCallId,
649
+ },
650
+ );
651
+
652
+ const lastMessage: UIMessage = JSON.parse(JSON.stringify(messages[messages.length - 1]));
653
+
654
+ const toolInvocationPart = lastMessage?.parts?.find(
655
+ part => part.type === 'tool-invocation' && part.toolInvocation?.toolCallId === toolCall.toolCallId,
656
+ ) as ToolInvocationUIPart | undefined;
657
+
658
+ if (toolInvocationPart) {
659
+ toolInvocationPart.toolInvocation = {
660
+ ...toolInvocationPart.toolInvocation,
661
+ state: 'result',
662
+ result,
663
+ };
664
+ }
665
+
666
+ const toolInvocation = lastMessage?.toolInvocations?.find(
667
+ toolInvocation => toolInvocation.toolCallId === toolCall.toolCallId,
668
+ ) as ToolInvocation | undefined;
669
+
670
+ if (toolInvocation) {
671
+ toolInvocation.state = 'result';
672
+ // @ts-ignore
673
+ toolInvocation.result = result;
674
+ }
675
+
676
+ // Convert messages to the correct format for the recursive call
677
+ const originalMessages = processedParams.messages;
678
+ const messageArray = Array.isArray(originalMessages) ? originalMessages : [originalMessages];
679
+
680
+ // Recursively call stream with updated messages
681
+ this.processStreamResponse(
682
+ {
683
+ ...processedParams,
684
+ messages: [...messageArray, ...messages, lastMessage],
685
+ },
686
+ writable,
687
+ );
688
+ }
689
+ }
690
+ } else {
691
+ setTimeout(() => {
692
+ writable.close();
693
+ }, 0);
626
694
  }
627
695
  },
628
696
  lastMessage: undefined,
629
697
  });
630
-
631
- // Handle tool calls if needed
632
- if (finishReasonToolCalls && !hasProcessedToolCalls) {
633
- hasProcessedToolCalls = true;
634
-
635
- for (const toolCall of toolCalls) {
636
- const clientTool = processedParams.clientTools?.[toolCall.toolName] as Tool;
637
- if (clientTool && clientTool.execute) {
638
- const result = await clientTool.execute(
639
- {
640
- context: toolCall?.args,
641
- runId: processedParams.runId,
642
- resourceId: processedParams.resourceId,
643
- threadId: processedParams.threadId,
644
- runtimeContext: processedParams.runtimeContext as RuntimeContext,
645
- },
646
- {
647
- messages: (response as unknown as { messages: CoreMessage[] }).messages,
648
- toolCallId: toolCall?.toolCallId,
649
- },
650
- );
651
-
652
- const lastMessage: UIMessage = JSON.parse(JSON.stringify(messages[messages.length - 1]));
653
-
654
- const toolInvocationPart = lastMessage?.parts?.find(
655
- part => part.type === 'tool-invocation' && part.toolInvocation?.toolCallId === toolCall.toolCallId,
656
- ) as ToolInvocationUIPart | undefined;
657
-
658
- if (toolInvocationPart) {
659
- toolInvocationPart.toolInvocation = {
660
- ...toolInvocationPart.toolInvocation,
661
- state: 'result',
662
- result,
663
- };
664
- }
665
-
666
- const toolInvocation = lastMessage?.toolInvocations?.find(
667
- toolInvocation => toolInvocation.toolCallId === toolCall.toolCallId,
668
- ) as ToolInvocation | undefined;
669
-
670
- if (toolInvocation) {
671
- toolInvocation.state = 'result';
672
- // @ts-ignore
673
- toolInvocation.result = result;
674
- }
675
-
676
- // Convert messages to the correct format for the recursive call
677
- const originalMessages = processedParams.messages;
678
- const messageArray = Array.isArray(originalMessages) ? originalMessages : [originalMessages];
679
-
680
- // Recursively call stream with updated messages
681
- this.processStreamResponse(
682
- {
683
- ...processedParams,
684
- messages: [...messageArray, ...messages, lastMessage],
685
- },
686
- writable,
687
- );
688
- }
689
- }
690
- }
691
698
  } catch (error) {
692
699
  console.error('Error processing stream response:', error);
693
700
  }