@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.cjs CHANGED
@@ -96,6 +96,7 @@ function useChat({
96
96
  const [selectedModel, setSelectedModel] = React3.useState(initialSelectedModel || DEFAULT_MODEL);
97
97
  const abortControllerRef = React3.useRef(null);
98
98
  const hasCheckedPersistRef = React3.useRef(false);
99
+ const streamingToolCallsRef = React3.useRef([]);
99
100
  React3.useEffect(() => {
100
101
  if (initialSelectedModel) {
101
102
  setSelectedModel((prev) => prev !== initialSelectedModel ? initialSelectedModel : prev);
@@ -177,6 +178,22 @@ function useChat({
177
178
  const data = line.slice(6).trim();
178
179
  if (data === "[DONE]") {
179
180
  setIsLoading(false);
181
+ const finalToolCalls = [...streamingToolCallsRef.current];
182
+ if (finalToolCalls.length > 0) {
183
+ setMessages(
184
+ (prev) => prev.map(
185
+ (msg) => msg.id === botMsgId ? { ...msg, toolCalls: finalToolCalls, thinkingComplete: true } : msg
186
+ )
187
+ );
188
+ } else {
189
+ setMessages(
190
+ (prev) => prev.map(
191
+ (msg) => msg.id === botMsgId ? { ...msg, thinkingComplete: true } : msg
192
+ )
193
+ );
194
+ }
195
+ setActiveToolCalls([]);
196
+ streamingToolCallsRef.current = [];
180
197
  for (const tool of pendingClientTools) {
181
198
  onToolCall?.({
182
199
  type: "client_call",
@@ -259,16 +276,15 @@ function useChat({
259
276
  toolName: parsed.tool_name,
260
277
  arguments: parsed.arguments
261
278
  });
262
- setActiveToolCalls((prev) => [
263
- ...prev,
264
- {
265
- id: `tool-${Date.now()}`,
266
- name: parsed.tool_name,
267
- arguments: parsed.arguments || {},
268
- status: "executing",
269
- timestamp: /* @__PURE__ */ new Date()
270
- }
271
- ]);
279
+ const newToolCall = {
280
+ id: `tool-${Date.now()}`,
281
+ name: parsed.tool_name,
282
+ arguments: parsed.arguments || {},
283
+ status: "executing",
284
+ timestamp: /* @__PURE__ */ new Date()
285
+ };
286
+ streamingToolCallsRef.current = [...streamingToolCallsRef.current, newToolCall];
287
+ setActiveToolCalls((prev) => [...prev, newToolCall]);
272
288
  break;
273
289
  case "tool_call_complete":
274
290
  onToolCall?.({
@@ -276,11 +292,25 @@ function useChat({
276
292
  toolName: parsed.tool_name,
277
293
  success: parsed.success
278
294
  });
279
- setActiveToolCalls(
280
- (prev) => prev.map(
281
- (tool) => tool.name === parsed.tool_name ? { ...tool, status: parsed.success ? "complete" : "error" } : tool
282
- )
283
- );
295
+ const newStatus = parsed.success ? "complete" : "error";
296
+ let updated = false;
297
+ streamingToolCallsRef.current = streamingToolCallsRef.current.map((tool) => {
298
+ if (!updated && tool.name === parsed.tool_name && tool.status === "executing") {
299
+ updated = true;
300
+ return { ...tool, status: newStatus };
301
+ }
302
+ return tool;
303
+ });
304
+ setActiveToolCalls((prev) => {
305
+ let updated2 = false;
306
+ return prev.map((tool) => {
307
+ if (!updated2 && tool.name === parsed.tool_name && tool.status === "executing") {
308
+ updated2 = true;
309
+ return { ...tool, status: newStatus };
310
+ }
311
+ return tool;
312
+ });
313
+ });
284
314
  break;
285
315
  case "tool_result_links":
286
316
  if (parsed.links && Array.isArray(parsed.links)) {
@@ -297,6 +327,20 @@ function useChat({
297
327
  }
298
328
  break;
299
329
  case "client_tool_call":
330
+ onToolCall?.({
331
+ type: "start",
332
+ toolName: parsed.tool_name,
333
+ arguments: parsed.arguments
334
+ });
335
+ const clientToolCall = {
336
+ id: `tool-${Date.now()}`,
337
+ name: parsed.tool_name,
338
+ arguments: parsed.arguments || {},
339
+ status: "executing",
340
+ timestamp: /* @__PURE__ */ new Date()
341
+ };
342
+ streamingToolCallsRef.current = [...streamingToolCallsRef.current, clientToolCall];
343
+ setActiveToolCalls((prev) => [...prev, clientToolCall]);
300
344
  pendingClientTools.push({
301
345
  toolName: parsed.tool_name,
302
346
  toolCallId: parsed.tool_call_id,
@@ -363,6 +407,7 @@ function useChat({
363
407
  return { userMsgId: "", botMsgId: "" };
364
408
  }
365
409
  setActiveToolCalls([]);
410
+ streamingToolCallsRef.current = [];
366
411
  const userMsgId = generateMessageId("user");
367
412
  const botMsgId = generateMessageId("bot");
368
413
  setMessages((prev) => [
@@ -597,7 +642,16 @@ function useConversations({ productId, apiUrl = "" }) {
597
642
  id: `history-${idx}`,
598
643
  content: msg.content,
599
644
  isBot: msg.role === "assistant",
600
- timestamp: /* @__PURE__ */ new Date()
645
+ timestamp: /* @__PURE__ */ new Date(),
646
+ thinking: msg.thinking,
647
+ thinkingComplete: true,
648
+ toolCalls: msg.tool_calls?.map((tc, i) => ({
649
+ id: `history-tool-${idx}-${i}`,
650
+ name: tc.name,
651
+ arguments: tc.arguments || {},
652
+ status: tc.status,
653
+ timestamp: /* @__PURE__ */ new Date()
654
+ }))
601
655
  }));
602
656
  }
603
657
  } catch (error) {
@@ -625,7 +679,16 @@ function useConversations({ productId, apiUrl = "" }) {
625
679
  id: `history-${idx}`,
626
680
  content: msg.content,
627
681
  isBot: msg.role === "assistant",
628
- timestamp: /* @__PURE__ */ new Date()
682
+ timestamp: /* @__PURE__ */ new Date(),
683
+ thinking: msg.thinking,
684
+ thinkingComplete: true,
685
+ toolCalls: msg.tool_calls?.map((tc, i) => ({
686
+ id: `history-tool-${idx}-${i}`,
687
+ name: tc.name,
688
+ arguments: tc.arguments || {},
689
+ status: tc.status,
690
+ timestamp: /* @__PURE__ */ new Date()
691
+ }))
629
692
  }));
630
693
  }
631
694
  } catch (error) {
@@ -1946,15 +2009,19 @@ function MessageList({
1946
2009
  (lastIdx, m, i) => m.isBot ? i : lastIdx,
1947
2010
  -1
1948
2011
  );
1949
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: messages.map((msg, index) => /* @__PURE__ */ jsxRuntime.jsx(
1950
- MessageBubble,
1951
- {
1952
- message: msg,
1953
- toolCalls: index === lastBotIndex ? activeToolCalls : void 0,
1954
- isLoading: index === lastBotIndex && isGenerating
1955
- },
1956
- msg.id
1957
- )) });
2012
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: messages.map((msg, index) => {
2013
+ const isLastBot = index === lastBotIndex;
2014
+ const toolCallsToShow = isLastBot && isGenerating ? activeToolCalls : msg.toolCalls || [];
2015
+ return /* @__PURE__ */ jsxRuntime.jsx(
2016
+ MessageBubble,
2017
+ {
2018
+ message: msg,
2019
+ toolCalls: toolCallsToShow,
2020
+ isLoading: isLastBot && isGenerating
2021
+ },
2022
+ msg.id
2023
+ );
2024
+ }) });
1958
2025
  }
1959
2026
  var MessagesContainer = React3.forwardRef(({ children }, ref) => {
1960
2027
  const styles = useWidgetStyles2();