@emblemvault/hustle-react 1.4.1 → 1.4.3

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
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { C as ChatMessage, T as ToolCall } from '../hustle-S48t4lTZ.cjs';
2
+ import { C as ChatMessage, T as ToolCall } from '../hustle-C0Ltl5k4.cjs';
3
3
  import React from 'react';
4
4
  import 'hustle-incognito';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { C as ChatMessage, T as ToolCall } from '../hustle-S48t4lTZ.js';
2
+ import { C as ChatMessage, T as ToolCall } from '../hustle-C0Ltl5k4.js';
3
3
  import React from 'react';
4
4
  import 'hustle-incognito';
5
5
 
@@ -3597,7 +3597,14 @@ function HustleChat({
3597
3597
  setIsStreaming(true);
3598
3598
  setCurrentToolCalls([]);
3599
3599
  try {
3600
- const chatMessages = messagesRef.current.filter((m) => !m.isStreaming).map((m) => ({ role: m.role, content: m.content }));
3600
+ const chatMessages = messagesRef.current.filter((m) => !m.isStreaming).map((m) => {
3601
+ const msg = { role: m.role, content: m.content };
3602
+ if (m.role === "assistant" && m.toolInvocations && m.toolInvocations.length > 0) {
3603
+ msg.toolInvocations = m.toolInvocations;
3604
+ msg.parts = m.parts;
3605
+ }
3606
+ return msg;
3607
+ });
3601
3608
  chatMessages.push({ role: "user", content: "continue" });
3602
3609
  const stream = chatStream({
3603
3610
  messages: chatMessages,
@@ -3605,6 +3612,9 @@ function HustleChat({
3605
3612
  });
3606
3613
  let fullContent = "";
3607
3614
  const toolCallsAccumulated = [];
3615
+ const toolInvocationsAccumulated = [];
3616
+ const partsAccumulated = [{ type: "step-start" }];
3617
+ let stepCounter = 0;
3608
3618
  for await (const chunk of stream) {
3609
3619
  if (chunk.type === "text") {
3610
3620
  fullContent += chunk.value;
@@ -3616,22 +3626,79 @@ function HustleChat({
3616
3626
  } else if (chunk.type === "tool_call") {
3617
3627
  const toolCall = chunk.value;
3618
3628
  toolCallsAccumulated.push(toolCall);
3629
+ const invocation = {
3630
+ state: "call",
3631
+ step: stepCounter++,
3632
+ toolCallId: toolCall.toolCallId,
3633
+ toolName: toolCall.toolName,
3634
+ args: toolCall.args
3635
+ };
3636
+ toolInvocationsAccumulated.push(invocation);
3637
+ partsAccumulated.push({ type: "tool-invocation", toolInvocation: invocation });
3619
3638
  setCurrentToolCalls([...toolCallsAccumulated]);
3620
3639
  setMessages(
3621
3640
  (prev) => prev.map(
3622
- (m) => m.id === assistantMessage.id ? { ...m, toolCalls: [...toolCallsAccumulated] } : m
3641
+ (m) => m.id === assistantMessage.id ? {
3642
+ ...m,
3643
+ toolCalls: [...toolCallsAccumulated],
3644
+ toolInvocations: [...toolInvocationsAccumulated],
3645
+ parts: [...partsAccumulated]
3646
+ } : m
3623
3647
  )
3624
3648
  );
3625
3649
  onToolCall?.(toolCall);
3650
+ } else if (chunk.type === "tool_result") {
3651
+ const toolResult = chunk.value;
3652
+ const invocationIndex = toolInvocationsAccumulated.findIndex(
3653
+ (inv) => inv.toolCallId === toolResult.toolCallId
3654
+ );
3655
+ if (invocationIndex !== -1) {
3656
+ toolInvocationsAccumulated[invocationIndex] = {
3657
+ ...toolInvocationsAccumulated[invocationIndex],
3658
+ state: "result",
3659
+ result: toolResult.result
3660
+ };
3661
+ const partIndex = partsAccumulated.findIndex(
3662
+ (p) => p.type === "tool-invocation" && p.toolInvocation.toolCallId === toolResult.toolCallId
3663
+ );
3664
+ if (partIndex !== -1) {
3665
+ partsAccumulated[partIndex] = {
3666
+ type: "tool-invocation",
3667
+ toolInvocation: toolInvocationsAccumulated[invocationIndex]
3668
+ };
3669
+ }
3670
+ }
3671
+ setMessages(
3672
+ (prev) => prev.map(
3673
+ (m) => m.id === assistantMessage.id ? {
3674
+ ...m,
3675
+ toolInvocations: [...toolInvocationsAccumulated],
3676
+ parts: [...partsAccumulated]
3677
+ } : m
3678
+ )
3679
+ );
3626
3680
  } else if (chunk.type === "error") {
3627
3681
  console.error("Stream error:", chunk.value);
3628
3682
  }
3629
3683
  }
3630
3684
  const processedResponse = await stream.response;
3631
3685
  const finalContent = processedResponse?.content || fullContent || "(No response)";
3686
+ const finalParts = [{ type: "step-start" }];
3687
+ if (finalContent) {
3688
+ finalParts.push({ type: "text", text: finalContent });
3689
+ }
3690
+ for (const inv of toolInvocationsAccumulated) {
3691
+ finalParts.push({ type: "tool-invocation", toolInvocation: inv });
3692
+ }
3632
3693
  setMessages(
3633
3694
  (prev) => prev.map(
3634
- (m) => m.id === assistantMessage.id ? { ...m, isStreaming: false, content: finalContent } : m
3695
+ (m) => m.id === assistantMessage.id ? {
3696
+ ...m,
3697
+ isStreaming: false,
3698
+ content: finalContent,
3699
+ toolInvocations: toolInvocationsAccumulated.length > 0 ? toolInvocationsAccumulated : void 0,
3700
+ parts: toolInvocationsAccumulated.length > 0 ? finalParts : void 0
3701
+ } : m
3635
3702
  )
3636
3703
  );
3637
3704
  onResponse?.(finalContent);
@@ -3693,7 +3760,14 @@ function HustleChat({
3693
3760
  setIsStreaming(true);
3694
3761
  setCurrentToolCalls([]);
3695
3762
  try {
3696
- const chatMessages = messages.filter((m) => !m.isStreaming).map((m) => ({ role: m.role, content: m.content }));
3763
+ const chatMessages = messages.filter((m) => !m.isStreaming).map((m) => {
3764
+ const msg = { role: m.role, content: m.content };
3765
+ if (m.role === "assistant" && m.toolInvocations && m.toolInvocations.length > 0) {
3766
+ msg.toolInvocations = m.toolInvocations;
3767
+ msg.parts = m.parts;
3768
+ }
3769
+ return msg;
3770
+ });
3697
3771
  chatMessages.push({ role: "user", content });
3698
3772
  const stream = chatStream({
3699
3773
  messages: chatMessages,
@@ -3703,6 +3777,9 @@ function HustleChat({
3703
3777
  setAttachments([]);
3704
3778
  let fullContent = "";
3705
3779
  const toolCallsAccumulated = [];
3780
+ const toolInvocationsAccumulated = [];
3781
+ const partsAccumulated = [{ type: "step-start" }];
3782
+ let stepCounter = 0;
3706
3783
  for await (const chunk of stream) {
3707
3784
  if (chunk.type === "text") {
3708
3785
  fullContent += chunk.value;
@@ -3714,22 +3791,79 @@ function HustleChat({
3714
3791
  } else if (chunk.type === "tool_call") {
3715
3792
  const toolCall = chunk.value;
3716
3793
  toolCallsAccumulated.push(toolCall);
3794
+ const invocation = {
3795
+ state: "call",
3796
+ step: stepCounter++,
3797
+ toolCallId: toolCall.toolCallId,
3798
+ toolName: toolCall.toolName,
3799
+ args: toolCall.args
3800
+ };
3801
+ toolInvocationsAccumulated.push(invocation);
3802
+ partsAccumulated.push({ type: "tool-invocation", toolInvocation: invocation });
3717
3803
  setCurrentToolCalls([...toolCallsAccumulated]);
3718
3804
  setMessages(
3719
3805
  (prev) => prev.map(
3720
- (m) => m.id === assistantMessage.id ? { ...m, toolCalls: [...toolCallsAccumulated] } : m
3806
+ (m) => m.id === assistantMessage.id ? {
3807
+ ...m,
3808
+ toolCalls: [...toolCallsAccumulated],
3809
+ toolInvocations: [...toolInvocationsAccumulated],
3810
+ parts: [...partsAccumulated]
3811
+ } : m
3721
3812
  )
3722
3813
  );
3723
3814
  onToolCall?.(toolCall);
3815
+ } else if (chunk.type === "tool_result") {
3816
+ const toolResult = chunk.value;
3817
+ const invocationIndex = toolInvocationsAccumulated.findIndex(
3818
+ (inv) => inv.toolCallId === toolResult.toolCallId
3819
+ );
3820
+ if (invocationIndex !== -1) {
3821
+ toolInvocationsAccumulated[invocationIndex] = {
3822
+ ...toolInvocationsAccumulated[invocationIndex],
3823
+ state: "result",
3824
+ result: toolResult.result
3825
+ };
3826
+ const partIndex = partsAccumulated.findIndex(
3827
+ (p) => p.type === "tool-invocation" && p.toolInvocation.toolCallId === toolResult.toolCallId
3828
+ );
3829
+ if (partIndex !== -1) {
3830
+ partsAccumulated[partIndex] = {
3831
+ type: "tool-invocation",
3832
+ toolInvocation: toolInvocationsAccumulated[invocationIndex]
3833
+ };
3834
+ }
3835
+ }
3836
+ setMessages(
3837
+ (prev) => prev.map(
3838
+ (m) => m.id === assistantMessage.id ? {
3839
+ ...m,
3840
+ toolInvocations: [...toolInvocationsAccumulated],
3841
+ parts: [...partsAccumulated]
3842
+ } : m
3843
+ )
3844
+ );
3724
3845
  } else if (chunk.type === "error") {
3725
3846
  console.error("Stream error:", chunk.value);
3726
3847
  }
3727
3848
  }
3728
3849
  const processedResponse = await stream.response;
3729
3850
  const finalContent = processedResponse?.content || fullContent || "(No response)";
3851
+ const finalParts = [{ type: "step-start" }];
3852
+ if (finalContent) {
3853
+ finalParts.push({ type: "text", text: finalContent });
3854
+ }
3855
+ for (const inv of toolInvocationsAccumulated) {
3856
+ finalParts.push({ type: "tool-invocation", toolInvocation: inv });
3857
+ }
3730
3858
  setMessages(
3731
3859
  (prev) => prev.map(
3732
- (m) => m.id === assistantMessage.id ? { ...m, isStreaming: false, content: finalContent } : m
3860
+ (m) => m.id === assistantMessage.id ? {
3861
+ ...m,
3862
+ isStreaming: false,
3863
+ content: finalContent,
3864
+ toolInvocations: toolInvocationsAccumulated.length > 0 ? toolInvocationsAccumulated : void 0,
3865
+ parts: toolInvocationsAccumulated.length > 0 ? finalParts : void 0
3866
+ } : m
3733
3867
  )
3734
3868
  );
3735
3869
  onResponse?.(finalContent);