@usecrow/ui 0.1.25 → 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
@@ -78,6 +78,7 @@ function useChat({
78
78
  onConversationId,
79
79
  onWorkflowEvent,
80
80
  onToolCall,
81
+ onToolResult,
81
82
  onRestoredConversation
82
83
  }) {
83
84
  const effectiveWelcomeMessage = welcomeMessage || DEFAULT_WELCOME_MESSAGE;
@@ -95,6 +96,7 @@ function useChat({
95
96
  const [selectedModel, setSelectedModel] = React3.useState(initialSelectedModel || DEFAULT_MODEL);
96
97
  const abortControllerRef = React3.useRef(null);
97
98
  const hasCheckedPersistRef = React3.useRef(false);
99
+ const streamingToolCallsRef = React3.useRef([]);
98
100
  React3.useEffect(() => {
99
101
  if (initialSelectedModel) {
100
102
  setSelectedModel((prev) => prev !== initialSelectedModel ? initialSelectedModel : prev);
@@ -176,6 +178,22 @@ function useChat({
176
178
  const data = line.slice(6).trim();
177
179
  if (data === "[DONE]") {
178
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 = [];
179
197
  for (const tool of pendingClientTools) {
180
198
  onToolCall?.({
181
199
  type: "client_call",
@@ -258,16 +276,15 @@ function useChat({
258
276
  toolName: parsed.tool_name,
259
277
  arguments: parsed.arguments
260
278
  });
261
- setActiveToolCalls((prev) => [
262
- ...prev,
263
- {
264
- id: `tool-${Date.now()}`,
265
- name: parsed.tool_name,
266
- arguments: parsed.arguments || {},
267
- status: "executing",
268
- timestamp: /* @__PURE__ */ new Date()
269
- }
270
- ]);
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]);
271
288
  break;
272
289
  case "tool_call_complete":
273
290
  onToolCall?.({
@@ -275,11 +292,25 @@ function useChat({
275
292
  toolName: parsed.tool_name,
276
293
  success: parsed.success
277
294
  });
278
- setActiveToolCalls(
279
- (prev) => prev.map(
280
- (tool) => tool.name === parsed.tool_name ? { ...tool, status: parsed.success ? "complete" : "error" } : tool
281
- )
282
- );
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
+ });
283
314
  break;
284
315
  case "tool_result_links":
285
316
  if (parsed.links && Array.isArray(parsed.links)) {
@@ -290,7 +321,26 @@ function useChat({
290
321
  );
291
322
  }
292
323
  break;
324
+ case "tool_result":
325
+ if (parsed.tool_name && parsed.result) {
326
+ onToolResult?.(parsed.tool_name, parsed.result);
327
+ }
328
+ break;
293
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]);
294
344
  pendingClientTools.push({
295
345
  toolName: parsed.tool_name,
296
346
  toolCallId: parsed.tool_call_id,
@@ -349,7 +399,7 @@ function useChat({
349
399
  abortControllerRef.current = null;
350
400
  }
351
401
  },
352
- [apiUrl, productId, conversationId, selectedModel, persistAnonymousConversations, onVerificationStatus, onConversationId, onWorkflowEvent, onToolCall]
402
+ [apiUrl, productId, conversationId, selectedModel, persistAnonymousConversations, onVerificationStatus, onConversationId, onWorkflowEvent, onToolCall, onToolResult]
353
403
  );
354
404
  const sendMessage = React3.useCallback(
355
405
  (content) => {
@@ -357,6 +407,7 @@ function useChat({
357
407
  return { userMsgId: "", botMsgId: "" };
358
408
  }
359
409
  setActiveToolCalls([]);
410
+ streamingToolCallsRef.current = [];
360
411
  const userMsgId = generateMessageId("user");
361
412
  const botMsgId = generateMessageId("bot");
362
413
  setMessages((prev) => [
@@ -591,7 +642,16 @@ function useConversations({ productId, apiUrl = "" }) {
591
642
  id: `history-${idx}`,
592
643
  content: msg.content,
593
644
  isBot: msg.role === "assistant",
594
- 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
+ }))
595
655
  }));
596
656
  }
597
657
  } catch (error) {
@@ -619,7 +679,16 @@ function useConversations({ productId, apiUrl = "" }) {
619
679
  id: `history-${idx}`,
620
680
  content: msg.content,
621
681
  isBot: msg.role === "assistant",
622
- 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
+ }))
623
692
  }));
624
693
  }
625
694
  } catch (error) {
@@ -1940,15 +2009,19 @@ function MessageList({
1940
2009
  (lastIdx, m, i) => m.isBot ? i : lastIdx,
1941
2010
  -1
1942
2011
  );
1943
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: messages.map((msg, index) => /* @__PURE__ */ jsxRuntime.jsx(
1944
- MessageBubble,
1945
- {
1946
- message: msg,
1947
- toolCalls: index === lastBotIndex ? activeToolCalls : void 0,
1948
- isLoading: index === lastBotIndex && isGenerating
1949
- },
1950
- msg.id
1951
- )) });
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
+ }) });
1952
2025
  }
1953
2026
  var MessagesContainer = React3.forwardRef(({ children }, ref) => {
1954
2027
  const styles = useWidgetStyles2();
@@ -2773,7 +2846,8 @@ function CrowWidget({
2773
2846
  welcomeMessage: welcomeMessageProp,
2774
2847
  onReady,
2775
2848
  onIdentify,
2776
- tools
2849
+ tools,
2850
+ onToolResult
2777
2851
  }) {
2778
2852
  const {
2779
2853
  styles,
@@ -2851,6 +2925,7 @@ function CrowWidget({
2851
2925
  break;
2852
2926
  }
2853
2927
  },
2928
+ onToolResult,
2854
2929
  onToolCall: async (event) => {
2855
2930
  if (event.type === "client_call" && event.toolName && event.toolCallId) {
2856
2931
  try {
@@ -3290,7 +3365,8 @@ function CrowCopilot({
3290
3365
  styles: propStyles,
3291
3366
  previewMode = false,
3292
3367
  className,
3293
- onReady
3368
+ onReady,
3369
+ onToolResult
3294
3370
  }) {
3295
3371
  const {
3296
3372
  styles,
@@ -3331,6 +3407,7 @@ function CrowCopilot({
3331
3407
  },
3332
3408
  onConversationId: () => {
3333
3409
  },
3410
+ onToolResult,
3334
3411
  onToolCall: (event) => {
3335
3412
  if (event.type === "client_call" && event.toolName) {
3336
3413
  console.log(