@meetsmore-oss/use-ai-client 1.5.1 → 1.7.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 +817 -432
- package/dist/bundled.js.map +1 -1
- package/dist/index.d.ts +105 -45
- package/dist/index.js +815 -427
- 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
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
});
|
|
1265
|
-
continue;
|
|
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
|
-
);
|
|
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) => {
|
|
1278
1338
|
contentParts.push({
|
|
1279
1339
|
type: "transformed_file",
|
|
1280
|
-
text
|
|
1340
|
+
text,
|
|
1281
1341
|
originalFile: {
|
|
1282
|
-
name:
|
|
1283
|
-
mimeType:
|
|
1284
|
-
size:
|
|
1342
|
+
name: files[i].name,
|
|
1343
|
+
mimeType: files[i].type,
|
|
1344
|
+
size: files[i].size
|
|
1285
1345
|
}
|
|
1286
1346
|
});
|
|
1287
|
-
onFileProgress?.(
|
|
1288
|
-
}
|
|
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
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
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(",")
|
|
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
|
|
2590
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
|
|
@@ -2798,8 +3072,6 @@ var UseAIClient = class {
|
|
|
2798
3072
|
_tools = [];
|
|
2799
3073
|
_messages = [];
|
|
2800
3074
|
_state = null;
|
|
2801
|
-
// MCP headers provider
|
|
2802
|
-
mcpHeadersProvider;
|
|
2803
3075
|
// Agent selection
|
|
2804
3076
|
_availableAgents = [];
|
|
2805
3077
|
_defaultAgent = null;
|
|
@@ -2958,22 +3230,15 @@ var UseAIClient = class {
|
|
|
2958
3230
|
updateState(state) {
|
|
2959
3231
|
this._state = state;
|
|
2960
3232
|
}
|
|
2961
|
-
/**
|
|
2962
|
-
* Sets the MCP headers provider.
|
|
2963
|
-
* The provider will be called each time a message is sent to get fresh headers.
|
|
2964
|
-
*
|
|
2965
|
-
* @param provider - Function that returns MCP headers configuration
|
|
2966
|
-
*/
|
|
2967
|
-
setMcpHeadersProvider(provider) {
|
|
2968
|
-
this.mcpHeadersProvider = provider;
|
|
2969
|
-
}
|
|
2970
3233
|
/**
|
|
2971
3234
|
* Sends a user prompt to the AI.
|
|
2972
3235
|
*
|
|
2973
3236
|
* @param prompt - The user's prompt/question (text part)
|
|
2974
3237
|
* @param multimodalContent - Optional multimodal content (text, images, files)
|
|
3238
|
+
* @param forwardedProps - Optional props to forward to the server (e.g., telemetryMetadata, mcpHeaders).
|
|
3239
|
+
* Internally merged with other forwardedProps.
|
|
2975
3240
|
*/
|
|
2976
|
-
async sendPrompt(prompt, multimodalContent) {
|
|
3241
|
+
async sendPrompt(prompt, multimodalContent, forwardedProps) {
|
|
2977
3242
|
let messageContent = prompt;
|
|
2978
3243
|
if (multimodalContent && multimodalContent.length > 0) {
|
|
2979
3244
|
messageContent = multimodalContent.map((part) => {
|
|
@@ -3003,14 +3268,6 @@ var UseAIClient = class {
|
|
|
3003
3268
|
// Type cast needed for Message type compatibility
|
|
3004
3269
|
};
|
|
3005
3270
|
this._messages.push(userMessage);
|
|
3006
|
-
let mcpHeaders;
|
|
3007
|
-
if (this.mcpHeadersProvider) {
|
|
3008
|
-
try {
|
|
3009
|
-
mcpHeaders = await this.mcpHeadersProvider();
|
|
3010
|
-
} catch (error) {
|
|
3011
|
-
console.error("[UseAIClient] Failed to get MCP headers:", error);
|
|
3012
|
-
}
|
|
3013
|
-
}
|
|
3014
3271
|
const runInput = {
|
|
3015
3272
|
threadId: this.threadId,
|
|
3016
3273
|
// Use getter to ensure non-null
|
|
@@ -3019,13 +3276,14 @@ var UseAIClient = class {
|
|
|
3019
3276
|
tools: this._tools.map((t) => ({
|
|
3020
3277
|
name: t.name,
|
|
3021
3278
|
description: t.description,
|
|
3022
|
-
parameters: t.parameters
|
|
3279
|
+
parameters: t.parameters,
|
|
3280
|
+
annotations: t.annotations
|
|
3023
3281
|
})),
|
|
3024
3282
|
state: this._state,
|
|
3025
3283
|
context: [],
|
|
3026
3284
|
forwardedProps: {
|
|
3027
|
-
...
|
|
3028
|
-
...
|
|
3285
|
+
...this._selectedAgent ? { agent: this._selectedAgent } : {},
|
|
3286
|
+
...forwardedProps || {}
|
|
3029
3287
|
}
|
|
3030
3288
|
};
|
|
3031
3289
|
this.send({
|
|
@@ -3062,6 +3320,24 @@ var UseAIClient = class {
|
|
|
3062
3320
|
this._messages.push(toolResultMsg);
|
|
3063
3321
|
this.send(toolResultMessage);
|
|
3064
3322
|
}
|
|
3323
|
+
/**
|
|
3324
|
+
* Sends a tool approval response back to the server.
|
|
3325
|
+
*
|
|
3326
|
+
* @param toolCallId - The ID of the tool call being approved/rejected
|
|
3327
|
+
* @param approved - Whether the tool execution is approved
|
|
3328
|
+
* @param reason - Optional reason for rejection (shown to AI)
|
|
3329
|
+
*/
|
|
3330
|
+
sendToolApprovalResponse(toolCallId, approved, reason) {
|
|
3331
|
+
const message = {
|
|
3332
|
+
type: "tool_approval_response",
|
|
3333
|
+
data: {
|
|
3334
|
+
toolCallId,
|
|
3335
|
+
approved,
|
|
3336
|
+
reason
|
|
3337
|
+
}
|
|
3338
|
+
};
|
|
3339
|
+
this.send(message);
|
|
3340
|
+
}
|
|
3065
3341
|
/**
|
|
3066
3342
|
* Retrieves accumulated tool call data for a specific tool call ID.
|
|
3067
3343
|
* Used to get the complete tool name and arguments after they've been streamed
|
|
@@ -3534,7 +3810,7 @@ var LocalStorageChatRepository = class {
|
|
|
3534
3810
|
};
|
|
3535
3811
|
|
|
3536
3812
|
// src/hooks/useChatManagement.ts
|
|
3537
|
-
import { useState as
|
|
3813
|
+
import { useState as useState6, useCallback as useCallback4, useRef as useRef5, useEffect as useEffect5 } from "react";
|
|
3538
3814
|
var CHAT_TITLE_MAX_LENGTH = 50;
|
|
3539
3815
|
function deepEquals(a, b) {
|
|
3540
3816
|
return JSON.stringify(a) === JSON.stringify(b);
|
|
@@ -3577,10 +3853,11 @@ function useChatManagement({
|
|
|
3577
3853
|
onSendMessage,
|
|
3578
3854
|
setOpen,
|
|
3579
3855
|
connected,
|
|
3580
|
-
loading
|
|
3856
|
+
loading,
|
|
3857
|
+
hasPendingApproval
|
|
3581
3858
|
}) {
|
|
3582
|
-
const [currentChatId, setCurrentChatId] =
|
|
3583
|
-
const [pendingChatId, setPendingChatId] =
|
|
3859
|
+
const [currentChatId, setCurrentChatId] = useState6(null);
|
|
3860
|
+
const [pendingChatId, setPendingChatId] = useState6(null);
|
|
3584
3861
|
const currentChatIdSnapshot = useRef5(null);
|
|
3585
3862
|
const pendingChatIdSnapshot = useRef5(null);
|
|
3586
3863
|
useEffect5(() => {
|
|
@@ -3799,6 +4076,10 @@ function useChatManagement({
|
|
|
3799
4076
|
useEffect5(() => {
|
|
3800
4077
|
loadingRef.current = loading;
|
|
3801
4078
|
}, [loading]);
|
|
4079
|
+
const hasPendingApprovalRef = useRef5(hasPendingApproval);
|
|
4080
|
+
useEffect5(() => {
|
|
4081
|
+
hasPendingApprovalRef.current = hasPendingApproval;
|
|
4082
|
+
}, [hasPendingApproval]);
|
|
3802
4083
|
const processMessageQueue = useCallback4(async () => {
|
|
3803
4084
|
if (isProcessingQueueRef.current || pendingMessagesRef.current.length === 0 || !onSendMessage) {
|
|
3804
4085
|
return;
|
|
@@ -3806,7 +4087,7 @@ function useChatManagement({
|
|
|
3806
4087
|
isProcessingQueueRef.current = true;
|
|
3807
4088
|
while (pendingMessagesRef.current.length > 0) {
|
|
3808
4089
|
const { message, options } = pendingMessagesRef.current.shift();
|
|
3809
|
-
const { newChat = false, attachments = [], openChat = true, metadata } = options ?? {};
|
|
4090
|
+
const { newChat = false, attachments = [], openChat = true, metadata, forwardedProps } = options ?? {};
|
|
3810
4091
|
if (newChat) {
|
|
3811
4092
|
await createNewChat({ metadata });
|
|
3812
4093
|
}
|
|
@@ -3828,21 +4109,21 @@ function useChatManagement({
|
|
|
3828
4109
|
};
|
|
3829
4110
|
})
|
|
3830
4111
|
);
|
|
3831
|
-
await onSendMessage(message, fileAttachments.length > 0 ? fileAttachments : void 0);
|
|
4112
|
+
await onSendMessage(message, fileAttachments.length > 0 ? fileAttachments : void 0, forwardedProps);
|
|
3832
4113
|
if (openChat && setOpen) {
|
|
3833
4114
|
setOpen(true);
|
|
3834
4115
|
}
|
|
3835
4116
|
await new Promise((resolve) => {
|
|
3836
|
-
const
|
|
4117
|
+
const checkReady = () => {
|
|
3837
4118
|
setTimeout(() => {
|
|
3838
|
-
if (!loadingRef.current) {
|
|
4119
|
+
if (!loadingRef.current && !hasPendingApprovalRef.current) {
|
|
3839
4120
|
resolve();
|
|
3840
4121
|
} else {
|
|
3841
|
-
|
|
4122
|
+
checkReady();
|
|
3842
4123
|
}
|
|
3843
4124
|
}, 100);
|
|
3844
4125
|
};
|
|
3845
|
-
|
|
4126
|
+
checkReady();
|
|
3846
4127
|
});
|
|
3847
4128
|
}
|
|
3848
4129
|
isProcessingQueueRef.current = false;
|
|
@@ -3879,7 +4160,7 @@ function useChatManagement({
|
|
|
3879
4160
|
}
|
|
3880
4161
|
|
|
3881
4162
|
// src/hooks/useAgentSelection.ts
|
|
3882
|
-
import { useState as
|
|
4163
|
+
import { useState as useState7, useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo3 } from "react";
|
|
3883
4164
|
function filterAgents(serverAgents, defaultAgentId, visibleAgentIds) {
|
|
3884
4165
|
const getDefaultAgentFallback = () => {
|
|
3885
4166
|
const defaultAgentInfo = serverAgents.find((a) => a.id === defaultAgentId);
|
|
@@ -3905,9 +4186,9 @@ function useAgentSelection({
|
|
|
3905
4186
|
connected,
|
|
3906
4187
|
visibleAgentIds
|
|
3907
4188
|
}) {
|
|
3908
|
-
const [serverAgents, setServerAgents] =
|
|
3909
|
-
const [defaultAgent, setDefaultAgent] =
|
|
3910
|
-
const [selectedAgent, setSelectedAgent] =
|
|
4189
|
+
const [serverAgents, setServerAgents] = useState7([]);
|
|
4190
|
+
const [defaultAgent, setDefaultAgent] = useState7(null);
|
|
4191
|
+
const [selectedAgent, setSelectedAgent] = useState7(null);
|
|
3911
4192
|
const availableAgents = useMemo3(
|
|
3912
4193
|
() => filterAgents(serverAgents, defaultAgent, visibleAgentIds),
|
|
3913
4194
|
[serverAgents, defaultAgent, visibleAgentIds]
|
|
@@ -3944,7 +4225,7 @@ function useAgentSelection({
|
|
|
3944
4225
|
}
|
|
3945
4226
|
|
|
3946
4227
|
// src/hooks/useCommandManagement.ts
|
|
3947
|
-
import { useState as
|
|
4228
|
+
import { useState as useState8, useCallback as useCallback6, useRef as useRef6, useEffect as useEffect7 } from "react";
|
|
3948
4229
|
|
|
3949
4230
|
// src/commands/LocalStorageCommandRepository.ts
|
|
3950
4231
|
var STORAGE_KEY_PREFIX2 = "use-ai:command:";
|
|
@@ -4077,7 +4358,7 @@ function useCommandManagement({
|
|
|
4077
4358
|
const repositoryRef = useRef6(
|
|
4078
4359
|
repository || new LocalStorageCommandRepository()
|
|
4079
4360
|
);
|
|
4080
|
-
const [commands, setCommands] =
|
|
4361
|
+
const [commands, setCommands] = useState8([]);
|
|
4081
4362
|
const refreshCommands = useCallback6(async () => {
|
|
4082
4363
|
try {
|
|
4083
4364
|
const cmdList = await repositoryRef.current.listCommands();
|
|
@@ -4119,10 +4400,10 @@ function useCommandManagement({
|
|
|
4119
4400
|
}
|
|
4120
4401
|
|
|
4121
4402
|
// src/hooks/useToolRegistry.ts
|
|
4122
|
-
import { useState as
|
|
4403
|
+
import { useState as useState9, useCallback as useCallback7, useRef as useRef7, useMemo as useMemo4 } from "react";
|
|
4123
4404
|
function useToolRegistry() {
|
|
4124
4405
|
const toolRegistryRef = useRef7(/* @__PURE__ */ new Map());
|
|
4125
|
-
const [toolRegistryVersion, setToolRegistryVersion] =
|
|
4406
|
+
const [toolRegistryVersion, setToolRegistryVersion] = useState9(0);
|
|
4126
4407
|
const toolOwnershipRef = useRef7(/* @__PURE__ */ new Map());
|
|
4127
4408
|
const invisibleRef = useRef7(/* @__PURE__ */ new Set());
|
|
4128
4409
|
const registerTools = useCallback7((id, tools, options) => {
|
|
@@ -4182,7 +4463,7 @@ function useToolRegistry() {
|
|
|
4182
4463
|
}
|
|
4183
4464
|
|
|
4184
4465
|
// src/hooks/usePromptState.ts
|
|
4185
|
-
import { useState as
|
|
4466
|
+
import { useState as useState10, useCallback as useCallback8, useRef as useRef8, useMemo as useMemo5, useEffect as useEffect8 } from "react";
|
|
4186
4467
|
function usePromptState({
|
|
4187
4468
|
systemPrompt,
|
|
4188
4469
|
clientRef,
|
|
@@ -4191,7 +4472,7 @@ function usePromptState({
|
|
|
4191
4472
|
const promptsRef = useRef8(/* @__PURE__ */ new Map());
|
|
4192
4473
|
const suggestionsRef = useRef8(/* @__PURE__ */ new Map());
|
|
4193
4474
|
const waitersRef = useRef8(/* @__PURE__ */ new Map());
|
|
4194
|
-
const [suggestionsVersion, setSuggestionsVersion] =
|
|
4475
|
+
const [suggestionsVersion, setSuggestionsVersion] = useState10(0);
|
|
4195
4476
|
const buildStateFromPrompts = useCallback8(() => {
|
|
4196
4477
|
const promptParts = [];
|
|
4197
4478
|
if (systemPrompt) {
|
|
@@ -4254,14 +4535,14 @@ function usePromptState({
|
|
|
4254
4535
|
}
|
|
4255
4536
|
|
|
4256
4537
|
// src/hooks/useFeedback.ts
|
|
4257
|
-
import { useState as
|
|
4538
|
+
import { useState as useState11, useEffect as useEffect9, useRef as useRef9, useCallback as useCallback9 } from "react";
|
|
4258
4539
|
function useFeedback({
|
|
4259
4540
|
clientRef,
|
|
4260
4541
|
repository,
|
|
4261
4542
|
getDisplayedChatId,
|
|
4262
4543
|
setMessages
|
|
4263
4544
|
}) {
|
|
4264
|
-
const [enabled, setEnabled] =
|
|
4545
|
+
const [enabled, setEnabled] = useState11(false);
|
|
4265
4546
|
const enabledRef = useRef9(false);
|
|
4266
4547
|
useEffect9(() => {
|
|
4267
4548
|
enabledRef.current = enabled;
|
|
@@ -4315,8 +4596,120 @@ function useFeedback({
|
|
|
4315
4596
|
};
|
|
4316
4597
|
}
|
|
4317
4598
|
|
|
4599
|
+
// src/hooks/useToolExecution.ts
|
|
4600
|
+
import { useState as useState12, useCallback as useCallback10, useRef as useRef10 } from "react";
|
|
4601
|
+
function useToolExecution({
|
|
4602
|
+
clientRef,
|
|
4603
|
+
aggregatedToolsRef,
|
|
4604
|
+
toolOwnershipRef,
|
|
4605
|
+
promptsRef,
|
|
4606
|
+
isInvisible,
|
|
4607
|
+
getWaiter
|
|
4608
|
+
}) {
|
|
4609
|
+
const [pendingApprovals, setPendingApprovals] = useState12([]);
|
|
4610
|
+
const pendingApprovalToolCallsRef = useRef10(/* @__PURE__ */ new Map());
|
|
4611
|
+
const handleApprovalRequest = useCallback10((event) => {
|
|
4612
|
+
console.log("[useToolExecution] Tool approval requested:", event.toolCallName, event.toolCallId);
|
|
4613
|
+
setPendingApprovals((prev) => [
|
|
4614
|
+
...prev,
|
|
4615
|
+
{
|
|
4616
|
+
toolCallId: event.toolCallId,
|
|
4617
|
+
toolCallName: event.toolCallName,
|
|
4618
|
+
toolCallArgs: event.toolCallArgs,
|
|
4619
|
+
annotations: event.annotations
|
|
4620
|
+
}
|
|
4621
|
+
]);
|
|
4622
|
+
}, []);
|
|
4623
|
+
const executeToolCall = useCallback10(async (toolCallId, name, input) => {
|
|
4624
|
+
const client = clientRef.current;
|
|
4625
|
+
if (!client) {
|
|
4626
|
+
console.error("[useToolExecution] No client available for tool execution");
|
|
4627
|
+
return;
|
|
4628
|
+
}
|
|
4629
|
+
try {
|
|
4630
|
+
const ownerId = toolOwnershipRef.current.get(name);
|
|
4631
|
+
console.log(`[useToolExecution] Tool "${name}" owned by component:`, ownerId);
|
|
4632
|
+
console.log("[useToolExecution] Executing tool...");
|
|
4633
|
+
const result = await executeDefinedTool(aggregatedToolsRef.current, name, input);
|
|
4634
|
+
const isErrorResult = result && typeof result === "object" && ("error" in result || result.success === false);
|
|
4635
|
+
const ownerIsInvisible = ownerId ? isInvisible(ownerId) : false;
|
|
4636
|
+
if (ownerId && !isErrorResult && !ownerIsInvisible) {
|
|
4637
|
+
const waiter = getWaiter(ownerId);
|
|
4638
|
+
if (waiter) {
|
|
4639
|
+
console.log(`[useToolExecution] Waiting for prompt change from ${ownerId}...`);
|
|
4640
|
+
await waiter();
|
|
4641
|
+
console.log("[useToolExecution] Prompt change wait complete");
|
|
4642
|
+
}
|
|
4643
|
+
} else if (isErrorResult) {
|
|
4644
|
+
console.log("[useToolExecution] Tool returned error, skipping prompt wait");
|
|
4645
|
+
} else if (ownerIsInvisible) {
|
|
4646
|
+
console.log("[useToolExecution] Component is invisible, skipping prompt wait");
|
|
4647
|
+
}
|
|
4648
|
+
let updatedState = null;
|
|
4649
|
+
if (ownerId) {
|
|
4650
|
+
const prompt = promptsRef.current.get(ownerId);
|
|
4651
|
+
if (prompt) {
|
|
4652
|
+
updatedState = { context: prompt };
|
|
4653
|
+
console.log(`[useToolExecution] Updated state from ${ownerId}`);
|
|
4654
|
+
}
|
|
4655
|
+
}
|
|
4656
|
+
client.sendToolResponse(toolCallId, result, updatedState);
|
|
4657
|
+
} catch (err) {
|
|
4658
|
+
console.error("Tool execution error:", err);
|
|
4659
|
+
client.sendToolResponse(toolCallId, {
|
|
4660
|
+
error: err instanceof Error ? err.message : "Unknown error"
|
|
4661
|
+
});
|
|
4662
|
+
}
|
|
4663
|
+
}, [clientRef, aggregatedToolsRef, toolOwnershipRef, promptsRef, isInvisible, getWaiter]);
|
|
4664
|
+
const storePendingToolCall = useCallback10((toolCallId, name, input, toolCallData) => {
|
|
4665
|
+
console.log(`[useToolExecution] Storing pending tool call "${name}" for approval`);
|
|
4666
|
+
pendingApprovalToolCallsRef.current.set(toolCallId, { name, input, toolCallData });
|
|
4667
|
+
}, []);
|
|
4668
|
+
const executePendingToolAfterApproval = useCallback10(async (toolCallId) => {
|
|
4669
|
+
const pendingTool = pendingApprovalToolCallsRef.current.get(toolCallId);
|
|
4670
|
+
if (!pendingTool) {
|
|
4671
|
+
console.warn(`[useToolExecution] No pending tool found for ${toolCallId}`);
|
|
4672
|
+
return;
|
|
4673
|
+
}
|
|
4674
|
+
pendingApprovalToolCallsRef.current.delete(toolCallId);
|
|
4675
|
+
await executeToolCall(toolCallId, pendingTool.name, pendingTool.input);
|
|
4676
|
+
}, [executeToolCall]);
|
|
4677
|
+
const approveAll = useCallback10(async () => {
|
|
4678
|
+
if (!clientRef.current) return;
|
|
4679
|
+
console.log("[useToolExecution] Approving all tool calls:", pendingApprovals.length);
|
|
4680
|
+
const pendingTools = [...pendingApprovals];
|
|
4681
|
+
for (const pending of pendingTools) {
|
|
4682
|
+
clientRef.current.sendToolApprovalResponse(pending.toolCallId, true);
|
|
4683
|
+
}
|
|
4684
|
+
setPendingApprovals([]);
|
|
4685
|
+
for (const tool of pendingTools) {
|
|
4686
|
+
await executePendingToolAfterApproval(tool.toolCallId);
|
|
4687
|
+
}
|
|
4688
|
+
}, [clientRef, pendingApprovals, executePendingToolAfterApproval]);
|
|
4689
|
+
const rejectAll = useCallback10((reason) => {
|
|
4690
|
+
if (!clientRef.current) return;
|
|
4691
|
+
console.log("[useToolExecution] Rejecting all tool calls:", pendingApprovals.length, reason);
|
|
4692
|
+
const pendingTools = [...pendingApprovals];
|
|
4693
|
+
for (const pending of pendingTools) {
|
|
4694
|
+
clientRef.current.sendToolApprovalResponse(pending.toolCallId, false, reason);
|
|
4695
|
+
}
|
|
4696
|
+
setPendingApprovals([]);
|
|
4697
|
+
for (const tool of pendingTools) {
|
|
4698
|
+
pendingApprovalToolCallsRef.current.delete(tool.toolCallId);
|
|
4699
|
+
}
|
|
4700
|
+
}, [clientRef, pendingApprovals]);
|
|
4701
|
+
return {
|
|
4702
|
+
pendingApprovals,
|
|
4703
|
+
handleApprovalRequest,
|
|
4704
|
+
executeToolCall,
|
|
4705
|
+
storePendingToolCall,
|
|
4706
|
+
approveAll,
|
|
4707
|
+
rejectAll
|
|
4708
|
+
};
|
|
4709
|
+
}
|
|
4710
|
+
|
|
4318
4711
|
// src/providers/useAIProvider.tsx
|
|
4319
|
-
import { Fragment as Fragment3, jsx as
|
|
4712
|
+
import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4320
4713
|
var __UseAIContext = createContext4(null);
|
|
4321
4714
|
var hasWarnedAboutMissingProvider = false;
|
|
4322
4715
|
var noOpContextValue = {
|
|
@@ -4384,7 +4777,7 @@ function UseAIProvider({
|
|
|
4384
4777
|
CustomButton,
|
|
4385
4778
|
CustomChat,
|
|
4386
4779
|
chatRepository,
|
|
4387
|
-
|
|
4780
|
+
forwardedPropsProvider,
|
|
4388
4781
|
fileUploadConfig: fileUploadConfigProp,
|
|
4389
4782
|
commandRepository,
|
|
4390
4783
|
renderChat = true,
|
|
@@ -4396,24 +4789,24 @@ function UseAIProvider({
|
|
|
4396
4789
|
const fileUploadConfig = fileUploadConfigProp === false ? void 0 : fileUploadConfigProp ?? DEFAULT_FILE_UPLOAD_CONFIG;
|
|
4397
4790
|
const theme = { ...defaultTheme, ...customTheme };
|
|
4398
4791
|
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 =
|
|
4792
|
+
const [connected, setConnected] = useState13(false);
|
|
4793
|
+
const [isChatOpen, setIsChatOpen] = useState13(false);
|
|
4794
|
+
const [loading, setLoading] = useState13(false);
|
|
4795
|
+
const [messages, setMessages] = useState13([]);
|
|
4796
|
+
const [fileProcessingState, setFileProcessingState] = useState13(null);
|
|
4797
|
+
const handleSetChatOpen = useCallback11((open) => {
|
|
4405
4798
|
setIsChatOpen(open);
|
|
4406
4799
|
onOpenChange?.(open);
|
|
4407
4800
|
}, [onOpenChange]);
|
|
4408
|
-
const [streamingText, setStreamingText] =
|
|
4409
|
-
const streamingChatIdRef =
|
|
4410
|
-
const [executingTool, setExecutingTool] =
|
|
4411
|
-
const executingToolFallbackRef =
|
|
4412
|
-
const clientRef =
|
|
4413
|
-
const repositoryRef =
|
|
4801
|
+
const [streamingText, setStreamingText] = useState13("");
|
|
4802
|
+
const streamingChatIdRef = useRef11(null);
|
|
4803
|
+
const [executingTool, setExecutingTool] = useState13(null);
|
|
4804
|
+
const executingToolFallbackRef = useRef11(null);
|
|
4805
|
+
const clientRef = useRef11(null);
|
|
4806
|
+
const repositoryRef = useRef11(
|
|
4414
4807
|
chatRepository || new LocalStorageChatRepository()
|
|
4415
4808
|
);
|
|
4416
|
-
const handleSendMessageRef =
|
|
4809
|
+
const handleSendMessageRef = useRef11(null);
|
|
4417
4810
|
const {
|
|
4418
4811
|
registerTools,
|
|
4419
4812
|
unregisterTools,
|
|
@@ -4435,11 +4828,19 @@ function UseAIProvider({
|
|
|
4435
4828
|
clientRef,
|
|
4436
4829
|
connected
|
|
4437
4830
|
});
|
|
4438
|
-
const stableSendMessage =
|
|
4831
|
+
const stableSendMessage = useCallback11(async (message, attachments, forwardedProps) => {
|
|
4439
4832
|
if (handleSendMessageRef.current) {
|
|
4440
|
-
await handleSendMessageRef.current(message, attachments);
|
|
4833
|
+
await handleSendMessageRef.current(message, attachments, forwardedProps);
|
|
4441
4834
|
}
|
|
4442
4835
|
}, []);
|
|
4836
|
+
const toolExecution = useToolExecution({
|
|
4837
|
+
clientRef,
|
|
4838
|
+
aggregatedToolsRef,
|
|
4839
|
+
toolOwnershipRef,
|
|
4840
|
+
promptsRef,
|
|
4841
|
+
isInvisible,
|
|
4842
|
+
getWaiter
|
|
4843
|
+
});
|
|
4443
4844
|
const chatManagement = useChatManagement({
|
|
4444
4845
|
repository: repositoryRef.current,
|
|
4445
4846
|
clientRef,
|
|
@@ -4448,7 +4849,8 @@ function UseAIProvider({
|
|
|
4448
4849
|
onSendMessage: stableSendMessage,
|
|
4449
4850
|
setOpen: handleSetChatOpen,
|
|
4450
4851
|
connected,
|
|
4451
|
-
loading
|
|
4852
|
+
loading,
|
|
4853
|
+
hasPendingApproval: toolExecution.pendingApprovals.length > 0
|
|
4452
4854
|
});
|
|
4453
4855
|
const {
|
|
4454
4856
|
currentChatId,
|
|
@@ -4488,9 +4890,6 @@ function UseAIProvider({
|
|
|
4488
4890
|
useEffect10(() => {
|
|
4489
4891
|
console.log("[UseAIProvider] Initializing client with serverUrl:", serverUrl);
|
|
4490
4892
|
const client = new UseAIClient(serverUrl);
|
|
4491
|
-
if (mcpHeadersProvider) {
|
|
4492
|
-
client.setMcpHeadersProvider(mcpHeadersProvider);
|
|
4493
|
-
}
|
|
4494
4893
|
const unsubscribeConnection = client.onConnectionStateChange((isConnected) => {
|
|
4495
4894
|
console.log("[UseAIProvider] Connection state changed:", isConnected);
|
|
4496
4895
|
setConnected(isConnected);
|
|
@@ -4518,44 +4917,20 @@ function UseAIProvider({
|
|
|
4518
4917
|
}
|
|
4519
4918
|
const name = toolCallData.name;
|
|
4520
4919
|
const input = JSON.parse(toolCallData.args);
|
|
4521
|
-
|
|
4920
|
+
const tool = aggregatedToolsRef.current[name];
|
|
4921
|
+
if (!tool) {
|
|
4522
4922
|
console.log(`[Provider] Tool "${name}" not found in useAI tools, skipping (likely a workflow tool)`);
|
|
4523
4923
|
return;
|
|
4524
4924
|
}
|
|
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
|
-
});
|
|
4925
|
+
if (tool._options?.annotations?.destructiveHint === true) {
|
|
4926
|
+
console.log(`[Provider] Tool "${name}" requires approval, deferring execution`);
|
|
4927
|
+
toolExecution.storePendingToolCall(toolCallId, name, input, toolCallData);
|
|
4928
|
+
return;
|
|
4558
4929
|
}
|
|
4930
|
+
await toolExecution.executeToolCall(toolCallId, name, input);
|
|
4931
|
+
} else if (event.type === TOOL_APPROVAL_REQUEST) {
|
|
4932
|
+
const e = event;
|
|
4933
|
+
toolExecution.handleApprovalRequest(e);
|
|
4559
4934
|
} else if (event.type === EventType.TEXT_MESSAGE_CONTENT) {
|
|
4560
4935
|
const contentEvent = event;
|
|
4561
4936
|
setStreamingText((prev) => prev + contentEvent.delta);
|
|
@@ -4588,14 +4963,7 @@ function UseAIProvider({
|
|
|
4588
4963
|
client.disconnect();
|
|
4589
4964
|
};
|
|
4590
4965
|
}, [serverUrl]);
|
|
4591
|
-
|
|
4592
|
-
const client = clientRef.current;
|
|
4593
|
-
if (!client) return;
|
|
4594
|
-
if (mcpHeadersProvider) {
|
|
4595
|
-
client.setMcpHeadersProvider(mcpHeadersProvider);
|
|
4596
|
-
}
|
|
4597
|
-
}, [mcpHeadersProvider]);
|
|
4598
|
-
const lastRegisteredToolsRef = useRef10("");
|
|
4966
|
+
const lastRegisteredToolsRef = useRef11("");
|
|
4599
4967
|
useEffect10(() => {
|
|
4600
4968
|
const client = clientRef.current;
|
|
4601
4969
|
if (!client || !client.isConnected() || !hasTools) return;
|
|
@@ -4614,7 +4982,7 @@ function UseAIProvider({
|
|
|
4614
4982
|
console.error("Failed to register tools:", err);
|
|
4615
4983
|
}
|
|
4616
4984
|
}, [hasTools, aggregatedTools, connected]);
|
|
4617
|
-
const handleSendMessage =
|
|
4985
|
+
const handleSendMessage = useCallback11(async (message, attachments, messageForwardedProps) => {
|
|
4618
4986
|
if (!clientRef.current) return;
|
|
4619
4987
|
setStreamingText("");
|
|
4620
4988
|
const activatedChatId = activatePendingChat();
|
|
@@ -4668,8 +5036,18 @@ function UseAIProvider({
|
|
|
4668
5036
|
}
|
|
4669
5037
|
setLoading(true);
|
|
4670
5038
|
}
|
|
4671
|
-
|
|
4672
|
-
|
|
5039
|
+
const providerResult = forwardedPropsProvider ? forwardedPropsProvider() : {};
|
|
5040
|
+
const providerProps = providerResult instanceof Promise ? await providerResult : providerResult;
|
|
5041
|
+
const mergedForwardedProps = {
|
|
5042
|
+
...providerProps,
|
|
5043
|
+
...messageForwardedProps
|
|
5044
|
+
};
|
|
5045
|
+
await clientRef.current.sendPrompt(
|
|
5046
|
+
message,
|
|
5047
|
+
multimodalContent,
|
|
5048
|
+
Object.keys(mergedForwardedProps).length > 0 ? mergedForwardedProps : void 0
|
|
5049
|
+
);
|
|
5050
|
+
}, [activatePendingChat, currentChatId, saveUserMessage, fileUploadConfig, getCurrentChat, forwardedPropsProvider]);
|
|
4673
5051
|
handleSendMessageRef.current = handleSendMessage;
|
|
4674
5052
|
const value = {
|
|
4675
5053
|
serverUrl,
|
|
@@ -4746,7 +5124,14 @@ function UseAIProvider({
|
|
|
4746
5124
|
isOpen: isChatOpen,
|
|
4747
5125
|
setOpen: handleSetChatOpen
|
|
4748
5126
|
},
|
|
4749
|
-
|
|
5127
|
+
tools: {
|
|
5128
|
+
executing: executingToolDisplay,
|
|
5129
|
+
pending: {
|
|
5130
|
+
tools: toolExecution.pendingApprovals,
|
|
5131
|
+
approveAll: toolExecution.approveAll,
|
|
5132
|
+
rejectAll: toolExecution.rejectAll
|
|
5133
|
+
}
|
|
5134
|
+
},
|
|
4750
5135
|
feedback: {
|
|
4751
5136
|
enabled: feedback.enabled,
|
|
4752
5137
|
submit: feedback.submitFeedback
|
|
@@ -4779,21 +5164,24 @@ function UseAIProvider({
|
|
|
4779
5164
|
onDeleteCommand: deleteCommand,
|
|
4780
5165
|
executingTool: executingToolDisplay,
|
|
4781
5166
|
feedbackEnabled: feedback.enabled,
|
|
4782
|
-
onFeedback: feedback.submitFeedback
|
|
5167
|
+
onFeedback: feedback.submitFeedback,
|
|
5168
|
+
pendingApprovals: toolExecution.pendingApprovals,
|
|
5169
|
+
onApproveToolCall: toolExecution.pendingApprovals.length > 0 ? toolExecution.approveAll : void 0,
|
|
5170
|
+
onRejectToolCall: toolExecution.pendingApprovals.length > 0 ? toolExecution.rejectAll : void 0
|
|
4783
5171
|
};
|
|
4784
5172
|
const renderDefaultChat = () => {
|
|
4785
5173
|
if (isUIDisabled) return null;
|
|
4786
|
-
return /* @__PURE__ */
|
|
5174
|
+
return /* @__PURE__ */ jsx14(UseAIFloatingChatWrapper, { isOpen: isChatOpen, onClose: () => handleSetChatOpen(false), children: /* @__PURE__ */ jsx14(
|
|
4787
5175
|
UseAIChatPanel,
|
|
4788
5176
|
{
|
|
4789
5177
|
...chatPanelProps,
|
|
4790
|
-
closeButton: /* @__PURE__ */
|
|
5178
|
+
closeButton: /* @__PURE__ */ jsx14(CloseButton, { onClick: () => handleSetChatOpen(false) })
|
|
4791
5179
|
}
|
|
4792
5180
|
) });
|
|
4793
5181
|
};
|
|
4794
5182
|
const renderCustomChat = () => {
|
|
4795
5183
|
if (!CustomChat) return null;
|
|
4796
|
-
return /* @__PURE__ */
|
|
5184
|
+
return /* @__PURE__ */ jsx14(
|
|
4797
5185
|
CustomChat,
|
|
4798
5186
|
{
|
|
4799
5187
|
isOpen: isChatOpen,
|
|
@@ -4812,8 +5200,8 @@ function UseAIProvider({
|
|
|
4812
5200
|
};
|
|
4813
5201
|
const renderBuiltInChat = () => {
|
|
4814
5202
|
if (!renderChat) return null;
|
|
4815
|
-
return /* @__PURE__ */
|
|
4816
|
-
ButtonComponent && /* @__PURE__ */
|
|
5203
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
5204
|
+
ButtonComponent && /* @__PURE__ */ jsx14(
|
|
4817
5205
|
ButtonComponent,
|
|
4818
5206
|
{
|
|
4819
5207
|
onClick: () => handleSetChatOpen(true),
|
|
@@ -4823,7 +5211,7 @@ function UseAIProvider({
|
|
|
4823
5211
|
hasCustomChat ? renderCustomChat() : renderDefaultChat()
|
|
4824
5212
|
] });
|
|
4825
5213
|
};
|
|
4826
|
-
return /* @__PURE__ */
|
|
5214
|
+
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
5215
|
children,
|
|
4828
5216
|
renderBuiltInChat()
|
|
4829
5217
|
] }) }) }) });
|
|
@@ -4843,11 +5231,11 @@ function useAIContext() {
|
|
|
4843
5231
|
}
|
|
4844
5232
|
|
|
4845
5233
|
// src/hooks/useStableTools.ts
|
|
4846
|
-
import { useRef as
|
|
5234
|
+
import { useRef as useRef12 } from "react";
|
|
4847
5235
|
function useStableTools(tools) {
|
|
4848
|
-
const latestToolsRef =
|
|
4849
|
-
const stableToolsRef =
|
|
4850
|
-
const prevToolNamesRef =
|
|
5236
|
+
const latestToolsRef = useRef12({});
|
|
5237
|
+
const stableToolsRef = useRef12({});
|
|
5238
|
+
const prevToolNamesRef = useRef12("");
|
|
4851
5239
|
if (!tools) {
|
|
4852
5240
|
latestToolsRef.current = {};
|
|
4853
5241
|
return void 0;
|
|
@@ -4917,13 +5305,13 @@ function useAI(options = {}) {
|
|
|
4917
5305
|
const { connected, tools, client, prompts } = useAIContext();
|
|
4918
5306
|
const { register: registerTools, unregister: unregisterTools } = tools;
|
|
4919
5307
|
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 =
|
|
5308
|
+
const [response, setResponse] = useState14(null);
|
|
5309
|
+
const [loading, setLoading] = useState14(false);
|
|
5310
|
+
const [error, setError] = useState14(null);
|
|
5311
|
+
const hookId = useRef13(`useAI-${Math.random().toString(36).substr(2, 9)}`);
|
|
5312
|
+
const toolsRef = useRef13({});
|
|
5313
|
+
const componentRef = useRef13(null);
|
|
5314
|
+
const promptChangeResolvers = useRef13([]);
|
|
4927
5315
|
const stableTools = useStableTools(options.tools);
|
|
4928
5316
|
const toolsKey = useMemo6(() => {
|
|
4929
5317
|
if (!options.tools) return "";
|
|
@@ -4935,7 +5323,7 @@ function useAI(options = {}) {
|
|
|
4935
5323
|
componentRef.current.setAttribute("data-useai-context", "true");
|
|
4936
5324
|
}
|
|
4937
5325
|
}, []);
|
|
4938
|
-
const waitForPromptChange =
|
|
5326
|
+
const waitForPromptChange = useCallback12(() => {
|
|
4939
5327
|
return new Promise((resolve) => {
|
|
4940
5328
|
const timeoutMs = 100;
|
|
4941
5329
|
const timeoutId = setTimeout(() => {
|
|
@@ -4967,7 +5355,7 @@ function useAI(options = {}) {
|
|
|
4967
5355
|
promptChangeResolvers.current = [];
|
|
4968
5356
|
}
|
|
4969
5357
|
}, [enabled, options.prompt, memoizedSuggestions, updatePrompt]);
|
|
4970
|
-
const updatePromptRef =
|
|
5358
|
+
const updatePromptRef = useRef13(updatePrompt);
|
|
4971
5359
|
updatePromptRef.current = updatePrompt;
|
|
4972
5360
|
useEffect11(() => {
|
|
4973
5361
|
const id = hookId.current;
|
|
@@ -4998,7 +5386,7 @@ function useAI(options = {}) {
|
|
|
4998
5386
|
unsubscribe();
|
|
4999
5387
|
};
|
|
5000
5388
|
}, [enabled, client]);
|
|
5001
|
-
const handleAGUIEvent =
|
|
5389
|
+
const handleAGUIEvent = useCallback12(async (event) => {
|
|
5002
5390
|
switch (event.type) {
|
|
5003
5391
|
case EventType.TEXT_MESSAGE_END: {
|
|
5004
5392
|
const content = client?.currentMessageContent;
|
|
@@ -5018,7 +5406,7 @@ function useAI(options = {}) {
|
|
|
5018
5406
|
}
|
|
5019
5407
|
}
|
|
5020
5408
|
}, [client, options.onError]);
|
|
5021
|
-
const generate =
|
|
5409
|
+
const generate = useCallback12(async (prompt) => {
|
|
5022
5410
|
if (!enabled) {
|
|
5023
5411
|
const error2 = new Error("AI features are disabled");
|
|
5024
5412
|
setError(error2);
|
|
@@ -5054,17 +5442,17 @@ function useAI(options = {}) {
|
|
|
5054
5442
|
}
|
|
5055
5443
|
|
|
5056
5444
|
// src/useAIWorkflow.ts
|
|
5057
|
-
import { useState as
|
|
5445
|
+
import { useState as useState15, useCallback as useCallback13, useRef as useRef14, useEffect as useEffect12 } from "react";
|
|
5058
5446
|
import { EventType as EventType3 } from "@meetsmore-oss/use-ai-core";
|
|
5059
5447
|
import { v4 as uuidv43 } from "uuid";
|
|
5060
5448
|
function useAIWorkflow(runner, workflowId) {
|
|
5061
5449
|
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 =
|
|
5450
|
+
const [status, setStatus] = useState15("idle");
|
|
5451
|
+
const [text, setText] = useState15(null);
|
|
5452
|
+
const [error, setError] = useState15(null);
|
|
5453
|
+
const currentWorkflowRef = useRef14(null);
|
|
5454
|
+
const eventListenerIdRef = useRef14(`useAIWorkflow-${Math.random().toString(36).substr(2, 9)}`);
|
|
5455
|
+
const handleWorkflowEvent = useCallback13(async (event) => {
|
|
5068
5456
|
const currentWorkflow = currentWorkflowRef.current;
|
|
5069
5457
|
if (!currentWorkflow) return;
|
|
5070
5458
|
if (event.type === EventType3.RUN_STARTED) {
|
|
@@ -5156,7 +5544,7 @@ function useAIWorkflow(runner, workflowId) {
|
|
|
5156
5544
|
unsubscribe();
|
|
5157
5545
|
};
|
|
5158
5546
|
}, [client, handleWorkflowEvent]);
|
|
5159
|
-
const trigger =
|
|
5547
|
+
const trigger = useCallback13(async (options) => {
|
|
5160
5548
|
if (!client?.isConnected()) {
|
|
5161
5549
|
const err = new Error("Not connected to server");
|
|
5162
5550
|
setError(err);
|
|
@@ -5232,7 +5620,7 @@ export {
|
|
|
5232
5620
|
defaultTheme,
|
|
5233
5621
|
defineTool,
|
|
5234
5622
|
executeDefinedTool,
|
|
5235
|
-
|
|
5623
|
+
findTransformerPattern,
|
|
5236
5624
|
generateChatId,
|
|
5237
5625
|
generateCommandId,
|
|
5238
5626
|
generateMessageId,
|