@meetsmore-oss/use-ai-client 1.5.0 → 1.6.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 +794 -388
- package/dist/bundled.js.map +1 -1
- package/dist/index.d.ts +63 -9
- package/dist/index.js +794 -389
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
} from "./chunk-STF3H6F5.js";
|
|
5
5
|
|
|
6
6
|
// src/useAI.ts
|
|
7
|
-
import { useState as
|
|
7
|
+
import { useState as useState14, useEffect as useEffect11, useRef as useRef13, useCallback as useCallback12, 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 useState13, useEffect as useEffect10, useCallback as useCallback11, useRef as useRef11 } from "react";
|
|
11
11
|
|
|
12
12
|
// src/types.ts
|
|
13
|
-
import { EventType, ErrorCode } from "@meetsmore-oss/use-ai-core";
|
|
13
|
+
import { EventType, ErrorCode, TOOL_APPROVAL_REQUEST } from "@meetsmore-oss/use-ai-core";
|
|
14
14
|
|
|
15
15
|
// src/theme/strings.ts
|
|
16
16
|
import { createContext, useContext } from "react";
|
|
@@ -109,6 +109,25 @@ var defaultStrings = {
|
|
|
109
109
|
toolExecution: {
|
|
110
110
|
/** Fallback messages when no tool title is provided (one randomly selected) */
|
|
111
111
|
fallbackMessages: ["Working", "Processing", "Thinking"]
|
|
112
|
+
},
|
|
113
|
+
// Tool approval dialog
|
|
114
|
+
toolApproval: {
|
|
115
|
+
/** Title shown in the approval dialog */
|
|
116
|
+
title: "Confirmation Required",
|
|
117
|
+
/** Message shown in the approval dialog. {toolName} is replaced with tool name. */
|
|
118
|
+
message: '"{toolName}" is waiting for your approval.',
|
|
119
|
+
/** Message shown when multiple tools are awaiting approval. {count} is replaced with number. */
|
|
120
|
+
batchMessage: "{count} actions are waiting for your approval.",
|
|
121
|
+
/** Label for approve button */
|
|
122
|
+
approve: "Allow",
|
|
123
|
+
/** Label for approve all button (batch mode) */
|
|
124
|
+
approveAll: "Allow All",
|
|
125
|
+
/** Label for reject button */
|
|
126
|
+
reject: "Deny",
|
|
127
|
+
/** Label for reject all button (batch mode) */
|
|
128
|
+
rejectAll: "Deny All",
|
|
129
|
+
/** Label for showing tool arguments */
|
|
130
|
+
showDetails: "Show details"
|
|
112
131
|
}
|
|
113
132
|
};
|
|
114
133
|
var StringsContext = createContext(defaultStrings);
|
|
@@ -255,7 +274,7 @@ function UseAIFloatingButton({
|
|
|
255
274
|
}
|
|
256
275
|
|
|
257
276
|
// src/components/UseAIChatPanel.tsx
|
|
258
|
-
import { useState as
|
|
277
|
+
import { useState as useState5, useRef as useRef4, useEffect as useEffect4 } from "react";
|
|
259
278
|
|
|
260
279
|
// src/components/MarkdownContent.tsx
|
|
261
280
|
import ReactMarkdown from "react-markdown";
|
|
@@ -1177,30 +1196,30 @@ function matchesMimeType(mimeType, pattern) {
|
|
|
1177
1196
|
const regex = new RegExp(`^${regexPattern}$`);
|
|
1178
1197
|
return regex.test(mimeType);
|
|
1179
1198
|
}
|
|
1180
|
-
function
|
|
1199
|
+
function findTransformerPattern(mimeType, transformers) {
|
|
1181
1200
|
if (!transformers) {
|
|
1182
1201
|
return void 0;
|
|
1183
1202
|
}
|
|
1184
|
-
let
|
|
1203
|
+
let bestKey;
|
|
1185
1204
|
let bestIsExact = false;
|
|
1186
1205
|
let bestLength = -1;
|
|
1187
|
-
for (const
|
|
1206
|
+
for (const pattern of Object.keys(transformers)) {
|
|
1188
1207
|
if (!matchesMimeType(mimeType, pattern)) {
|
|
1189
1208
|
continue;
|
|
1190
1209
|
}
|
|
1191
1210
|
const isExact = !pattern.includes("*");
|
|
1192
1211
|
if (isExact && !bestIsExact) {
|
|
1193
|
-
|
|
1212
|
+
bestKey = pattern;
|
|
1194
1213
|
bestIsExact = true;
|
|
1195
1214
|
bestLength = pattern.length;
|
|
1196
1215
|
continue;
|
|
1197
1216
|
}
|
|
1198
1217
|
if (isExact === bestIsExact && pattern.length > bestLength) {
|
|
1199
|
-
|
|
1218
|
+
bestKey = pattern;
|
|
1200
1219
|
bestLength = pattern.length;
|
|
1201
1220
|
}
|
|
1202
1221
|
}
|
|
1203
|
-
return
|
|
1222
|
+
return bestKey;
|
|
1204
1223
|
}
|
|
1205
1224
|
|
|
1206
1225
|
// src/fileUpload/EmbedFileUploadBackend.ts
|
|
@@ -1231,75 +1250,104 @@ var EmbedFileUploadBackend = class {
|
|
|
1231
1250
|
};
|
|
1232
1251
|
|
|
1233
1252
|
// src/fileUpload/processAttachments.ts
|
|
1253
|
+
function groupBy(items, keyFn) {
|
|
1254
|
+
const map = /* @__PURE__ */ new Map();
|
|
1255
|
+
for (const item of items) {
|
|
1256
|
+
const key = keyFn(item);
|
|
1257
|
+
const list = map.get(key);
|
|
1258
|
+
list ? list.push(item) : map.set(key, [item]);
|
|
1259
|
+
}
|
|
1260
|
+
return map;
|
|
1261
|
+
}
|
|
1234
1262
|
var transformationCache = /* @__PURE__ */ new Map();
|
|
1235
1263
|
function getFileCacheKey(file) {
|
|
1236
1264
|
return `${file.name}:${file.size}:${file.lastModified}`;
|
|
1237
1265
|
}
|
|
1238
|
-
async function
|
|
1239
|
-
const
|
|
1266
|
+
async function hashGroupCacheKey(files) {
|
|
1267
|
+
const raw = files.map(getFileCacheKey).join(", ");
|
|
1268
|
+
const data = new TextEncoder().encode(raw);
|
|
1269
|
+
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
1270
|
+
return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1271
|
+
}
|
|
1272
|
+
async function getTransformedContent(files, transformer, context, onProgress) {
|
|
1273
|
+
if (files.length === 0) {
|
|
1274
|
+
return [];
|
|
1275
|
+
}
|
|
1276
|
+
const cacheKey = await hashGroupCacheKey(files);
|
|
1240
1277
|
const cached = transformationCache.get(cacheKey);
|
|
1241
|
-
if (cached
|
|
1278
|
+
if (cached) {
|
|
1242
1279
|
return cached;
|
|
1243
1280
|
}
|
|
1244
|
-
const
|
|
1245
|
-
transformationCache.set(cacheKey,
|
|
1246
|
-
return
|
|
1281
|
+
const results = await transformer.transform(files, context, onProgress);
|
|
1282
|
+
transformationCache.set(cacheKey, results);
|
|
1283
|
+
return results;
|
|
1284
|
+
}
|
|
1285
|
+
async function toContentPart(attachment, backend) {
|
|
1286
|
+
if (attachment.transformedContent !== void 0) {
|
|
1287
|
+
return {
|
|
1288
|
+
type: "transformed_file",
|
|
1289
|
+
text: attachment.transformedContent,
|
|
1290
|
+
originalFile: {
|
|
1291
|
+
name: attachment.file.name,
|
|
1292
|
+
mimeType: attachment.file.type,
|
|
1293
|
+
size: attachment.file.size
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
const url = await backend.prepareForSend(attachment.file);
|
|
1298
|
+
if (attachment.file.type.startsWith("image/")) {
|
|
1299
|
+
return { type: "image", url };
|
|
1300
|
+
}
|
|
1301
|
+
return {
|
|
1302
|
+
type: "file",
|
|
1303
|
+
url,
|
|
1304
|
+
mimeType: attachment.file.type,
|
|
1305
|
+
name: attachment.file.name
|
|
1306
|
+
};
|
|
1247
1307
|
}
|
|
1248
1308
|
async function processAttachments(attachments, config) {
|
|
1249
1309
|
const { getCurrentChat, backend = new EmbedFileUploadBackend(), transformers = {}, onFileProgress } = config;
|
|
1250
1310
|
const contentParts = [];
|
|
1251
1311
|
const chat = await getCurrentChat();
|
|
1252
1312
|
const context = { chat };
|
|
1253
|
-
|
|
1313
|
+
const groups = groupBy(
|
|
1314
|
+
attachments,
|
|
1315
|
+
(attachment) => attachment.transformedContent !== void 0 ? null : findTransformerPattern(attachment.file.type, transformers) ?? null
|
|
1316
|
+
);
|
|
1317
|
+
for (const [key, groupAttachments] of groups) {
|
|
1318
|
+
if (key === null) {
|
|
1319
|
+
const parts = await Promise.all(
|
|
1320
|
+
groupAttachments.map((a) => toContentPart(a, backend))
|
|
1321
|
+
);
|
|
1322
|
+
contentParts.push(...parts);
|
|
1323
|
+
continue;
|
|
1324
|
+
}
|
|
1325
|
+
const transformer = transformers[key];
|
|
1326
|
+
const files = groupAttachments.map((a) => a.file);
|
|
1327
|
+
groupAttachments.forEach((a) => onFileProgress?.(a.id, { status: "processing" }));
|
|
1254
1328
|
try {
|
|
1255
|
-
|
|
1329
|
+
const results = await getTransformedContent(
|
|
1330
|
+
files,
|
|
1331
|
+
transformer,
|
|
1332
|
+
context,
|
|
1333
|
+
(progress) => {
|
|
1334
|
+
groupAttachments.forEach((a) => onFileProgress?.(a.id, { status: "processing", progress }));
|
|
1335
|
+
}
|
|
1336
|
+
);
|
|
1337
|
+
results.forEach((text, i) => {
|
|
1256
1338
|
contentParts.push({
|
|
1257
1339
|
type: "transformed_file",
|
|
1258
|
-
text
|
|
1340
|
+
text,
|
|
1259
1341
|
originalFile: {
|
|
1260
|
-
name:
|
|
1261
|
-
mimeType:
|
|
1262
|
-
size:
|
|
1342
|
+
name: files[i].name,
|
|
1343
|
+
mimeType: files[i].type,
|
|
1344
|
+
size: files[i].size
|
|
1263
1345
|
}
|
|
1264
1346
|
});
|
|
1265
|
-
|
|
1266
|
-
}
|
|
1267
|
-
const transformer = findTransformer(attachment.file.type, transformers);
|
|
1268
|
-
if (transformer) {
|
|
1269
|
-
onFileProgress?.(attachment.id, { status: "processing" });
|
|
1270
|
-
const transformedText = await getTransformedContent(
|
|
1271
|
-
attachment.file,
|
|
1272
|
-
transformer,
|
|
1273
|
-
context,
|
|
1274
|
-
(progress) => {
|
|
1275
|
-
onFileProgress?.(attachment.id, { status: "processing", progress });
|
|
1276
|
-
}
|
|
1277
|
-
);
|
|
1278
|
-
contentParts.push({
|
|
1279
|
-
type: "transformed_file",
|
|
1280
|
-
text: transformedText,
|
|
1281
|
-
originalFile: {
|
|
1282
|
-
name: attachment.file.name,
|
|
1283
|
-
mimeType: attachment.file.type,
|
|
1284
|
-
size: attachment.file.size
|
|
1285
|
-
}
|
|
1286
|
-
});
|
|
1287
|
-
onFileProgress?.(attachment.id, { status: "done" });
|
|
1288
|
-
} else {
|
|
1289
|
-
const url = await backend.prepareForSend(attachment.file);
|
|
1290
|
-
if (attachment.file.type.startsWith("image/")) {
|
|
1291
|
-
contentParts.push({ type: "image", url });
|
|
1292
|
-
} else {
|
|
1293
|
-
contentParts.push({
|
|
1294
|
-
type: "file",
|
|
1295
|
-
url,
|
|
1296
|
-
mimeType: attachment.file.type,
|
|
1297
|
-
name: attachment.file.name
|
|
1298
|
-
});
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1347
|
+
onFileProgress?.(groupAttachments[i].id, { status: "done" });
|
|
1348
|
+
});
|
|
1301
1349
|
} catch (error) {
|
|
1302
|
-
onFileProgress?.(
|
|
1350
|
+
groupAttachments.forEach((a) => onFileProgress?.(a.id, { status: "error" }));
|
|
1303
1351
|
throw error;
|
|
1304
1352
|
}
|
|
1305
1353
|
}
|
|
@@ -1370,12 +1418,14 @@ function useFileUpload({
|
|
|
1370
1418
|
setFileError(null);
|
|
1371
1419
|
setProcessingState(/* @__PURE__ */ new Map());
|
|
1372
1420
|
}, [resetDependency]);
|
|
1373
|
-
const runTransformer = useCallback2(async (attachmentId, file,
|
|
1421
|
+
const runTransformer = useCallback2(async (attachmentId, file, transformerKey) => {
|
|
1422
|
+
const transformer = transformers?.[transformerKey];
|
|
1423
|
+
if (!transformer) return;
|
|
1374
1424
|
setProcessingState((prev) => new Map(prev).set(attachmentId, { status: "processing" }));
|
|
1375
1425
|
try {
|
|
1376
1426
|
const chat = await getCurrentChat();
|
|
1377
1427
|
const context = { chat };
|
|
1378
|
-
const transformedContent = await getTransformedContent(file, transformer, context, (progress) => {
|
|
1428
|
+
const [transformedContent] = await getTransformedContent([file], transformer, context, (progress) => {
|
|
1379
1429
|
setProcessingState((prev) => new Map(prev).set(attachmentId, {
|
|
1380
1430
|
status: "processing",
|
|
1381
1431
|
progress
|
|
@@ -1389,7 +1439,7 @@ function useFileUpload({
|
|
|
1389
1439
|
console.error(`[useFileUpload] Transformation failed for ${file.name}:`, error);
|
|
1390
1440
|
setProcessingState((prev) => new Map(prev).set(attachmentId, { status: "error" }));
|
|
1391
1441
|
}
|
|
1392
|
-
}, [getCurrentChat]);
|
|
1442
|
+
}, [getCurrentChat, transformers]);
|
|
1393
1443
|
const handleFiles = useCallback2(async (files) => {
|
|
1394
1444
|
const fileArray = Array.from(files);
|
|
1395
1445
|
for (const file of fileArray) {
|
|
@@ -1411,9 +1461,9 @@ function useFileUpload({
|
|
|
1411
1461
|
preview
|
|
1412
1462
|
};
|
|
1413
1463
|
setAttachments((prev) => [...prev, attachment]);
|
|
1414
|
-
const
|
|
1415
|
-
if (
|
|
1416
|
-
runTransformer(attachmentId, file,
|
|
1464
|
+
const transformerKey = findTransformerPattern(file.type, transformers);
|
|
1465
|
+
if (transformerKey) {
|
|
1466
|
+
runTransformer(attachmentId, file, transformerKey);
|
|
1417
1467
|
}
|
|
1418
1468
|
}
|
|
1419
1469
|
}, [maxFileSize, acceptedTypes, strings, transformers, runTransformer]);
|
|
@@ -1574,8 +1624,210 @@ function useDropdownState(options = {}) {
|
|
|
1574
1624
|
};
|
|
1575
1625
|
}
|
|
1576
1626
|
|
|
1627
|
+
// src/components/ToolApprovalDialog.tsx
|
|
1628
|
+
import { useState as useState4 } from "react";
|
|
1629
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1630
|
+
function ToolApprovalDialog({
|
|
1631
|
+
toolCallName,
|
|
1632
|
+
toolCallArgs,
|
|
1633
|
+
annotations,
|
|
1634
|
+
toolCount = 1,
|
|
1635
|
+
pendingTools = [],
|
|
1636
|
+
onApprove,
|
|
1637
|
+
onReject,
|
|
1638
|
+
theme,
|
|
1639
|
+
strings
|
|
1640
|
+
}) {
|
|
1641
|
+
const [showDetails, setShowDetails] = useState4(false);
|
|
1642
|
+
const displayName = annotations?.title || toolCallName;
|
|
1643
|
+
const isBatch = toolCount > 1;
|
|
1644
|
+
const message = isBatch ? strings.toolApproval.batchMessage?.replace("{count}", String(toolCount)) ?? `${toolCount} actions are waiting for your approval` : strings.toolApproval.message.replace("{toolName}", displayName);
|
|
1645
|
+
const getToolDisplayName = (tool) => tool.annotations?.title || tool.toolCallName;
|
|
1646
|
+
return /* @__PURE__ */ jsxs7(
|
|
1647
|
+
"div",
|
|
1648
|
+
{
|
|
1649
|
+
"data-testid": "tool-approval-dialog",
|
|
1650
|
+
style: {
|
|
1651
|
+
border: `2px solid ${theme.primaryColor}`,
|
|
1652
|
+
borderRadius: "12px",
|
|
1653
|
+
background: theme.backgroundColor,
|
|
1654
|
+
overflow: "hidden"
|
|
1655
|
+
},
|
|
1656
|
+
children: [
|
|
1657
|
+
/* @__PURE__ */ jsxs7(
|
|
1658
|
+
"div",
|
|
1659
|
+
{
|
|
1660
|
+
style: {
|
|
1661
|
+
padding: "12px 14px",
|
|
1662
|
+
borderBottom: `1px solid ${theme.borderColor}`,
|
|
1663
|
+
background: theme.assistantMessageBackground
|
|
1664
|
+
},
|
|
1665
|
+
children: [
|
|
1666
|
+
/* @__PURE__ */ jsxs7("div", { style: {
|
|
1667
|
+
display: "flex",
|
|
1668
|
+
alignItems: "center",
|
|
1669
|
+
gap: "8px",
|
|
1670
|
+
marginBottom: "4px"
|
|
1671
|
+
}, children: [
|
|
1672
|
+
/* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: theme.primaryColor, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1673
|
+
/* @__PURE__ */ jsx10("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
|
|
1674
|
+
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
|
|
1675
|
+
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
|
|
1676
|
+
] }),
|
|
1677
|
+
/* @__PURE__ */ jsx10("span", { style: {
|
|
1678
|
+
fontWeight: 600,
|
|
1679
|
+
fontSize: "14px",
|
|
1680
|
+
color: theme.textColor
|
|
1681
|
+
}, children: strings.toolApproval.title })
|
|
1682
|
+
] }),
|
|
1683
|
+
/* @__PURE__ */ jsx10("div", { style: {
|
|
1684
|
+
fontSize: "13px",
|
|
1685
|
+
color: theme.secondaryTextColor,
|
|
1686
|
+
paddingLeft: "24px"
|
|
1687
|
+
}, children: message })
|
|
1688
|
+
]
|
|
1689
|
+
}
|
|
1690
|
+
),
|
|
1691
|
+
/* @__PURE__ */ jsxs7("div", { style: { padding: "8px 14px" }, children: [
|
|
1692
|
+
/* @__PURE__ */ jsxs7(
|
|
1693
|
+
"button",
|
|
1694
|
+
{
|
|
1695
|
+
onClick: () => setShowDetails(!showDetails),
|
|
1696
|
+
style: {
|
|
1697
|
+
background: "transparent",
|
|
1698
|
+
border: "none",
|
|
1699
|
+
padding: 0,
|
|
1700
|
+
cursor: "pointer",
|
|
1701
|
+
fontSize: "12px",
|
|
1702
|
+
color: theme.secondaryTextColor,
|
|
1703
|
+
display: "flex",
|
|
1704
|
+
alignItems: "center",
|
|
1705
|
+
gap: "4px"
|
|
1706
|
+
},
|
|
1707
|
+
children: [
|
|
1708
|
+
/* @__PURE__ */ jsx10(
|
|
1709
|
+
"svg",
|
|
1710
|
+
{
|
|
1711
|
+
width: "10",
|
|
1712
|
+
height: "10",
|
|
1713
|
+
viewBox: "0 0 12 12",
|
|
1714
|
+
fill: "none",
|
|
1715
|
+
style: {
|
|
1716
|
+
transform: showDetails ? "rotate(90deg)" : "rotate(0deg)",
|
|
1717
|
+
transition: "transform 0.15s"
|
|
1718
|
+
},
|
|
1719
|
+
children: /* @__PURE__ */ jsx10("path", { d: "M4 2L8 6L4 10", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
1720
|
+
}
|
|
1721
|
+
),
|
|
1722
|
+
strings.toolApproval.showDetails
|
|
1723
|
+
]
|
|
1724
|
+
}
|
|
1725
|
+
),
|
|
1726
|
+
showDetails && /* @__PURE__ */ jsx10("div", { style: {
|
|
1727
|
+
marginTop: "6px",
|
|
1728
|
+
display: "flex",
|
|
1729
|
+
flexDirection: "column",
|
|
1730
|
+
gap: "8px",
|
|
1731
|
+
maxHeight: "200px",
|
|
1732
|
+
overflow: "auto"
|
|
1733
|
+
}, children: (pendingTools.length > 0 ? pendingTools : [{
|
|
1734
|
+
toolCallId: "single",
|
|
1735
|
+
toolCallName,
|
|
1736
|
+
toolCallArgs,
|
|
1737
|
+
annotations
|
|
1738
|
+
}]).map((tool, index) => /* @__PURE__ */ jsxs7(
|
|
1739
|
+
"div",
|
|
1740
|
+
{
|
|
1741
|
+
style: {
|
|
1742
|
+
padding: "8px",
|
|
1743
|
+
background: theme.hoverBackground,
|
|
1744
|
+
borderRadius: "6px"
|
|
1745
|
+
},
|
|
1746
|
+
children: [
|
|
1747
|
+
/* @__PURE__ */ jsx10("div", { style: {
|
|
1748
|
+
fontSize: "12px",
|
|
1749
|
+
fontWeight: 500,
|
|
1750
|
+
color: theme.textColor,
|
|
1751
|
+
marginBottom: "4px"
|
|
1752
|
+
}, children: getToolDisplayName(tool) }),
|
|
1753
|
+
/* @__PURE__ */ jsx10("pre", { style: {
|
|
1754
|
+
margin: 0,
|
|
1755
|
+
fontSize: "11px",
|
|
1756
|
+
overflow: "auto",
|
|
1757
|
+
color: theme.secondaryTextColor,
|
|
1758
|
+
whiteSpace: "pre-wrap",
|
|
1759
|
+
wordBreak: "break-word"
|
|
1760
|
+
}, children: JSON.stringify(tool.toolCallArgs, null, 2) })
|
|
1761
|
+
]
|
|
1762
|
+
},
|
|
1763
|
+
tool.toolCallId
|
|
1764
|
+
)) })
|
|
1765
|
+
] }),
|
|
1766
|
+
/* @__PURE__ */ jsxs7("div", { style: {
|
|
1767
|
+
display: "flex",
|
|
1768
|
+
gap: "8px",
|
|
1769
|
+
padding: "8px 14px 12px"
|
|
1770
|
+
}, children: [
|
|
1771
|
+
/* @__PURE__ */ jsx10(
|
|
1772
|
+
"button",
|
|
1773
|
+
{
|
|
1774
|
+
"data-testid": "approve-tool-button",
|
|
1775
|
+
onClick: onApprove,
|
|
1776
|
+
style: {
|
|
1777
|
+
flex: 1,
|
|
1778
|
+
padding: "8px 16px",
|
|
1779
|
+
borderRadius: "8px",
|
|
1780
|
+
border: "none",
|
|
1781
|
+
background: theme.primaryGradient,
|
|
1782
|
+
color: "white",
|
|
1783
|
+
fontWeight: 500,
|
|
1784
|
+
cursor: "pointer",
|
|
1785
|
+
fontSize: "13px",
|
|
1786
|
+
transition: "opacity 0.15s"
|
|
1787
|
+
},
|
|
1788
|
+
onMouseEnter: (e) => {
|
|
1789
|
+
e.currentTarget.style.opacity = "0.9";
|
|
1790
|
+
},
|
|
1791
|
+
onMouseLeave: (e) => {
|
|
1792
|
+
e.currentTarget.style.opacity = "1";
|
|
1793
|
+
},
|
|
1794
|
+
children: isBatch ? strings.toolApproval.approveAll ?? "Approve All" : strings.toolApproval.approve
|
|
1795
|
+
}
|
|
1796
|
+
),
|
|
1797
|
+
/* @__PURE__ */ jsx10(
|
|
1798
|
+
"button",
|
|
1799
|
+
{
|
|
1800
|
+
"data-testid": "reject-tool-button",
|
|
1801
|
+
onClick: () => onReject(),
|
|
1802
|
+
style: {
|
|
1803
|
+
flex: 1,
|
|
1804
|
+
padding: "8px 16px",
|
|
1805
|
+
borderRadius: "8px",
|
|
1806
|
+
border: `1px solid ${theme.borderColor}`,
|
|
1807
|
+
background: "transparent",
|
|
1808
|
+
color: theme.textColor,
|
|
1809
|
+
fontWeight: 500,
|
|
1810
|
+
cursor: "pointer",
|
|
1811
|
+
fontSize: "13px",
|
|
1812
|
+
transition: "all 0.15s"
|
|
1813
|
+
},
|
|
1814
|
+
onMouseEnter: (e) => {
|
|
1815
|
+
e.currentTarget.style.background = theme.hoverBackground;
|
|
1816
|
+
},
|
|
1817
|
+
onMouseLeave: (e) => {
|
|
1818
|
+
e.currentTarget.style.background = "transparent";
|
|
1819
|
+
},
|
|
1820
|
+
children: isBatch ? strings.toolApproval.rejectAll ?? "Reject All" : strings.toolApproval.reject
|
|
1821
|
+
}
|
|
1822
|
+
)
|
|
1823
|
+
] })
|
|
1824
|
+
]
|
|
1825
|
+
}
|
|
1826
|
+
);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1577
1829
|
// src/components/UseAIChatPanel.tsx
|
|
1578
|
-
import { Fragment, jsx as
|
|
1830
|
+
import { Fragment, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1579
1831
|
function FeedbackButton({ type, isSelected, onClick, selectedColor, unselectedColor }) {
|
|
1580
1832
|
const buttonRef = useRef4(null);
|
|
1581
1833
|
const handleClick = () => {
|
|
@@ -1591,7 +1843,7 @@ function FeedbackButton({ type, isSelected, onClick, selectedColor, unselectedCo
|
|
|
1591
1843
|
};
|
|
1592
1844
|
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
1845
|
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__ */
|
|
1846
|
+
return /* @__PURE__ */ jsx11(
|
|
1595
1847
|
"button",
|
|
1596
1848
|
{
|
|
1597
1849
|
ref: buttonRef,
|
|
@@ -1624,7 +1876,7 @@ function FeedbackButton({ type, isSelected, onClick, selectedColor, unselectedCo
|
|
|
1624
1876
|
e.currentTarget.style.color = unselectedColor;
|
|
1625
1877
|
}
|
|
1626
1878
|
},
|
|
1627
|
-
children: /* @__PURE__ */
|
|
1879
|
+
children: /* @__PURE__ */ jsx11(
|
|
1628
1880
|
"svg",
|
|
1629
1881
|
{
|
|
1630
1882
|
width: "14",
|
|
@@ -1635,7 +1887,7 @@ function FeedbackButton({ type, isSelected, onClick, selectedColor, unselectedCo
|
|
|
1635
1887
|
strokeWidth: "2",
|
|
1636
1888
|
strokeLinecap: "round",
|
|
1637
1889
|
strokeLinejoin: "round",
|
|
1638
|
-
children: /* @__PURE__ */
|
|
1890
|
+
children: /* @__PURE__ */ jsx11("path", { d: type === "upvote" ? thumbsUpPath : thumbsDownPath })
|
|
1639
1891
|
}
|
|
1640
1892
|
)
|
|
1641
1893
|
}
|
|
@@ -1676,18 +1928,21 @@ function UseAIChatPanel({
|
|
|
1676
1928
|
closeButton,
|
|
1677
1929
|
executingTool,
|
|
1678
1930
|
feedbackEnabled,
|
|
1679
|
-
onFeedback
|
|
1931
|
+
onFeedback,
|
|
1932
|
+
pendingApprovals = [],
|
|
1933
|
+
onApproveToolCall,
|
|
1934
|
+
onRejectToolCall
|
|
1680
1935
|
}) {
|
|
1681
1936
|
const strings = useStrings();
|
|
1682
1937
|
const theme = useTheme();
|
|
1683
|
-
const [input, setInput] =
|
|
1938
|
+
const [input, setInput] = useState5("");
|
|
1684
1939
|
const chatHistoryDropdown = useDropdownState();
|
|
1685
1940
|
const agentDropdown = useDropdownState();
|
|
1686
|
-
const [chatHistory, setChatHistory] =
|
|
1941
|
+
const [chatHistory, setChatHistory] = useState5([]);
|
|
1687
1942
|
const messagesEndRef = useRef4(null);
|
|
1688
|
-
const [displayedSuggestions, setDisplayedSuggestions] =
|
|
1943
|
+
const [displayedSuggestions, setDisplayedSuggestions] = useState5([]);
|
|
1689
1944
|
const textareaRef = useRef4(null);
|
|
1690
|
-
const [hoveredMessageId, setHoveredMessageId] =
|
|
1945
|
+
const [hoveredMessageId, setHoveredMessageId] = useState5(null);
|
|
1691
1946
|
const {
|
|
1692
1947
|
attachments,
|
|
1693
1948
|
fileError,
|
|
@@ -1774,7 +2029,7 @@ function UseAIChatPanel({
|
|
|
1774
2029
|
chatHistoryDropdown.close();
|
|
1775
2030
|
}
|
|
1776
2031
|
};
|
|
1777
|
-
return /* @__PURE__ */
|
|
2032
|
+
return /* @__PURE__ */ jsxs8(
|
|
1778
2033
|
"div",
|
|
1779
2034
|
{
|
|
1780
2035
|
onClick: () => {
|
|
@@ -1792,7 +2047,7 @@ function UseAIChatPanel({
|
|
|
1792
2047
|
},
|
|
1793
2048
|
children: [
|
|
1794
2049
|
DropZoneOverlay,
|
|
1795
|
-
/* @__PURE__ */
|
|
2050
|
+
/* @__PURE__ */ jsxs8(
|
|
1796
2051
|
"div",
|
|
1797
2052
|
{
|
|
1798
2053
|
style: {
|
|
@@ -1805,7 +2060,7 @@ function UseAIChatPanel({
|
|
|
1805
2060
|
gap: "12px"
|
|
1806
2061
|
},
|
|
1807
2062
|
children: [
|
|
1808
|
-
/* @__PURE__ */
|
|
2063
|
+
/* @__PURE__ */ jsx11("div", { style: { flex: 1, minWidth: 0, position: "relative" }, children: onListChats ? /* @__PURE__ */ jsxs8(
|
|
1809
2064
|
"button",
|
|
1810
2065
|
{
|
|
1811
2066
|
"data-testid": "chat-history-dropdown-button",
|
|
@@ -1838,7 +2093,7 @@ function UseAIChatPanel({
|
|
|
1838
2093
|
e.currentTarget.style.background = "transparent";
|
|
1839
2094
|
},
|
|
1840
2095
|
children: [
|
|
1841
|
-
/* @__PURE__ */
|
|
2096
|
+
/* @__PURE__ */ jsx11("span", { style: {
|
|
1842
2097
|
overflow: "hidden",
|
|
1843
2098
|
textOverflow: "ellipsis",
|
|
1844
2099
|
whiteSpace: "nowrap",
|
|
@@ -1855,13 +2110,13 @@ function UseAIChatPanel({
|
|
|
1855
2110
|
}
|
|
1856
2111
|
return strings.header.newChat;
|
|
1857
2112
|
})() }),
|
|
1858
|
-
/* @__PURE__ */
|
|
2113
|
+
/* @__PURE__ */ jsx11("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx11("path", { d: "M3 4.5L6 7.5L9 4.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1859
2114
|
]
|
|
1860
2115
|
}
|
|
1861
|
-
) : /* @__PURE__ */
|
|
1862
|
-
/* @__PURE__ */
|
|
1863
|
-
availableAgents && availableAgents.length > 1 && onAgentChange && /* @__PURE__ */
|
|
1864
|
-
/* @__PURE__ */
|
|
2116
|
+
) : /* @__PURE__ */ jsx11("div", { style: { fontSize: "14px", fontWeight: "600", color: theme.textColor, padding: "6px 8px" }, children: strings.header.aiAssistant }) }),
|
|
2117
|
+
/* @__PURE__ */ jsxs8("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
|
|
2118
|
+
availableAgents && availableAgents.length > 1 && onAgentChange && /* @__PURE__ */ jsxs8("div", { style: { position: "relative" }, children: [
|
|
2119
|
+
/* @__PURE__ */ jsxs8(
|
|
1865
2120
|
"button",
|
|
1866
2121
|
{
|
|
1867
2122
|
"data-testid": "agent-selector",
|
|
@@ -1890,7 +2145,7 @@ function UseAIChatPanel({
|
|
|
1890
2145
|
},
|
|
1891
2146
|
title: "Select AI model",
|
|
1892
2147
|
children: [
|
|
1893
|
-
/* @__PURE__ */
|
|
2148
|
+
/* @__PURE__ */ jsx11("span", { style: {
|
|
1894
2149
|
overflow: "hidden",
|
|
1895
2150
|
textOverflow: "ellipsis",
|
|
1896
2151
|
whiteSpace: "nowrap",
|
|
@@ -1899,11 +2154,11 @@ function UseAIChatPanel({
|
|
|
1899
2154
|
const agent = availableAgents.find((a) => a.id === (selectedAgent ?? defaultAgent));
|
|
1900
2155
|
return agent?.name || "AI";
|
|
1901
2156
|
})() }),
|
|
1902
|
-
/* @__PURE__ */
|
|
2157
|
+
/* @__PURE__ */ jsx11("svg", { width: "10", height: "10", viewBox: "0 0 12 12", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx11("path", { d: "M3 4.5L6 7.5L9 4.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1903
2158
|
]
|
|
1904
2159
|
}
|
|
1905
2160
|
),
|
|
1906
|
-
agentDropdown.isOpen && /* @__PURE__ */
|
|
2161
|
+
agentDropdown.isOpen && /* @__PURE__ */ jsx11(
|
|
1907
2162
|
"div",
|
|
1908
2163
|
{
|
|
1909
2164
|
style: {
|
|
@@ -1923,7 +2178,7 @@ function UseAIChatPanel({
|
|
|
1923
2178
|
},
|
|
1924
2179
|
children: availableAgents.map((agent) => {
|
|
1925
2180
|
const isSelected = agent.id === (selectedAgent ?? defaultAgent);
|
|
1926
|
-
return /* @__PURE__ */
|
|
2181
|
+
return /* @__PURE__ */ jsxs8(
|
|
1927
2182
|
"div",
|
|
1928
2183
|
{
|
|
1929
2184
|
"data-testid": "agent-option",
|
|
@@ -1953,13 +2208,13 @@ function UseAIChatPanel({
|
|
|
1953
2208
|
}
|
|
1954
2209
|
},
|
|
1955
2210
|
children: [
|
|
1956
|
-
/* @__PURE__ */
|
|
1957
|
-
/* @__PURE__ */
|
|
2211
|
+
/* @__PURE__ */ jsxs8("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
2212
|
+
/* @__PURE__ */ jsx11("div", { style: {
|
|
1958
2213
|
fontSize: "13px",
|
|
1959
2214
|
fontWeight: isSelected ? "600" : "500",
|
|
1960
2215
|
color: isSelected ? theme.primaryColor : theme.textColor
|
|
1961
2216
|
}, children: agent.name }),
|
|
1962
|
-
agent.annotation && /* @__PURE__ */
|
|
2217
|
+
agent.annotation && /* @__PURE__ */ jsx11("div", { style: {
|
|
1963
2218
|
fontSize: "11px",
|
|
1964
2219
|
color: theme.secondaryTextColor,
|
|
1965
2220
|
marginTop: "2px",
|
|
@@ -1968,7 +2223,7 @@ function UseAIChatPanel({
|
|
|
1968
2223
|
whiteSpace: "nowrap"
|
|
1969
2224
|
}, children: agent.annotation })
|
|
1970
2225
|
] }),
|
|
1971
|
-
isSelected && /* @__PURE__ */
|
|
2226
|
+
isSelected && /* @__PURE__ */ jsx11("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx11("path", { d: "M2 7L5.5 10.5L12 4", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1972
2227
|
]
|
|
1973
2228
|
},
|
|
1974
2229
|
agent.id
|
|
@@ -1977,7 +2232,7 @@ function UseAIChatPanel({
|
|
|
1977
2232
|
}
|
|
1978
2233
|
)
|
|
1979
2234
|
] }),
|
|
1980
|
-
onNewChat && /* @__PURE__ */
|
|
2235
|
+
onNewChat && /* @__PURE__ */ jsx11(
|
|
1981
2236
|
"button",
|
|
1982
2237
|
{
|
|
1983
2238
|
"data-testid": "new-chat-button",
|
|
@@ -2004,10 +2259,10 @@ function UseAIChatPanel({
|
|
|
2004
2259
|
e.currentTarget.style.color = theme.secondaryTextColor;
|
|
2005
2260
|
},
|
|
2006
2261
|
title: strings.header.newChat,
|
|
2007
|
-
children: /* @__PURE__ */
|
|
2262
|
+
children: /* @__PURE__ */ jsx11("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx11("path", { d: "M8 3.5V12.5M3.5 8H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) })
|
|
2008
2263
|
}
|
|
2009
2264
|
),
|
|
2010
|
-
onDeleteChat && messages.length > 0 && /* @__PURE__ */
|
|
2265
|
+
onDeleteChat && messages.length > 0 && /* @__PURE__ */ jsx11(
|
|
2011
2266
|
"button",
|
|
2012
2267
|
{
|
|
2013
2268
|
"data-testid": "delete-chat-button",
|
|
@@ -2031,7 +2286,7 @@ function UseAIChatPanel({
|
|
|
2031
2286
|
e.currentTarget.style.color = theme.secondaryTextColor;
|
|
2032
2287
|
},
|
|
2033
2288
|
title: strings.header.deleteChat,
|
|
2034
|
-
children: /* @__PURE__ */
|
|
2289
|
+
children: /* @__PURE__ */ jsx11("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx11("path", { d: "M2 4H14M6.5 7V11M9.5 7V11M3 4L4 13C4 13.5304 4.21071 14.0391 4.58579 14.4142C4.96086 14.7893 5.46957 15 6 15H10C10.5304 15 11.0391 14.7893 11.4142 14.4142C11.7893 14.0391 12 13.5304 12 13L13 4M5.5 4V2.5C5.5 2.23478 5.60536 1.98043 5.79289 1.79289C5.98043 1.60536 6.23478 1.5 6.5 1.5H9.5C9.76522 1.5 10.0196 1.60536 10.2071 1.79289C10.3946 1.98043 10.5 2.23478 10.5 2.5V4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
2035
2290
|
}
|
|
2036
2291
|
),
|
|
2037
2292
|
closeButton
|
|
@@ -2039,7 +2294,7 @@ function UseAIChatPanel({
|
|
|
2039
2294
|
]
|
|
2040
2295
|
}
|
|
2041
2296
|
),
|
|
2042
|
-
chatHistoryDropdown.isOpen && onListChats && /* @__PURE__ */
|
|
2297
|
+
chatHistoryDropdown.isOpen && onListChats && /* @__PURE__ */ jsx11(
|
|
2043
2298
|
"div",
|
|
2044
2299
|
{
|
|
2045
2300
|
style: {
|
|
@@ -2056,7 +2311,7 @@ function UseAIChatPanel({
|
|
|
2056
2311
|
flexDirection: "column",
|
|
2057
2312
|
overflow: "hidden"
|
|
2058
2313
|
},
|
|
2059
|
-
children: /* @__PURE__ */
|
|
2314
|
+
children: /* @__PURE__ */ jsx11(
|
|
2060
2315
|
"div",
|
|
2061
2316
|
{
|
|
2062
2317
|
style: {
|
|
@@ -2064,7 +2319,7 @@ function UseAIChatPanel({
|
|
|
2064
2319
|
overflowY: "auto",
|
|
2065
2320
|
padding: "8px"
|
|
2066
2321
|
},
|
|
2067
|
-
children: chatHistory.length === 0 ? /* @__PURE__ */
|
|
2322
|
+
children: chatHistory.length === 0 ? /* @__PURE__ */ jsx11(
|
|
2068
2323
|
"div",
|
|
2069
2324
|
{
|
|
2070
2325
|
style: {
|
|
@@ -2073,9 +2328,9 @@ function UseAIChatPanel({
|
|
|
2073
2328
|
padding: "32px 16px",
|
|
2074
2329
|
fontSize: "13px"
|
|
2075
2330
|
},
|
|
2076
|
-
children: /* @__PURE__ */
|
|
2331
|
+
children: /* @__PURE__ */ jsx11("p", { style: { margin: 0 }, children: strings.chatHistory.noChatHistory })
|
|
2077
2332
|
}
|
|
2078
|
-
) : chatHistory.map((chat) => /* @__PURE__ */
|
|
2333
|
+
) : chatHistory.map((chat) => /* @__PURE__ */ jsxs8(
|
|
2079
2334
|
"div",
|
|
2080
2335
|
{
|
|
2081
2336
|
"data-testid": "chat-history-item",
|
|
@@ -2099,10 +2354,10 @@ function UseAIChatPanel({
|
|
|
2099
2354
|
}
|
|
2100
2355
|
},
|
|
2101
2356
|
children: [
|
|
2102
|
-
/* @__PURE__ */
|
|
2103
|
-
/* @__PURE__ */
|
|
2357
|
+
/* @__PURE__ */ jsx11("div", { style: { fontSize: "13px", fontWeight: "500", color: theme.textColor, marginBottom: "4px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: chat.title || strings.header.newChat }),
|
|
2358
|
+
/* @__PURE__ */ jsxs8("div", { style: { fontSize: "11px", color: theme.secondaryTextColor }, children: [
|
|
2104
2359
|
new Date(chat.updatedAt).toLocaleDateString([], { month: "short", day: "numeric" }),
|
|
2105
|
-
currentChatId === chat.id && /* @__PURE__ */
|
|
2360
|
+
currentChatId === chat.id && /* @__PURE__ */ jsxs8("span", { style: {
|
|
2106
2361
|
marginLeft: "8px",
|
|
2107
2362
|
color: theme.primaryColor,
|
|
2108
2363
|
fontWeight: "600"
|
|
@@ -2121,7 +2376,7 @@ function UseAIChatPanel({
|
|
|
2121
2376
|
),
|
|
2122
2377
|
chatHistoryDropdown.Backdrop,
|
|
2123
2378
|
agentDropdown.Backdrop,
|
|
2124
|
-
/* @__PURE__ */
|
|
2379
|
+
/* @__PURE__ */ jsxs8(
|
|
2125
2380
|
"div",
|
|
2126
2381
|
{
|
|
2127
2382
|
style: {
|
|
@@ -2133,7 +2388,7 @@ function UseAIChatPanel({
|
|
|
2133
2388
|
gap: "12px"
|
|
2134
2389
|
},
|
|
2135
2390
|
children: [
|
|
2136
|
-
messages.length === 0 && /* @__PURE__ */
|
|
2391
|
+
messages.length === 0 && /* @__PURE__ */ jsxs8(
|
|
2137
2392
|
"div",
|
|
2138
2393
|
{
|
|
2139
2394
|
style: {
|
|
@@ -2144,12 +2399,12 @@ function UseAIChatPanel({
|
|
|
2144
2399
|
gap: "20px"
|
|
2145
2400
|
},
|
|
2146
2401
|
children: [
|
|
2147
|
-
/* @__PURE__ */
|
|
2148
|
-
/* @__PURE__ */
|
|
2149
|
-
/* @__PURE__ */
|
|
2150
|
-
/* @__PURE__ */
|
|
2402
|
+
/* @__PURE__ */ jsxs8("div", { style: { textAlign: "center", color: theme.secondaryTextColor, fontSize: "14px" }, children: [
|
|
2403
|
+
/* @__PURE__ */ jsx11("p", { style: { margin: 0, fontSize: "32px", marginBottom: "12px" }, children: "\u{1F4AC}" }),
|
|
2404
|
+
/* @__PURE__ */ jsx11("p", { style: { margin: 0 }, children: strings.emptyChat.startConversation }),
|
|
2405
|
+
/* @__PURE__ */ jsx11("p", { style: { margin: "8px 0 0", fontSize: "12px" }, children: strings.emptyChat.askMeToHelp })
|
|
2151
2406
|
] }),
|
|
2152
|
-
displayedSuggestions.length > 0 && /* @__PURE__ */
|
|
2407
|
+
displayedSuggestions.length > 0 && /* @__PURE__ */ jsx11(
|
|
2153
2408
|
"div",
|
|
2154
2409
|
{
|
|
2155
2410
|
style: {
|
|
@@ -2159,7 +2414,7 @@ function UseAIChatPanel({
|
|
|
2159
2414
|
width: "100%",
|
|
2160
2415
|
maxWidth: "320px"
|
|
2161
2416
|
},
|
|
2162
|
-
children: displayedSuggestions.map((suggestion, index) => /* @__PURE__ */
|
|
2417
|
+
children: displayedSuggestions.map((suggestion, index) => /* @__PURE__ */ jsx11(
|
|
2163
2418
|
"button",
|
|
2164
2419
|
{
|
|
2165
2420
|
"data-testid": "chat-suggestion-button",
|
|
@@ -2203,7 +2458,7 @@ function UseAIChatPanel({
|
|
|
2203
2458
|
]
|
|
2204
2459
|
}
|
|
2205
2460
|
),
|
|
2206
|
-
messages.map((message) => /* @__PURE__ */
|
|
2461
|
+
messages.map((message) => /* @__PURE__ */ jsxs8(
|
|
2207
2462
|
"div",
|
|
2208
2463
|
{
|
|
2209
2464
|
"data-testid": `chat-message-${message.role}`,
|
|
@@ -2216,7 +2471,7 @@ function UseAIChatPanel({
|
|
|
2216
2471
|
onMouseEnter: () => message.role === "user" && setHoveredMessageId(message.id),
|
|
2217
2472
|
onMouseLeave: () => setHoveredMessageId(null),
|
|
2218
2473
|
children: [
|
|
2219
|
-
/* @__PURE__ */
|
|
2474
|
+
/* @__PURE__ */ jsxs8(
|
|
2220
2475
|
"div",
|
|
2221
2476
|
{
|
|
2222
2477
|
style: {
|
|
@@ -2224,7 +2479,7 @@ function UseAIChatPanel({
|
|
|
2224
2479
|
maxWidth: "80%"
|
|
2225
2480
|
},
|
|
2226
2481
|
children: [
|
|
2227
|
-
message.role === "user" && hoveredMessageId === message.id && onSaveCommand && !slashCommands.isSavingCommand(message.id) && /* @__PURE__ */
|
|
2482
|
+
message.role === "user" && hoveredMessageId === message.id && onSaveCommand && !slashCommands.isSavingCommand(message.id) && /* @__PURE__ */ jsx11(
|
|
2228
2483
|
"button",
|
|
2229
2484
|
{
|
|
2230
2485
|
"data-testid": "save-command-button",
|
|
@@ -2260,14 +2515,14 @@ function UseAIChatPanel({
|
|
|
2260
2515
|
e.currentTarget.style.transform = "scale(1)";
|
|
2261
2516
|
e.currentTarget.style.boxShadow = "0 2px 6px rgba(0, 0, 0, 0.15)";
|
|
2262
2517
|
},
|
|
2263
|
-
children: /* @__PURE__ */
|
|
2264
|
-
/* @__PURE__ */
|
|
2265
|
-
/* @__PURE__ */
|
|
2266
|
-
/* @__PURE__ */
|
|
2518
|
+
children: /* @__PURE__ */ jsxs8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2519
|
+
/* @__PURE__ */ jsx11("path", { d: "M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" }),
|
|
2520
|
+
/* @__PURE__ */ jsx11("polyline", { points: "17 21 17 13 7 13 7 21" }),
|
|
2521
|
+
/* @__PURE__ */ jsx11("polyline", { points: "7 3 7 8 15 8" })
|
|
2267
2522
|
] })
|
|
2268
2523
|
}
|
|
2269
2524
|
),
|
|
2270
|
-
/* @__PURE__ */
|
|
2525
|
+
/* @__PURE__ */ jsxs8(
|
|
2271
2526
|
"div",
|
|
2272
2527
|
{
|
|
2273
2528
|
"data-testid": "chat-message-content",
|
|
@@ -2282,7 +2537,7 @@ function UseAIChatPanel({
|
|
|
2282
2537
|
wordWrap: "break-word"
|
|
2283
2538
|
},
|
|
2284
2539
|
children: [
|
|
2285
|
-
message.role === "user" && hasFileContent(message.content) && /* @__PURE__ */
|
|
2540
|
+
message.role === "user" && hasFileContent(message.content) && /* @__PURE__ */ jsx11("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px", marginBottom: "8px" }, children: message.content.filter((part) => part.type === "file").map((part, idx) => /* @__PURE__ */ jsx11(
|
|
2286
2541
|
FilePlaceholder,
|
|
2287
2542
|
{
|
|
2288
2543
|
name: part.file.name,
|
|
@@ -2290,7 +2545,7 @@ function UseAIChatPanel({
|
|
|
2290
2545
|
},
|
|
2291
2546
|
idx
|
|
2292
2547
|
)) }),
|
|
2293
|
-
message.role === "assistant" ? /* @__PURE__ */
|
|
2548
|
+
message.role === "assistant" ? /* @__PURE__ */ jsx11(MarkdownContent, { content: getTextContent(message.content) }) : getTextContent(message.content)
|
|
2294
2549
|
]
|
|
2295
2550
|
}
|
|
2296
2551
|
),
|
|
@@ -2301,7 +2556,7 @@ function UseAIChatPanel({
|
|
|
2301
2556
|
]
|
|
2302
2557
|
}
|
|
2303
2558
|
),
|
|
2304
|
-
message.role === "assistant" && message.traceId && feedbackEnabled && onFeedback && /* @__PURE__ */
|
|
2559
|
+
message.role === "assistant" && message.traceId && feedbackEnabled && onFeedback && /* @__PURE__ */ jsxs8(
|
|
2305
2560
|
"div",
|
|
2306
2561
|
{
|
|
2307
2562
|
"data-testid": "feedback-buttons",
|
|
@@ -2312,7 +2567,7 @@ function UseAIChatPanel({
|
|
|
2312
2567
|
padding: "0 4px"
|
|
2313
2568
|
},
|
|
2314
2569
|
children: [
|
|
2315
|
-
/* @__PURE__ */
|
|
2570
|
+
/* @__PURE__ */ jsx11(
|
|
2316
2571
|
FeedbackButton,
|
|
2317
2572
|
{
|
|
2318
2573
|
type: "upvote",
|
|
@@ -2325,7 +2580,7 @@ function UseAIChatPanel({
|
|
|
2325
2580
|
unselectedColor: theme.secondaryTextColor
|
|
2326
2581
|
}
|
|
2327
2582
|
),
|
|
2328
|
-
/* @__PURE__ */
|
|
2583
|
+
/* @__PURE__ */ jsx11(
|
|
2329
2584
|
FeedbackButton,
|
|
2330
2585
|
{
|
|
2331
2586
|
type: "downvote",
|
|
@@ -2341,7 +2596,7 @@ function UseAIChatPanel({
|
|
|
2341
2596
|
]
|
|
2342
2597
|
}
|
|
2343
2598
|
),
|
|
2344
|
-
/* @__PURE__ */
|
|
2599
|
+
/* @__PURE__ */ jsx11(
|
|
2345
2600
|
"div",
|
|
2346
2601
|
{
|
|
2347
2602
|
style: {
|
|
@@ -2360,14 +2615,14 @@ function UseAIChatPanel({
|
|
|
2360
2615
|
},
|
|
2361
2616
|
message.id
|
|
2362
2617
|
)),
|
|
2363
|
-
loading && /* @__PURE__ */
|
|
2618
|
+
loading && /* @__PURE__ */ jsx11(
|
|
2364
2619
|
"div",
|
|
2365
2620
|
{
|
|
2366
2621
|
style: {
|
|
2367
2622
|
display: "flex",
|
|
2368
2623
|
alignItems: "flex-start"
|
|
2369
2624
|
},
|
|
2370
|
-
children: /* @__PURE__ */
|
|
2625
|
+
children: /* @__PURE__ */ jsx11(
|
|
2371
2626
|
"div",
|
|
2372
2627
|
{
|
|
2373
2628
|
className: "markdown-content",
|
|
@@ -2380,20 +2635,20 @@ function UseAIChatPanel({
|
|
|
2380
2635
|
color: theme.textColor,
|
|
2381
2636
|
maxWidth: "80%"
|
|
2382
2637
|
},
|
|
2383
|
-
children: streamingText ? /* @__PURE__ */
|
|
2384
|
-
/* @__PURE__ */
|
|
2385
|
-
fileProcessing.progress != null && /* @__PURE__ */
|
|
2386
|
-
/* @__PURE__ */
|
|
2638
|
+
children: streamingText ? /* @__PURE__ */ jsx11(MarkdownContent, { content: streamingText }) : fileProcessing && fileProcessing.status === "processing" ? /* @__PURE__ */ jsxs8("div", { children: [
|
|
2639
|
+
/* @__PURE__ */ jsx11("span", { style: { opacity: 0.6 }, children: strings.input.processingFile }),
|
|
2640
|
+
fileProcessing.progress != null && /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
2641
|
+
/* @__PURE__ */ jsxs8("span", { style: { opacity: 0.6, marginLeft: "4px" }, children: [
|
|
2387
2642
|
Math.round(fileProcessing.progress),
|
|
2388
2643
|
"%"
|
|
2389
2644
|
] }),
|
|
2390
|
-
/* @__PURE__ */
|
|
2645
|
+
/* @__PURE__ */ jsx11("div", { style: {
|
|
2391
2646
|
marginTop: "6px",
|
|
2392
2647
|
height: "4px",
|
|
2393
2648
|
borderRadius: "2px",
|
|
2394
2649
|
background: theme.borderColor,
|
|
2395
2650
|
overflow: "hidden"
|
|
2396
|
-
}, children: /* @__PURE__ */
|
|
2651
|
+
}, children: /* @__PURE__ */ jsx11("div", { style: {
|
|
2397
2652
|
height: "100%",
|
|
2398
2653
|
width: `${fileProcessing.progress}%`,
|
|
2399
2654
|
borderRadius: "2px",
|
|
@@ -2401,17 +2656,17 @@ function UseAIChatPanel({
|
|
|
2401
2656
|
transition: "width 0.3s ease"
|
|
2402
2657
|
} }) })
|
|
2403
2658
|
] }),
|
|
2404
|
-
fileProcessing.progress == null && /* @__PURE__ */
|
|
2405
|
-
] }) : /* @__PURE__ */
|
|
2659
|
+
fileProcessing.progress == null && /* @__PURE__ */ jsx11("span", { className: "dots", style: { marginLeft: "4px" }, children: "..." })
|
|
2660
|
+
] }) : /* @__PURE__ */ jsx11("span", { className: "dots", style: { opacity: 0.6 }, children: "..." })
|
|
2406
2661
|
}
|
|
2407
2662
|
)
|
|
2408
2663
|
}
|
|
2409
2664
|
),
|
|
2410
|
-
/* @__PURE__ */
|
|
2665
|
+
/* @__PURE__ */ jsx11("div", { ref: messagesEndRef })
|
|
2411
2666
|
]
|
|
2412
2667
|
}
|
|
2413
2668
|
),
|
|
2414
|
-
/* @__PURE__ */
|
|
2669
|
+
/* @__PURE__ */ jsxs8(
|
|
2415
2670
|
"div",
|
|
2416
2671
|
{
|
|
2417
2672
|
style: {
|
|
@@ -2419,7 +2674,7 @@ function UseAIChatPanel({
|
|
|
2419
2674
|
borderTop: `1px solid ${theme.borderColor}`
|
|
2420
2675
|
},
|
|
2421
2676
|
children: [
|
|
2422
|
-
fileError && /* @__PURE__ */
|
|
2677
|
+
fileError && /* @__PURE__ */ jsx11(
|
|
2423
2678
|
"div",
|
|
2424
2679
|
{
|
|
2425
2680
|
"data-testid": "file-error",
|
|
@@ -2434,7 +2689,7 @@ function UseAIChatPanel({
|
|
|
2434
2689
|
children: fileError
|
|
2435
2690
|
}
|
|
2436
2691
|
),
|
|
2437
|
-
attachments.length > 0 && /* @__PURE__ */
|
|
2692
|
+
attachments.length > 0 && /* @__PURE__ */ jsx11(
|
|
2438
2693
|
"div",
|
|
2439
2694
|
{
|
|
2440
2695
|
"data-testid": "file-attachments",
|
|
@@ -2444,7 +2699,7 @@ function UseAIChatPanel({
|
|
|
2444
2699
|
gap: "8px",
|
|
2445
2700
|
marginBottom: "8px"
|
|
2446
2701
|
},
|
|
2447
|
-
children: attachments.map((attachment) => /* @__PURE__ */
|
|
2702
|
+
children: attachments.map((attachment) => /* @__PURE__ */ jsx11(
|
|
2448
2703
|
FileChip,
|
|
2449
2704
|
{
|
|
2450
2705
|
attachment,
|
|
@@ -2456,143 +2711,159 @@ function UseAIChatPanel({
|
|
|
2456
2711
|
))
|
|
2457
2712
|
}
|
|
2458
2713
|
),
|
|
2459
|
-
/* @__PURE__ */
|
|
2460
|
-
"
|
|
2714
|
+
/* @__PURE__ */ jsx11(
|
|
2715
|
+
"input",
|
|
2461
2716
|
{
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
children: [
|
|
2470
|
-
slashCommands.AutocompleteComponent,
|
|
2471
|
-
/* @__PURE__ */ jsx10(
|
|
2472
|
-
"input",
|
|
2473
|
-
{
|
|
2474
|
-
ref: fileInputRef,
|
|
2475
|
-
type: "file",
|
|
2476
|
-
multiple: true,
|
|
2477
|
-
"data-testid": "file-input",
|
|
2478
|
-
style: { display: "none" },
|
|
2479
|
-
onChange: handleFileInputChange,
|
|
2480
|
-
accept: acceptedTypes?.join(",")
|
|
2481
|
-
}
|
|
2482
|
-
),
|
|
2483
|
-
/* @__PURE__ */ jsx10(
|
|
2484
|
-
"textarea",
|
|
2485
|
-
{
|
|
2486
|
-
ref: textareaRef,
|
|
2487
|
-
"data-testid": "chat-input",
|
|
2488
|
-
className: "chat-input",
|
|
2489
|
-
value: input,
|
|
2490
|
-
onChange: handleInputChange,
|
|
2491
|
-
onKeyDown: handleKeyDown,
|
|
2492
|
-
placeholder: !connected ? strings.input.connectingPlaceholder : loading ? `${executingTool?.displayText ?? strings.input.thinking}...` : strings.input.placeholder,
|
|
2493
|
-
disabled: !connected || loading,
|
|
2494
|
-
rows: 1,
|
|
2495
|
-
style: {
|
|
2496
|
-
width: "100%",
|
|
2497
|
-
padding: "10px 14px 6px",
|
|
2498
|
-
border: "none",
|
|
2499
|
-
fontSize: "14px",
|
|
2500
|
-
lineHeight: "1.4",
|
|
2501
|
-
resize: "none",
|
|
2502
|
-
maxHeight: `${maxTextareaHeight}px`,
|
|
2503
|
-
fontFamily: "inherit",
|
|
2504
|
-
outline: "none",
|
|
2505
|
-
background: "transparent",
|
|
2506
|
-
overflowY: "auto",
|
|
2507
|
-
boxSizing: "border-box"
|
|
2508
|
-
}
|
|
2509
|
-
}
|
|
2510
|
-
),
|
|
2511
|
-
/* @__PURE__ */ jsxs7(
|
|
2512
|
-
"div",
|
|
2513
|
-
{
|
|
2514
|
-
style: {
|
|
2515
|
-
display: "flex",
|
|
2516
|
-
alignItems: "center",
|
|
2517
|
-
justifyContent: "space-between",
|
|
2518
|
-
padding: "4px 8px"
|
|
2519
|
-
},
|
|
2520
|
-
children: [
|
|
2521
|
-
/* @__PURE__ */ jsx10("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: fileUploadEnabled && /* @__PURE__ */ jsx10(
|
|
2522
|
-
"button",
|
|
2523
|
-
{
|
|
2524
|
-
"data-testid": "file-picker-button",
|
|
2525
|
-
onClick: openFilePicker,
|
|
2526
|
-
disabled: !connected || loading,
|
|
2527
|
-
style: {
|
|
2528
|
-
padding: "4px",
|
|
2529
|
-
background: "transparent",
|
|
2530
|
-
border: `1px solid ${theme.borderColor}`,
|
|
2531
|
-
borderRadius: "50%",
|
|
2532
|
-
cursor: connected && !loading ? "pointer" : "not-allowed",
|
|
2533
|
-
color: theme.secondaryTextColor,
|
|
2534
|
-
display: "flex",
|
|
2535
|
-
alignItems: "center",
|
|
2536
|
-
justifyContent: "center",
|
|
2537
|
-
width: "28px",
|
|
2538
|
-
height: "28px",
|
|
2539
|
-
transition: "all 0.15s",
|
|
2540
|
-
opacity: connected && !loading ? 1 : 0.5
|
|
2541
|
-
},
|
|
2542
|
-
onMouseEnter: (e) => {
|
|
2543
|
-
if (connected && !loading) {
|
|
2544
|
-
e.currentTarget.style.color = theme.primaryColor;
|
|
2545
|
-
e.currentTarget.style.borderColor = theme.primaryColor;
|
|
2546
|
-
}
|
|
2547
|
-
},
|
|
2548
|
-
onMouseLeave: (e) => {
|
|
2549
|
-
e.currentTarget.style.color = theme.secondaryTextColor;
|
|
2550
|
-
e.currentTarget.style.borderColor = theme.borderColor;
|
|
2551
|
-
},
|
|
2552
|
-
title: strings.fileUpload.attachFiles,
|
|
2553
|
-
children: /* @__PURE__ */ jsxs7("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2554
|
-
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
|
|
2555
|
-
/* @__PURE__ */ jsx10("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
2556
|
-
] })
|
|
2557
|
-
}
|
|
2558
|
-
) }),
|
|
2559
|
-
/* @__PURE__ */ jsx10(
|
|
2560
|
-
"button",
|
|
2561
|
-
{
|
|
2562
|
-
"data-testid": "chat-send-button",
|
|
2563
|
-
className: "chat-send-button",
|
|
2564
|
-
onClick: handleSend,
|
|
2565
|
-
disabled: !connected || loading || !input.trim() && attachments.length === 0,
|
|
2566
|
-
style: {
|
|
2567
|
-
padding: "6px",
|
|
2568
|
-
background: connected && !loading && (input.trim() || attachments.length > 0) ? theme.primaryGradient : theme.buttonDisabledBackground,
|
|
2569
|
-
color: connected && !loading && (input.trim() || attachments.length > 0) ? "white" : theme.secondaryTextColor,
|
|
2570
|
-
border: "none",
|
|
2571
|
-
borderRadius: "50%",
|
|
2572
|
-
cursor: connected && !loading && (input.trim() || attachments.length > 0) ? "pointer" : "not-allowed",
|
|
2573
|
-
display: "flex",
|
|
2574
|
-
alignItems: "center",
|
|
2575
|
-
justifyContent: "center",
|
|
2576
|
-
width: "32px",
|
|
2577
|
-
height: "32px",
|
|
2578
|
-
transition: "all 0.2s"
|
|
2579
|
-
},
|
|
2580
|
-
children: /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2581
|
-
/* @__PURE__ */ jsx10("line", { x1: "12", y1: "19", x2: "12", y2: "5" }),
|
|
2582
|
-
/* @__PURE__ */ jsx10("polyline", { points: "5 12 12 5 19 12" })
|
|
2583
|
-
] })
|
|
2584
|
-
}
|
|
2585
|
-
)
|
|
2586
|
-
]
|
|
2587
|
-
}
|
|
2588
|
-
)
|
|
2589
|
-
]
|
|
2717
|
+
ref: fileInputRef,
|
|
2718
|
+
type: "file",
|
|
2719
|
+
multiple: true,
|
|
2720
|
+
"data-testid": "file-input",
|
|
2721
|
+
style: { display: "none" },
|
|
2722
|
+
onChange: handleFileInputChange,
|
|
2723
|
+
accept: acceptedTypes?.join(",")
|
|
2590
2724
|
}
|
|
2725
|
+
),
|
|
2726
|
+
pendingApprovals.length > 0 && onApproveToolCall && onRejectToolCall ? /* @__PURE__ */ jsx11(
|
|
2727
|
+
ToolApprovalDialog,
|
|
2728
|
+
{
|
|
2729
|
+
toolCallName: pendingApprovals[0].toolCallName,
|
|
2730
|
+
toolCallArgs: pendingApprovals[0].toolCallArgs,
|
|
2731
|
+
annotations: pendingApprovals[0].annotations,
|
|
2732
|
+
toolCount: pendingApprovals.length,
|
|
2733
|
+
pendingTools: pendingApprovals,
|
|
2734
|
+
onApprove: onApproveToolCall,
|
|
2735
|
+
onReject: onRejectToolCall,
|
|
2736
|
+
theme,
|
|
2737
|
+
strings
|
|
2738
|
+
}
|
|
2739
|
+
) : (
|
|
2740
|
+
/* Input container - single border around everything */
|
|
2741
|
+
/* @__PURE__ */ jsxs8(
|
|
2742
|
+
"div",
|
|
2743
|
+
{
|
|
2744
|
+
style: {
|
|
2745
|
+
border: `1px solid ${theme.borderColor}`,
|
|
2746
|
+
borderRadius: "12px",
|
|
2747
|
+
background: theme.backgroundColor,
|
|
2748
|
+
overflow: "hidden",
|
|
2749
|
+
position: "relative"
|
|
2750
|
+
},
|
|
2751
|
+
children: [
|
|
2752
|
+
slashCommands.AutocompleteComponent,
|
|
2753
|
+
/* @__PURE__ */ jsx11(
|
|
2754
|
+
"textarea",
|
|
2755
|
+
{
|
|
2756
|
+
ref: textareaRef,
|
|
2757
|
+
"data-testid": "chat-input",
|
|
2758
|
+
className: "chat-input",
|
|
2759
|
+
value: input,
|
|
2760
|
+
onChange: handleInputChange,
|
|
2761
|
+
onKeyDown: handleKeyDown,
|
|
2762
|
+
placeholder: !connected ? strings.input.connectingPlaceholder : loading ? `${executingTool?.displayText ?? strings.input.thinking}...` : strings.input.placeholder,
|
|
2763
|
+
disabled: !connected || loading || pendingApprovals.length > 0,
|
|
2764
|
+
rows: 1,
|
|
2765
|
+
style: {
|
|
2766
|
+
width: "100%",
|
|
2767
|
+
padding: "10px 14px 6px",
|
|
2768
|
+
border: "none",
|
|
2769
|
+
fontSize: "14px",
|
|
2770
|
+
lineHeight: "1.4",
|
|
2771
|
+
resize: "none",
|
|
2772
|
+
maxHeight: `${maxTextareaHeight}px`,
|
|
2773
|
+
fontFamily: "inherit",
|
|
2774
|
+
outline: "none",
|
|
2775
|
+
background: "transparent",
|
|
2776
|
+
overflowY: "auto",
|
|
2777
|
+
boxSizing: "border-box"
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
),
|
|
2781
|
+
/* @__PURE__ */ jsxs8(
|
|
2782
|
+
"div",
|
|
2783
|
+
{
|
|
2784
|
+
style: {
|
|
2785
|
+
display: "flex",
|
|
2786
|
+
alignItems: "center",
|
|
2787
|
+
justifyContent: "space-between",
|
|
2788
|
+
padding: "4px 8px"
|
|
2789
|
+
},
|
|
2790
|
+
children: [
|
|
2791
|
+
/* @__PURE__ */ jsx11("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: fileUploadEnabled && /* @__PURE__ */ jsx11(
|
|
2792
|
+
"button",
|
|
2793
|
+
{
|
|
2794
|
+
"data-testid": "file-picker-button",
|
|
2795
|
+
onClick: openFilePicker,
|
|
2796
|
+
disabled: !connected || loading || pendingApprovals.length > 0,
|
|
2797
|
+
style: {
|
|
2798
|
+
padding: "4px",
|
|
2799
|
+
background: "transparent",
|
|
2800
|
+
border: `1px solid ${theme.borderColor}`,
|
|
2801
|
+
borderRadius: "50%",
|
|
2802
|
+
cursor: connected && !loading && pendingApprovals.length === 0 ? "pointer" : "not-allowed",
|
|
2803
|
+
color: theme.secondaryTextColor,
|
|
2804
|
+
display: "flex",
|
|
2805
|
+
alignItems: "center",
|
|
2806
|
+
justifyContent: "center",
|
|
2807
|
+
width: "28px",
|
|
2808
|
+
height: "28px",
|
|
2809
|
+
transition: "all 0.15s",
|
|
2810
|
+
opacity: connected && !loading && pendingApprovals.length === 0 ? 1 : 0.5
|
|
2811
|
+
},
|
|
2812
|
+
onMouseEnter: (e) => {
|
|
2813
|
+
if (connected && !loading && pendingApprovals.length === 0) {
|
|
2814
|
+
e.currentTarget.style.color = theme.primaryColor;
|
|
2815
|
+
e.currentTarget.style.borderColor = theme.primaryColor;
|
|
2816
|
+
}
|
|
2817
|
+
},
|
|
2818
|
+
onMouseLeave: (e) => {
|
|
2819
|
+
e.currentTarget.style.color = theme.secondaryTextColor;
|
|
2820
|
+
e.currentTarget.style.borderColor = theme.borderColor;
|
|
2821
|
+
},
|
|
2822
|
+
title: strings.fileUpload.attachFiles,
|
|
2823
|
+
children: /* @__PURE__ */ jsxs8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2824
|
+
/* @__PURE__ */ jsx11("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
|
|
2825
|
+
/* @__PURE__ */ jsx11("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
2826
|
+
] })
|
|
2827
|
+
}
|
|
2828
|
+
) }),
|
|
2829
|
+
/* @__PURE__ */ jsx11(
|
|
2830
|
+
"button",
|
|
2831
|
+
{
|
|
2832
|
+
"data-testid": "chat-send-button",
|
|
2833
|
+
className: "chat-send-button",
|
|
2834
|
+
onClick: handleSend,
|
|
2835
|
+
disabled: !connected || loading || pendingApprovals.length > 0 || !input.trim() && attachments.length === 0,
|
|
2836
|
+
style: {
|
|
2837
|
+
padding: "6px",
|
|
2838
|
+
background: connected && !loading && pendingApprovals.length === 0 && (input.trim() || attachments.length > 0) ? theme.primaryGradient : theme.buttonDisabledBackground,
|
|
2839
|
+
color: connected && !loading && pendingApprovals.length === 0 && (input.trim() || attachments.length > 0) ? "white" : theme.secondaryTextColor,
|
|
2840
|
+
border: "none",
|
|
2841
|
+
borderRadius: "50%",
|
|
2842
|
+
cursor: connected && !loading && pendingApprovals.length === 0 && (input.trim() || attachments.length > 0) ? "pointer" : "not-allowed",
|
|
2843
|
+
display: "flex",
|
|
2844
|
+
alignItems: "center",
|
|
2845
|
+
justifyContent: "center",
|
|
2846
|
+
width: "32px",
|
|
2847
|
+
height: "32px",
|
|
2848
|
+
transition: "all 0.2s"
|
|
2849
|
+
},
|
|
2850
|
+
children: /* @__PURE__ */ jsxs8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2851
|
+
/* @__PURE__ */ jsx11("line", { x1: "12", y1: "19", x2: "12", y2: "5" }),
|
|
2852
|
+
/* @__PURE__ */ jsx11("polyline", { points: "5 12 12 5 19 12" })
|
|
2853
|
+
] })
|
|
2854
|
+
}
|
|
2855
|
+
)
|
|
2856
|
+
]
|
|
2857
|
+
}
|
|
2858
|
+
)
|
|
2859
|
+
]
|
|
2860
|
+
}
|
|
2861
|
+
)
|
|
2591
2862
|
)
|
|
2592
2863
|
]
|
|
2593
2864
|
}
|
|
2594
2865
|
),
|
|
2595
|
-
/* @__PURE__ */
|
|
2866
|
+
/* @__PURE__ */ jsx11("style", { children: `
|
|
2596
2867
|
/* Markdown content styles */
|
|
2597
2868
|
.markdown-content > :first-child {
|
|
2598
2869
|
margin-top: 0 !important;
|
|
@@ -2617,7 +2888,7 @@ function UseAIChatPanel({
|
|
|
2617
2888
|
}
|
|
2618
2889
|
|
|
2619
2890
|
// src/components/UseAIFloatingChatWrapper.tsx
|
|
2620
|
-
import { Fragment as Fragment2, jsx as
|
|
2891
|
+
import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2621
2892
|
function UseAIFloatingChatWrapper({
|
|
2622
2893
|
isOpen,
|
|
2623
2894
|
onClose,
|
|
@@ -2625,8 +2896,8 @@ function UseAIFloatingChatWrapper({
|
|
|
2625
2896
|
}) {
|
|
2626
2897
|
const theme = useTheme();
|
|
2627
2898
|
if (!isOpen) return null;
|
|
2628
|
-
return /* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2899
|
+
return /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
2900
|
+
/* @__PURE__ */ jsx12(
|
|
2630
2901
|
"div",
|
|
2631
2902
|
{
|
|
2632
2903
|
style: {
|
|
@@ -2642,7 +2913,7 @@ function UseAIFloatingChatWrapper({
|
|
|
2642
2913
|
onClick: onClose
|
|
2643
2914
|
}
|
|
2644
2915
|
),
|
|
2645
|
-
/* @__PURE__ */
|
|
2916
|
+
/* @__PURE__ */ jsx12(
|
|
2646
2917
|
"div",
|
|
2647
2918
|
{
|
|
2648
2919
|
style: {
|
|
@@ -2661,7 +2932,7 @@ function UseAIFloatingChatWrapper({
|
|
|
2661
2932
|
children
|
|
2662
2933
|
}
|
|
2663
2934
|
),
|
|
2664
|
-
/* @__PURE__ */
|
|
2935
|
+
/* @__PURE__ */ jsx12("style", { children: `
|
|
2665
2936
|
@keyframes fadeIn {
|
|
2666
2937
|
from { opacity: 0; }
|
|
2667
2938
|
to { opacity: 1; }
|
|
@@ -2681,7 +2952,7 @@ function UseAIFloatingChatWrapper({
|
|
|
2681
2952
|
}
|
|
2682
2953
|
function CloseButton({ onClick }) {
|
|
2683
2954
|
const theme = useTheme();
|
|
2684
|
-
return /* @__PURE__ */
|
|
2955
|
+
return /* @__PURE__ */ jsx12(
|
|
2685
2956
|
"button",
|
|
2686
2957
|
{
|
|
2687
2958
|
"data-testid": "chat-close-button",
|
|
@@ -2716,7 +2987,7 @@ function CloseButton({ onClick }) {
|
|
|
2716
2987
|
|
|
2717
2988
|
// src/components/UseAIChat.tsx
|
|
2718
2989
|
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
2719
|
-
import { jsx as
|
|
2990
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
2720
2991
|
var __UseAIChatContext = createContext3(null);
|
|
2721
2992
|
function useChatUIContext() {
|
|
2722
2993
|
const context = useContext3(__UseAIChatContext);
|
|
@@ -2752,27 +3023,30 @@ function UseAIChat({ floating = false }) {
|
|
|
2752
3023
|
onSaveCommand: ctx.commands.save,
|
|
2753
3024
|
onRenameCommand: ctx.commands.rename,
|
|
2754
3025
|
onDeleteCommand: ctx.commands.delete,
|
|
2755
|
-
executingTool: ctx.
|
|
3026
|
+
executingTool: ctx.tools.executing,
|
|
2756
3027
|
feedbackEnabled: ctx.feedback?.enabled,
|
|
2757
|
-
onFeedback: ctx.feedback?.submit
|
|
3028
|
+
onFeedback: ctx.feedback?.submit,
|
|
3029
|
+
pendingApprovals: ctx.tools.pending.tools,
|
|
3030
|
+
onApproveToolCall: ctx.tools.pending.tools.length > 0 ? ctx.tools.pending.approveAll : void 0,
|
|
3031
|
+
onRejectToolCall: ctx.tools.pending.tools.length > 0 ? ctx.tools.pending.rejectAll : void 0
|
|
2758
3032
|
};
|
|
2759
3033
|
if (floating) {
|
|
2760
|
-
return /* @__PURE__ */
|
|
3034
|
+
return /* @__PURE__ */ jsx13(
|
|
2761
3035
|
UseAIFloatingChatWrapper,
|
|
2762
3036
|
{
|
|
2763
3037
|
isOpen: ctx.ui.isOpen,
|
|
2764
3038
|
onClose: () => ctx.ui.setOpen(false),
|
|
2765
|
-
children: /* @__PURE__ */
|
|
3039
|
+
children: /* @__PURE__ */ jsx13(
|
|
2766
3040
|
UseAIChatPanel,
|
|
2767
3041
|
{
|
|
2768
3042
|
...chatPanelProps,
|
|
2769
|
-
closeButton: /* @__PURE__ */
|
|
3043
|
+
closeButton: /* @__PURE__ */ jsx13(CloseButton, { onClick: () => ctx.ui.setOpen(false) })
|
|
2770
3044
|
}
|
|
2771
3045
|
)
|
|
2772
3046
|
}
|
|
2773
3047
|
);
|
|
2774
3048
|
}
|
|
2775
|
-
return /* @__PURE__ */
|
|
3049
|
+
return /* @__PURE__ */ jsx13(UseAIChatPanel, { ...chatPanelProps });
|
|
2776
3050
|
}
|
|
2777
3051
|
|
|
2778
3052
|
// src/client.ts
|
|
@@ -3019,7 +3293,8 @@ var UseAIClient = class {
|
|
|
3019
3293
|
tools: this._tools.map((t) => ({
|
|
3020
3294
|
name: t.name,
|
|
3021
3295
|
description: t.description,
|
|
3022
|
-
parameters: t.parameters
|
|
3296
|
+
parameters: t.parameters,
|
|
3297
|
+
annotations: t.annotations
|
|
3023
3298
|
})),
|
|
3024
3299
|
state: this._state,
|
|
3025
3300
|
context: [],
|
|
@@ -3062,6 +3337,24 @@ var UseAIClient = class {
|
|
|
3062
3337
|
this._messages.push(toolResultMsg);
|
|
3063
3338
|
this.send(toolResultMessage);
|
|
3064
3339
|
}
|
|
3340
|
+
/**
|
|
3341
|
+
* Sends a tool approval response back to the server.
|
|
3342
|
+
*
|
|
3343
|
+
* @param toolCallId - The ID of the tool call being approved/rejected
|
|
3344
|
+
* @param approved - Whether the tool execution is approved
|
|
3345
|
+
* @param reason - Optional reason for rejection (shown to AI)
|
|
3346
|
+
*/
|
|
3347
|
+
sendToolApprovalResponse(toolCallId, approved, reason) {
|
|
3348
|
+
const message = {
|
|
3349
|
+
type: "tool_approval_response",
|
|
3350
|
+
data: {
|
|
3351
|
+
toolCallId,
|
|
3352
|
+
approved,
|
|
3353
|
+
reason
|
|
3354
|
+
}
|
|
3355
|
+
};
|
|
3356
|
+
this.send(message);
|
|
3357
|
+
}
|
|
3065
3358
|
/**
|
|
3066
3359
|
* Retrieves accumulated tool call data for a specific tool call ID.
|
|
3067
3360
|
* Used to get the complete tool name and arguments after they've been streamed
|
|
@@ -3534,7 +3827,7 @@ var LocalStorageChatRepository = class {
|
|
|
3534
3827
|
};
|
|
3535
3828
|
|
|
3536
3829
|
// src/hooks/useChatManagement.ts
|
|
3537
|
-
import { useState as
|
|
3830
|
+
import { useState as useState6, useCallback as useCallback4, useRef as useRef5, useEffect as useEffect5 } from "react";
|
|
3538
3831
|
var CHAT_TITLE_MAX_LENGTH = 50;
|
|
3539
3832
|
function deepEquals(a, b) {
|
|
3540
3833
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
@@ -3577,10 +3870,11 @@ function useChatManagement({
|
|
|
3577
3870
|
onSendMessage,
|
|
3578
3871
|
setOpen,
|
|
3579
3872
|
connected,
|
|
3580
|
-
loading
|
|
3873
|
+
loading,
|
|
3874
|
+
hasPendingApproval
|
|
3581
3875
|
}) {
|
|
3582
|
-
const [currentChatId, setCurrentChatId] =
|
|
3583
|
-
const [pendingChatId, setPendingChatId] =
|
|
3876
|
+
const [currentChatId, setCurrentChatId] = useState6(null);
|
|
3877
|
+
const [pendingChatId, setPendingChatId] = useState6(null);
|
|
3584
3878
|
const currentChatIdSnapshot = useRef5(null);
|
|
3585
3879
|
const pendingChatIdSnapshot = useRef5(null);
|
|
3586
3880
|
useEffect5(() => {
|
|
@@ -3799,6 +4093,10 @@ function useChatManagement({
|
|
|
3799
4093
|
useEffect5(() => {
|
|
3800
4094
|
loadingRef.current = loading;
|
|
3801
4095
|
}, [loading]);
|
|
4096
|
+
const hasPendingApprovalRef = useRef5(hasPendingApproval);
|
|
4097
|
+
useEffect5(() => {
|
|
4098
|
+
hasPendingApprovalRef.current = hasPendingApproval;
|
|
4099
|
+
}, [hasPendingApproval]);
|
|
3802
4100
|
const processMessageQueue = useCallback4(async () => {
|
|
3803
4101
|
if (isProcessingQueueRef.current || pendingMessagesRef.current.length === 0 || !onSendMessage) {
|
|
3804
4102
|
return;
|
|
@@ -3833,16 +4131,16 @@ function useChatManagement({
|
|
|
3833
4131
|
setOpen(true);
|
|
3834
4132
|
}
|
|
3835
4133
|
await new Promise((resolve) => {
|
|
3836
|
-
const
|
|
4134
|
+
const checkReady = () => {
|
|
3837
4135
|
setTimeout(() => {
|
|
3838
|
-
if (!loadingRef.current) {
|
|
4136
|
+
if (!loadingRef.current && !hasPendingApprovalRef.current) {
|
|
3839
4137
|
resolve();
|
|
3840
4138
|
} else {
|
|
3841
|
-
|
|
4139
|
+
checkReady();
|
|
3842
4140
|
}
|
|
3843
4141
|
}, 100);
|
|
3844
4142
|
};
|
|
3845
|
-
|
|
4143
|
+
checkReady();
|
|
3846
4144
|
});
|
|
3847
4145
|
}
|
|
3848
4146
|
isProcessingQueueRef.current = false;
|
|
@@ -3879,7 +4177,7 @@ function useChatManagement({
|
|
|
3879
4177
|
}
|
|
3880
4178
|
|
|
3881
4179
|
// src/hooks/useAgentSelection.ts
|
|
3882
|
-
import { useState as
|
|
4180
|
+
import { useState as useState7, useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo3 } from "react";
|
|
3883
4181
|
function filterAgents(serverAgents, defaultAgentId, visibleAgentIds) {
|
|
3884
4182
|
const getDefaultAgentFallback = () => {
|
|
3885
4183
|
const defaultAgentInfo = serverAgents.find((a) => a.id === defaultAgentId);
|
|
@@ -3905,9 +4203,9 @@ function useAgentSelection({
|
|
|
3905
4203
|
connected,
|
|
3906
4204
|
visibleAgentIds
|
|
3907
4205
|
}) {
|
|
3908
|
-
const [serverAgents, setServerAgents] =
|
|
3909
|
-
const [defaultAgent, setDefaultAgent] =
|
|
3910
|
-
const [selectedAgent, setSelectedAgent] =
|
|
4206
|
+
const [serverAgents, setServerAgents] = useState7([]);
|
|
4207
|
+
const [defaultAgent, setDefaultAgent] = useState7(null);
|
|
4208
|
+
const [selectedAgent, setSelectedAgent] = useState7(null);
|
|
3911
4209
|
const availableAgents = useMemo3(
|
|
3912
4210
|
() => filterAgents(serverAgents, defaultAgent, visibleAgentIds),
|
|
3913
4211
|
[serverAgents, defaultAgent, visibleAgentIds]
|
|
@@ -3944,7 +4242,7 @@ function useAgentSelection({
|
|
|
3944
4242
|
}
|
|
3945
4243
|
|
|
3946
4244
|
// src/hooks/useCommandManagement.ts
|
|
3947
|
-
import { useState as
|
|
4245
|
+
import { useState as useState8, useCallback as useCallback6, useRef as useRef6, useEffect as useEffect7 } from "react";
|
|
3948
4246
|
|
|
3949
4247
|
// src/commands/LocalStorageCommandRepository.ts
|
|
3950
4248
|
var STORAGE_KEY_PREFIX2 = "use-ai:command:";
|
|
@@ -4077,7 +4375,7 @@ function useCommandManagement({
|
|
|
4077
4375
|
const repositoryRef = useRef6(
|
|
4078
4376
|
repository || new LocalStorageCommandRepository()
|
|
4079
4377
|
);
|
|
4080
|
-
const [commands, setCommands] =
|
|
4378
|
+
const [commands, setCommands] = useState8([]);
|
|
4081
4379
|
const refreshCommands = useCallback6(async () => {
|
|
4082
4380
|
try {
|
|
4083
4381
|
const cmdList = await repositoryRef.current.listCommands();
|
|
@@ -4119,10 +4417,10 @@ function useCommandManagement({
|
|
|
4119
4417
|
}
|
|
4120
4418
|
|
|
4121
4419
|
// src/hooks/useToolRegistry.ts
|
|
4122
|
-
import { useState as
|
|
4420
|
+
import { useState as useState9, useCallback as useCallback7, useRef as useRef7, useMemo as useMemo4 } from "react";
|
|
4123
4421
|
function useToolRegistry() {
|
|
4124
4422
|
const toolRegistryRef = useRef7(/* @__PURE__ */ new Map());
|
|
4125
|
-
const [toolRegistryVersion, setToolRegistryVersion] =
|
|
4423
|
+
const [toolRegistryVersion, setToolRegistryVersion] = useState9(0);
|
|
4126
4424
|
const toolOwnershipRef = useRef7(/* @__PURE__ */ new Map());
|
|
4127
4425
|
const invisibleRef = useRef7(/* @__PURE__ */ new Set());
|
|
4128
4426
|
const registerTools = useCallback7((id, tools, options) => {
|
|
@@ -4182,7 +4480,7 @@ function useToolRegistry() {
|
|
|
4182
4480
|
}
|
|
4183
4481
|
|
|
4184
4482
|
// src/hooks/usePromptState.ts
|
|
4185
|
-
import { useState as
|
|
4483
|
+
import { useState as useState10, useCallback as useCallback8, useRef as useRef8, useMemo as useMemo5, useEffect as useEffect8 } from "react";
|
|
4186
4484
|
function usePromptState({
|
|
4187
4485
|
systemPrompt,
|
|
4188
4486
|
clientRef,
|
|
@@ -4191,7 +4489,7 @@ function usePromptState({
|
|
|
4191
4489
|
const promptsRef = useRef8(/* @__PURE__ */ new Map());
|
|
4192
4490
|
const suggestionsRef = useRef8(/* @__PURE__ */ new Map());
|
|
4193
4491
|
const waitersRef = useRef8(/* @__PURE__ */ new Map());
|
|
4194
|
-
const [suggestionsVersion, setSuggestionsVersion] =
|
|
4492
|
+
const [suggestionsVersion, setSuggestionsVersion] = useState10(0);
|
|
4195
4493
|
const buildStateFromPrompts = useCallback8(() => {
|
|
4196
4494
|
const promptParts = [];
|
|
4197
4495
|
if (systemPrompt) {
|
|
@@ -4254,14 +4552,14 @@ function usePromptState({
|
|
|
4254
4552
|
}
|
|
4255
4553
|
|
|
4256
4554
|
// src/hooks/useFeedback.ts
|
|
4257
|
-
import { useState as
|
|
4555
|
+
import { useState as useState11, useEffect as useEffect9, useRef as useRef9, useCallback as useCallback9 } from "react";
|
|
4258
4556
|
function useFeedback({
|
|
4259
4557
|
clientRef,
|
|
4260
4558
|
repository,
|
|
4261
4559
|
getDisplayedChatId,
|
|
4262
4560
|
setMessages
|
|
4263
4561
|
}) {
|
|
4264
|
-
const [enabled, setEnabled] =
|
|
4562
|
+
const [enabled, setEnabled] = useState11(false);
|
|
4265
4563
|
const enabledRef = useRef9(false);
|
|
4266
4564
|
useEffect9(() => {
|
|
4267
4565
|
enabledRef.current = enabled;
|
|
@@ -4315,8 +4613,120 @@ function useFeedback({
|
|
|
4315
4613
|
};
|
|
4316
4614
|
}
|
|
4317
4615
|
|
|
4616
|
+
// src/hooks/useToolExecution.ts
|
|
4617
|
+
import { useState as useState12, useCallback as useCallback10, useRef as useRef10 } from "react";
|
|
4618
|
+
function useToolExecution({
|
|
4619
|
+
clientRef,
|
|
4620
|
+
aggregatedToolsRef,
|
|
4621
|
+
toolOwnershipRef,
|
|
4622
|
+
promptsRef,
|
|
4623
|
+
isInvisible,
|
|
4624
|
+
getWaiter
|
|
4625
|
+
}) {
|
|
4626
|
+
const [pendingApprovals, setPendingApprovals] = useState12([]);
|
|
4627
|
+
const pendingApprovalToolCallsRef = useRef10(/* @__PURE__ */ new Map());
|
|
4628
|
+
const handleApprovalRequest = useCallback10((event) => {
|
|
4629
|
+
console.log("[useToolExecution] Tool approval requested:", event.toolCallName, event.toolCallId);
|
|
4630
|
+
setPendingApprovals((prev) => [
|
|
4631
|
+
...prev,
|
|
4632
|
+
{
|
|
4633
|
+
toolCallId: event.toolCallId,
|
|
4634
|
+
toolCallName: event.toolCallName,
|
|
4635
|
+
toolCallArgs: event.toolCallArgs,
|
|
4636
|
+
annotations: event.annotations
|
|
4637
|
+
}
|
|
4638
|
+
]);
|
|
4639
|
+
}, []);
|
|
4640
|
+
const executeToolCall = useCallback10(async (toolCallId, name, input) => {
|
|
4641
|
+
const client = clientRef.current;
|
|
4642
|
+
if (!client) {
|
|
4643
|
+
console.error("[useToolExecution] No client available for tool execution");
|
|
4644
|
+
return;
|
|
4645
|
+
}
|
|
4646
|
+
try {
|
|
4647
|
+
const ownerId = toolOwnershipRef.current.get(name);
|
|
4648
|
+
console.log(`[useToolExecution] Tool "${name}" owned by component:`, ownerId);
|
|
4649
|
+
console.log("[useToolExecution] Executing tool...");
|
|
4650
|
+
const result = await executeDefinedTool(aggregatedToolsRef.current, name, input);
|
|
4651
|
+
const isErrorResult = result && typeof result === "object" && ("error" in result || result.success === false);
|
|
4652
|
+
const ownerIsInvisible = ownerId ? isInvisible(ownerId) : false;
|
|
4653
|
+
if (ownerId && !isErrorResult && !ownerIsInvisible) {
|
|
4654
|
+
const waiter = getWaiter(ownerId);
|
|
4655
|
+
if (waiter) {
|
|
4656
|
+
console.log(`[useToolExecution] Waiting for prompt change from ${ownerId}...`);
|
|
4657
|
+
await waiter();
|
|
4658
|
+
console.log("[useToolExecution] Prompt change wait complete");
|
|
4659
|
+
}
|
|
4660
|
+
} else if (isErrorResult) {
|
|
4661
|
+
console.log("[useToolExecution] Tool returned error, skipping prompt wait");
|
|
4662
|
+
} else if (ownerIsInvisible) {
|
|
4663
|
+
console.log("[useToolExecution] Component is invisible, skipping prompt wait");
|
|
4664
|
+
}
|
|
4665
|
+
let updatedState = null;
|
|
4666
|
+
if (ownerId) {
|
|
4667
|
+
const prompt = promptsRef.current.get(ownerId);
|
|
4668
|
+
if (prompt) {
|
|
4669
|
+
updatedState = { context: prompt };
|
|
4670
|
+
console.log(`[useToolExecution] Updated state from ${ownerId}`);
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
client.sendToolResponse(toolCallId, result, updatedState);
|
|
4674
|
+
} catch (err) {
|
|
4675
|
+
console.error("Tool execution error:", err);
|
|
4676
|
+
client.sendToolResponse(toolCallId, {
|
|
4677
|
+
error: err instanceof Error ? err.message : "Unknown error"
|
|
4678
|
+
});
|
|
4679
|
+
}
|
|
4680
|
+
}, [clientRef, aggregatedToolsRef, toolOwnershipRef, promptsRef, isInvisible, getWaiter]);
|
|
4681
|
+
const storePendingToolCall = useCallback10((toolCallId, name, input, toolCallData) => {
|
|
4682
|
+
console.log(`[useToolExecution] Storing pending tool call "${name}" for approval`);
|
|
4683
|
+
pendingApprovalToolCallsRef.current.set(toolCallId, { name, input, toolCallData });
|
|
4684
|
+
}, []);
|
|
4685
|
+
const executePendingToolAfterApproval = useCallback10(async (toolCallId) => {
|
|
4686
|
+
const pendingTool = pendingApprovalToolCallsRef.current.get(toolCallId);
|
|
4687
|
+
if (!pendingTool) {
|
|
4688
|
+
console.warn(`[useToolExecution] No pending tool found for ${toolCallId}`);
|
|
4689
|
+
return;
|
|
4690
|
+
}
|
|
4691
|
+
pendingApprovalToolCallsRef.current.delete(toolCallId);
|
|
4692
|
+
await executeToolCall(toolCallId, pendingTool.name, pendingTool.input);
|
|
4693
|
+
}, [executeToolCall]);
|
|
4694
|
+
const approveAll = useCallback10(async () => {
|
|
4695
|
+
if (!clientRef.current) return;
|
|
4696
|
+
console.log("[useToolExecution] Approving all tool calls:", pendingApprovals.length);
|
|
4697
|
+
const pendingTools = [...pendingApprovals];
|
|
4698
|
+
for (const pending of pendingTools) {
|
|
4699
|
+
clientRef.current.sendToolApprovalResponse(pending.toolCallId, true);
|
|
4700
|
+
}
|
|
4701
|
+
setPendingApprovals([]);
|
|
4702
|
+
for (const tool of pendingTools) {
|
|
4703
|
+
await executePendingToolAfterApproval(tool.toolCallId);
|
|
4704
|
+
}
|
|
4705
|
+
}, [clientRef, pendingApprovals, executePendingToolAfterApproval]);
|
|
4706
|
+
const rejectAll = useCallback10((reason) => {
|
|
4707
|
+
if (!clientRef.current) return;
|
|
4708
|
+
console.log("[useToolExecution] Rejecting all tool calls:", pendingApprovals.length, reason);
|
|
4709
|
+
const pendingTools = [...pendingApprovals];
|
|
4710
|
+
for (const pending of pendingTools) {
|
|
4711
|
+
clientRef.current.sendToolApprovalResponse(pending.toolCallId, false, reason);
|
|
4712
|
+
}
|
|
4713
|
+
setPendingApprovals([]);
|
|
4714
|
+
for (const tool of pendingTools) {
|
|
4715
|
+
pendingApprovalToolCallsRef.current.delete(tool.toolCallId);
|
|
4716
|
+
}
|
|
4717
|
+
}, [clientRef, pendingApprovals]);
|
|
4718
|
+
return {
|
|
4719
|
+
pendingApprovals,
|
|
4720
|
+
handleApprovalRequest,
|
|
4721
|
+
executeToolCall,
|
|
4722
|
+
storePendingToolCall,
|
|
4723
|
+
approveAll,
|
|
4724
|
+
rejectAll
|
|
4725
|
+
};
|
|
4726
|
+
}
|
|
4727
|
+
|
|
4318
4728
|
// src/providers/useAIProvider.tsx
|
|
4319
|
-
import { Fragment as Fragment3, jsx as
|
|
4729
|
+
import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4320
4730
|
var __UseAIContext = createContext4(null);
|
|
4321
4731
|
var hasWarnedAboutMissingProvider = false;
|
|
4322
4732
|
var noOpContextValue = {
|
|
@@ -4396,24 +4806,24 @@ function UseAIProvider({
|
|
|
4396
4806
|
const fileUploadConfig = fileUploadConfigProp === false ? void 0 : fileUploadConfigProp ?? DEFAULT_FILE_UPLOAD_CONFIG;
|
|
4397
4807
|
const theme = { ...defaultTheme, ...customTheme };
|
|
4398
4808
|
const strings = { ...defaultStrings, ...customStrings };
|
|
4399
|
-
const [connected, setConnected] =
|
|
4400
|
-
const [isChatOpen, setIsChatOpen] =
|
|
4401
|
-
const [loading, setLoading] =
|
|
4402
|
-
const [messages, setMessages] =
|
|
4403
|
-
const [fileProcessingState, setFileProcessingState] =
|
|
4404
|
-
const handleSetChatOpen =
|
|
4809
|
+
const [connected, setConnected] = useState13(false);
|
|
4810
|
+
const [isChatOpen, setIsChatOpen] = useState13(false);
|
|
4811
|
+
const [loading, setLoading] = useState13(false);
|
|
4812
|
+
const [messages, setMessages] = useState13([]);
|
|
4813
|
+
const [fileProcessingState, setFileProcessingState] = useState13(null);
|
|
4814
|
+
const handleSetChatOpen = useCallback11((open) => {
|
|
4405
4815
|
setIsChatOpen(open);
|
|
4406
4816
|
onOpenChange?.(open);
|
|
4407
4817
|
}, [onOpenChange]);
|
|
4408
|
-
const [streamingText, setStreamingText] =
|
|
4409
|
-
const streamingChatIdRef =
|
|
4410
|
-
const [executingTool, setExecutingTool] =
|
|
4411
|
-
const executingToolFallbackRef =
|
|
4412
|
-
const clientRef =
|
|
4413
|
-
const repositoryRef =
|
|
4818
|
+
const [streamingText, setStreamingText] = useState13("");
|
|
4819
|
+
const streamingChatIdRef = useRef11(null);
|
|
4820
|
+
const [executingTool, setExecutingTool] = useState13(null);
|
|
4821
|
+
const executingToolFallbackRef = useRef11(null);
|
|
4822
|
+
const clientRef = useRef11(null);
|
|
4823
|
+
const repositoryRef = useRef11(
|
|
4414
4824
|
chatRepository || new LocalStorageChatRepository()
|
|
4415
4825
|
);
|
|
4416
|
-
const handleSendMessageRef =
|
|
4826
|
+
const handleSendMessageRef = useRef11(null);
|
|
4417
4827
|
const {
|
|
4418
4828
|
registerTools,
|
|
4419
4829
|
unregisterTools,
|
|
@@ -4435,11 +4845,19 @@ function UseAIProvider({
|
|
|
4435
4845
|
clientRef,
|
|
4436
4846
|
connected
|
|
4437
4847
|
});
|
|
4438
|
-
const stableSendMessage =
|
|
4848
|
+
const stableSendMessage = useCallback11(async (message, attachments) => {
|
|
4439
4849
|
if (handleSendMessageRef.current) {
|
|
4440
4850
|
await handleSendMessageRef.current(message, attachments);
|
|
4441
4851
|
}
|
|
4442
4852
|
}, []);
|
|
4853
|
+
const toolExecution = useToolExecution({
|
|
4854
|
+
clientRef,
|
|
4855
|
+
aggregatedToolsRef,
|
|
4856
|
+
toolOwnershipRef,
|
|
4857
|
+
promptsRef,
|
|
4858
|
+
isInvisible,
|
|
4859
|
+
getWaiter
|
|
4860
|
+
});
|
|
4443
4861
|
const chatManagement = useChatManagement({
|
|
4444
4862
|
repository: repositoryRef.current,
|
|
4445
4863
|
clientRef,
|
|
@@ -4448,7 +4866,8 @@ function UseAIProvider({
|
|
|
4448
4866
|
onSendMessage: stableSendMessage,
|
|
4449
4867
|
setOpen: handleSetChatOpen,
|
|
4450
4868
|
connected,
|
|
4451
|
-
loading
|
|
4869
|
+
loading,
|
|
4870
|
+
hasPendingApproval: toolExecution.pendingApprovals.length > 0
|
|
4452
4871
|
});
|
|
4453
4872
|
const {
|
|
4454
4873
|
currentChatId,
|
|
@@ -4518,44 +4937,20 @@ function UseAIProvider({
|
|
|
4518
4937
|
}
|
|
4519
4938
|
const name = toolCallData.name;
|
|
4520
4939
|
const input = JSON.parse(toolCallData.args);
|
|
4521
|
-
|
|
4940
|
+
const tool = aggregatedToolsRef.current[name];
|
|
4941
|
+
if (!tool) {
|
|
4522
4942
|
console.log(`[Provider] Tool "${name}" not found in useAI tools, skipping (likely a workflow tool)`);
|
|
4523
4943
|
return;
|
|
4524
4944
|
}
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
const result = await executeDefinedTool(aggregatedToolsRef.current, name, input);
|
|
4530
|
-
const isErrorResult = result && typeof result === "object" && ("error" in result || result.success === false);
|
|
4531
|
-
const ownerIsInvisible = ownerId ? isInvisible(ownerId) : false;
|
|
4532
|
-
if (ownerId && !isErrorResult && !ownerIsInvisible) {
|
|
4533
|
-
const waiter = getWaiter(ownerId);
|
|
4534
|
-
if (waiter) {
|
|
4535
|
-
console.log(`[useAI] Waiting for prompt change from ${ownerId}...`);
|
|
4536
|
-
await waiter();
|
|
4537
|
-
console.log("[useAI] Prompt change wait complete");
|
|
4538
|
-
}
|
|
4539
|
-
} else if (isErrorResult) {
|
|
4540
|
-
console.log("[useAI] Tool returned error, skipping prompt wait");
|
|
4541
|
-
} else if (ownerIsInvisible) {
|
|
4542
|
-
console.log("[useAI] Component is invisible, skipping prompt wait");
|
|
4543
|
-
}
|
|
4544
|
-
let updatedState = null;
|
|
4545
|
-
if (ownerId) {
|
|
4546
|
-
const prompt = promptsRef.current.get(ownerId);
|
|
4547
|
-
if (prompt) {
|
|
4548
|
-
updatedState = { context: prompt };
|
|
4549
|
-
console.log(`[useAI] Updated state from ${ownerId}`);
|
|
4550
|
-
}
|
|
4551
|
-
}
|
|
4552
|
-
client.sendToolResponse(toolCallId, result, updatedState);
|
|
4553
|
-
} catch (err) {
|
|
4554
|
-
console.error("Tool execution error:", err);
|
|
4555
|
-
client.sendToolResponse(toolCallId, {
|
|
4556
|
-
error: err instanceof Error ? err.message : "Unknown error"
|
|
4557
|
-
});
|
|
4945
|
+
if (tool._options?.annotations?.destructiveHint === true) {
|
|
4946
|
+
console.log(`[Provider] Tool "${name}" requires approval, deferring execution`);
|
|
4947
|
+
toolExecution.storePendingToolCall(toolCallId, name, input, toolCallData);
|
|
4948
|
+
return;
|
|
4558
4949
|
}
|
|
4950
|
+
await toolExecution.executeToolCall(toolCallId, name, input);
|
|
4951
|
+
} else if (event.type === TOOL_APPROVAL_REQUEST) {
|
|
4952
|
+
const e = event;
|
|
4953
|
+
toolExecution.handleApprovalRequest(e);
|
|
4559
4954
|
} else if (event.type === EventType.TEXT_MESSAGE_CONTENT) {
|
|
4560
4955
|
const contentEvent = event;
|
|
4561
4956
|
setStreamingText((prev) => prev + contentEvent.delta);
|
|
@@ -4595,7 +4990,7 @@ function UseAIProvider({
|
|
|
4595
4990
|
client.setMcpHeadersProvider(mcpHeadersProvider);
|
|
4596
4991
|
}
|
|
4597
4992
|
}, [mcpHeadersProvider]);
|
|
4598
|
-
const lastRegisteredToolsRef =
|
|
4993
|
+
const lastRegisteredToolsRef = useRef11("");
|
|
4599
4994
|
useEffect10(() => {
|
|
4600
4995
|
const client = clientRef.current;
|
|
4601
4996
|
if (!client || !client.isConnected() || !hasTools) return;
|
|
@@ -4614,7 +5009,7 @@ function UseAIProvider({
|
|
|
4614
5009
|
console.error("Failed to register tools:", err);
|
|
4615
5010
|
}
|
|
4616
5011
|
}, [hasTools, aggregatedTools, connected]);
|
|
4617
|
-
const handleSendMessage =
|
|
5012
|
+
const handleSendMessage = useCallback11(async (message, attachments) => {
|
|
4618
5013
|
if (!clientRef.current) return;
|
|
4619
5014
|
setStreamingText("");
|
|
4620
5015
|
const activatedChatId = activatePendingChat();
|
|
@@ -4746,7 +5141,14 @@ function UseAIProvider({
|
|
|
4746
5141
|
isOpen: isChatOpen,
|
|
4747
5142
|
setOpen: handleSetChatOpen
|
|
4748
5143
|
},
|
|
4749
|
-
|
|
5144
|
+
tools: {
|
|
5145
|
+
executing: executingToolDisplay,
|
|
5146
|
+
pending: {
|
|
5147
|
+
tools: toolExecution.pendingApprovals,
|
|
5148
|
+
approveAll: toolExecution.approveAll,
|
|
5149
|
+
rejectAll: toolExecution.rejectAll
|
|
5150
|
+
}
|
|
5151
|
+
},
|
|
4750
5152
|
feedback: {
|
|
4751
5153
|
enabled: feedback.enabled,
|
|
4752
5154
|
submit: feedback.submitFeedback
|
|
@@ -4779,21 +5181,24 @@ function UseAIProvider({
|
|
|
4779
5181
|
onDeleteCommand: deleteCommand,
|
|
4780
5182
|
executingTool: executingToolDisplay,
|
|
4781
5183
|
feedbackEnabled: feedback.enabled,
|
|
4782
|
-
onFeedback: feedback.submitFeedback
|
|
5184
|
+
onFeedback: feedback.submitFeedback,
|
|
5185
|
+
pendingApprovals: toolExecution.pendingApprovals,
|
|
5186
|
+
onApproveToolCall: toolExecution.pendingApprovals.length > 0 ? toolExecution.approveAll : void 0,
|
|
5187
|
+
onRejectToolCall: toolExecution.pendingApprovals.length > 0 ? toolExecution.rejectAll : void 0
|
|
4783
5188
|
};
|
|
4784
5189
|
const renderDefaultChat = () => {
|
|
4785
5190
|
if (isUIDisabled) return null;
|
|
4786
|
-
return /* @__PURE__ */
|
|
5191
|
+
return /* @__PURE__ */ jsx14(UseAIFloatingChatWrapper, { isOpen: isChatOpen, onClose: () => handleSetChatOpen(false), children: /* @__PURE__ */ jsx14(
|
|
4787
5192
|
UseAIChatPanel,
|
|
4788
5193
|
{
|
|
4789
5194
|
...chatPanelProps,
|
|
4790
|
-
closeButton: /* @__PURE__ */
|
|
5195
|
+
closeButton: /* @__PURE__ */ jsx14(CloseButton, { onClick: () => handleSetChatOpen(false) })
|
|
4791
5196
|
}
|
|
4792
5197
|
) });
|
|
4793
5198
|
};
|
|
4794
5199
|
const renderCustomChat = () => {
|
|
4795
5200
|
if (!CustomChat) return null;
|
|
4796
|
-
return /* @__PURE__ */
|
|
5201
|
+
return /* @__PURE__ */ jsx14(
|
|
4797
5202
|
CustomChat,
|
|
4798
5203
|
{
|
|
4799
5204
|
isOpen: isChatOpen,
|
|
@@ -4812,8 +5217,8 @@ function UseAIProvider({
|
|
|
4812
5217
|
};
|
|
4813
5218
|
const renderBuiltInChat = () => {
|
|
4814
5219
|
if (!renderChat) return null;
|
|
4815
|
-
return /* @__PURE__ */
|
|
4816
|
-
ButtonComponent && /* @__PURE__ */
|
|
5220
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
5221
|
+
ButtonComponent && /* @__PURE__ */ jsx14(
|
|
4817
5222
|
ButtonComponent,
|
|
4818
5223
|
{
|
|
4819
5224
|
onClick: () => handleSetChatOpen(true),
|
|
@@ -4823,7 +5228,7 @@ function UseAIProvider({
|
|
|
4823
5228
|
hasCustomChat ? renderCustomChat() : renderDefaultChat()
|
|
4824
5229
|
] });
|
|
4825
5230
|
};
|
|
4826
|
-
return /* @__PURE__ */
|
|
5231
|
+
return /* @__PURE__ */ jsx14(ThemeContext.Provider, { value: theme, children: /* @__PURE__ */ jsx14(StringsContext.Provider, { value: strings, children: /* @__PURE__ */ jsx14(__UseAIContext.Provider, { value, children: /* @__PURE__ */ jsxs10(__UseAIChatContext.Provider, { value: chatUIContextValue, children: [
|
|
4827
5232
|
children,
|
|
4828
5233
|
renderBuiltInChat()
|
|
4829
5234
|
] }) }) }) });
|
|
@@ -4843,11 +5248,11 @@ function useAIContext() {
|
|
|
4843
5248
|
}
|
|
4844
5249
|
|
|
4845
5250
|
// src/hooks/useStableTools.ts
|
|
4846
|
-
import { useRef as
|
|
5251
|
+
import { useRef as useRef12 } from "react";
|
|
4847
5252
|
function useStableTools(tools) {
|
|
4848
|
-
const latestToolsRef =
|
|
4849
|
-
const stableToolsRef =
|
|
4850
|
-
const prevToolNamesRef =
|
|
5253
|
+
const latestToolsRef = useRef12({});
|
|
5254
|
+
const stableToolsRef = useRef12({});
|
|
5255
|
+
const prevToolNamesRef = useRef12("");
|
|
4851
5256
|
if (!tools) {
|
|
4852
5257
|
latestToolsRef.current = {};
|
|
4853
5258
|
return void 0;
|
|
@@ -4917,13 +5322,13 @@ function useAI(options = {}) {
|
|
|
4917
5322
|
const { connected, tools, client, prompts } = useAIContext();
|
|
4918
5323
|
const { register: registerTools, unregister: unregisterTools } = tools;
|
|
4919
5324
|
const { update: updatePrompt, registerWaiter, unregisterWaiter } = prompts;
|
|
4920
|
-
const [response, setResponse] =
|
|
4921
|
-
const [loading, setLoading] =
|
|
4922
|
-
const [error, setError] =
|
|
4923
|
-
const hookId =
|
|
4924
|
-
const toolsRef =
|
|
4925
|
-
const componentRef =
|
|
4926
|
-
const promptChangeResolvers =
|
|
5325
|
+
const [response, setResponse] = useState14(null);
|
|
5326
|
+
const [loading, setLoading] = useState14(false);
|
|
5327
|
+
const [error, setError] = useState14(null);
|
|
5328
|
+
const hookId = useRef13(`useAI-${Math.random().toString(36).substr(2, 9)}`);
|
|
5329
|
+
const toolsRef = useRef13({});
|
|
5330
|
+
const componentRef = useRef13(null);
|
|
5331
|
+
const promptChangeResolvers = useRef13([]);
|
|
4927
5332
|
const stableTools = useStableTools(options.tools);
|
|
4928
5333
|
const toolsKey = useMemo6(() => {
|
|
4929
5334
|
if (!options.tools) return "";
|
|
@@ -4935,7 +5340,7 @@ function useAI(options = {}) {
|
|
|
4935
5340
|
componentRef.current.setAttribute("data-useai-context", "true");
|
|
4936
5341
|
}
|
|
4937
5342
|
}, []);
|
|
4938
|
-
const waitForPromptChange =
|
|
5343
|
+
const waitForPromptChange = useCallback12(() => {
|
|
4939
5344
|
return new Promise((resolve) => {
|
|
4940
5345
|
const timeoutMs = 100;
|
|
4941
5346
|
const timeoutId = setTimeout(() => {
|
|
@@ -4967,7 +5372,7 @@ function useAI(options = {}) {
|
|
|
4967
5372
|
promptChangeResolvers.current = [];
|
|
4968
5373
|
}
|
|
4969
5374
|
}, [enabled, options.prompt, memoizedSuggestions, updatePrompt]);
|
|
4970
|
-
const updatePromptRef =
|
|
5375
|
+
const updatePromptRef = useRef13(updatePrompt);
|
|
4971
5376
|
updatePromptRef.current = updatePrompt;
|
|
4972
5377
|
useEffect11(() => {
|
|
4973
5378
|
const id = hookId.current;
|
|
@@ -4998,7 +5403,7 @@ function useAI(options = {}) {
|
|
|
4998
5403
|
unsubscribe();
|
|
4999
5404
|
};
|
|
5000
5405
|
}, [enabled, client]);
|
|
5001
|
-
const handleAGUIEvent =
|
|
5406
|
+
const handleAGUIEvent = useCallback12(async (event) => {
|
|
5002
5407
|
switch (event.type) {
|
|
5003
5408
|
case EventType.TEXT_MESSAGE_END: {
|
|
5004
5409
|
const content = client?.currentMessageContent;
|
|
@@ -5018,7 +5423,7 @@ function useAI(options = {}) {
|
|
|
5018
5423
|
}
|
|
5019
5424
|
}
|
|
5020
5425
|
}, [client, options.onError]);
|
|
5021
|
-
const generate =
|
|
5426
|
+
const generate = useCallback12(async (prompt) => {
|
|
5022
5427
|
if (!enabled) {
|
|
5023
5428
|
const error2 = new Error("AI features are disabled");
|
|
5024
5429
|
setError(error2);
|
|
@@ -5054,17 +5459,17 @@ function useAI(options = {}) {
|
|
|
5054
5459
|
}
|
|
5055
5460
|
|
|
5056
5461
|
// src/useAIWorkflow.ts
|
|
5057
|
-
import { useState as
|
|
5462
|
+
import { useState as useState15, useCallback as useCallback13, useRef as useRef14, useEffect as useEffect12 } from "react";
|
|
5058
5463
|
import { EventType as EventType3 } from "@meetsmore-oss/use-ai-core";
|
|
5059
5464
|
import { v4 as uuidv43 } from "uuid";
|
|
5060
5465
|
function useAIWorkflow(runner, workflowId) {
|
|
5061
5466
|
const { connected, client } = useAIContext();
|
|
5062
|
-
const [status, setStatus] =
|
|
5063
|
-
const [text, setText] =
|
|
5064
|
-
const [error, setError] =
|
|
5065
|
-
const currentWorkflowRef =
|
|
5066
|
-
const eventListenerIdRef =
|
|
5067
|
-
const handleWorkflowEvent =
|
|
5467
|
+
const [status, setStatus] = useState15("idle");
|
|
5468
|
+
const [text, setText] = useState15(null);
|
|
5469
|
+
const [error, setError] = useState15(null);
|
|
5470
|
+
const currentWorkflowRef = useRef14(null);
|
|
5471
|
+
const eventListenerIdRef = useRef14(`useAIWorkflow-${Math.random().toString(36).substr(2, 9)}`);
|
|
5472
|
+
const handleWorkflowEvent = useCallback13(async (event) => {
|
|
5068
5473
|
const currentWorkflow = currentWorkflowRef.current;
|
|
5069
5474
|
if (!currentWorkflow) return;
|
|
5070
5475
|
if (event.type === EventType3.RUN_STARTED) {
|
|
@@ -5156,7 +5561,7 @@ function useAIWorkflow(runner, workflowId) {
|
|
|
5156
5561
|
unsubscribe();
|
|
5157
5562
|
};
|
|
5158
5563
|
}, [client, handleWorkflowEvent]);
|
|
5159
|
-
const trigger =
|
|
5564
|
+
const trigger = useCallback13(async (options) => {
|
|
5160
5565
|
if (!client?.isConnected()) {
|
|
5161
5566
|
const err = new Error("Not connected to server");
|
|
5162
5567
|
setError(err);
|
|
@@ -5232,7 +5637,7 @@ export {
|
|
|
5232
5637
|
defaultTheme,
|
|
5233
5638
|
defineTool,
|
|
5234
5639
|
executeDefinedTool,
|
|
5235
|
-
|
|
5640
|
+
findTransformerPattern,
|
|
5236
5641
|
generateChatId,
|
|
5237
5642
|
generateCommandId,
|
|
5238
5643
|
generateMessageId,
|