@usecrow/ui 0.1.5 → 0.1.7
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 +137 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +137 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -390,6 +390,7 @@ interface WorkflowEvent {
|
|
|
390
390
|
interface ToolCallEvent {
|
|
391
391
|
type: "start" | "complete" | "client_call";
|
|
392
392
|
toolName: string;
|
|
393
|
+
toolCallId?: string;
|
|
393
394
|
arguments?: Record<string, unknown>;
|
|
394
395
|
success?: boolean;
|
|
395
396
|
}
|
|
@@ -417,6 +418,7 @@ declare function useChat({ productId, apiUrl, onVerificationStatus, onConversati
|
|
|
417
418
|
stopGeneration: () => void;
|
|
418
419
|
resetMessages: () => void;
|
|
419
420
|
loadMessages: (historyMessages: Message[]) => void;
|
|
421
|
+
submitToolResult: (toolCallId: string, toolName: string, result: Record<string, unknown>) => Promise<void>;
|
|
420
422
|
};
|
|
421
423
|
|
|
422
424
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -390,6 +390,7 @@ interface WorkflowEvent {
|
|
|
390
390
|
interface ToolCallEvent {
|
|
391
391
|
type: "start" | "complete" | "client_call";
|
|
392
392
|
toolName: string;
|
|
393
|
+
toolCallId?: string;
|
|
393
394
|
arguments?: Record<string, unknown>;
|
|
394
395
|
success?: boolean;
|
|
395
396
|
}
|
|
@@ -417,6 +418,7 @@ declare function useChat({ productId, apiUrl, onVerificationStatus, onConversati
|
|
|
417
418
|
stopGeneration: () => void;
|
|
418
419
|
resetMessages: () => void;
|
|
419
420
|
loadMessages: (historyMessages: Message[]) => void;
|
|
421
|
+
submitToolResult: (toolCallId: string, toolName: string, result: Record<string, unknown>) => Promise<void>;
|
|
420
422
|
};
|
|
421
423
|
|
|
422
424
|
/**
|
package/dist/index.js
CHANGED
|
@@ -100,6 +100,7 @@ function useChat({
|
|
|
100
100
|
async (message, botMsgId) => {
|
|
101
101
|
let accumulatedText = "";
|
|
102
102
|
let firstChunk = true;
|
|
103
|
+
const pendingClientTools = [];
|
|
103
104
|
abortControllerRef.current = new AbortController();
|
|
104
105
|
try {
|
|
105
106
|
const identityToken = window.__crow_identity_token;
|
|
@@ -131,6 +132,14 @@ function useChat({
|
|
|
131
132
|
const data = line.slice(6).trim();
|
|
132
133
|
if (data === "[DONE]") {
|
|
133
134
|
setIsLoading(false);
|
|
135
|
+
for (const tool of pendingClientTools) {
|
|
136
|
+
onToolCall?.({
|
|
137
|
+
type: "client_call",
|
|
138
|
+
toolName: tool.toolName,
|
|
139
|
+
toolCallId: tool.toolCallId,
|
|
140
|
+
arguments: tool.arguments
|
|
141
|
+
});
|
|
142
|
+
}
|
|
134
143
|
return;
|
|
135
144
|
}
|
|
136
145
|
try {
|
|
@@ -227,9 +236,9 @@ function useChat({
|
|
|
227
236
|
);
|
|
228
237
|
break;
|
|
229
238
|
case "client_tool_call":
|
|
230
|
-
|
|
231
|
-
type: "client_call",
|
|
239
|
+
pendingClientTools.push({
|
|
232
240
|
toolName: parsed.tool_name,
|
|
241
|
+
toolCallId: parsed.tool_call_id,
|
|
233
242
|
arguments: parsed.arguments
|
|
234
243
|
});
|
|
235
244
|
break;
|
|
@@ -343,6 +352,102 @@ function useChat({
|
|
|
343
352
|
const loadMessages = useCallback((historyMessages) => {
|
|
344
353
|
setMessages(historyMessages);
|
|
345
354
|
}, []);
|
|
355
|
+
const submitToolResult = useCallback(
|
|
356
|
+
async (toolCallId, toolName, result) => {
|
|
357
|
+
if (!conversationId) {
|
|
358
|
+
console.error("[Crow] Cannot submit tool result: no conversation ID");
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const botMsgId = generateMessageId("bot");
|
|
362
|
+
const pendingClientTools = [];
|
|
363
|
+
setMessages((prev) => [
|
|
364
|
+
...prev,
|
|
365
|
+
{
|
|
366
|
+
id: botMsgId,
|
|
367
|
+
content: "",
|
|
368
|
+
isBot: true,
|
|
369
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
370
|
+
}
|
|
371
|
+
]);
|
|
372
|
+
setIsLoading(true);
|
|
373
|
+
try {
|
|
374
|
+
const identityToken = window.__crow_identity_token;
|
|
375
|
+
const response = await fetch(`${apiUrl}/api/chat/tool-result`, {
|
|
376
|
+
method: "POST",
|
|
377
|
+
headers: { "Content-Type": "application/json" },
|
|
378
|
+
body: JSON.stringify({
|
|
379
|
+
product_id: productId,
|
|
380
|
+
conversation_id: conversationId,
|
|
381
|
+
tool_call_id: toolCallId,
|
|
382
|
+
tool_name: toolName,
|
|
383
|
+
result,
|
|
384
|
+
identity_token: identityToken,
|
|
385
|
+
model: selectedModel
|
|
386
|
+
})
|
|
387
|
+
});
|
|
388
|
+
if (!response.ok) {
|
|
389
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
390
|
+
}
|
|
391
|
+
const reader = response.body?.getReader();
|
|
392
|
+
const decoder = new TextDecoder();
|
|
393
|
+
let accumulatedText = "";
|
|
394
|
+
if (reader) {
|
|
395
|
+
while (true) {
|
|
396
|
+
const { done, value } = await reader.read();
|
|
397
|
+
if (done) break;
|
|
398
|
+
const chunk = decoder.decode(value);
|
|
399
|
+
const lines = chunk.split("\n");
|
|
400
|
+
for (const line of lines) {
|
|
401
|
+
if (line.startsWith("data: ")) {
|
|
402
|
+
const data = line.slice(6).trim();
|
|
403
|
+
if (data === "[DONE]") {
|
|
404
|
+
setIsLoading(false);
|
|
405
|
+
for (const tool of pendingClientTools) {
|
|
406
|
+
onToolCall?.({
|
|
407
|
+
type: "client_call",
|
|
408
|
+
toolName: tool.toolName,
|
|
409
|
+
toolCallId: tool.toolCallId,
|
|
410
|
+
arguments: tool.arguments
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
try {
|
|
416
|
+
const parsed = JSON.parse(data);
|
|
417
|
+
if (parsed.type === "content") {
|
|
418
|
+
accumulatedText += parsed.content;
|
|
419
|
+
setMessages(
|
|
420
|
+
(prev) => prev.map(
|
|
421
|
+
(msg) => msg.id === botMsgId ? { ...msg, content: accumulatedText } : msg
|
|
422
|
+
)
|
|
423
|
+
);
|
|
424
|
+
} else if (parsed.type === "client_tool_call") {
|
|
425
|
+
pendingClientTools.push({
|
|
426
|
+
toolName: parsed.tool_name,
|
|
427
|
+
toolCallId: parsed.tool_call_id,
|
|
428
|
+
arguments: parsed.arguments
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
} catch (e) {
|
|
432
|
+
console.error("[Crow] Parse error in tool result response:", e);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
} catch (error) {
|
|
439
|
+
console.error("[Crow] Error submitting tool result:", error);
|
|
440
|
+
setMessages(
|
|
441
|
+
(prev) => prev.map(
|
|
442
|
+
(msg) => msg.id === botMsgId ? { ...msg, content: "Sorry, I encountered an error processing the tool result." } : msg
|
|
443
|
+
)
|
|
444
|
+
);
|
|
445
|
+
} finally {
|
|
446
|
+
setIsLoading(false);
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
[apiUrl, productId, conversationId, selectedModel]
|
|
450
|
+
);
|
|
346
451
|
return {
|
|
347
452
|
messages,
|
|
348
453
|
isLoading,
|
|
@@ -354,7 +459,8 @@ function useChat({
|
|
|
354
459
|
sendMessage,
|
|
355
460
|
stopGeneration,
|
|
356
461
|
resetMessages,
|
|
357
|
-
loadMessages
|
|
462
|
+
loadMessages,
|
|
463
|
+
submitToolResult
|
|
358
464
|
};
|
|
359
465
|
}
|
|
360
466
|
function useConversations({ productId, apiUrl = "" }) {
|
|
@@ -642,8 +748,8 @@ var DEFAULT_WIDGET_STYLES = {
|
|
|
642
748
|
border: "#d1d5db",
|
|
643
749
|
text: "#111827",
|
|
644
750
|
// Bot messages
|
|
645
|
-
botBubble: "#
|
|
646
|
-
botText: "#
|
|
751
|
+
botBubble: "#000000",
|
|
752
|
+
botText: "#ffffff",
|
|
647
753
|
// User messages
|
|
648
754
|
userBubble: "#ffffff",
|
|
649
755
|
userText: "#000000",
|
|
@@ -2088,6 +2194,7 @@ function CrowWidget({
|
|
|
2088
2194
|
});
|
|
2089
2195
|
const messagesContainerRef = useRef(null);
|
|
2090
2196
|
const executeClientToolRef = useRef(null);
|
|
2197
|
+
const submitToolResultRef = useRef(null);
|
|
2091
2198
|
const [isCollapsed, setIsCollapsed] = useState(variant === "floating");
|
|
2092
2199
|
const [showConversationList, setShowConversationList] = useState(false);
|
|
2093
2200
|
const [isVerifiedUser, setIsVerifiedUser] = useState(false);
|
|
@@ -2134,11 +2241,30 @@ function CrowWidget({
|
|
|
2134
2241
|
break;
|
|
2135
2242
|
}
|
|
2136
2243
|
},
|
|
2137
|
-
onToolCall: (event) => {
|
|
2138
|
-
if (event.type === "client_call" && event.toolName) {
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2244
|
+
onToolCall: async (event) => {
|
|
2245
|
+
if (event.type === "client_call" && event.toolName && event.toolCallId) {
|
|
2246
|
+
try {
|
|
2247
|
+
const result = await executeClientToolRef.current?.(
|
|
2248
|
+
event.toolName,
|
|
2249
|
+
event.arguments || {}
|
|
2250
|
+
);
|
|
2251
|
+
if (result && submitToolResultRef.current) {
|
|
2252
|
+
await submitToolResultRef.current(
|
|
2253
|
+
event.toolCallId,
|
|
2254
|
+
event.toolName,
|
|
2255
|
+
result
|
|
2256
|
+
);
|
|
2257
|
+
}
|
|
2258
|
+
} catch (e) {
|
|
2259
|
+
console.error("[Crow Widget] Tool error:", e);
|
|
2260
|
+
if (submitToolResultRef.current) {
|
|
2261
|
+
await submitToolResultRef.current(
|
|
2262
|
+
event.toolCallId,
|
|
2263
|
+
event.toolName,
|
|
2264
|
+
{ success: false, error: String(e) }
|
|
2265
|
+
);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2142
2268
|
}
|
|
2143
2269
|
},
|
|
2144
2270
|
onRestoredConversation: () => {
|
|
@@ -2184,6 +2310,7 @@ function CrowWidget({
|
|
|
2184
2310
|
}
|
|
2185
2311
|
});
|
|
2186
2312
|
executeClientToolRef.current = executeClientTool;
|
|
2313
|
+
submitToolResultRef.current = chat.submitToolResult;
|
|
2187
2314
|
useEffect(() => {
|
|
2188
2315
|
if (!isLoadingStyles) {
|
|
2189
2316
|
onReady?.();
|