@ash-cloud/ash-ui 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +632 -338
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +168 -17
- package/dist/index.d.ts +168 -17
- package/dist/index.js +631 -340
- package/dist/index.js.map +1 -1
- package/dist/styles-full.css +1 -1
- package/dist/styles.css +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +8 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.js.map +1 -1
- package/dist/utils.cjs +22 -8
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js +22 -8
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, useState,
|
|
1
|
+
import { createContext, useState, useMemo, useCallback, useContext, useRef, useEffect } from 'react';
|
|
2
2
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import ReactMarkdown from 'react-markdown';
|
|
4
4
|
|
|
@@ -35,27 +35,41 @@ function mapToolToActionType(toolName, input) {
|
|
|
35
35
|
command: inputObj.command || "",
|
|
36
36
|
description: inputObj.description
|
|
37
37
|
};
|
|
38
|
-
case "Read":
|
|
38
|
+
case "Read": {
|
|
39
|
+
const limit = inputObj.limit;
|
|
39
40
|
return {
|
|
40
41
|
action: "file_read",
|
|
41
42
|
path: inputObj.file_path || "",
|
|
42
43
|
offset: inputObj.offset,
|
|
43
|
-
limit
|
|
44
|
+
limit,
|
|
45
|
+
linesRead: limit
|
|
46
|
+
// Use limit as approximate lines read if specified
|
|
44
47
|
};
|
|
45
|
-
|
|
48
|
+
}
|
|
49
|
+
case "Edit": {
|
|
50
|
+
const oldStr = inputObj.old_string;
|
|
51
|
+
const newStr = inputObj.new_string;
|
|
52
|
+
const oldLines = oldStr ? oldStr.split("\n").length : 0;
|
|
53
|
+
const newLines = newStr ? newStr.split("\n").length : 0;
|
|
46
54
|
return {
|
|
47
55
|
action: "file_edit",
|
|
48
56
|
path: inputObj.file_path || "",
|
|
49
|
-
oldString:
|
|
50
|
-
newString:
|
|
51
|
-
replaceAll: inputObj.replace_all
|
|
57
|
+
oldString: oldStr,
|
|
58
|
+
newString: newStr,
|
|
59
|
+
replaceAll: inputObj.replace_all,
|
|
60
|
+
linesAdded: newLines,
|
|
61
|
+
linesRemoved: oldLines
|
|
52
62
|
};
|
|
53
|
-
|
|
63
|
+
}
|
|
64
|
+
case "Write": {
|
|
65
|
+
const content = inputObj.content;
|
|
54
66
|
return {
|
|
55
67
|
action: "file_write",
|
|
56
68
|
path: inputObj.file_path || "",
|
|
57
|
-
content
|
|
69
|
+
content,
|
|
70
|
+
linesWritten: content ? content.split("\n").length : void 0
|
|
58
71
|
};
|
|
72
|
+
}
|
|
59
73
|
case "Grep":
|
|
60
74
|
return {
|
|
61
75
|
action: "search",
|
|
@@ -1304,275 +1318,422 @@ function StreamingText({
|
|
|
1304
1318
|
isStreaming && /* @__PURE__ */ jsx(LoadingIndicator, { variant: "cursor", size: "sm", className: "inline-block ml-0.5" })
|
|
1305
1319
|
] }) });
|
|
1306
1320
|
}
|
|
1307
|
-
function
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1321
|
+
function getFilePath(actionType) {
|
|
1322
|
+
switch (actionType.action) {
|
|
1323
|
+
case "file_read":
|
|
1324
|
+
case "file_edit":
|
|
1325
|
+
case "file_write":
|
|
1326
|
+
return actionType.path;
|
|
1327
|
+
default:
|
|
1328
|
+
return null;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
function getFileName(path) {
|
|
1332
|
+
const parts = path.split("/");
|
|
1333
|
+
return parts[parts.length - 1] || path;
|
|
1334
|
+
}
|
|
1335
|
+
function getFileExtension(path) {
|
|
1336
|
+
const fileName = getFileName(path);
|
|
1337
|
+
const dotIndex = fileName.lastIndexOf(".");
|
|
1338
|
+
if (dotIndex === -1) return null;
|
|
1339
|
+
return fileName.slice(dotIndex + 1).toLowerCase();
|
|
1340
|
+
}
|
|
1341
|
+
function getDiffStats(actionType) {
|
|
1342
|
+
switch (actionType.action) {
|
|
1343
|
+
case "file_edit": {
|
|
1344
|
+
const edit = actionType;
|
|
1345
|
+
if (edit.linesAdded !== void 0 || edit.linesRemoved !== void 0) {
|
|
1346
|
+
return { added: edit.linesAdded, removed: edit.linesRemoved };
|
|
1332
1347
|
}
|
|
1333
|
-
|
|
1334
|
-
setDisplayedToolCall(toolCall);
|
|
1348
|
+
return null;
|
|
1335
1349
|
}
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1350
|
+
case "file_read": {
|
|
1351
|
+
const read = actionType;
|
|
1352
|
+
if (read.linesRead !== void 0) {
|
|
1353
|
+
return { read: read.linesRead };
|
|
1354
|
+
}
|
|
1355
|
+
return null;
|
|
1356
|
+
}
|
|
1357
|
+
case "file_write": {
|
|
1358
|
+
const write = actionType;
|
|
1359
|
+
if (write.linesWritten !== void 0) {
|
|
1360
|
+
return { written: write.linesWritten };
|
|
1361
|
+
}
|
|
1362
|
+
return null;
|
|
1363
|
+
}
|
|
1364
|
+
default:
|
|
1365
|
+
return null;
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
function getFileTypeColor(ext) {
|
|
1369
|
+
switch (ext) {
|
|
1370
|
+
case "ts":
|
|
1371
|
+
case "tsx":
|
|
1372
|
+
return "text-blue-400";
|
|
1373
|
+
case "js":
|
|
1374
|
+
case "jsx":
|
|
1375
|
+
return "text-yellow-400";
|
|
1376
|
+
case "md":
|
|
1377
|
+
return "text-white/60";
|
|
1378
|
+
case "json":
|
|
1379
|
+
return "text-orange-400";
|
|
1380
|
+
case "sh":
|
|
1381
|
+
return "text-green-400";
|
|
1382
|
+
case "css":
|
|
1383
|
+
case "scss":
|
|
1384
|
+
return "text-pink-400";
|
|
1385
|
+
case "py":
|
|
1386
|
+
return "text-blue-300";
|
|
1387
|
+
default:
|
|
1388
|
+
return "text-white/70";
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
function CompactToolRow({ toolCall, showFullPath = false, className }) {
|
|
1392
|
+
const { actionType, status, summary } = toolCall;
|
|
1393
|
+
const label = getActionLabel(actionType);
|
|
1394
|
+
const filePath = getFilePath(actionType);
|
|
1395
|
+
const diffStats = getDiffStats(actionType);
|
|
1396
|
+
const displayPath = filePath ? showFullPath ? filePath : getFileName(filePath) : null;
|
|
1397
|
+
const ext = filePath ? getFileExtension(filePath) : null;
|
|
1398
|
+
const fileColor = getFileTypeColor(ext);
|
|
1399
|
+
const showSummary = !filePath && summary;
|
|
1400
|
+
return /* @__PURE__ */ jsxs(
|
|
1344
1401
|
"div",
|
|
1345
1402
|
{
|
|
1346
1403
|
className: cn(
|
|
1347
|
-
"flex items-center gap-
|
|
1348
|
-
|
|
1404
|
+
"flex items-center gap-2 py-1.5 text-sm min-w-0",
|
|
1405
|
+
className
|
|
1349
1406
|
),
|
|
1350
|
-
style: {
|
|
1351
|
-
animationDuration: `${animationDuration}ms`
|
|
1352
|
-
},
|
|
1353
1407
|
children: [
|
|
1354
|
-
/* @__PURE__ */
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
/* @__PURE__ */
|
|
1375
|
-
|
|
1408
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [
|
|
1409
|
+
/* @__PURE__ */ jsx(
|
|
1410
|
+
ActionIcon,
|
|
1411
|
+
{
|
|
1412
|
+
actionType,
|
|
1413
|
+
className: cn(
|
|
1414
|
+
"w-3.5 h-3.5",
|
|
1415
|
+
status === "pending" ? "text-yellow-400" : status === "failed" ? "text-red-400" : "text-white/50"
|
|
1416
|
+
)
|
|
1417
|
+
}
|
|
1418
|
+
),
|
|
1419
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
1420
|
+
"font-medium",
|
|
1421
|
+
status === "pending" ? "text-white/90" : status === "failed" ? "text-red-400" : "text-white/60"
|
|
1422
|
+
), children: label })
|
|
1423
|
+
] }),
|
|
1424
|
+
displayPath && /* @__PURE__ */ jsx("code", { className: cn(
|
|
1425
|
+
"px-1.5 py-0.5 rounded bg-white/5 font-mono text-xs truncate max-w-[200px]",
|
|
1426
|
+
fileColor
|
|
1427
|
+
), children: displayPath }),
|
|
1428
|
+
diffStats && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs shrink-0 font-mono", children: [
|
|
1429
|
+
diffStats.added !== void 0 && diffStats.added > 0 && /* @__PURE__ */ jsxs("span", { className: "text-emerald-400", children: [
|
|
1430
|
+
"+",
|
|
1431
|
+
diffStats.added
|
|
1432
|
+
] }),
|
|
1433
|
+
diffStats.removed !== void 0 && diffStats.removed > 0 && /* @__PURE__ */ jsxs("span", { className: "text-red-400", children: [
|
|
1434
|
+
"-",
|
|
1435
|
+
diffStats.removed
|
|
1436
|
+
] }),
|
|
1437
|
+
diffStats.read !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-white/40", children: [
|
|
1438
|
+
diffStats.read,
|
|
1439
|
+
" lines"
|
|
1440
|
+
] }),
|
|
1441
|
+
diffStats.written !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-emerald-400", children: [
|
|
1442
|
+
"+",
|
|
1443
|
+
diffStats.written
|
|
1444
|
+
] })
|
|
1445
|
+
] }),
|
|
1446
|
+
showSummary && /* @__PURE__ */ jsx("span", { className: "text-white/40 truncate min-w-0 text-xs", children: summary })
|
|
1376
1447
|
]
|
|
1377
1448
|
}
|
|
1378
1449
|
);
|
|
1450
|
+
}
|
|
1451
|
+
function getFileExtension2(path) {
|
|
1452
|
+
const fileName = path.split("/").pop() || path;
|
|
1453
|
+
const dotIndex = fileName.lastIndexOf(".");
|
|
1454
|
+
if (dotIndex === -1) return null;
|
|
1455
|
+
return fileName.slice(dotIndex + 1).toLowerCase();
|
|
1456
|
+
}
|
|
1457
|
+
function getFileIcon(ext) {
|
|
1458
|
+
switch (ext) {
|
|
1459
|
+
case "ts":
|
|
1460
|
+
case "tsx":
|
|
1461
|
+
return "TS";
|
|
1462
|
+
case "js":
|
|
1463
|
+
case "jsx":
|
|
1464
|
+
return "JS";
|
|
1465
|
+
case "md":
|
|
1466
|
+
return "MD";
|
|
1467
|
+
case "json":
|
|
1468
|
+
return "{}";
|
|
1469
|
+
case "sh":
|
|
1470
|
+
return "$";
|
|
1471
|
+
case "css":
|
|
1472
|
+
case "scss":
|
|
1473
|
+
return "#";
|
|
1474
|
+
case "py":
|
|
1475
|
+
return "PY";
|
|
1476
|
+
default:
|
|
1477
|
+
return "";
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
function getFileBgColor(ext) {
|
|
1481
|
+
switch (ext) {
|
|
1482
|
+
case "ts":
|
|
1483
|
+
case "tsx":
|
|
1484
|
+
return "bg-blue-500/20";
|
|
1485
|
+
case "js":
|
|
1486
|
+
case "jsx":
|
|
1487
|
+
return "bg-yellow-500/20";
|
|
1488
|
+
case "md":
|
|
1489
|
+
return "bg-white/10";
|
|
1490
|
+
case "json":
|
|
1491
|
+
return "bg-orange-500/20";
|
|
1492
|
+
case "sh":
|
|
1493
|
+
return "bg-green-500/20";
|
|
1494
|
+
case "css":
|
|
1495
|
+
case "scss":
|
|
1496
|
+
return "bg-pink-500/20";
|
|
1497
|
+
case "py":
|
|
1498
|
+
return "bg-blue-400/20";
|
|
1499
|
+
default:
|
|
1500
|
+
return "bg-white/10";
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
function FileBadge({
|
|
1504
|
+
path,
|
|
1505
|
+
linesAdded,
|
|
1506
|
+
linesRemoved,
|
|
1507
|
+
showOnlyFilename = true,
|
|
1508
|
+
className
|
|
1509
|
+
}) {
|
|
1510
|
+
const fileName = showOnlyFilename ? path.split("/").pop() || path : path;
|
|
1511
|
+
const ext = getFileExtension2(path);
|
|
1512
|
+
const icon = getFileIcon(ext);
|
|
1513
|
+
const bgColor = getFileBgColor(ext);
|
|
1514
|
+
const hasDiff = linesAdded !== void 0 && linesAdded > 0 || linesRemoved !== void 0 && linesRemoved > 0;
|
|
1379
1515
|
return /* @__PURE__ */ jsxs(
|
|
1380
|
-
"
|
|
1516
|
+
"span",
|
|
1381
1517
|
{
|
|
1382
1518
|
className: cn(
|
|
1383
|
-
"
|
|
1384
|
-
|
|
1385
|
-
displayedToolCall.status === "pending" && "ash-tool-status-pending",
|
|
1519
|
+
"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md text-xs font-mono",
|
|
1520
|
+
bgColor,
|
|
1386
1521
|
className
|
|
1387
1522
|
),
|
|
1388
1523
|
children: [
|
|
1389
|
-
|
|
1390
|
-
|
|
1524
|
+
icon && /* @__PURE__ */ jsx("span", { className: "text-[10px] opacity-60 font-semibold", children: icon }),
|
|
1525
|
+
/* @__PURE__ */ jsx("span", { className: "text-white/80 truncate max-w-[120px]", children: fileName }),
|
|
1526
|
+
hasDiff && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-0.5", children: [
|
|
1527
|
+
linesAdded !== void 0 && linesAdded > 0 && /* @__PURE__ */ jsxs("span", { className: "text-emerald-400", children: [
|
|
1528
|
+
"+",
|
|
1529
|
+
linesAdded
|
|
1530
|
+
] }),
|
|
1531
|
+
linesRemoved !== void 0 && linesRemoved > 0 && /* @__PURE__ */ jsxs("span", { className: "text-red-400", children: [
|
|
1532
|
+
"-",
|
|
1533
|
+
linesRemoved
|
|
1534
|
+
] })
|
|
1535
|
+
] })
|
|
1391
1536
|
]
|
|
1392
1537
|
}
|
|
1393
1538
|
);
|
|
1394
1539
|
}
|
|
1395
|
-
function
|
|
1396
|
-
const
|
|
1397
|
-
const
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1540
|
+
function extractFileChanges(toolCalls) {
|
|
1541
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
1542
|
+
for (const tc of toolCalls) {
|
|
1543
|
+
const { actionType } = tc;
|
|
1544
|
+
if (actionType.action === "file_edit") {
|
|
1545
|
+
const edit = actionType;
|
|
1546
|
+
const existing = fileMap.get(edit.path);
|
|
1547
|
+
if (existing) {
|
|
1548
|
+
existing.linesAdded = (existing.linesAdded || 0) + (edit.linesAdded || 0);
|
|
1549
|
+
existing.linesRemoved = (existing.linesRemoved || 0) + (edit.linesRemoved || 0);
|
|
1550
|
+
} else {
|
|
1551
|
+
fileMap.set(edit.path, {
|
|
1552
|
+
path: edit.path,
|
|
1553
|
+
linesAdded: edit.linesAdded,
|
|
1554
|
+
linesRemoved: edit.linesRemoved
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1557
|
+
} else if (actionType.action === "file_write") {
|
|
1558
|
+
const write = actionType;
|
|
1559
|
+
if (!fileMap.has(write.path)) {
|
|
1560
|
+
fileMap.set(write.path, {
|
|
1561
|
+
path: write.path,
|
|
1562
|
+
linesAdded: write.linesWritten
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
return Array.from(fileMap.values());
|
|
1568
|
+
}
|
|
1569
|
+
function countActionTypes(toolCalls) {
|
|
1570
|
+
const counts = {};
|
|
1571
|
+
for (const tc of toolCalls) {
|
|
1572
|
+
const action = tc.actionType.action;
|
|
1573
|
+
counts[action] = (counts[action] || 0) + 1;
|
|
1574
|
+
}
|
|
1575
|
+
return counts;
|
|
1576
|
+
}
|
|
1577
|
+
function getActionIconComponent(action) {
|
|
1578
|
+
switch (action) {
|
|
1579
|
+
case "file_read":
|
|
1580
|
+
return FileIcon;
|
|
1581
|
+
case "file_edit":
|
|
1582
|
+
case "file_write":
|
|
1583
|
+
return EditIcon;
|
|
1584
|
+
case "command_run":
|
|
1585
|
+
return TerminalIcon;
|
|
1586
|
+
case "search":
|
|
1587
|
+
case "glob":
|
|
1588
|
+
return SearchIcon;
|
|
1589
|
+
default:
|
|
1590
|
+
return null;
|
|
1591
|
+
}
|
|
1403
1592
|
}
|
|
1404
1593
|
function ToolExecutionGroup({
|
|
1405
1594
|
toolCalls,
|
|
1406
1595
|
defaultExpanded = false,
|
|
1407
|
-
animationDuration = 300,
|
|
1408
1596
|
className
|
|
1409
1597
|
}) {
|
|
1410
1598
|
const [expanded, setExpanded] = useState(defaultExpanded);
|
|
1411
|
-
const
|
|
1412
|
-
const
|
|
1413
|
-
const
|
|
1414
|
-
const
|
|
1415
|
-
|
|
1599
|
+
const [expandedCardId, setExpandedCardId] = useState(null);
|
|
1600
|
+
const fileChanges = useMemo(() => extractFileChanges(toolCalls), [toolCalls]);
|
|
1601
|
+
const actionCounts = useMemo(() => countActionTypes(toolCalls), [toolCalls]);
|
|
1602
|
+
const displayActions = useMemo(() => {
|
|
1603
|
+
return Object.entries(actionCounts).sort((a, b) => b[1] - a[1]).slice(0, 3).map(([action]) => action);
|
|
1604
|
+
}, [actionCounts]);
|
|
1416
1605
|
const totalCount = toolCalls.length;
|
|
1417
|
-
if (
|
|
1606
|
+
if (toolCalls.length === 0) {
|
|
1418
1607
|
return null;
|
|
1419
1608
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
className: cn(
|
|
1430
|
-
"rounded-xl border bg-[var(--ash-surface-dark,#0a0a0a)] overflow-hidden ash-animate-fade-in",
|
|
1431
|
-
borderClasses[groupStatus],
|
|
1432
|
-
groupStatus === "pending" && "ash-tool-status-pending",
|
|
1433
|
-
className
|
|
1434
|
-
),
|
|
1435
|
-
children: [
|
|
1436
|
-
/* @__PURE__ */ jsx(
|
|
1437
|
-
"button",
|
|
1438
|
-
{
|
|
1439
|
-
onClick: () => setExpanded(!expanded),
|
|
1440
|
-
className: cn(
|
|
1441
|
-
"w-full transition-colors hover:bg-white/5 cursor-pointer"
|
|
1442
|
-
),
|
|
1443
|
-
children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
1444
|
-
/* @__PURE__ */ jsx(
|
|
1445
|
-
CompactToolStatusLine,
|
|
1446
|
-
{
|
|
1447
|
-
toolCall: activeToolCall,
|
|
1448
|
-
previousToolCall,
|
|
1449
|
-
animationDuration,
|
|
1450
|
-
className: "border-0 rounded-none"
|
|
1451
|
-
}
|
|
1452
|
-
),
|
|
1453
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-2", children: [
|
|
1454
|
-
totalCount > 1 && /* @__PURE__ */ jsx(
|
|
1455
|
-
"div",
|
|
1456
|
-
{
|
|
1457
|
-
className: cn(
|
|
1458
|
-
"flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium",
|
|
1459
|
-
groupStatus === "pending" ? "bg-yellow-500/20 text-yellow-400" : groupStatus === "success" ? "bg-[var(--ash-accent)]/20 text-[var(--ash-accent)]" : groupStatus === "failed" ? "bg-red-500/20 text-red-400" : "bg-orange-500/20 text-orange-400"
|
|
1460
|
-
),
|
|
1461
|
-
children: groupStatus === "pending" ? /* @__PURE__ */ jsxs("span", { children: [
|
|
1462
|
-
completedCount,
|
|
1463
|
-
"/",
|
|
1464
|
-
totalCount
|
|
1465
|
-
] }) : failedCount > 0 ? /* @__PURE__ */ jsxs("span", { children: [
|
|
1466
|
-
completedCount,
|
|
1467
|
-
" ok, ",
|
|
1468
|
-
failedCount,
|
|
1469
|
-
" failed"
|
|
1470
|
-
] }) : /* @__PURE__ */ jsxs("span", { children: [
|
|
1471
|
-
totalCount,
|
|
1472
|
-
" tools"
|
|
1473
|
-
] })
|
|
1474
|
-
}
|
|
1475
|
-
),
|
|
1476
|
-
/* @__PURE__ */ jsx(
|
|
1477
|
-
ChevronDownIcon,
|
|
1478
|
-
{
|
|
1479
|
-
className: cn(
|
|
1480
|
-
"w-4 h-4 text-white/40 transition-transform duration-200",
|
|
1481
|
-
expanded && "rotate-180"
|
|
1482
|
-
)
|
|
1483
|
-
}
|
|
1484
|
-
)
|
|
1485
|
-
] })
|
|
1486
|
-
] })
|
|
1487
|
-
}
|
|
1488
|
-
),
|
|
1489
|
-
expanded && /* @__PURE__ */ jsxs("div", { className: "border-t border-white/5 bg-black/20", children: [
|
|
1490
|
-
/* @__PURE__ */ jsx("div", { className: "p-3 space-y-2", children: toolCalls.map((toolCall, index) => /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
1491
|
-
index < toolCalls.length - 1 && /* @__PURE__ */ jsx("div", { className: "absolute left-[19px] top-10 bottom-0 w-px bg-white/10" }),
|
|
1492
|
-
/* @__PURE__ */ jsx(
|
|
1493
|
-
ToolCallCard,
|
|
1494
|
-
{
|
|
1495
|
-
toolCall,
|
|
1496
|
-
defaultExpanded: false,
|
|
1497
|
-
className: "relative z-10"
|
|
1498
|
-
}
|
|
1499
|
-
)
|
|
1500
|
-
] }, toolCall.id)) }),
|
|
1501
|
-
groupStatus !== "pending" && /* @__PURE__ */ jsx(
|
|
1502
|
-
"div",
|
|
1609
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("ash-animate-fade-in", className), children: [
|
|
1610
|
+
/* @__PURE__ */ jsxs(
|
|
1611
|
+
"button",
|
|
1612
|
+
{
|
|
1613
|
+
onClick: () => setExpanded(!expanded),
|
|
1614
|
+
className: "w-full flex items-center gap-2 py-1 text-left group",
|
|
1615
|
+
children: [
|
|
1616
|
+
/* @__PURE__ */ jsx(
|
|
1617
|
+
ChevronRightIcon,
|
|
1503
1618
|
{
|
|
1504
1619
|
className: cn(
|
|
1505
|
-
"
|
|
1506
|
-
|
|
1507
|
-
)
|
|
1508
|
-
children: groupStatus === "success" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1509
|
-
/* @__PURE__ */ jsx(CheckIcon, { className: "w-4 h-4 text-[var(--ash-accent)]" }),
|
|
1510
|
-
/* @__PURE__ */ jsxs("span", { className: "text-sm text-[var(--ash-accent)] font-medium", children: [
|
|
1511
|
-
"All ",
|
|
1512
|
-
totalCount,
|
|
1513
|
-
" tool",
|
|
1514
|
-
totalCount !== 1 ? "s" : "",
|
|
1515
|
-
" completed successfully"
|
|
1516
|
-
] })
|
|
1517
|
-
] }) : groupStatus === "failed" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1518
|
-
/* @__PURE__ */ jsx(StatusIndicator, { status: "failed", size: "sm" }),
|
|
1519
|
-
/* @__PURE__ */ jsxs("span", { className: "text-sm text-red-400 font-medium", children: [
|
|
1520
|
-
failedCount,
|
|
1521
|
-
" tool",
|
|
1522
|
-
failedCount !== 1 ? "s" : "",
|
|
1523
|
-
" failed"
|
|
1524
|
-
] })
|
|
1525
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1526
|
-
/* @__PURE__ */ jsx(StatusIndicator, { status: "failed", size: "sm" }),
|
|
1527
|
-
/* @__PURE__ */ jsxs("span", { className: "text-sm text-orange-400 font-medium", children: [
|
|
1528
|
-
completedCount,
|
|
1529
|
-
" succeeded, ",
|
|
1530
|
-
failedCount,
|
|
1531
|
-
" failed"
|
|
1532
|
-
] })
|
|
1533
|
-
] })
|
|
1620
|
+
"w-3.5 h-3.5 text-white/40 transition-transform duration-200 shrink-0",
|
|
1621
|
+
expanded && "rotate-90"
|
|
1622
|
+
)
|
|
1534
1623
|
}
|
|
1535
|
-
)
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1624
|
+
),
|
|
1625
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-white/60", children: [
|
|
1626
|
+
totalCount,
|
|
1627
|
+
" tool call",
|
|
1628
|
+
totalCount !== 1 ? "s" : ""
|
|
1629
|
+
] }),
|
|
1630
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: displayActions.map((action) => {
|
|
1631
|
+
const IconComponent = getActionIconComponent(action);
|
|
1632
|
+
if (!IconComponent) return null;
|
|
1633
|
+
return /* @__PURE__ */ jsx(
|
|
1634
|
+
IconComponent,
|
|
1635
|
+
{
|
|
1636
|
+
className: "w-3.5 h-3.5 text-white/30"
|
|
1637
|
+
},
|
|
1638
|
+
action
|
|
1639
|
+
);
|
|
1640
|
+
}) }),
|
|
1641
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1" }),
|
|
1642
|
+
!expanded && fileChanges.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 flex-wrap justify-end", children: [
|
|
1643
|
+
fileChanges.slice(0, 4).map((fc) => /* @__PURE__ */ jsx(
|
|
1644
|
+
FileBadge,
|
|
1645
|
+
{
|
|
1646
|
+
path: fc.path,
|
|
1647
|
+
linesAdded: fc.linesAdded,
|
|
1648
|
+
linesRemoved: fc.linesRemoved
|
|
1649
|
+
},
|
|
1650
|
+
fc.path
|
|
1651
|
+
)),
|
|
1652
|
+
fileChanges.length > 4 && /* @__PURE__ */ jsxs("span", { className: "text-xs text-white/40", children: [
|
|
1653
|
+
"+",
|
|
1654
|
+
fileChanges.length - 4,
|
|
1655
|
+
" more"
|
|
1656
|
+
] })
|
|
1657
|
+
] })
|
|
1658
|
+
]
|
|
1659
|
+
}
|
|
1660
|
+
),
|
|
1661
|
+
expanded && /* @__PURE__ */ jsx("div", { className: "pl-5 border-l border-white/10 ml-1.5 mt-1 space-y-0.5", children: toolCalls.map((toolCall) => /* @__PURE__ */ jsx("div", { children: expandedCardId === toolCall.id ? /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
|
|
1662
|
+
/* @__PURE__ */ jsx(
|
|
1663
|
+
ToolCallCard,
|
|
1664
|
+
{
|
|
1665
|
+
toolCall,
|
|
1666
|
+
defaultExpanded: true
|
|
1667
|
+
}
|
|
1668
|
+
),
|
|
1669
|
+
/* @__PURE__ */ jsx(
|
|
1670
|
+
"button",
|
|
1671
|
+
{
|
|
1672
|
+
onClick: () => setExpandedCardId(null),
|
|
1673
|
+
className: "text-xs text-white/40 hover:text-white/60 mt-1 pl-1",
|
|
1674
|
+
children: "Collapse"
|
|
1675
|
+
}
|
|
1676
|
+
)
|
|
1677
|
+
] }) : /* @__PURE__ */ jsx(
|
|
1678
|
+
"button",
|
|
1679
|
+
{
|
|
1680
|
+
onClick: () => setExpandedCardId(toolCall.id),
|
|
1681
|
+
className: "w-full text-left hover:bg-white/5 rounded px-1 -mx-1 transition-colors",
|
|
1682
|
+
children: /* @__PURE__ */ jsx(CompactToolRow, { toolCall })
|
|
1683
|
+
}
|
|
1684
|
+
) }, toolCall.id)) })
|
|
1685
|
+
] });
|
|
1545
1686
|
}
|
|
1546
|
-
function
|
|
1547
|
-
|
|
1548
|
-
|
|
1687
|
+
function extractFileChanges2(toolCalls) {
|
|
1688
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
1689
|
+
for (const tc of toolCalls) {
|
|
1690
|
+
const { actionType } = tc;
|
|
1691
|
+
if (actionType.action === "file_edit") {
|
|
1692
|
+
const edit = actionType;
|
|
1693
|
+
const existing = fileMap.get(edit.path);
|
|
1694
|
+
if (existing) {
|
|
1695
|
+
existing.linesAdded = (existing.linesAdded || 0) + (edit.linesAdded || 0);
|
|
1696
|
+
existing.linesRemoved = (existing.linesRemoved || 0) + (edit.linesRemoved || 0);
|
|
1697
|
+
} else {
|
|
1698
|
+
fileMap.set(edit.path, {
|
|
1699
|
+
path: edit.path,
|
|
1700
|
+
linesAdded: edit.linesAdded,
|
|
1701
|
+
linesRemoved: edit.linesRemoved
|
|
1702
|
+
});
|
|
1703
|
+
}
|
|
1704
|
+
} else if (actionType.action === "file_write") {
|
|
1705
|
+
if (!fileMap.has(actionType.path)) {
|
|
1706
|
+
fileMap.set(actionType.path, {
|
|
1707
|
+
path: actionType.path,
|
|
1708
|
+
linesAdded: actionType.linesWritten
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1549
1712
|
}
|
|
1550
|
-
|
|
1551
|
-
return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);
|
|
1713
|
+
return Array.from(fileMap.values());
|
|
1552
1714
|
}
|
|
1553
|
-
function
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
return "success";
|
|
1559
|
-
case "failed":
|
|
1560
|
-
return "error";
|
|
1561
|
-
default:
|
|
1562
|
-
return "pending";
|
|
1715
|
+
function countActionTypes2(toolCalls) {
|
|
1716
|
+
const counts = {};
|
|
1717
|
+
for (const tc of toolCalls) {
|
|
1718
|
+
const action = tc.actionType.action;
|
|
1719
|
+
counts[action] = (counts[action] || 0) + 1;
|
|
1563
1720
|
}
|
|
1721
|
+
return counts;
|
|
1564
1722
|
}
|
|
1565
|
-
function
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
case "
|
|
1571
|
-
return
|
|
1572
|
-
case "
|
|
1573
|
-
return
|
|
1723
|
+
function getActionIconComponent2(action) {
|
|
1724
|
+
switch (action) {
|
|
1725
|
+
case "file_read":
|
|
1726
|
+
return FileIcon;
|
|
1727
|
+
case "file_edit":
|
|
1728
|
+
case "file_write":
|
|
1729
|
+
return EditIcon;
|
|
1730
|
+
case "command_run":
|
|
1731
|
+
return TerminalIcon;
|
|
1732
|
+
case "search":
|
|
1733
|
+
case "glob":
|
|
1734
|
+
return SearchIcon;
|
|
1574
1735
|
default:
|
|
1575
|
-
return
|
|
1736
|
+
return null;
|
|
1576
1737
|
}
|
|
1577
1738
|
}
|
|
1578
1739
|
function StepAccordion({
|
|
@@ -1591,109 +1752,70 @@ function StepAccordion({
|
|
|
1591
1752
|
setInternalExpanded((prev) => !prev);
|
|
1592
1753
|
}
|
|
1593
1754
|
}, [onToggle]);
|
|
1755
|
+
const fileChanges = useMemo(() => extractFileChanges2(toolCalls), [toolCalls]);
|
|
1756
|
+
const actionCounts = useMemo(() => countActionTypes2(toolCalls), [toolCalls]);
|
|
1757
|
+
const displayActions = useMemo(() => {
|
|
1758
|
+
return Object.entries(actionCounts).sort((a, b) => b[1] - a[1]).slice(0, 3).map(([action]) => action);
|
|
1759
|
+
}, [actionCounts]);
|
|
1594
1760
|
if (toolCalls.length === 0) {
|
|
1595
1761
|
return null;
|
|
1596
1762
|
}
|
|
1597
|
-
const
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
),
|
|
1609
|
-
children: [
|
|
1610
|
-
/* @__PURE__ */ jsxs(
|
|
1611
|
-
"button",
|
|
1612
|
-
{
|
|
1613
|
-
type: "button",
|
|
1614
|
-
onClick: handleToggle,
|
|
1615
|
-
className: "w-full flex items-center gap-2 px-3 py-2 bg-white/5 hover:bg-white/10 transition-colors text-left cursor-pointer",
|
|
1616
|
-
children: [
|
|
1617
|
-
/* @__PURE__ */ jsx(
|
|
1618
|
-
ChevronDownIcon,
|
|
1619
|
-
{
|
|
1620
|
-
className: cn(
|
|
1621
|
-
"w-4 h-4 text-white/40 transition-transform duration-200 flex-shrink-0",
|
|
1622
|
-
!isExpanded && "-rotate-90"
|
|
1623
|
-
)
|
|
1624
|
-
}
|
|
1625
|
-
),
|
|
1626
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0 flex items-center gap-2", children: runningStep ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1627
|
-
/* @__PURE__ */ jsx(SpinnerIcon, { className: "w-3.5 h-3.5 animate-spin text-[var(--ash-accent)] flex-shrink-0" }),
|
|
1628
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-white/80 truncate", children: getToolLabel(runningStep.toolName, runningStep.summary) })
|
|
1629
|
-
] }) : hasError ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1630
|
-
/* @__PURE__ */ jsx(ErrorIcon, { className: "w-3.5 h-3.5 text-red-500 flex-shrink-0" }),
|
|
1631
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-red-400 truncate", children: "Completed with errors" })
|
|
1632
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1633
|
-
/* @__PURE__ */ jsx(CheckIcon, { className: "w-3.5 h-3.5 text-[var(--ash-accent)] flex-shrink-0" }),
|
|
1634
|
-
/* @__PURE__ */ jsxs("span", { className: "text-sm text-white/70 truncate", children: [
|
|
1635
|
-
completedSteps,
|
|
1636
|
-
" step",
|
|
1637
|
-
completedSteps !== 1 ? "s" : "",
|
|
1638
|
-
" completed"
|
|
1639
|
-
] })
|
|
1640
|
-
] }) }),
|
|
1641
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs px-1.5 py-0.5 rounded-full bg-white/10 text-white/50 flex-shrink-0", children: [
|
|
1642
|
-
completedSteps,
|
|
1643
|
-
"/",
|
|
1644
|
-
toolCalls.length
|
|
1645
|
-
] })
|
|
1646
|
-
]
|
|
1647
|
-
}
|
|
1648
|
-
),
|
|
1649
|
-
isExpanded && /* @__PURE__ */ jsx("div", { className: "border-t border-white/10 ash-accordion-content", children: /* @__PURE__ */ jsx("div", { className: "divide-y divide-white/5", children: toolCalls.map((toolCall, index) => {
|
|
1650
|
-
const stepStatus = toStepStatus(toolCall.status);
|
|
1651
|
-
const startTime = toolCall.startedAt ? new Date(toolCall.startedAt).getTime() : 0;
|
|
1652
|
-
const endTime = toolCall.completedAt ? new Date(toolCall.completedAt).getTime() : 0;
|
|
1653
|
-
const hasDuration = startTime > 0 && endTime > 0;
|
|
1654
|
-
return /* @__PURE__ */ jsxs(
|
|
1655
|
-
"div",
|
|
1763
|
+
const totalCount = toolCalls.length;
|
|
1764
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("ash-animate-fade-in", className), children: [
|
|
1765
|
+
/* @__PURE__ */ jsxs(
|
|
1766
|
+
"button",
|
|
1767
|
+
{
|
|
1768
|
+
type: "button",
|
|
1769
|
+
onClick: handleToggle,
|
|
1770
|
+
className: "w-full flex items-center gap-2 py-1 text-left group",
|
|
1771
|
+
children: [
|
|
1772
|
+
/* @__PURE__ */ jsx(
|
|
1773
|
+
ChevronRightIcon,
|
|
1656
1774
|
{
|
|
1657
1775
|
className: cn(
|
|
1658
|
-
"
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1776
|
+
"w-3.5 h-3.5 text-white/40 transition-transform duration-200 shrink-0",
|
|
1777
|
+
isExpanded && "rotate-90"
|
|
1778
|
+
)
|
|
1779
|
+
}
|
|
1780
|
+
),
|
|
1781
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-white/60", children: [
|
|
1782
|
+
totalCount,
|
|
1783
|
+
" tool call",
|
|
1784
|
+
totalCount !== 1 ? "s" : ""
|
|
1785
|
+
] }),
|
|
1786
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: displayActions.map((action) => {
|
|
1787
|
+
const IconComponent = getActionIconComponent2(action);
|
|
1788
|
+
if (!IconComponent) return null;
|
|
1789
|
+
return /* @__PURE__ */ jsx(
|
|
1790
|
+
IconComponent,
|
|
1791
|
+
{
|
|
1792
|
+
className: "w-3.5 h-3.5 text-white/30"
|
|
1793
|
+
},
|
|
1794
|
+
action
|
|
1795
|
+
);
|
|
1796
|
+
}) }),
|
|
1797
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1" }),
|
|
1798
|
+
!isExpanded && fileChanges.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 flex-wrap justify-end", children: [
|
|
1799
|
+
fileChanges.slice(0, 4).map((fc) => /* @__PURE__ */ jsx(
|
|
1800
|
+
FileBadge,
|
|
1801
|
+
{
|
|
1802
|
+
path: fc.path,
|
|
1803
|
+
linesAdded: fc.linesAdded,
|
|
1804
|
+
linesRemoved: fc.linesRemoved
|
|
1805
|
+
},
|
|
1806
|
+
fc.path
|
|
1807
|
+
)),
|
|
1808
|
+
fileChanges.length > 4 && /* @__PURE__ */ jsxs("span", { className: "text-xs text-white/40", children: [
|
|
1809
|
+
"+",
|
|
1810
|
+
fileChanges.length - 4,
|
|
1811
|
+
" more"
|
|
1812
|
+
] })
|
|
1813
|
+
] })
|
|
1814
|
+
]
|
|
1815
|
+
}
|
|
1816
|
+
),
|
|
1817
|
+
isExpanded && /* @__PURE__ */ jsx("div", { className: "pl-5 border-l border-white/10 ml-1.5 mt-1 space-y-0.5", children: toolCalls.map((toolCall) => /* @__PURE__ */ jsx(CompactToolRow, { toolCall }, toolCall.id)) })
|
|
1818
|
+
] });
|
|
1697
1819
|
}
|
|
1698
1820
|
|
|
1699
1821
|
// src/types.ts
|
|
@@ -1796,10 +1918,18 @@ function MessageList({
|
|
|
1796
1918
|
onOptionSelect,
|
|
1797
1919
|
renderWidget,
|
|
1798
1920
|
onWidgetAction,
|
|
1921
|
+
autoScroll = true,
|
|
1799
1922
|
className
|
|
1800
1923
|
}) {
|
|
1801
1924
|
const contextConfig = useDisplayConfig();
|
|
1802
1925
|
const config = displayConfigProp || contextConfig;
|
|
1926
|
+
const containerRef = useRef(null);
|
|
1927
|
+
const messagesEndRef = useRef(null);
|
|
1928
|
+
useEffect(() => {
|
|
1929
|
+
if (autoScroll && messagesEndRef.current && containerRef.current) {
|
|
1930
|
+
messagesEndRef.current.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
1931
|
+
}
|
|
1932
|
+
}, [entries, streamingContent, loading, autoScroll]);
|
|
1803
1933
|
const createWidgetActionHandler = useCallback(
|
|
1804
1934
|
(entryId, widgetType) => {
|
|
1805
1935
|
if (!onWidgetAction) return void 0;
|
|
@@ -1823,7 +1953,7 @@ function MessageList({
|
|
|
1823
1953
|
}
|
|
1824
1954
|
return groupEntriesForCompactMode(entries, config);
|
|
1825
1955
|
}, [entries, config]);
|
|
1826
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex-1 overflow-y-auto p-4 space-y-4 ash-scrollbar", className), children: [
|
|
1956
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: cn("flex-1 overflow-y-auto p-4 space-y-4 ash-scrollbar", className), children: [
|
|
1827
1957
|
groupedEntries.map((groupedEntry) => {
|
|
1828
1958
|
if (groupedEntry.type === "single") {
|
|
1829
1959
|
const entry = groupedEntry.entry;
|
|
@@ -1867,7 +1997,8 @@ function MessageList({
|
|
|
1867
1997
|
loading && !streamingContent && /* @__PURE__ */ jsxs("div", { className: "flex gap-3 ash-animate-fade-in", children: [
|
|
1868
1998
|
/* @__PURE__ */ jsx("div", { className: "w-7 h-7 rounded-full bg-[var(--ash-accent)]/20 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsx(BotIcon, { className: "w-4 h-4 text-[var(--ash-accent)]" }) }),
|
|
1869
1999
|
/* @__PURE__ */ jsx("div", { className: "rounded-xl p-3 bg-white/5", children: /* @__PURE__ */ jsx(LoadingIndicator, { variant: "dots" }) })
|
|
1870
|
-
] })
|
|
2000
|
+
] }),
|
|
2001
|
+
/* @__PURE__ */ jsx("div", { ref: messagesEndRef })
|
|
1871
2002
|
] });
|
|
1872
2003
|
}
|
|
1873
2004
|
function getLevelIcon(level) {
|
|
@@ -2014,6 +2145,94 @@ function LogsPanel({
|
|
|
2014
2145
|
}
|
|
2015
2146
|
);
|
|
2016
2147
|
}
|
|
2148
|
+
function CompactToolStatusLine({
|
|
2149
|
+
toolCall,
|
|
2150
|
+
previousToolCall,
|
|
2151
|
+
animationDuration = 300,
|
|
2152
|
+
className
|
|
2153
|
+
}) {
|
|
2154
|
+
const [isAnimating, setIsAnimating] = useState(false);
|
|
2155
|
+
const [displayedToolCall, setDisplayedToolCall] = useState(toolCall);
|
|
2156
|
+
const [exitingToolCall, setExitingToolCall] = useState(null);
|
|
2157
|
+
const prevToolCallRef = useRef(null);
|
|
2158
|
+
useEffect(() => {
|
|
2159
|
+
if (toolCall.id !== prevToolCallRef.current) {
|
|
2160
|
+
if (prevToolCallRef.current !== null && previousToolCall) {
|
|
2161
|
+
setExitingToolCall(previousToolCall);
|
|
2162
|
+
setIsAnimating(true);
|
|
2163
|
+
const timer = setTimeout(() => {
|
|
2164
|
+
setDisplayedToolCall(toolCall);
|
|
2165
|
+
setExitingToolCall(null);
|
|
2166
|
+
setIsAnimating(false);
|
|
2167
|
+
}, animationDuration);
|
|
2168
|
+
prevToolCallRef.current = toolCall.id;
|
|
2169
|
+
return () => clearTimeout(timer);
|
|
2170
|
+
} else {
|
|
2171
|
+
setDisplayedToolCall(toolCall);
|
|
2172
|
+
prevToolCallRef.current = toolCall.id;
|
|
2173
|
+
}
|
|
2174
|
+
} else {
|
|
2175
|
+
setDisplayedToolCall(toolCall);
|
|
2176
|
+
}
|
|
2177
|
+
return void 0;
|
|
2178
|
+
}, [toolCall, previousToolCall, animationDuration]);
|
|
2179
|
+
const statusClasses = {
|
|
2180
|
+
pending: "border-yellow-500/30",
|
|
2181
|
+
success: "border-[var(--ash-accent)]/30",
|
|
2182
|
+
failed: "border-red-500/30"
|
|
2183
|
+
};
|
|
2184
|
+
const renderToolCallContent = (tc, isExiting) => /* @__PURE__ */ jsxs(
|
|
2185
|
+
"div",
|
|
2186
|
+
{
|
|
2187
|
+
className: cn(
|
|
2188
|
+
"flex items-center gap-3 px-4 py-2.5",
|
|
2189
|
+
isExiting ? "ash-status-line-exit" : isAnimating ? "ash-status-line-enter" : ""
|
|
2190
|
+
),
|
|
2191
|
+
style: {
|
|
2192
|
+
animationDuration: `${animationDuration}ms`
|
|
2193
|
+
},
|
|
2194
|
+
children: [
|
|
2195
|
+
/* @__PURE__ */ jsx(
|
|
2196
|
+
"div",
|
|
2197
|
+
{
|
|
2198
|
+
className: cn(
|
|
2199
|
+
"w-6 h-6 rounded-lg flex items-center justify-center shrink-0",
|
|
2200
|
+
tc.status === "pending" ? "bg-yellow-500/20" : tc.status === "failed" ? "bg-red-500/20" : "bg-[var(--ash-accent)]/20"
|
|
2201
|
+
),
|
|
2202
|
+
children: /* @__PURE__ */ jsx(
|
|
2203
|
+
ActionIcon,
|
|
2204
|
+
{
|
|
2205
|
+
actionType: tc.actionType,
|
|
2206
|
+
className: cn(
|
|
2207
|
+
"w-3.5 h-3.5",
|
|
2208
|
+
tc.status === "pending" ? "text-yellow-400" : tc.status === "failed" ? "text-red-400" : "text-[var(--ash-accent)]"
|
|
2209
|
+
)
|
|
2210
|
+
}
|
|
2211
|
+
)
|
|
2212
|
+
}
|
|
2213
|
+
),
|
|
2214
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-white shrink-0", children: getActionLabel(tc.actionType) }),
|
|
2215
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-sm truncate text-white/60 flex-1 min-w-0", children: tc.summary }),
|
|
2216
|
+
/* @__PURE__ */ jsx(StatusIndicator, { status: tc.status, size: "sm" })
|
|
2217
|
+
]
|
|
2218
|
+
}
|
|
2219
|
+
);
|
|
2220
|
+
return /* @__PURE__ */ jsxs(
|
|
2221
|
+
"div",
|
|
2222
|
+
{
|
|
2223
|
+
className: cn(
|
|
2224
|
+
"relative rounded-xl border bg-[var(--ash-surface-dark,#0a0a0a)] overflow-hidden",
|
|
2225
|
+
statusClasses[displayedToolCall.status],
|
|
2226
|
+
displayedToolCall.status === "pending" && "ash-tool-status-pending",
|
|
2227
|
+
className
|
|
2228
|
+
),
|
|
2229
|
+
children: [
|
|
2230
|
+
exitingToolCall && /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: renderToolCallContent(exitingToolCall, true) }),
|
|
2231
|
+
renderToolCallContent(displayedToolCall, false)
|
|
2232
|
+
]
|
|
2233
|
+
}
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2017
2236
|
function TodoStatusIcon({ status, className = "w-4 h-4" }) {
|
|
2018
2237
|
switch (status) {
|
|
2019
2238
|
case "completed":
|
|
@@ -3173,7 +3392,79 @@ function useAgentChat(options) {
|
|
|
3173
3392
|
setEntries
|
|
3174
3393
|
};
|
|
3175
3394
|
}
|
|
3395
|
+
function textToBase64(text) {
|
|
3396
|
+
const encoder = new TextEncoder();
|
|
3397
|
+
const bytes = encoder.encode(text);
|
|
3398
|
+
let binary = "";
|
|
3399
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
3400
|
+
const byte = bytes[i];
|
|
3401
|
+
if (byte !== void 0) {
|
|
3402
|
+
binary += String.fromCharCode(byte);
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
return btoa(binary);
|
|
3406
|
+
}
|
|
3407
|
+
function generateFilename(template) {
|
|
3408
|
+
const timestamp = Date.now();
|
|
3409
|
+
const date = new Date(timestamp);
|
|
3410
|
+
const dateStr = date.toISOString().split("T")[0] ?? "unknown-date";
|
|
3411
|
+
const timeStr = (date.toTimeString().split(" ")[0] ?? "00-00-00").replace(/:/g, "-");
|
|
3412
|
+
return template.replace("{timestamp}", String(timestamp)).replace("{date}", dateStr).replace("{time}", timeStr);
|
|
3413
|
+
}
|
|
3414
|
+
function useLongTextConversion({
|
|
3415
|
+
threshold = 5e3,
|
|
3416
|
+
filenameTemplate = "pasted-text-{timestamp}.txt",
|
|
3417
|
+
onConversion
|
|
3418
|
+
} = {}) {
|
|
3419
|
+
const [lastConversion, setLastConversion] = useState(null);
|
|
3420
|
+
const processText = useCallback((text) => {
|
|
3421
|
+
if (text.length <= threshold) {
|
|
3422
|
+
return { text };
|
|
3423
|
+
}
|
|
3424
|
+
const filename = generateFilename(filenameTemplate);
|
|
3425
|
+
const content = textToBase64(text);
|
|
3426
|
+
const encoder = new TextEncoder();
|
|
3427
|
+
const size = encoder.encode(text).length;
|
|
3428
|
+
const lineCount = text.split("\n").length;
|
|
3429
|
+
const attachment = {
|
|
3430
|
+
filename,
|
|
3431
|
+
content,
|
|
3432
|
+
mimeType: "text/plain",
|
|
3433
|
+
size
|
|
3434
|
+
};
|
|
3435
|
+
const preview = text.slice(0, 100) + (text.length > 100 ? "..." : "");
|
|
3436
|
+
const conversionInfo = {
|
|
3437
|
+
originalLength: text.length,
|
|
3438
|
+
filename,
|
|
3439
|
+
preview,
|
|
3440
|
+
lineCount
|
|
3441
|
+
};
|
|
3442
|
+
setLastConversion(conversionInfo);
|
|
3443
|
+
onConversion?.(conversionInfo);
|
|
3444
|
+
return { text: "", attachment };
|
|
3445
|
+
}, [threshold, filenameTemplate, onConversion]);
|
|
3446
|
+
const handlePaste = useCallback((event, _currentValue, _setValue, addAttachment) => {
|
|
3447
|
+
const pastedText = event.clipboardData.getData("text/plain");
|
|
3448
|
+
if (pastedText.length > threshold) {
|
|
3449
|
+
event.preventDefault();
|
|
3450
|
+
const result = processText(pastedText);
|
|
3451
|
+
if (result.attachment) {
|
|
3452
|
+
addAttachment(result.attachment);
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
}, [threshold, processText]);
|
|
3456
|
+
const clearLastConversion = useCallback(() => {
|
|
3457
|
+
setLastConversion(null);
|
|
3458
|
+
}, []);
|
|
3459
|
+
return {
|
|
3460
|
+
processText,
|
|
3461
|
+
handlePaste,
|
|
3462
|
+
lastConversion,
|
|
3463
|
+
clearLastConversion,
|
|
3464
|
+
threshold
|
|
3465
|
+
};
|
|
3466
|
+
}
|
|
3176
3467
|
|
|
3177
|
-
export { ActionIcon, AlertCircleIcon, AlertTriangleIcon, AssistantMessage, BotIcon, BrainIcon, BugIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon, ClipboardListIcon, CodeBlock, CodeIcon, CompactToolStatusLine, CopyIcon, DEFAULT_DISPLAY_CONFIG, DisplayModeProvider, DisplayModeToggle, EditIcon, EnvVarsPanel, ErrorIcon, ErrorMessage, FileIcon, FilePlusIcon, FolderSearchIcon, GlobeIcon, InfoIcon, JsonDisplay, ListChecksIcon, LoaderIcon, LoadingIndicator, LogsPanel, MessageEntry, MessageList, MessageSquareIcon, MoonIcon, OptionCards, PaperclipIcon, PlugIcon, SearchIcon, SendIcon, SparklesIcon, SpinnerIcon, StatusIndicator, StepAccordion, StopCircleIcon, StreamingText, SunIcon, TerminalIcon, ThemeProvider, ThinkingMessage, TodoPanel, ToolCallCard, ToolCallMessage, ToolExecutionGroup, ToolIcon, TypewriterText, UserIcon, UserMessage, XCircleIcon, XIcon, allKeyframesCss, borderRadius, cn, colors, createToolCall, extractTextContent, extractToolCallsFromGroup, formatFileSize, formatTimestamp, formatToolName, generateToolSummary, getActionIcon, getActionLabel, groupEntriesForCompactMode, inlineStyles, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction, isWidgetEntry, keyframes, keyframesCss, mapToolToActionType, normalizeToolResult, parseCommandResult, parseMcpToolName, parseOptionsFromContent, shadows, spacing, tokensToCssVariables, transitions, truncate, typography, updateToolCallWithResult, useAgentChat, useDisplayConfig, useDisplayMode, useFileUpload, useMessageQueue, useStopExecution, useTheme, widget, zIndex };
|
|
3468
|
+
export { ActionIcon, AlertCircleIcon, AlertTriangleIcon, AssistantMessage, BotIcon, BrainIcon, BugIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon, ClipboardListIcon, CodeBlock, CodeIcon, CompactToolRow, CompactToolStatusLine, CopyIcon, DEFAULT_DISPLAY_CONFIG, DisplayModeProvider, DisplayModeToggle, EditIcon, EnvVarsPanel, ErrorIcon, ErrorMessage, FileBadge, FileIcon, FilePlusIcon, FolderSearchIcon, GlobeIcon, InfoIcon, JsonDisplay, ListChecksIcon, LoaderIcon, LoadingIndicator, LogsPanel, MessageEntry, MessageList, MessageSquareIcon, MoonIcon, OptionCards, PaperclipIcon, PlugIcon, SearchIcon, SendIcon, SparklesIcon, SpinnerIcon, StatusIndicator, StepAccordion, StopCircleIcon, StreamingText, SunIcon, TerminalIcon, ThemeProvider, ThinkingMessage, TodoPanel, ToolCallCard, ToolCallMessage, ToolExecutionGroup, ToolIcon, TypewriterText, UserIcon, UserMessage, XCircleIcon, XIcon, allKeyframesCss, borderRadius, cn, colors, createToolCall, extractTextContent, extractToolCallsFromGroup, formatFileSize, formatTimestamp, formatToolName, generateToolSummary, getActionIcon, getActionLabel, groupEntriesForCompactMode, inlineStyles, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction, isWidgetEntry, keyframes, keyframesCss, mapToolToActionType, normalizeToolResult, parseCommandResult, parseMcpToolName, parseOptionsFromContent, shadows, spacing, tokensToCssVariables, transitions, truncate, typography, updateToolCallWithResult, useAgentChat, useDisplayConfig, useDisplayMode, useFileUpload, useLongTextConversion, useMessageQueue, useStopExecution, useTheme, widget, zIndex };
|
|
3178
3469
|
//# sourceMappingURL=index.js.map
|
|
3179
3470
|
//# sourceMappingURL=index.js.map
|