@usecrow/ui 0.1.26 → 0.1.27

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/dist/index.d.cts CHANGED
@@ -452,6 +452,7 @@ interface Message {
452
452
  citations?: Citation[];
453
453
  thinking?: string;
454
454
  thinkingComplete?: boolean;
455
+ toolCalls?: ToolCall[];
455
456
  links?: ToolResultLink[];
456
457
  }
457
458
  interface Citation {
package/dist/index.d.ts CHANGED
@@ -452,6 +452,7 @@ interface Message {
452
452
  citations?: Citation[];
453
453
  thinking?: string;
454
454
  thinkingComplete?: boolean;
455
+ toolCalls?: ToolCall[];
455
456
  links?: ToolResultLink[];
456
457
  }
457
458
  interface Citation {
package/dist/index.js CHANGED
@@ -70,6 +70,7 @@ function useChat({
70
70
  const [selectedModel, setSelectedModel] = useState(initialSelectedModel || DEFAULT_MODEL);
71
71
  const abortControllerRef = useRef(null);
72
72
  const hasCheckedPersistRef = useRef(false);
73
+ const streamingToolCallsRef = useRef([]);
73
74
  useEffect(() => {
74
75
  if (initialSelectedModel) {
75
76
  setSelectedModel((prev) => prev !== initialSelectedModel ? initialSelectedModel : prev);
@@ -151,6 +152,22 @@ function useChat({
151
152
  const data = line.slice(6).trim();
152
153
  if (data === "[DONE]") {
153
154
  setIsLoading(false);
155
+ const finalToolCalls = [...streamingToolCallsRef.current];
156
+ if (finalToolCalls.length > 0) {
157
+ setMessages(
158
+ (prev) => prev.map(
159
+ (msg) => msg.id === botMsgId ? { ...msg, toolCalls: finalToolCalls, thinkingComplete: true } : msg
160
+ )
161
+ );
162
+ } else {
163
+ setMessages(
164
+ (prev) => prev.map(
165
+ (msg) => msg.id === botMsgId ? { ...msg, thinkingComplete: true } : msg
166
+ )
167
+ );
168
+ }
169
+ setActiveToolCalls([]);
170
+ streamingToolCallsRef.current = [];
154
171
  for (const tool of pendingClientTools) {
155
172
  onToolCall?.({
156
173
  type: "client_call",
@@ -233,16 +250,15 @@ function useChat({
233
250
  toolName: parsed.tool_name,
234
251
  arguments: parsed.arguments
235
252
  });
236
- setActiveToolCalls((prev) => [
237
- ...prev,
238
- {
239
- id: `tool-${Date.now()}`,
240
- name: parsed.tool_name,
241
- arguments: parsed.arguments || {},
242
- status: "executing",
243
- timestamp: /* @__PURE__ */ new Date()
244
- }
245
- ]);
253
+ const newToolCall = {
254
+ id: `tool-${Date.now()}`,
255
+ name: parsed.tool_name,
256
+ arguments: parsed.arguments || {},
257
+ status: "executing",
258
+ timestamp: /* @__PURE__ */ new Date()
259
+ };
260
+ streamingToolCallsRef.current = [...streamingToolCallsRef.current, newToolCall];
261
+ setActiveToolCalls((prev) => [...prev, newToolCall]);
246
262
  break;
247
263
  case "tool_call_complete":
248
264
  onToolCall?.({
@@ -250,11 +266,25 @@ function useChat({
250
266
  toolName: parsed.tool_name,
251
267
  success: parsed.success
252
268
  });
253
- setActiveToolCalls(
254
- (prev) => prev.map(
255
- (tool) => tool.name === parsed.tool_name ? { ...tool, status: parsed.success ? "complete" : "error" } : tool
256
- )
257
- );
269
+ const newStatus = parsed.success ? "complete" : "error";
270
+ let updated = false;
271
+ streamingToolCallsRef.current = streamingToolCallsRef.current.map((tool) => {
272
+ if (!updated && tool.name === parsed.tool_name && tool.status === "executing") {
273
+ updated = true;
274
+ return { ...tool, status: newStatus };
275
+ }
276
+ return tool;
277
+ });
278
+ setActiveToolCalls((prev) => {
279
+ let updated2 = false;
280
+ return prev.map((tool) => {
281
+ if (!updated2 && tool.name === parsed.tool_name && tool.status === "executing") {
282
+ updated2 = true;
283
+ return { ...tool, status: newStatus };
284
+ }
285
+ return tool;
286
+ });
287
+ });
258
288
  break;
259
289
  case "tool_result_links":
260
290
  if (parsed.links && Array.isArray(parsed.links)) {
@@ -271,6 +301,20 @@ function useChat({
271
301
  }
272
302
  break;
273
303
  case "client_tool_call":
304
+ onToolCall?.({
305
+ type: "start",
306
+ toolName: parsed.tool_name,
307
+ arguments: parsed.arguments
308
+ });
309
+ const clientToolCall = {
310
+ id: `tool-${Date.now()}`,
311
+ name: parsed.tool_name,
312
+ arguments: parsed.arguments || {},
313
+ status: "executing",
314
+ timestamp: /* @__PURE__ */ new Date()
315
+ };
316
+ streamingToolCallsRef.current = [...streamingToolCallsRef.current, clientToolCall];
317
+ setActiveToolCalls((prev) => [...prev, clientToolCall]);
274
318
  pendingClientTools.push({
275
319
  toolName: parsed.tool_name,
276
320
  toolCallId: parsed.tool_call_id,
@@ -337,6 +381,7 @@ function useChat({
337
381
  return { userMsgId: "", botMsgId: "" };
338
382
  }
339
383
  setActiveToolCalls([]);
384
+ streamingToolCallsRef.current = [];
340
385
  const userMsgId = generateMessageId("user");
341
386
  const botMsgId = generateMessageId("bot");
342
387
  setMessages((prev) => [
@@ -571,7 +616,16 @@ function useConversations({ productId, apiUrl = "" }) {
571
616
  id: `history-${idx}`,
572
617
  content: msg.content,
573
618
  isBot: msg.role === "assistant",
574
- timestamp: /* @__PURE__ */ new Date()
619
+ timestamp: /* @__PURE__ */ new Date(),
620
+ thinking: msg.thinking,
621
+ thinkingComplete: true,
622
+ toolCalls: msg.tool_calls?.map((tc, i) => ({
623
+ id: `history-tool-${idx}-${i}`,
624
+ name: tc.name,
625
+ arguments: tc.arguments || {},
626
+ status: tc.status,
627
+ timestamp: /* @__PURE__ */ new Date()
628
+ }))
575
629
  }));
576
630
  }
577
631
  } catch (error) {
@@ -599,7 +653,16 @@ function useConversations({ productId, apiUrl = "" }) {
599
653
  id: `history-${idx}`,
600
654
  content: msg.content,
601
655
  isBot: msg.role === "assistant",
602
- timestamp: /* @__PURE__ */ new Date()
656
+ timestamp: /* @__PURE__ */ new Date(),
657
+ thinking: msg.thinking,
658
+ thinkingComplete: true,
659
+ toolCalls: msg.tool_calls?.map((tc, i) => ({
660
+ id: `history-tool-${idx}-${i}`,
661
+ name: tc.name,
662
+ arguments: tc.arguments || {},
663
+ status: tc.status,
664
+ timestamp: /* @__PURE__ */ new Date()
665
+ }))
603
666
  }));
604
667
  }
605
668
  } catch (error) {
@@ -1920,15 +1983,19 @@ function MessageList({
1920
1983
  (lastIdx, m, i) => m.isBot ? i : lastIdx,
1921
1984
  -1
1922
1985
  );
1923
- return /* @__PURE__ */ jsx(Fragment, { children: messages.map((msg, index) => /* @__PURE__ */ jsx(
1924
- MessageBubble,
1925
- {
1926
- message: msg,
1927
- toolCalls: index === lastBotIndex ? activeToolCalls : void 0,
1928
- isLoading: index === lastBotIndex && isGenerating
1929
- },
1930
- msg.id
1931
- )) });
1986
+ return /* @__PURE__ */ jsx(Fragment, { children: messages.map((msg, index) => {
1987
+ const isLastBot = index === lastBotIndex;
1988
+ const toolCallsToShow = isLastBot && isGenerating ? activeToolCalls : msg.toolCalls || [];
1989
+ return /* @__PURE__ */ jsx(
1990
+ MessageBubble,
1991
+ {
1992
+ message: msg,
1993
+ toolCalls: toolCallsToShow,
1994
+ isLoading: isLastBot && isGenerating
1995
+ },
1996
+ msg.id
1997
+ );
1998
+ }) });
1932
1999
  }
1933
2000
  var MessagesContainer = forwardRef(({ children }, ref) => {
1934
2001
  const styles = useWidgetStyles2();