@meetsmore-oss/use-ai-client 1.3.0 → 1.5.0
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/bundled.js +3837 -2406
- package/dist/bundled.js.map +1 -1
- package/dist/{chunk-QTQR7MAU.js → chunk-STF3H6F5.js} +1 -1
- package/dist/chunk-STF3H6F5.js.map +1 -0
- package/dist/{chunk-AKQM6IWU.js → chunk-UM4UCU4W.js} +1 -1
- package/dist/chunk-UM4UCU4W.js.map +1 -0
- package/dist/index.d.ts +94 -12
- package/dist/index.js +387 -89
- package/dist/index.js.map +1 -1
- package/dist/{types-64CH2HXY.js → types-GWPQMSYT.js} +2 -2
- package/dist/{types-STDS67SG.js → types-RJZTRF3U.js} +2 -2
- package/package.json +2 -2
- package/dist/chunk-AKQM6IWU.js.map +0 -1
- package/dist/chunk-QTQR7MAU.js.map +0 -1
- /package/dist/{types-64CH2HXY.js.map → types-GWPQMSYT.js.map} +0 -0
- /package/dist/{types-STDS67SG.js.map → types-RJZTRF3U.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateChatId,
|
|
3
3
|
generateMessageId
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-STF3H6F5.js";
|
|
5
5
|
|
|
6
6
|
// src/useAI.ts
|
|
7
|
-
import { useState as
|
|
7
|
+
import { useState as useState12, useEffect as useEffect11, useRef as useRef12, useCallback as useCallback11, useMemo as useMemo6 } from "react";
|
|
8
8
|
|
|
9
9
|
// src/providers/useAIProvider.tsx
|
|
10
|
-
import { createContext as createContext4, useContext as useContext4, useState as
|
|
10
|
+
import { createContext as createContext4, useContext as useContext4, useState as useState11, useEffect as useEffect10, useCallback as useCallback10, useRef as useRef10 } from "react";
|
|
11
11
|
|
|
12
12
|
// src/types.ts
|
|
13
13
|
import { EventType, ErrorCode } from "@meetsmore-oss/use-ai-core";
|
|
@@ -51,7 +51,9 @@ var defaultStrings = {
|
|
|
51
51
|
/** Input placeholder when connecting */
|
|
52
52
|
connectingPlaceholder: "Connecting...",
|
|
53
53
|
/** Loading indicator text */
|
|
54
|
-
thinking: "Thinking"
|
|
54
|
+
thinking: "Thinking",
|
|
55
|
+
/** File processing indicator text (shown during file transformation like OCR) */
|
|
56
|
+
processingFile: "Processing file..."
|
|
55
57
|
},
|
|
56
58
|
// File upload
|
|
57
59
|
fileUpload: {
|
|
@@ -102,6 +104,11 @@ var defaultStrings = {
|
|
|
102
104
|
RATE_LIMITED: "Too many requests. Please wait a moment before trying again.",
|
|
103
105
|
/** Error for unknown/unexpected errors */
|
|
104
106
|
UNKNOWN_ERROR: "An unexpected error occurred. Please try again."
|
|
107
|
+
},
|
|
108
|
+
// Tool execution status
|
|
109
|
+
toolExecution: {
|
|
110
|
+
/** Fallback messages when no tool title is provided (one randomly selected) */
|
|
111
|
+
fallbackMessages: ["Working", "Processing", "Thinking"]
|
|
105
112
|
}
|
|
106
113
|
};
|
|
107
114
|
var StringsContext = createContext(defaultStrings);
|
|
@@ -1244,7 +1251,6 @@ async function processAttachments(attachments, config) {
|
|
|
1244
1251
|
const chat = await getCurrentChat();
|
|
1245
1252
|
const context = { chat };
|
|
1246
1253
|
for (const attachment of attachments) {
|
|
1247
|
-
onFileProgress?.(attachment.id, { status: "processing" });
|
|
1248
1254
|
try {
|
|
1249
1255
|
if (attachment.transformedContent !== void 0) {
|
|
1250
1256
|
contentParts.push({
|
|
@@ -1256,11 +1262,11 @@ async function processAttachments(attachments, config) {
|
|
|
1256
1262
|
size: attachment.file.size
|
|
1257
1263
|
}
|
|
1258
1264
|
});
|
|
1259
|
-
onFileProgress?.(attachment.id, { status: "done" });
|
|
1260
1265
|
continue;
|
|
1261
1266
|
}
|
|
1262
1267
|
const transformer = findTransformer(attachment.file.type, transformers);
|
|
1263
1268
|
if (transformer) {
|
|
1269
|
+
onFileProgress?.(attachment.id, { status: "processing" });
|
|
1264
1270
|
const transformedText = await getTransformedContent(
|
|
1265
1271
|
attachment.file,
|
|
1266
1272
|
transformer,
|
|
@@ -1278,6 +1284,7 @@ async function processAttachments(attachments, config) {
|
|
|
1278
1284
|
size: attachment.file.size
|
|
1279
1285
|
}
|
|
1280
1286
|
});
|
|
1287
|
+
onFileProgress?.(attachment.id, { status: "done" });
|
|
1281
1288
|
} else {
|
|
1282
1289
|
const url = await backend.prepareForSend(attachment.file);
|
|
1283
1290
|
if (attachment.file.type.startsWith("image/")) {
|
|
@@ -1291,7 +1298,6 @@ async function processAttachments(attachments, config) {
|
|
|
1291
1298
|
});
|
|
1292
1299
|
}
|
|
1293
1300
|
}
|
|
1294
|
-
onFileProgress?.(attachment.id, { status: "done" });
|
|
1295
1301
|
} catch (error) {
|
|
1296
1302
|
onFileProgress?.(attachment.id, { status: "error" });
|
|
1297
1303
|
throw error;
|
|
@@ -1570,6 +1576,71 @@ function useDropdownState(options = {}) {
|
|
|
1570
1576
|
|
|
1571
1577
|
// src/components/UseAIChatPanel.tsx
|
|
1572
1578
|
import { Fragment, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1579
|
+
function FeedbackButton({ type, isSelected, onClick, selectedColor, unselectedColor }) {
|
|
1580
|
+
const buttonRef = useRef4(null);
|
|
1581
|
+
const handleClick = () => {
|
|
1582
|
+
if (!isSelected && buttonRef.current) {
|
|
1583
|
+
buttonRef.current.style.transform = "scale(1.3)";
|
|
1584
|
+
setTimeout(() => {
|
|
1585
|
+
if (buttonRef.current) {
|
|
1586
|
+
buttonRef.current.style.transform = "scale(1)";
|
|
1587
|
+
}
|
|
1588
|
+
}, 150);
|
|
1589
|
+
}
|
|
1590
|
+
onClick();
|
|
1591
|
+
};
|
|
1592
|
+
const thumbsUpPath = "M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3";
|
|
1593
|
+
const thumbsDownPath = "M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17";
|
|
1594
|
+
return /* @__PURE__ */ jsx10(
|
|
1595
|
+
"button",
|
|
1596
|
+
{
|
|
1597
|
+
ref: buttonRef,
|
|
1598
|
+
"data-testid": `feedback-${type}`,
|
|
1599
|
+
onClick: handleClick,
|
|
1600
|
+
title: type === "upvote" ? "Good response" : "Poor response",
|
|
1601
|
+
style: {
|
|
1602
|
+
background: "transparent",
|
|
1603
|
+
border: "none",
|
|
1604
|
+
padding: "4px",
|
|
1605
|
+
cursor: "pointer",
|
|
1606
|
+
color: isSelected ? selectedColor : unselectedColor,
|
|
1607
|
+
opacity: isSelected ? 1 : 0.5,
|
|
1608
|
+
transition: "all 0.15s",
|
|
1609
|
+
display: "flex",
|
|
1610
|
+
alignItems: "center",
|
|
1611
|
+
justifyContent: "center",
|
|
1612
|
+
borderRadius: "4px",
|
|
1613
|
+
transform: "scale(1)"
|
|
1614
|
+
},
|
|
1615
|
+
onMouseEnter: (e) => {
|
|
1616
|
+
if (!isSelected) {
|
|
1617
|
+
e.currentTarget.style.opacity = "0.8";
|
|
1618
|
+
e.currentTarget.style.color = selectedColor;
|
|
1619
|
+
}
|
|
1620
|
+
},
|
|
1621
|
+
onMouseLeave: (e) => {
|
|
1622
|
+
if (!isSelected) {
|
|
1623
|
+
e.currentTarget.style.opacity = "0.5";
|
|
1624
|
+
e.currentTarget.style.color = unselectedColor;
|
|
1625
|
+
}
|
|
1626
|
+
},
|
|
1627
|
+
children: /* @__PURE__ */ jsx10(
|
|
1628
|
+
"svg",
|
|
1629
|
+
{
|
|
1630
|
+
width: "14",
|
|
1631
|
+
height: "14",
|
|
1632
|
+
viewBox: "0 0 24 24",
|
|
1633
|
+
fill: isSelected ? "currentColor" : "none",
|
|
1634
|
+
stroke: "currentColor",
|
|
1635
|
+
strokeWidth: "2",
|
|
1636
|
+
strokeLinecap: "round",
|
|
1637
|
+
strokeLinejoin: "round",
|
|
1638
|
+
children: /* @__PURE__ */ jsx10("path", { d: type === "upvote" ? thumbsUpPath : thumbsDownPath })
|
|
1639
|
+
}
|
|
1640
|
+
)
|
|
1641
|
+
}
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1573
1644
|
function getTextContent(content) {
|
|
1574
1645
|
if (typeof content === "string") {
|
|
1575
1646
|
return content;
|
|
@@ -1597,11 +1668,15 @@ function UseAIChatPanel({
|
|
|
1597
1668
|
selectedAgent,
|
|
1598
1669
|
onAgentChange,
|
|
1599
1670
|
fileUploadConfig,
|
|
1671
|
+
fileProcessing,
|
|
1600
1672
|
commands = [],
|
|
1601
1673
|
onSaveCommand,
|
|
1602
1674
|
onRenameCommand,
|
|
1603
1675
|
onDeleteCommand,
|
|
1604
|
-
closeButton
|
|
1676
|
+
closeButton,
|
|
1677
|
+
executingTool,
|
|
1678
|
+
feedbackEnabled,
|
|
1679
|
+
onFeedback
|
|
1605
1680
|
}) {
|
|
1606
1681
|
const strings = useStrings();
|
|
1607
1682
|
const theme = useTheme();
|
|
@@ -2226,6 +2301,46 @@ function UseAIChatPanel({
|
|
|
2226
2301
|
]
|
|
2227
2302
|
}
|
|
2228
2303
|
),
|
|
2304
|
+
message.role === "assistant" && message.traceId && feedbackEnabled && onFeedback && /* @__PURE__ */ jsxs7(
|
|
2305
|
+
"div",
|
|
2306
|
+
{
|
|
2307
|
+
"data-testid": "feedback-buttons",
|
|
2308
|
+
style: {
|
|
2309
|
+
display: "flex",
|
|
2310
|
+
gap: "4px",
|
|
2311
|
+
marginTop: "4px",
|
|
2312
|
+
padding: "0 4px"
|
|
2313
|
+
},
|
|
2314
|
+
children: [
|
|
2315
|
+
/* @__PURE__ */ jsx10(
|
|
2316
|
+
FeedbackButton,
|
|
2317
|
+
{
|
|
2318
|
+
type: "upvote",
|
|
2319
|
+
isSelected: message.feedback === "upvote",
|
|
2320
|
+
onClick: () => {
|
|
2321
|
+
const newFeedback = message.feedback === "upvote" ? null : "upvote";
|
|
2322
|
+
onFeedback(message.id, message.traceId, newFeedback);
|
|
2323
|
+
},
|
|
2324
|
+
selectedColor: theme.primaryColor,
|
|
2325
|
+
unselectedColor: theme.secondaryTextColor
|
|
2326
|
+
}
|
|
2327
|
+
),
|
|
2328
|
+
/* @__PURE__ */ jsx10(
|
|
2329
|
+
FeedbackButton,
|
|
2330
|
+
{
|
|
2331
|
+
type: "downvote",
|
|
2332
|
+
isSelected: message.feedback === "downvote",
|
|
2333
|
+
onClick: () => {
|
|
2334
|
+
const newFeedback = message.feedback === "downvote" ? null : "downvote";
|
|
2335
|
+
onFeedback(message.id, message.traceId, newFeedback);
|
|
2336
|
+
},
|
|
2337
|
+
selectedColor: theme.errorTextColor,
|
|
2338
|
+
unselectedColor: theme.secondaryTextColor
|
|
2339
|
+
}
|
|
2340
|
+
)
|
|
2341
|
+
]
|
|
2342
|
+
}
|
|
2343
|
+
),
|
|
2229
2344
|
/* @__PURE__ */ jsx10(
|
|
2230
2345
|
"div",
|
|
2231
2346
|
{
|
|
@@ -2265,10 +2380,29 @@ function UseAIChatPanel({
|
|
|
2265
2380
|
color: theme.textColor,
|
|
2266
2381
|
maxWidth: "80%"
|
|
2267
2382
|
},
|
|
2268
|
-
children: streamingText ? /* @__PURE__ */ jsx10(MarkdownContent, { content: streamingText }) : /* @__PURE__ */ jsxs7(
|
|
2269
|
-
/* @__PURE__ */ jsx10("span", { style: { opacity: 0.6 }, children: strings.input.
|
|
2270
|
-
/* @__PURE__ */
|
|
2271
|
-
|
|
2383
|
+
children: streamingText ? /* @__PURE__ */ jsx10(MarkdownContent, { content: streamingText }) : fileProcessing && fileProcessing.status === "processing" ? /* @__PURE__ */ jsxs7("div", { children: [
|
|
2384
|
+
/* @__PURE__ */ jsx10("span", { style: { opacity: 0.6 }, children: strings.input.processingFile }),
|
|
2385
|
+
fileProcessing.progress != null && /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
2386
|
+
/* @__PURE__ */ jsxs7("span", { style: { opacity: 0.6, marginLeft: "4px" }, children: [
|
|
2387
|
+
Math.round(fileProcessing.progress),
|
|
2388
|
+
"%"
|
|
2389
|
+
] }),
|
|
2390
|
+
/* @__PURE__ */ jsx10("div", { style: {
|
|
2391
|
+
marginTop: "6px",
|
|
2392
|
+
height: "4px",
|
|
2393
|
+
borderRadius: "2px",
|
|
2394
|
+
background: theme.borderColor,
|
|
2395
|
+
overflow: "hidden"
|
|
2396
|
+
}, children: /* @__PURE__ */ jsx10("div", { style: {
|
|
2397
|
+
height: "100%",
|
|
2398
|
+
width: `${fileProcessing.progress}%`,
|
|
2399
|
+
borderRadius: "2px",
|
|
2400
|
+
background: theme.primaryColor,
|
|
2401
|
+
transition: "width 0.3s ease"
|
|
2402
|
+
} }) })
|
|
2403
|
+
] }),
|
|
2404
|
+
fileProcessing.progress == null && /* @__PURE__ */ jsx10("span", { className: "dots", style: { marginLeft: "4px" }, children: "..." })
|
|
2405
|
+
] }) : /* @__PURE__ */ jsx10("span", { className: "dots", style: { opacity: 0.6 }, children: "..." })
|
|
2272
2406
|
}
|
|
2273
2407
|
)
|
|
2274
2408
|
}
|
|
@@ -2355,7 +2489,7 @@ function UseAIChatPanel({
|
|
|
2355
2489
|
value: input,
|
|
2356
2490
|
onChange: handleInputChange,
|
|
2357
2491
|
onKeyDown: handleKeyDown,
|
|
2358
|
-
placeholder: connected ? strings.input.
|
|
2492
|
+
placeholder: !connected ? strings.input.connectingPlaceholder : loading ? `${executingTool?.displayText ?? strings.input.thinking}...` : strings.input.placeholder,
|
|
2359
2493
|
disabled: !connected || loading,
|
|
2360
2494
|
rows: 1,
|
|
2361
2495
|
style: {
|
|
@@ -2613,10 +2747,14 @@ function UseAIChat({ floating = false }) {
|
|
|
2613
2747
|
selectedAgent: ctx.agents.selected,
|
|
2614
2748
|
onAgentChange: ctx.agents.set,
|
|
2615
2749
|
fileUploadConfig: ctx.fileUploadConfig,
|
|
2750
|
+
fileProcessing: ctx.fileProcessing,
|
|
2616
2751
|
commands: ctx.commands.list,
|
|
2617
2752
|
onSaveCommand: ctx.commands.save,
|
|
2618
2753
|
onRenameCommand: ctx.commands.rename,
|
|
2619
|
-
onDeleteCommand: ctx.commands.delete
|
|
2754
|
+
onDeleteCommand: ctx.commands.delete,
|
|
2755
|
+
executingTool: ctx.executingTool,
|
|
2756
|
+
feedbackEnabled: ctx.feedback?.enabled,
|
|
2757
|
+
onFeedback: ctx.feedback?.submit
|
|
2620
2758
|
};
|
|
2621
2759
|
if (floating) {
|
|
2622
2760
|
return /* @__PURE__ */ jsx12(
|
|
@@ -2677,6 +2815,9 @@ var UseAIClient = class {
|
|
|
2677
2815
|
_currentAssistantToolCalls = [];
|
|
2678
2816
|
// Tool call assembly
|
|
2679
2817
|
currentToolCalls = /* @__PURE__ */ new Map();
|
|
2818
|
+
// Feedback tracking
|
|
2819
|
+
_langfuseEnabled = false;
|
|
2820
|
+
langfuseConfigHandlers = /* @__PURE__ */ new Set();
|
|
2680
2821
|
/**
|
|
2681
2822
|
* Establishes a Socket.IO connection to the server.
|
|
2682
2823
|
* Connection state changes are notified via onConnectionStateChange().
|
|
@@ -2719,6 +2860,11 @@ var UseAIClient = class {
|
|
|
2719
2860
|
this._defaultAgent = data.defaultAgent;
|
|
2720
2861
|
this.agentsChangeHandlers.forEach((handler) => handler(data.agents, data.defaultAgent));
|
|
2721
2862
|
});
|
|
2863
|
+
this.socket.on("config", (data) => {
|
|
2864
|
+
console.log("[Client] Received server config:", data);
|
|
2865
|
+
this._langfuseEnabled = data.langfuseEnabled ?? false;
|
|
2866
|
+
this.langfuseConfigHandlers.forEach((handler) => handler(this._langfuseEnabled));
|
|
2867
|
+
});
|
|
2722
2868
|
this.socket.on("connect_error", (error) => {
|
|
2723
2869
|
console.warn("[UseAI] Connection error:", error.message);
|
|
2724
2870
|
});
|
|
@@ -3135,6 +3281,41 @@ var UseAIClient = class {
|
|
|
3135
3281
|
isConnected() {
|
|
3136
3282
|
return this.socket !== null && this.socket.connected;
|
|
3137
3283
|
}
|
|
3284
|
+
/**
|
|
3285
|
+
* Subscribes to Langfuse config changes.
|
|
3286
|
+
*
|
|
3287
|
+
* @param handler - Callback function receiving langfuse enabled status
|
|
3288
|
+
* @returns Cleanup function to unsubscribe
|
|
3289
|
+
*/
|
|
3290
|
+
onLangfuseConfigChange(handler) {
|
|
3291
|
+
this.langfuseConfigHandlers.add(handler);
|
|
3292
|
+
handler(this._langfuseEnabled);
|
|
3293
|
+
return () => {
|
|
3294
|
+
this.langfuseConfigHandlers.delete(handler);
|
|
3295
|
+
};
|
|
3296
|
+
}
|
|
3297
|
+
/**
|
|
3298
|
+
* Submits feedback for an assistant message.
|
|
3299
|
+
* Sends feedback to the server, which forwards it to Langfuse.
|
|
3300
|
+
*
|
|
3301
|
+
* @param messageId - The client-side message ID
|
|
3302
|
+
* @param traceId - The Langfuse trace ID (runId from RUN_FINISHED)
|
|
3303
|
+
* @param feedback - 'upvote' for positive, 'downvote' for negative, null to remove
|
|
3304
|
+
*/
|
|
3305
|
+
submitFeedback(messageId, traceId, feedback) {
|
|
3306
|
+
if (!this.socket?.connected) {
|
|
3307
|
+
console.warn("[UseAI] Cannot submit feedback: not connected");
|
|
3308
|
+
return;
|
|
3309
|
+
}
|
|
3310
|
+
if (!this._langfuseEnabled) {
|
|
3311
|
+
console.warn("[UseAI] Cannot submit feedback: Langfuse not enabled on server");
|
|
3312
|
+
return;
|
|
3313
|
+
}
|
|
3314
|
+
this.send({
|
|
3315
|
+
type: "message_feedback",
|
|
3316
|
+
data: { messageId, traceId, feedback }
|
|
3317
|
+
});
|
|
3318
|
+
}
|
|
3138
3319
|
};
|
|
3139
3320
|
|
|
3140
3321
|
// src/defineTool.ts
|
|
@@ -3174,8 +3355,8 @@ function defineTool(description, schemaOrFn, fnOrOptions, options) {
|
|
|
3174
3355
|
description,
|
|
3175
3356
|
parameters
|
|
3176
3357
|
};
|
|
3177
|
-
if (this._options.
|
|
3178
|
-
toolDef.
|
|
3358
|
+
if (this._options.annotations) {
|
|
3359
|
+
toolDef.annotations = this._options.annotations;
|
|
3179
3360
|
}
|
|
3180
3361
|
return toolDef;
|
|
3181
3362
|
},
|
|
@@ -3373,7 +3554,9 @@ function transformMessagesToUI(storageMessages) {
|
|
|
3373
3554
|
role: msg.role,
|
|
3374
3555
|
content: msg.content,
|
|
3375
3556
|
timestamp: msg.createdAt,
|
|
3376
|
-
displayMode: msg.displayMode
|
|
3557
|
+
displayMode: msg.displayMode,
|
|
3558
|
+
traceId: msg.traceId,
|
|
3559
|
+
feedback: msg.feedback
|
|
3377
3560
|
}));
|
|
3378
3561
|
}
|
|
3379
3562
|
function transformMessagesToClientFormat(uiMessages) {
|
|
@@ -3389,6 +3572,8 @@ function transformMessagesToClientFormat(uiMessages) {
|
|
|
3389
3572
|
function useChatManagement({
|
|
3390
3573
|
repository,
|
|
3391
3574
|
clientRef,
|
|
3575
|
+
messages,
|
|
3576
|
+
setMessages,
|
|
3392
3577
|
onSendMessage,
|
|
3393
3578
|
setOpen,
|
|
3394
3579
|
connected,
|
|
@@ -3396,7 +3581,6 @@ function useChatManagement({
|
|
|
3396
3581
|
}) {
|
|
3397
3582
|
const [currentChatId, setCurrentChatId] = useState5(null);
|
|
3398
3583
|
const [pendingChatId, setPendingChatId] = useState5(null);
|
|
3399
|
-
const [messages, setMessages] = useState5([]);
|
|
3400
3584
|
const currentChatIdSnapshot = useRef5(null);
|
|
3401
3585
|
const pendingChatIdSnapshot = useRef5(null);
|
|
3402
3586
|
useEffect5(() => {
|
|
@@ -3515,7 +3699,7 @@ function useChatManagement({
|
|
|
3515
3699
|
console.error("[ChatManagement] Chat not found:", chatId);
|
|
3516
3700
|
return false;
|
|
3517
3701
|
}
|
|
3518
|
-
const { generateMessageId: generateMessageId2 } = await import("./types-
|
|
3702
|
+
const { generateMessageId: generateMessageId2 } = await import("./types-GWPQMSYT.js");
|
|
3519
3703
|
chat.messages.push({
|
|
3520
3704
|
id: generateMessageId2(),
|
|
3521
3705
|
role: "user",
|
|
@@ -3537,7 +3721,7 @@ function useChatManagement({
|
|
|
3537
3721
|
return false;
|
|
3538
3722
|
}
|
|
3539
3723
|
}, [repository, reloadMessages]);
|
|
3540
|
-
const saveAIResponse = useCallback4(async (content, displayMode) => {
|
|
3724
|
+
const saveAIResponse = useCallback4(async (content, displayMode, traceId) => {
|
|
3541
3725
|
const currentChatIdValue = currentChatIdSnapshot.current;
|
|
3542
3726
|
const pendingChatIdValue = pendingChatIdSnapshot.current;
|
|
3543
3727
|
const displayedChatId2 = pendingChatIdValue || currentChatIdValue;
|
|
@@ -3551,13 +3735,14 @@ function useChatManagement({
|
|
|
3551
3735
|
console.error("[ChatManagement] Chat not found:", currentChatIdValue);
|
|
3552
3736
|
return;
|
|
3553
3737
|
}
|
|
3554
|
-
const { generateMessageId: generateMessageId2 } = await import("./types-
|
|
3738
|
+
const { generateMessageId: generateMessageId2 } = await import("./types-GWPQMSYT.js");
|
|
3555
3739
|
chat.messages.push({
|
|
3556
3740
|
id: generateMessageId2(),
|
|
3557
3741
|
role: "assistant",
|
|
3558
3742
|
content,
|
|
3559
3743
|
createdAt: /* @__PURE__ */ new Date(),
|
|
3560
|
-
displayMode
|
|
3744
|
+
displayMode,
|
|
3745
|
+
traceId
|
|
3561
3746
|
});
|
|
3562
3747
|
if (!chat.title) {
|
|
3563
3748
|
const firstUserMessage = chat.messages.find((msg) => msg.role === "user");
|
|
@@ -3675,7 +3860,6 @@ function useChatManagement({
|
|
|
3675
3860
|
return {
|
|
3676
3861
|
currentChatId,
|
|
3677
3862
|
pendingChatId,
|
|
3678
|
-
messages,
|
|
3679
3863
|
displayedChatId,
|
|
3680
3864
|
createNewChat,
|
|
3681
3865
|
loadChat,
|
|
@@ -4069,6 +4253,68 @@ function usePromptState({
|
|
|
4069
4253
|
};
|
|
4070
4254
|
}
|
|
4071
4255
|
|
|
4256
|
+
// src/hooks/useFeedback.ts
|
|
4257
|
+
import { useState as useState10, useEffect as useEffect9, useRef as useRef9, useCallback as useCallback9 } from "react";
|
|
4258
|
+
function useFeedback({
|
|
4259
|
+
clientRef,
|
|
4260
|
+
repository,
|
|
4261
|
+
getDisplayedChatId,
|
|
4262
|
+
setMessages
|
|
4263
|
+
}) {
|
|
4264
|
+
const [enabled, setEnabled] = useState10(false);
|
|
4265
|
+
const enabledRef = useRef9(false);
|
|
4266
|
+
useEffect9(() => {
|
|
4267
|
+
enabledRef.current = enabled;
|
|
4268
|
+
}, [enabled]);
|
|
4269
|
+
useEffect9(() => {
|
|
4270
|
+
const client = clientRef.current;
|
|
4271
|
+
if (!client) return;
|
|
4272
|
+
const unsubscribe = client.onLangfuseConfigChange((isEnabled) => {
|
|
4273
|
+
setEnabled(isEnabled);
|
|
4274
|
+
});
|
|
4275
|
+
return unsubscribe;
|
|
4276
|
+
}, [clientRef.current]);
|
|
4277
|
+
const updateFeedbackInStorage = useCallback9(async (messageId, feedback) => {
|
|
4278
|
+
const displayedChatId = getDisplayedChatId();
|
|
4279
|
+
if (!displayedChatId) {
|
|
4280
|
+
console.warn("[useFeedback] No chat ID, cannot update feedback");
|
|
4281
|
+
return;
|
|
4282
|
+
}
|
|
4283
|
+
try {
|
|
4284
|
+
const chat = await repository.loadChat(displayedChatId);
|
|
4285
|
+
if (!chat) {
|
|
4286
|
+
console.error("[useFeedback] Chat not found:", displayedChatId);
|
|
4287
|
+
return;
|
|
4288
|
+
}
|
|
4289
|
+
const message = chat.messages.find((msg) => msg.id === messageId);
|
|
4290
|
+
if (message) {
|
|
4291
|
+
message.feedback = feedback;
|
|
4292
|
+
await repository.saveChat(chat);
|
|
4293
|
+
setMessages(
|
|
4294
|
+
(prevMessages) => prevMessages.map(
|
|
4295
|
+
(msg) => msg.id === messageId ? { ...msg, feedback } : msg
|
|
4296
|
+
)
|
|
4297
|
+
);
|
|
4298
|
+
} else {
|
|
4299
|
+
console.warn("[useFeedback] Message not found:", messageId);
|
|
4300
|
+
}
|
|
4301
|
+
} catch (error) {
|
|
4302
|
+
console.error("[useFeedback] Failed to update feedback:", error);
|
|
4303
|
+
}
|
|
4304
|
+
}, [repository, getDisplayedChatId, setMessages]);
|
|
4305
|
+
const submitFeedback = useCallback9((messageId, traceId, feedback) => {
|
|
4306
|
+
updateFeedbackInStorage(messageId, feedback);
|
|
4307
|
+
const client = clientRef.current;
|
|
4308
|
+
if (client && enabledRef.current) {
|
|
4309
|
+
client.submitFeedback(messageId, traceId, feedback);
|
|
4310
|
+
}
|
|
4311
|
+
}, [clientRef, updateFeedbackInStorage]);
|
|
4312
|
+
return {
|
|
4313
|
+
enabled,
|
|
4314
|
+
submitFeedback
|
|
4315
|
+
};
|
|
4316
|
+
}
|
|
4317
|
+
|
|
4072
4318
|
// src/providers/useAIProvider.tsx
|
|
4073
4319
|
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4074
4320
|
var __UseAIContext = createContext4(null);
|
|
@@ -4150,20 +4396,24 @@ function UseAIProvider({
|
|
|
4150
4396
|
const fileUploadConfig = fileUploadConfigProp === false ? void 0 : fileUploadConfigProp ?? DEFAULT_FILE_UPLOAD_CONFIG;
|
|
4151
4397
|
const theme = { ...defaultTheme, ...customTheme };
|
|
4152
4398
|
const strings = { ...defaultStrings, ...customStrings };
|
|
4153
|
-
const [connected, setConnected] =
|
|
4154
|
-
const [isChatOpen, setIsChatOpen] =
|
|
4155
|
-
const [loading, setLoading] =
|
|
4156
|
-
const
|
|
4399
|
+
const [connected, setConnected] = useState11(false);
|
|
4400
|
+
const [isChatOpen, setIsChatOpen] = useState11(false);
|
|
4401
|
+
const [loading, setLoading] = useState11(false);
|
|
4402
|
+
const [messages, setMessages] = useState11([]);
|
|
4403
|
+
const [fileProcessingState, setFileProcessingState] = useState11(null);
|
|
4404
|
+
const handleSetChatOpen = useCallback10((open) => {
|
|
4157
4405
|
setIsChatOpen(open);
|
|
4158
4406
|
onOpenChange?.(open);
|
|
4159
4407
|
}, [onOpenChange]);
|
|
4160
|
-
const [streamingText, setStreamingText] =
|
|
4161
|
-
const streamingChatIdRef =
|
|
4162
|
-
const
|
|
4163
|
-
const
|
|
4408
|
+
const [streamingText, setStreamingText] = useState11("");
|
|
4409
|
+
const streamingChatIdRef = useRef10(null);
|
|
4410
|
+
const [executingTool, setExecutingTool] = useState11(null);
|
|
4411
|
+
const executingToolFallbackRef = useRef10(null);
|
|
4412
|
+
const clientRef = useRef10(null);
|
|
4413
|
+
const repositoryRef = useRef10(
|
|
4164
4414
|
chatRepository || new LocalStorageChatRepository()
|
|
4165
4415
|
);
|
|
4166
|
-
const handleSendMessageRef =
|
|
4416
|
+
const handleSendMessageRef = useRef10(null);
|
|
4167
4417
|
const {
|
|
4168
4418
|
registerTools,
|
|
4169
4419
|
unregisterTools,
|
|
@@ -4185,7 +4435,7 @@ function UseAIProvider({
|
|
|
4185
4435
|
clientRef,
|
|
4186
4436
|
connected
|
|
4187
4437
|
});
|
|
4188
|
-
const stableSendMessage =
|
|
4438
|
+
const stableSendMessage = useCallback10(async (message, attachments) => {
|
|
4189
4439
|
if (handleSendMessageRef.current) {
|
|
4190
4440
|
await handleSendMessageRef.current(message, attachments);
|
|
4191
4441
|
}
|
|
@@ -4193,6 +4443,8 @@ function UseAIProvider({
|
|
|
4193
4443
|
const chatManagement = useChatManagement({
|
|
4194
4444
|
repository: repositoryRef.current,
|
|
4195
4445
|
clientRef,
|
|
4446
|
+
messages,
|
|
4447
|
+
setMessages,
|
|
4196
4448
|
onSendMessage: stableSendMessage,
|
|
4197
4449
|
setOpen: handleSetChatOpen,
|
|
4198
4450
|
connected,
|
|
@@ -4201,7 +4453,6 @@ function UseAIProvider({
|
|
|
4201
4453
|
const {
|
|
4202
4454
|
currentChatId,
|
|
4203
4455
|
pendingChatId,
|
|
4204
|
-
messages,
|
|
4205
4456
|
displayedChatId,
|
|
4206
4457
|
createNewChat,
|
|
4207
4458
|
loadChat,
|
|
@@ -4215,6 +4466,12 @@ function UseAIProvider({
|
|
|
4215
4466
|
getCurrentChat,
|
|
4216
4467
|
updateMetadata
|
|
4217
4468
|
} = chatManagement;
|
|
4469
|
+
const feedback = useFeedback({
|
|
4470
|
+
clientRef,
|
|
4471
|
+
repository: repositoryRef.current,
|
|
4472
|
+
getDisplayedChatId: () => displayedChatId,
|
|
4473
|
+
setMessages
|
|
4474
|
+
});
|
|
4218
4475
|
const {
|
|
4219
4476
|
availableAgents,
|
|
4220
4477
|
defaultAgent,
|
|
@@ -4228,7 +4485,7 @@ function UseAIProvider({
|
|
|
4228
4485
|
renameCommand,
|
|
4229
4486
|
deleteCommand
|
|
4230
4487
|
} = useCommandManagement({ repository: commandRepository });
|
|
4231
|
-
|
|
4488
|
+
useEffect10(() => {
|
|
4232
4489
|
console.log("[UseAIProvider] Initializing client with serverUrl:", serverUrl);
|
|
4233
4490
|
const client = new UseAIClient(serverUrl);
|
|
4234
4491
|
if (mcpHeadersProvider) {
|
|
@@ -4241,9 +4498,19 @@ function UseAIProvider({
|
|
|
4241
4498
|
console.log("[UseAIProvider] Connecting...");
|
|
4242
4499
|
client.connect();
|
|
4243
4500
|
const unsubscribe = client.onEvent("globalChat", async (event) => {
|
|
4244
|
-
if (event.type === EventType.
|
|
4501
|
+
if (event.type === EventType.TOOL_CALL_START) {
|
|
4502
|
+
const e = event;
|
|
4503
|
+
const tool = aggregatedToolsRef.current[e.toolCallName];
|
|
4504
|
+
const title = e.annotations?.title ?? tool?._options?.annotations?.title ?? null;
|
|
4505
|
+
if (!title) {
|
|
4506
|
+
const fallbacks = strings.toolExecution.fallbackMessages;
|
|
4507
|
+
executingToolFallbackRef.current = fallbacks[Math.floor(Math.random() * fallbacks.length)];
|
|
4508
|
+
}
|
|
4509
|
+
setExecutingTool({ toolCallId: e.toolCallId, title });
|
|
4510
|
+
} else if (event.type === EventType.TOOL_CALL_END) {
|
|
4245
4511
|
const toolCallEnd = event;
|
|
4246
4512
|
const toolCallId = toolCallEnd.toolCallId;
|
|
4513
|
+
setExecutingTool((prev) => prev?.toolCallId === toolCallId ? null : prev);
|
|
4247
4514
|
const toolCallData = client["currentToolCalls"].get(toolCallId);
|
|
4248
4515
|
if (!toolCallData) {
|
|
4249
4516
|
console.error(`[Provider] Tool call ${toolCallId} not found`);
|
|
@@ -4293,14 +4560,16 @@ function UseAIProvider({
|
|
|
4293
4560
|
const contentEvent = event;
|
|
4294
4561
|
setStreamingText((prev) => prev + contentEvent.delta);
|
|
4295
4562
|
} else if (event.type === EventType.TEXT_MESSAGE_END) {
|
|
4563
|
+
setStreamingText("");
|
|
4564
|
+
streamingChatIdRef.current = null;
|
|
4565
|
+
} else if (event.type === EventType.RUN_FINISHED) {
|
|
4296
4566
|
const content = client.currentMessageContent;
|
|
4297
4567
|
if (content) {
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
streamingChatIdRef.current = null;
|
|
4302
|
-
setLoading(false);
|
|
4568
|
+
const finishedEvent = event;
|
|
4569
|
+
const traceId = finishedEvent.runId;
|
|
4570
|
+
saveAIResponse(content, void 0, traceId);
|
|
4303
4571
|
}
|
|
4572
|
+
setLoading(false);
|
|
4304
4573
|
} else if (event.type === EventType.RUN_ERROR) {
|
|
4305
4574
|
const errorEvent = event;
|
|
4306
4575
|
const errorCode = errorEvent.message;
|
|
@@ -4319,15 +4588,15 @@ function UseAIProvider({
|
|
|
4319
4588
|
client.disconnect();
|
|
4320
4589
|
};
|
|
4321
4590
|
}, [serverUrl]);
|
|
4322
|
-
|
|
4591
|
+
useEffect10(() => {
|
|
4323
4592
|
const client = clientRef.current;
|
|
4324
4593
|
if (!client) return;
|
|
4325
4594
|
if (mcpHeadersProvider) {
|
|
4326
4595
|
client.setMcpHeadersProvider(mcpHeadersProvider);
|
|
4327
4596
|
}
|
|
4328
4597
|
}, [mcpHeadersProvider]);
|
|
4329
|
-
const lastRegisteredToolsRef =
|
|
4330
|
-
|
|
4598
|
+
const lastRegisteredToolsRef = useRef10("");
|
|
4599
|
+
useEffect10(() => {
|
|
4331
4600
|
const client = clientRef.current;
|
|
4332
4601
|
if (!client || !client.isConnected() || !hasTools) return;
|
|
4333
4602
|
const toolKeys = Object.keys(aggregatedTools).sort().join(",");
|
|
@@ -4345,7 +4614,7 @@ function UseAIProvider({
|
|
|
4345
4614
|
console.error("Failed to register tools:", err);
|
|
4346
4615
|
}
|
|
4347
4616
|
}, [hasTools, aggregatedTools, connected]);
|
|
4348
|
-
const handleSendMessage =
|
|
4617
|
+
const handleSendMessage = useCallback10(async (message, attachments) => {
|
|
4349
4618
|
if (!clientRef.current) return;
|
|
4350
4619
|
setStreamingText("");
|
|
4351
4620
|
const activatedChatId = activatePendingChat();
|
|
@@ -4369,21 +4638,36 @@ function UseAIProvider({
|
|
|
4369
4638
|
});
|
|
4370
4639
|
}
|
|
4371
4640
|
persistedContent = persistedParts;
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
backend: fileUploadConfig?.backend,
|
|
4375
|
-
transformers: fileUploadConfig?.transformers
|
|
4376
|
-
});
|
|
4377
|
-
multimodalContent = [];
|
|
4378
|
-
if (message.trim()) {
|
|
4379
|
-
multimodalContent.push({ type: "text", text: message });
|
|
4641
|
+
if (activeChatId) {
|
|
4642
|
+
await saveUserMessage(activeChatId, persistedContent);
|
|
4380
4643
|
}
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4644
|
+
setLoading(true);
|
|
4645
|
+
try {
|
|
4646
|
+
const fileContent = await processAttachments(attachments, {
|
|
4647
|
+
getCurrentChat,
|
|
4648
|
+
backend: fileUploadConfig?.backend,
|
|
4649
|
+
transformers: fileUploadConfig?.transformers,
|
|
4650
|
+
onFileProgress: (_fileId, state) => {
|
|
4651
|
+
setFileProcessingState(state);
|
|
4652
|
+
}
|
|
4653
|
+
});
|
|
4654
|
+
multimodalContent = [];
|
|
4655
|
+
if (message.trim()) {
|
|
4656
|
+
multimodalContent.push({ type: "text", text: message });
|
|
4657
|
+
}
|
|
4658
|
+
multimodalContent.push(...fileContent);
|
|
4659
|
+
} catch (error) {
|
|
4660
|
+
setLoading(false);
|
|
4661
|
+
throw error;
|
|
4662
|
+
} finally {
|
|
4663
|
+
setFileProcessingState(null);
|
|
4664
|
+
}
|
|
4665
|
+
} else {
|
|
4666
|
+
if (activeChatId) {
|
|
4667
|
+
await saveUserMessage(activeChatId, persistedContent);
|
|
4668
|
+
}
|
|
4669
|
+
setLoading(true);
|
|
4385
4670
|
}
|
|
4386
|
-
setLoading(true);
|
|
4387
4671
|
await clientRef.current.sendPrompt(message, multimodalContent);
|
|
4388
4672
|
}, [activatePendingChat, currentChatId, saveUserMessage, fileUploadConfig, getCurrentChat]);
|
|
4389
4673
|
handleSendMessageRef.current = handleSendMessage;
|
|
@@ -4426,6 +4710,9 @@ function UseAIProvider({
|
|
|
4426
4710
|
}
|
|
4427
4711
|
};
|
|
4428
4712
|
const effectiveStreamingText = streamingChatIdRef.current === displayedChatId ? streamingText : "";
|
|
4713
|
+
const executingToolDisplay = executingTool ? {
|
|
4714
|
+
displayText: executingTool.title ?? executingToolFallbackRef.current ?? strings.toolExecution.fallbackMessages[0]
|
|
4715
|
+
} : null;
|
|
4429
4716
|
const chatUIContextValue = {
|
|
4430
4717
|
connected,
|
|
4431
4718
|
loading,
|
|
@@ -4434,6 +4721,7 @@ function UseAIProvider({
|
|
|
4434
4721
|
streamingText: effectiveStreamingText,
|
|
4435
4722
|
suggestions: aggregatedSuggestions,
|
|
4436
4723
|
fileUploadConfig,
|
|
4724
|
+
fileProcessing: fileProcessingState,
|
|
4437
4725
|
history: {
|
|
4438
4726
|
currentId: displayedChatId,
|
|
4439
4727
|
create: createNewChat,
|
|
@@ -4457,6 +4745,11 @@ function UseAIProvider({
|
|
|
4457
4745
|
ui: {
|
|
4458
4746
|
isOpen: isChatOpen,
|
|
4459
4747
|
setOpen: handleSetChatOpen
|
|
4748
|
+
},
|
|
4749
|
+
executingTool: executingToolDisplay,
|
|
4750
|
+
feedback: {
|
|
4751
|
+
enabled: feedback.enabled,
|
|
4752
|
+
submit: feedback.submitFeedback
|
|
4460
4753
|
}
|
|
4461
4754
|
};
|
|
4462
4755
|
const isUIDisabled = CustomButton === null || CustomChat === null;
|
|
@@ -4479,10 +4772,14 @@ function UseAIProvider({
|
|
|
4479
4772
|
selectedAgent,
|
|
4480
4773
|
onAgentChange: setAgent,
|
|
4481
4774
|
fileUploadConfig,
|
|
4775
|
+
fileProcessing: fileProcessingState,
|
|
4482
4776
|
commands,
|
|
4483
4777
|
onSaveCommand: saveCommand,
|
|
4484
4778
|
onRenameCommand: renameCommand,
|
|
4485
|
-
onDeleteCommand: deleteCommand
|
|
4779
|
+
onDeleteCommand: deleteCommand,
|
|
4780
|
+
executingTool: executingToolDisplay,
|
|
4781
|
+
feedbackEnabled: feedback.enabled,
|
|
4782
|
+
onFeedback: feedback.submitFeedback
|
|
4486
4783
|
};
|
|
4487
4784
|
const renderDefaultChat = () => {
|
|
4488
4785
|
if (isUIDisabled) return null;
|
|
@@ -4546,11 +4843,11 @@ function useAIContext() {
|
|
|
4546
4843
|
}
|
|
4547
4844
|
|
|
4548
4845
|
// src/hooks/useStableTools.ts
|
|
4549
|
-
import { useRef as
|
|
4846
|
+
import { useRef as useRef11 } from "react";
|
|
4550
4847
|
function useStableTools(tools) {
|
|
4551
|
-
const latestToolsRef =
|
|
4552
|
-
const stableToolsRef =
|
|
4553
|
-
const prevToolNamesRef =
|
|
4848
|
+
const latestToolsRef = useRef11({});
|
|
4849
|
+
const stableToolsRef = useRef11({});
|
|
4850
|
+
const prevToolNamesRef = useRef11("");
|
|
4554
4851
|
if (!tools) {
|
|
4555
4852
|
latestToolsRef.current = {};
|
|
4556
4853
|
return void 0;
|
|
@@ -4620,25 +4917,25 @@ function useAI(options = {}) {
|
|
|
4620
4917
|
const { connected, tools, client, prompts } = useAIContext();
|
|
4621
4918
|
const { register: registerTools, unregister: unregisterTools } = tools;
|
|
4622
4919
|
const { update: updatePrompt, registerWaiter, unregisterWaiter } = prompts;
|
|
4623
|
-
const [response, setResponse] =
|
|
4624
|
-
const [loading, setLoading] =
|
|
4625
|
-
const [error, setError] =
|
|
4626
|
-
const hookId =
|
|
4627
|
-
const toolsRef =
|
|
4628
|
-
const componentRef =
|
|
4629
|
-
const promptChangeResolvers =
|
|
4920
|
+
const [response, setResponse] = useState12(null);
|
|
4921
|
+
const [loading, setLoading] = useState12(false);
|
|
4922
|
+
const [error, setError] = useState12(null);
|
|
4923
|
+
const hookId = useRef12(`useAI-${Math.random().toString(36).substr(2, 9)}`);
|
|
4924
|
+
const toolsRef = useRef12({});
|
|
4925
|
+
const componentRef = useRef12(null);
|
|
4926
|
+
const promptChangeResolvers = useRef12([]);
|
|
4630
4927
|
const stableTools = useStableTools(options.tools);
|
|
4631
4928
|
const toolsKey = useMemo6(() => {
|
|
4632
4929
|
if (!options.tools) return "";
|
|
4633
4930
|
return Object.keys(options.tools).sort().join(",");
|
|
4634
4931
|
}, [options.tools]);
|
|
4635
4932
|
const memoizedSuggestions = useMemo6(() => options.suggestions, [options.suggestions]);
|
|
4636
|
-
|
|
4933
|
+
useEffect11(() => {
|
|
4637
4934
|
if (componentRef.current) {
|
|
4638
4935
|
componentRef.current.setAttribute("data-useai-context", "true");
|
|
4639
4936
|
}
|
|
4640
4937
|
}, []);
|
|
4641
|
-
const waitForPromptChange =
|
|
4938
|
+
const waitForPromptChange = useCallback11(() => {
|
|
4642
4939
|
return new Promise((resolve) => {
|
|
4643
4940
|
const timeoutMs = 100;
|
|
4644
4941
|
const timeoutId = setTimeout(() => {
|
|
@@ -4655,14 +4952,14 @@ function useAI(options = {}) {
|
|
|
4655
4952
|
promptChangeResolvers.current.push(resolveAndCleanup);
|
|
4656
4953
|
});
|
|
4657
4954
|
}, []);
|
|
4658
|
-
|
|
4955
|
+
useEffect11(() => {
|
|
4659
4956
|
if (!enabled || options.invisible) return;
|
|
4660
4957
|
registerWaiter(hookId.current, waitForPromptChange);
|
|
4661
4958
|
return () => {
|
|
4662
4959
|
unregisterWaiter(hookId.current);
|
|
4663
4960
|
};
|
|
4664
4961
|
}, [enabled, options.invisible, registerWaiter, unregisterWaiter, waitForPromptChange]);
|
|
4665
|
-
|
|
4962
|
+
useEffect11(() => {
|
|
4666
4963
|
if (!enabled) return;
|
|
4667
4964
|
updatePrompt(hookId.current, options.prompt, memoizedSuggestions);
|
|
4668
4965
|
if (promptChangeResolvers.current.length > 0) {
|
|
@@ -4670,15 +4967,15 @@ function useAI(options = {}) {
|
|
|
4670
4967
|
promptChangeResolvers.current = [];
|
|
4671
4968
|
}
|
|
4672
4969
|
}, [enabled, options.prompt, memoizedSuggestions, updatePrompt]);
|
|
4673
|
-
const updatePromptRef =
|
|
4970
|
+
const updatePromptRef = useRef12(updatePrompt);
|
|
4674
4971
|
updatePromptRef.current = updatePrompt;
|
|
4675
|
-
|
|
4972
|
+
useEffect11(() => {
|
|
4676
4973
|
const id = hookId.current;
|
|
4677
4974
|
return () => {
|
|
4678
4975
|
updatePromptRef.current(id, void 0, void 0);
|
|
4679
4976
|
};
|
|
4680
4977
|
}, []);
|
|
4681
|
-
|
|
4978
|
+
useEffect11(() => {
|
|
4682
4979
|
if (!enabled) return;
|
|
4683
4980
|
if (stableTools) {
|
|
4684
4981
|
const componentId = options.id || componentRef.current?.id;
|
|
@@ -4692,7 +4989,7 @@ function useAI(options = {}) {
|
|
|
4692
4989
|
}
|
|
4693
4990
|
};
|
|
4694
4991
|
}, [enabled, toolsKey, stableTools, options.id, options.invisible, registerTools, unregisterTools]);
|
|
4695
|
-
|
|
4992
|
+
useEffect11(() => {
|
|
4696
4993
|
if (!enabled || !client) return;
|
|
4697
4994
|
const unsubscribe = client.onEvent(hookId.current, (event) => {
|
|
4698
4995
|
handleAGUIEvent(event);
|
|
@@ -4701,7 +4998,7 @@ function useAI(options = {}) {
|
|
|
4701
4998
|
unsubscribe();
|
|
4702
4999
|
};
|
|
4703
5000
|
}, [enabled, client]);
|
|
4704
|
-
const handleAGUIEvent =
|
|
5001
|
+
const handleAGUIEvent = useCallback11(async (event) => {
|
|
4705
5002
|
switch (event.type) {
|
|
4706
5003
|
case EventType.TEXT_MESSAGE_END: {
|
|
4707
5004
|
const content = client?.currentMessageContent;
|
|
@@ -4721,7 +5018,7 @@ function useAI(options = {}) {
|
|
|
4721
5018
|
}
|
|
4722
5019
|
}
|
|
4723
5020
|
}, [client, options.onError]);
|
|
4724
|
-
const generate =
|
|
5021
|
+
const generate = useCallback11(async (prompt) => {
|
|
4725
5022
|
if (!enabled) {
|
|
4726
5023
|
const error2 = new Error("AI features are disabled");
|
|
4727
5024
|
setError(error2);
|
|
@@ -4757,17 +5054,17 @@ function useAI(options = {}) {
|
|
|
4757
5054
|
}
|
|
4758
5055
|
|
|
4759
5056
|
// src/useAIWorkflow.ts
|
|
4760
|
-
import { useState as
|
|
5057
|
+
import { useState as useState13, useCallback as useCallback12, useRef as useRef13, useEffect as useEffect12 } from "react";
|
|
4761
5058
|
import { EventType as EventType3 } from "@meetsmore-oss/use-ai-core";
|
|
4762
5059
|
import { v4 as uuidv43 } from "uuid";
|
|
4763
5060
|
function useAIWorkflow(runner, workflowId) {
|
|
4764
5061
|
const { connected, client } = useAIContext();
|
|
4765
|
-
const [status, setStatus] =
|
|
4766
|
-
const [text, setText] =
|
|
4767
|
-
const [error, setError] =
|
|
4768
|
-
const currentWorkflowRef =
|
|
4769
|
-
const eventListenerIdRef =
|
|
4770
|
-
const handleWorkflowEvent =
|
|
5062
|
+
const [status, setStatus] = useState13("idle");
|
|
5063
|
+
const [text, setText] = useState13(null);
|
|
5064
|
+
const [error, setError] = useState13(null);
|
|
5065
|
+
const currentWorkflowRef = useRef13(null);
|
|
5066
|
+
const eventListenerIdRef = useRef13(`useAIWorkflow-${Math.random().toString(36).substr(2, 9)}`);
|
|
5067
|
+
const handleWorkflowEvent = useCallback12(async (event) => {
|
|
4771
5068
|
const currentWorkflow = currentWorkflowRef.current;
|
|
4772
5069
|
if (!currentWorkflow) return;
|
|
4773
5070
|
if (event.type === EventType3.RUN_STARTED) {
|
|
@@ -4852,14 +5149,14 @@ function useAIWorkflow(runner, workflowId) {
|
|
|
4852
5149
|
}
|
|
4853
5150
|
}
|
|
4854
5151
|
}, [client]);
|
|
4855
|
-
|
|
5152
|
+
useEffect12(() => {
|
|
4856
5153
|
if (!client) return;
|
|
4857
5154
|
const unsubscribe = client.onEvent(eventListenerIdRef.current, handleWorkflowEvent);
|
|
4858
5155
|
return () => {
|
|
4859
5156
|
unsubscribe();
|
|
4860
5157
|
};
|
|
4861
5158
|
}, [client, handleWorkflowEvent]);
|
|
4862
|
-
const trigger =
|
|
5159
|
+
const trigger = useCallback12(async (options) => {
|
|
4863
5160
|
if (!client?.isConnected()) {
|
|
4864
5161
|
const err = new Error("Not connected to server");
|
|
4865
5162
|
setError(err);
|
|
@@ -4948,6 +5245,7 @@ export {
|
|
|
4948
5245
|
useChatManagement,
|
|
4949
5246
|
useCommandManagement,
|
|
4950
5247
|
useDropdownState,
|
|
5248
|
+
useFeedback,
|
|
4951
5249
|
useFileUpload,
|
|
4952
5250
|
usePromptState,
|
|
4953
5251
|
useSlashCommands,
|