@ash-cloud/ash-ui 0.0.9 → 0.1.1
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/design-tokens.cjs +20 -0
- package/dist/design-tokens.cjs.map +1 -1
- package/dist/design-tokens.d.cts +31 -1
- package/dist/design-tokens.d.ts +31 -1
- package/dist/design-tokens.js +20 -1
- package/dist/design-tokens.js.map +1 -1
- package/dist/icons.cjs +23 -0
- package/dist/icons.cjs.map +1 -1
- package/dist/icons.d.cts +4 -1
- package/dist/icons.d.ts +4 -1
- package/dist/icons.js +21 -1
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +687 -118
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +463 -22
- package/dist/index.d.ts +463 -22
- package/dist/index.js +679 -120
- package/dist/index.js.map +1 -1
- package/dist/styles-full.css +1 -1
- package/dist/styles.css +1 -1
- package/dist/types.cjs +8 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +238 -2
- package/dist/types.d.ts +238 -2
- package/dist/types.js +8 -1
- package/dist/types.js.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { lazy, createContext, useState, useRef, useMemo, useEffect, Suspense,
|
|
1
|
+
import { lazy, createContext, useState, useCallback, useRef, useMemo, useEffect, Suspense, Fragment as Fragment$1, useContext } from 'react';
|
|
2
2
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
// src/components/ToolCallCard.tsx
|
|
@@ -692,6 +692,26 @@ function ErrorIcon({ className }) {
|
|
|
692
692
|
/* @__PURE__ */ jsx("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
|
|
693
693
|
] });
|
|
694
694
|
}
|
|
695
|
+
function MicrophoneIcon({ className }) {
|
|
696
|
+
return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
697
|
+
/* @__PURE__ */ jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }),
|
|
698
|
+
/* @__PURE__ */ jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
|
|
699
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
|
|
700
|
+
/* @__PURE__ */ jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
|
|
701
|
+
] });
|
|
702
|
+
}
|
|
703
|
+
function HomeIcon({ className }) {
|
|
704
|
+
return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
705
|
+
/* @__PURE__ */ jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }),
|
|
706
|
+
/* @__PURE__ */ jsx("polyline", { points: "9 22 9 12 15 12 15 22" })
|
|
707
|
+
] });
|
|
708
|
+
}
|
|
709
|
+
function ArrowUpIcon({ className }) {
|
|
710
|
+
return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
711
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "19", x2: "12", y2: "5" }),
|
|
712
|
+
/* @__PURE__ */ jsx("polyline", { points: "5 12 12 5 19 12" })
|
|
713
|
+
] });
|
|
714
|
+
}
|
|
695
715
|
function StatusIndicator({ status, size = "sm", className }) {
|
|
696
716
|
const sizeClasses = {
|
|
697
717
|
sm: "w-2 h-2",
|
|
@@ -752,14 +772,41 @@ function CodeBlock({
|
|
|
752
772
|
className
|
|
753
773
|
}) {
|
|
754
774
|
const [expanded, setExpanded] = useState(false);
|
|
775
|
+
const [copied, setCopied] = useState(false);
|
|
755
776
|
const lines = children.split("\n");
|
|
756
777
|
const isLong = lines.length > 10 || children.length > 500;
|
|
757
|
-
|
|
778
|
+
const handleCopy = useCallback(async () => {
|
|
779
|
+
try {
|
|
780
|
+
await navigator.clipboard.writeText(children);
|
|
781
|
+
setCopied(true);
|
|
782
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
783
|
+
} catch (err) {
|
|
784
|
+
console.error("Failed to copy:", err);
|
|
785
|
+
}
|
|
786
|
+
}, [children]);
|
|
787
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative rounded-lg overflow-hidden border border-white/10", className), children: [
|
|
788
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-2 bg-[var(--ash-code-header-bg)] border-b border-white/10", children: [
|
|
789
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-white/60 font-medium", children: language || "code" }),
|
|
790
|
+
/* @__PURE__ */ jsx(
|
|
791
|
+
"button",
|
|
792
|
+
{
|
|
793
|
+
onClick: handleCopy,
|
|
794
|
+
className: "flex items-center gap-1.5 text-xs text-white/60 hover:text-white transition-colors",
|
|
795
|
+
children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
796
|
+
/* @__PURE__ */ jsx(CheckIcon, { className: "w-3.5 h-3.5" }),
|
|
797
|
+
/* @__PURE__ */ jsx("span", { children: "Copied!" })
|
|
798
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
799
|
+
/* @__PURE__ */ jsx(CopyIcon, { className: "w-3.5 h-3.5" }),
|
|
800
|
+
/* @__PURE__ */ jsx("span", { children: "Copy" })
|
|
801
|
+
] })
|
|
802
|
+
}
|
|
803
|
+
)
|
|
804
|
+
] }),
|
|
758
805
|
/* @__PURE__ */ jsx(
|
|
759
806
|
"pre",
|
|
760
807
|
{
|
|
761
808
|
className: cn(
|
|
762
|
-
"
|
|
809
|
+
"text-xs font-mono text-white/90 p-4 bg-black/30 overflow-x-auto whitespace-pre-wrap break-words",
|
|
763
810
|
!expanded && isLong && "overflow-y-hidden"
|
|
764
811
|
),
|
|
765
812
|
style: !expanded && isLong ? { maxHeight } : void 0,
|
|
@@ -943,7 +990,7 @@ function SectionHeader({ children }) {
|
|
|
943
990
|
return /* @__PURE__ */ jsx("div", { className: "ash-tool-section-header", children });
|
|
944
991
|
}
|
|
945
992
|
function SectionContent({ children }) {
|
|
946
|
-
return /* @__PURE__ */ jsx("div", { className: "px-3 py-
|
|
993
|
+
return /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5", children });
|
|
947
994
|
}
|
|
948
995
|
function CommandRunDetails({ action }) {
|
|
949
996
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -1064,7 +1111,7 @@ function WebSearchDetails({ action }) {
|
|
|
1064
1111
|
/* @__PURE__ */ jsx(SectionContent, { children: /* @__PURE__ */ jsx("span", { className: "text-sm text-white/90", children: action.query }) })
|
|
1065
1112
|
] });
|
|
1066
1113
|
}
|
|
1067
|
-
function McpToolDetails({ action }) {
|
|
1114
|
+
function McpToolDetails({ action, isError }) {
|
|
1068
1115
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1069
1116
|
/* @__PURE__ */ jsx(SectionHeader, { children: "TOOL" }),
|
|
1070
1117
|
/* @__PURE__ */ jsx(SectionContent, { children: /* @__PURE__ */ jsxs("code", { className: "text-xs font-mono bg-white/10 text-white/90 px-1 py-0.5 rounded", children: [
|
|
@@ -1077,20 +1124,20 @@ function McpToolDetails({ action }) {
|
|
|
1077
1124
|
/* @__PURE__ */ jsx(SectionContent, { children: /* @__PURE__ */ jsx(JsonDisplay, { value: action.arguments }) })
|
|
1078
1125
|
] }),
|
|
1079
1126
|
action.result && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1080
|
-
/* @__PURE__ */ jsx(SectionHeader, { children: "RESULT" }),
|
|
1081
|
-
/* @__PURE__ */ jsx(SectionContent, { children: action.result.type === "markdown" ? /* @__PURE__ */ jsx(CodeBlock, { children: String(action.result.value) }) : /* @__PURE__ */ jsx(JsonDisplay, { value: action.result.value }) })
|
|
1127
|
+
/* @__PURE__ */ jsx(SectionHeader, { children: isError ? "ERROR" : "RESULT" }),
|
|
1128
|
+
/* @__PURE__ */ jsx(SectionContent, { children: /* @__PURE__ */ jsx("div", { className: isError ? "text-red-400" : "", children: action.result.type === "markdown" ? /* @__PURE__ */ jsx(CodeBlock, { children: String(action.result.value) }) : /* @__PURE__ */ jsx(JsonDisplay, { value: action.result.value }) }) })
|
|
1082
1129
|
] })
|
|
1083
1130
|
] });
|
|
1084
1131
|
}
|
|
1085
|
-
function GenericToolDetails({ action }) {
|
|
1132
|
+
function GenericToolDetails({ action, isError }) {
|
|
1086
1133
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1087
1134
|
action.arguments && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1088
1135
|
/* @__PURE__ */ jsx(SectionHeader, { children: "ARGS" }),
|
|
1089
1136
|
/* @__PURE__ */ jsx(SectionContent, { children: /* @__PURE__ */ jsx(JsonDisplay, { value: action.arguments }) })
|
|
1090
1137
|
] }),
|
|
1091
1138
|
action.result && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1092
|
-
/* @__PURE__ */ jsx(SectionHeader, { children: "RESULT" }),
|
|
1093
|
-
/* @__PURE__ */ jsx(SectionContent, { children: action.result.type === "markdown" ? /* @__PURE__ */ jsx(CodeBlock, { children: String(action.result.value) }) : /* @__PURE__ */ jsx(JsonDisplay, { value: action.result.value }) })
|
|
1139
|
+
/* @__PURE__ */ jsx(SectionHeader, { children: isError ? "ERROR" : "RESULT" }),
|
|
1140
|
+
/* @__PURE__ */ jsx(SectionContent, { children: /* @__PURE__ */ jsx("div", { className: isError ? "text-red-400" : "", children: action.result.type === "markdown" ? /* @__PURE__ */ jsx(CodeBlock, { children: String(action.result.value) }) : /* @__PURE__ */ jsx(JsonDisplay, { value: action.result.value }) }) })
|
|
1094
1141
|
] })
|
|
1095
1142
|
] });
|
|
1096
1143
|
}
|
|
@@ -1162,7 +1209,7 @@ function TodoWriteDetails({ action }) {
|
|
|
1162
1209
|
}) }) })
|
|
1163
1210
|
] });
|
|
1164
1211
|
}
|
|
1165
|
-
function ToolDetails({ actionType }) {
|
|
1212
|
+
function ToolDetails({ actionType, isError }) {
|
|
1166
1213
|
switch (actionType.action) {
|
|
1167
1214
|
case "command_run":
|
|
1168
1215
|
return /* @__PURE__ */ jsx(CommandRunDetails, { action: actionType });
|
|
@@ -1181,9 +1228,9 @@ function ToolDetails({ actionType }) {
|
|
|
1181
1228
|
case "web_search":
|
|
1182
1229
|
return /* @__PURE__ */ jsx(WebSearchDetails, { action: actionType });
|
|
1183
1230
|
case "mcp_tool":
|
|
1184
|
-
return /* @__PURE__ */ jsx(McpToolDetails, { action: actionType });
|
|
1231
|
+
return /* @__PURE__ */ jsx(McpToolDetails, { action: actionType, isError });
|
|
1185
1232
|
case "generic_tool":
|
|
1186
|
-
return /* @__PURE__ */ jsx(GenericToolDetails, { action: actionType });
|
|
1233
|
+
return /* @__PURE__ */ jsx(GenericToolDetails, { action: actionType, isError });
|
|
1187
1234
|
case "todo_write":
|
|
1188
1235
|
return /* @__PURE__ */ jsx(TodoWriteDetails, { action: actionType });
|
|
1189
1236
|
default:
|
|
@@ -1244,7 +1291,7 @@ function ToolCallCard({ toolCall, defaultExpanded = false, className }) {
|
|
|
1244
1291
|
"div",
|
|
1245
1292
|
{
|
|
1246
1293
|
className: cn(
|
|
1247
|
-
"rounded-
|
|
1294
|
+
"rounded-lg border bg-[var(--ash-surface-dark,#0a0a0a)] overflow-hidden",
|
|
1248
1295
|
statusClasses[status],
|
|
1249
1296
|
className
|
|
1250
1297
|
),
|
|
@@ -1254,35 +1301,35 @@ function ToolCallCard({ toolCall, defaultExpanded = false, className }) {
|
|
|
1254
1301
|
{
|
|
1255
1302
|
onClick: () => canExpand && setExpanded(!expanded),
|
|
1256
1303
|
className: cn(
|
|
1257
|
-
"w-full px-
|
|
1304
|
+
"w-full px-3 py-2 flex items-center justify-between transition-colors",
|
|
1258
1305
|
canExpand ? "hover:bg-white/5 cursor-pointer" : "cursor-default"
|
|
1259
1306
|
),
|
|
1260
1307
|
disabled: !canExpand,
|
|
1261
1308
|
children: [
|
|
1262
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
1309
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [
|
|
1263
1310
|
/* @__PURE__ */ jsx("div", { className: cn(
|
|
1264
|
-
"w-
|
|
1311
|
+
"w-5 h-5 rounded flex items-center justify-center shrink-0",
|
|
1265
1312
|
status === "pending" ? "bg-yellow-500/20" : status === "failed" ? "bg-red-500/20" : "bg-[var(--ash-accent)]/20"
|
|
1266
1313
|
), children: /* @__PURE__ */ jsx(
|
|
1267
1314
|
ActionIcon,
|
|
1268
1315
|
{
|
|
1269
1316
|
actionType,
|
|
1270
1317
|
className: cn(
|
|
1271
|
-
"w-3
|
|
1318
|
+
"w-3 h-3",
|
|
1272
1319
|
status === "pending" ? "text-yellow-400" : status === "failed" ? "text-red-400" : "text-[var(--ash-accent)]"
|
|
1273
1320
|
)
|
|
1274
1321
|
}
|
|
1275
1322
|
) }),
|
|
1276
|
-
/* @__PURE__ */ jsx("span", { className: "text-
|
|
1277
|
-
/* @__PURE__ */ jsx("span", { className: "font-mono text-
|
|
1323
|
+
/* @__PURE__ */ jsx("span", { className: "text-[13px] font-medium text-white shrink-0", children: getActionLabel(actionType) }),
|
|
1324
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-[12px] truncate text-white/50 min-w-0", children: summary })
|
|
1278
1325
|
] }),
|
|
1279
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
1326
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [
|
|
1280
1327
|
/* @__PURE__ */ jsx(StatusIndicator, { status, size: "sm" }),
|
|
1281
1328
|
canExpand && /* @__PURE__ */ jsx(
|
|
1282
1329
|
ChevronDownIcon,
|
|
1283
1330
|
{
|
|
1284
1331
|
className: cn(
|
|
1285
|
-
"w-
|
|
1332
|
+
"w-3.5 h-3.5 text-white/30 transition-transform duration-200",
|
|
1286
1333
|
expanded && "rotate-180"
|
|
1287
1334
|
)
|
|
1288
1335
|
}
|
|
@@ -1291,11 +1338,15 @@ function ToolCallCard({ toolCall, defaultExpanded = false, className }) {
|
|
|
1291
1338
|
]
|
|
1292
1339
|
}
|
|
1293
1340
|
),
|
|
1294
|
-
expanded && canExpand && /* @__PURE__ */ jsxs("div", { className: "border-t border-white/5 max-h-[
|
|
1295
|
-
/* @__PURE__ */ jsx(ToolDetails, { actionType }),
|
|
1296
|
-
status === "success" && /* @__PURE__ */ jsx("div", { className: "px-
|
|
1297
|
-
/* @__PURE__ */ jsx(CheckIcon, { className: "w-
|
|
1298
|
-
/* @__PURE__ */ jsx("span", { className: "text-
|
|
1341
|
+
expanded && canExpand && /* @__PURE__ */ jsxs("div", { className: "border-t border-white/5 max-h-[350px] overflow-y-auto ash-scrollbar bg-black/20", children: [
|
|
1342
|
+
/* @__PURE__ */ jsx(ToolDetails, { actionType, isError: toolCall.isError || status === "failed" }),
|
|
1343
|
+
status === "success" && /* @__PURE__ */ jsx("div", { className: "px-3 py-2 border-t border-white/5 bg-[var(--ash-accent)]/5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
1344
|
+
/* @__PURE__ */ jsx(CheckIcon, { className: "w-3.5 h-3.5 text-[var(--ash-accent)]" }),
|
|
1345
|
+
/* @__PURE__ */ jsx("span", { className: "text-[12px] text-[var(--ash-accent)] font-medium", children: "Completed" })
|
|
1346
|
+
] }) }),
|
|
1347
|
+
status === "failed" && /* @__PURE__ */ jsx("div", { className: "px-3 py-2 border-t border-red-500/20 bg-red-500/10", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
1348
|
+
/* @__PURE__ */ jsx(XCircleIcon, { className: "w-3.5 h-3.5 text-red-400" }),
|
|
1349
|
+
/* @__PURE__ */ jsx("span", { className: "text-[12px] text-red-400 font-medium", children: "Failed" })
|
|
1299
1350
|
] }) })
|
|
1300
1351
|
] })
|
|
1301
1352
|
]
|
|
@@ -1303,15 +1354,69 @@ function ToolCallCard({ toolCall, defaultExpanded = false, className }) {
|
|
|
1303
1354
|
);
|
|
1304
1355
|
}
|
|
1305
1356
|
var ReactMarkdown = lazy(() => import('react-markdown'));
|
|
1306
|
-
function LazyMarkdown({ children, fallback, className }) {
|
|
1357
|
+
function LazyMarkdown({ children, fallback, components, className }) {
|
|
1307
1358
|
const [mounted, setMounted] = useState(false);
|
|
1308
1359
|
useEffect(() => {
|
|
1309
1360
|
setMounted(true);
|
|
1310
1361
|
}, []);
|
|
1362
|
+
const markdownComponents = useMemo(() => {
|
|
1363
|
+
if (!components) return void 0;
|
|
1364
|
+
return components;
|
|
1365
|
+
}, [components]);
|
|
1311
1366
|
if (!mounted) {
|
|
1312
1367
|
return /* @__PURE__ */ jsx("span", { className, children: fallback ?? children });
|
|
1313
1368
|
}
|
|
1314
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("span", { className, children: fallback ?? children }), children: /* @__PURE__ */ jsx(ReactMarkdown, { children }) });
|
|
1369
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("span", { className, children: fallback ?? children }), children: /* @__PURE__ */ jsx(ReactMarkdown, { components: markdownComponents, children }) });
|
|
1370
|
+
}
|
|
1371
|
+
function DefaultMentionBadge({ segment }) {
|
|
1372
|
+
const bgColor = segment.color ? `${segment.color}20` : "rgba(34, 197, 94, 0.2)";
|
|
1373
|
+
const textColor = segment.color || "#22c55e";
|
|
1374
|
+
const borderColor = segment.color ? `${segment.color}40` : "rgba(34, 197, 94, 0.4)";
|
|
1375
|
+
return /* @__PURE__ */ jsxs(
|
|
1376
|
+
"span",
|
|
1377
|
+
{
|
|
1378
|
+
className: "inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium mx-0.5",
|
|
1379
|
+
style: {
|
|
1380
|
+
backgroundColor: bgColor,
|
|
1381
|
+
color: textColor,
|
|
1382
|
+
border: `1px solid ${borderColor}`
|
|
1383
|
+
},
|
|
1384
|
+
title: segment.id ? `ID: ${segment.id}` : void 0,
|
|
1385
|
+
children: [
|
|
1386
|
+
"@",
|
|
1387
|
+
segment.name
|
|
1388
|
+
]
|
|
1389
|
+
}
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
function RichContentRenderer({
|
|
1393
|
+
content,
|
|
1394
|
+
renderers,
|
|
1395
|
+
className
|
|
1396
|
+
}) {
|
|
1397
|
+
return /* @__PURE__ */ jsx("div", { className: cn("rich-content", className), children: content.map((segment, index) => {
|
|
1398
|
+
const key = `segment-${index}`;
|
|
1399
|
+
switch (segment.type) {
|
|
1400
|
+
case "text":
|
|
1401
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(LazyMarkdown, { children: segment.content }) }, key);
|
|
1402
|
+
case "mention":
|
|
1403
|
+
if (renderers?.renderMention) {
|
|
1404
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: renderers.renderMention({ segment }) }, key);
|
|
1405
|
+
}
|
|
1406
|
+
return /* @__PURE__ */ jsx(DefaultMentionBadge, { segment }, key);
|
|
1407
|
+
case "component":
|
|
1408
|
+
if (renderers?.renderComponent) {
|
|
1409
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: renderers.renderComponent({ segment }) }, key);
|
|
1410
|
+
}
|
|
1411
|
+
return /* @__PURE__ */ jsxs("code", { className: "text-xs text-orange-400", children: [
|
|
1412
|
+
"[component: ",
|
|
1413
|
+
segment.componentType,
|
|
1414
|
+
"]"
|
|
1415
|
+
] }, key);
|
|
1416
|
+
default:
|
|
1417
|
+
return null;
|
|
1418
|
+
}
|
|
1419
|
+
}) });
|
|
1315
1420
|
}
|
|
1316
1421
|
function OptionCards({ options, onSelect, className }) {
|
|
1317
1422
|
return /* @__PURE__ */ jsx("div", { className: cn("grid gap-2 mt-3", className), style: {
|
|
@@ -1361,6 +1466,36 @@ function OptionCards({ options, onSelect, className }) {
|
|
|
1361
1466
|
option.id
|
|
1362
1467
|
)) });
|
|
1363
1468
|
}
|
|
1469
|
+
var scaleClasses = {
|
|
1470
|
+
dense: {
|
|
1471
|
+
text: "text-xs",
|
|
1472
|
+
padding: "px-2 py-1",
|
|
1473
|
+
gap: "gap-1.5",
|
|
1474
|
+
avatar: "w-4 h-4",
|
|
1475
|
+
messageGap: "space-y-0.5"
|
|
1476
|
+
},
|
|
1477
|
+
compact: {
|
|
1478
|
+
text: "text-[13px]",
|
|
1479
|
+
padding: "px-3 py-2",
|
|
1480
|
+
gap: "gap-2",
|
|
1481
|
+
avatar: "w-5 h-5",
|
|
1482
|
+
messageGap: "space-y-1"
|
|
1483
|
+
},
|
|
1484
|
+
default: {
|
|
1485
|
+
text: "text-sm",
|
|
1486
|
+
padding: "px-4 py-3",
|
|
1487
|
+
gap: "gap-3",
|
|
1488
|
+
avatar: "w-6 h-6",
|
|
1489
|
+
messageGap: "space-y-2"
|
|
1490
|
+
},
|
|
1491
|
+
comfortable: {
|
|
1492
|
+
text: "text-[15px]",
|
|
1493
|
+
padding: "px-5 py-4",
|
|
1494
|
+
gap: "gap-4",
|
|
1495
|
+
avatar: "w-7 h-7",
|
|
1496
|
+
messageGap: "space-y-3"
|
|
1497
|
+
}
|
|
1498
|
+
};
|
|
1364
1499
|
function parseFilesFromContent(content) {
|
|
1365
1500
|
const fileMarker = "[Uploaded files available at /uploads/]";
|
|
1366
1501
|
const markerIndex = content.indexOf(fileMarker);
|
|
@@ -1372,97 +1507,229 @@ function parseFilesFromContent(content) {
|
|
|
1372
1507
|
const files = fileSection.split("\n").filter((line) => line.startsWith("- ")).map((line) => line.substring(2).trim());
|
|
1373
1508
|
return { text, files };
|
|
1374
1509
|
}
|
|
1375
|
-
function UserMessage({
|
|
1510
|
+
function UserMessage({
|
|
1511
|
+
entry,
|
|
1512
|
+
variant = "bubble",
|
|
1513
|
+
scale = "compact",
|
|
1514
|
+
showAvatar = false,
|
|
1515
|
+
// Hidden by default for ChatGPT style
|
|
1516
|
+
showTimestamp = true,
|
|
1517
|
+
renderMetadata,
|
|
1518
|
+
metadata,
|
|
1519
|
+
className
|
|
1520
|
+
}) {
|
|
1376
1521
|
const { text, files } = parseFilesFromContent(entry.content);
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1522
|
+
const s = scaleClasses[scale];
|
|
1523
|
+
const variantClasses = {
|
|
1524
|
+
bubble: "rounded-[20px] bg-[var(--ash-user-bg)] text-[var(--ash-user-text)] border border-[var(--ash-user-border)]",
|
|
1525
|
+
plain: "bg-transparent text-[var(--ash-text-primary)]",
|
|
1526
|
+
minimal: "bg-transparent text-[var(--ash-text-secondary)]"
|
|
1527
|
+
};
|
|
1528
|
+
return /* @__PURE__ */ jsxs(
|
|
1529
|
+
"div",
|
|
1530
|
+
{
|
|
1531
|
+
"data-message-role": "user",
|
|
1532
|
+
className: cn("flex justify-end ash-animate-fade-in pr-1", s.gap, className),
|
|
1533
|
+
children: [
|
|
1534
|
+
/* @__PURE__ */ jsxs("div", { className: "max-w-[85%] flex flex-col items-end", children: [
|
|
1535
|
+
/* @__PURE__ */ jsxs("div", { className: cn(variantClasses[variant], variant === "bubble" && "px-4 py-3"), children: [
|
|
1536
|
+
/* @__PURE__ */ jsx("p", { className: cn(s.text, "leading-snug whitespace-pre-wrap"), children: text || "(files attached)" }),
|
|
1537
|
+
files.length > 0 && variant === "bubble" && /* @__PURE__ */ jsx("div", { className: "mt-1.5 pt-1.5 border-t border-[var(--ash-user-text)]/15 flex flex-wrap gap-1", children: files.map((file, index) => /* @__PURE__ */ jsxs(
|
|
1538
|
+
"span",
|
|
1539
|
+
{
|
|
1540
|
+
className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-[var(--ash-user-text)]/10 text-[11px]",
|
|
1541
|
+
title: file,
|
|
1542
|
+
children: [
|
|
1543
|
+
/* @__PURE__ */ jsx(PaperclipIcon, { className: "w-2.5 h-2.5 opacity-60" }),
|
|
1544
|
+
file.split(" (")[0]
|
|
1545
|
+
]
|
|
1546
|
+
},
|
|
1547
|
+
index
|
|
1548
|
+
)) })
|
|
1549
|
+
] }),
|
|
1550
|
+
renderMetadata ? renderMetadata({ entry, metadata }) : showTimestamp && entry.timestamp && /* @__PURE__ */ jsxs("div", { className: "text-[10px] text-[var(--ash-text-faint)] mt-0.5 mr-1 tabular-nums flex items-center gap-1.5", children: [
|
|
1551
|
+
metadata?.model && /* @__PURE__ */ jsx("span", { children: metadata.model }),
|
|
1552
|
+
metadata?.model && /* @__PURE__ */ jsx("span", { className: "opacity-50", children: "\xB7" }),
|
|
1553
|
+
formatTimestamp(entry.timestamp)
|
|
1554
|
+
] })
|
|
1384
1555
|
] }),
|
|
1385
|
-
/* @__PURE__ */ jsx("div", { className: "flex
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
title: file,
|
|
1390
|
-
children: file.split(" (")[0]
|
|
1391
|
-
},
|
|
1392
|
-
index
|
|
1393
|
-
)) })
|
|
1394
|
-
] }),
|
|
1395
|
-
entry.timestamp && /* @__PURE__ */ jsx("div", { className: "text-xs text-white/40 mt-2", children: formatTimestamp(entry.timestamp) })
|
|
1396
|
-
] }),
|
|
1397
|
-
/* @__PURE__ */ jsx("div", { className: "w-7 h-7 rounded-full bg-white/10 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsx(UserIcon, { className: "w-4 h-4 text-white/50" }) })
|
|
1398
|
-
] });
|
|
1556
|
+
showAvatar && /* @__PURE__ */ jsx("div", { className: cn(s.avatar, "rounded-full bg-[var(--ash-avatar-user-bg)] flex items-center justify-center shrink-0 mt-0.5"), children: /* @__PURE__ */ jsx(UserIcon, { className: "w-3 h-3 text-[var(--ash-text-muted)]" }) })
|
|
1557
|
+
]
|
|
1558
|
+
}
|
|
1559
|
+
);
|
|
1399
1560
|
}
|
|
1400
|
-
function AssistantMessage({
|
|
1401
|
-
|
|
1561
|
+
function AssistantMessage({
|
|
1562
|
+
entry,
|
|
1563
|
+
variant = "bubble",
|
|
1564
|
+
scale = "compact",
|
|
1565
|
+
showAvatar = true,
|
|
1566
|
+
showTimestamp = true,
|
|
1567
|
+
onOptionSelect,
|
|
1568
|
+
richContentRenderers,
|
|
1569
|
+
markdownComponents,
|
|
1570
|
+
renderMetadata,
|
|
1571
|
+
metadata,
|
|
1572
|
+
className
|
|
1573
|
+
}) {
|
|
1574
|
+
const parsedOptions = !entry.richContent ? parseOptionsFromContent(entry.content) : null;
|
|
1575
|
+
const s = scaleClasses[scale];
|
|
1402
1576
|
const handleOptionSelect = (option) => {
|
|
1403
1577
|
if (onOptionSelect) {
|
|
1404
1578
|
onOptionSelect(`Option ${option.id}: ${option.label}`);
|
|
1405
1579
|
}
|
|
1406
1580
|
};
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1581
|
+
const variantClasses = {
|
|
1582
|
+
bubble: "rounded-[16px] bg-[var(--ash-assistant-bg)] border border-[var(--ash-assistant-border)]",
|
|
1583
|
+
plain: "bg-transparent",
|
|
1584
|
+
minimal: "bg-transparent"
|
|
1585
|
+
};
|
|
1586
|
+
const renderContent = (textContent) => {
|
|
1587
|
+
if (entry.richContent && entry.richContent.length > 0) {
|
|
1588
|
+
return /* @__PURE__ */ jsx(
|
|
1589
|
+
RichContentRenderer,
|
|
1590
|
+
{
|
|
1591
|
+
content: entry.richContent,
|
|
1592
|
+
renderers: richContentRenderers
|
|
1593
|
+
}
|
|
1594
|
+
);
|
|
1595
|
+
}
|
|
1596
|
+
return /* @__PURE__ */ jsx(LazyMarkdown, { components: markdownComponents, children: textContent || entry.content });
|
|
1597
|
+
};
|
|
1598
|
+
return /* @__PURE__ */ jsxs(
|
|
1599
|
+
"div",
|
|
1600
|
+
{
|
|
1601
|
+
"data-message-role": "assistant",
|
|
1602
|
+
className: cn("flex ash-animate-fade-in pl-1", s.gap, className),
|
|
1603
|
+
children: [
|
|
1604
|
+
showAvatar && /* @__PURE__ */ jsx("div", { className: cn(s.avatar, "rounded-full bg-[var(--ash-avatar-assistant-bg)] flex items-center justify-center shrink-0 mt-0.5"), children: /* @__PURE__ */ jsx(SparklesIcon, { className: "w-3 h-3 text-white" }) }),
|
|
1605
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
1606
|
+
/* @__PURE__ */ jsx("div", { className: cn(variantClasses[variant], variant === "bubble" && "px-4 py-3"), children: /* @__PURE__ */ jsx("div", { className: cn("ash-message-content prose prose-sm prose-invert max-w-none leading-relaxed text-[var(--ash-assistant-text)]", s.text), children: parsedOptions ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1607
|
+
parsedOptions.preamble && renderContent(parsedOptions.preamble),
|
|
1608
|
+
/* @__PURE__ */ jsx(
|
|
1609
|
+
OptionCards,
|
|
1610
|
+
{
|
|
1611
|
+
options: parsedOptions.options,
|
|
1612
|
+
onSelect: handleOptionSelect
|
|
1613
|
+
}
|
|
1614
|
+
)
|
|
1615
|
+
] }) : renderContent() }) }),
|
|
1616
|
+
renderMetadata ? renderMetadata({ entry, metadata }) : showTimestamp && entry.timestamp && /* @__PURE__ */ jsxs("div", { className: "text-[10px] text-[var(--ash-text-faint)] mt-0.5 ml-1 tabular-nums flex items-center gap-1.5", children: [
|
|
1617
|
+
metadata?.model && /* @__PURE__ */ jsx("span", { children: metadata.model }),
|
|
1618
|
+
metadata?.model && /* @__PURE__ */ jsx("span", { className: "opacity-50", children: "\xB7" }),
|
|
1619
|
+
formatTimestamp(entry.timestamp)
|
|
1620
|
+
] })
|
|
1621
|
+
] })
|
|
1622
|
+
]
|
|
1623
|
+
}
|
|
1624
|
+
);
|
|
1423
1625
|
}
|
|
1424
|
-
function ThinkingMessage({ entry, className }) {
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1626
|
+
function ThinkingMessage({ entry, scale = "compact", showAvatar = true, className }) {
|
|
1627
|
+
const s = scaleClasses[scale];
|
|
1628
|
+
return /* @__PURE__ */ jsxs(
|
|
1629
|
+
"div",
|
|
1630
|
+
{
|
|
1631
|
+
"data-message-role": "thinking",
|
|
1632
|
+
className: cn("flex ash-animate-fade-in pl-1", s.gap, className),
|
|
1633
|
+
children: [
|
|
1634
|
+
showAvatar && /* @__PURE__ */ jsx("div", { className: cn(s.avatar, "rounded-md bg-[var(--ash-avatar-thinking-bg)] flex items-center justify-center shrink-0 mt-0.5"), children: /* @__PURE__ */ jsx(SparklesIcon, { className: "w-3 h-3 text-purple-400" }) }),
|
|
1635
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: cn("rounded-lg bg-[var(--ash-thinking-bg)] border border-[var(--ash-thinking-border)]", s.padding), children: [
|
|
1636
|
+
/* @__PURE__ */ jsx("div", { className: "text-[10px] text-[var(--ash-thinking-text)] opacity-80 mb-1 font-medium uppercase tracking-wide", children: "Thinking" }),
|
|
1637
|
+
/* @__PURE__ */ jsx("div", { className: cn(s.text, "text-[var(--ash-thinking-text)] opacity-70 italic whitespace-pre-wrap leading-relaxed"), children: entry.content })
|
|
1638
|
+
] }) })
|
|
1639
|
+
]
|
|
1640
|
+
}
|
|
1641
|
+
);
|
|
1432
1642
|
}
|
|
1433
|
-
function ToolCallMessage({ entry, defaultExpanded = false, className }) {
|
|
1643
|
+
function ToolCallMessage({ entry, scale = "compact", showAvatar = true, defaultExpanded = false, className }) {
|
|
1434
1644
|
if (entry.entryType.type !== "tool_call") return null;
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1645
|
+
const s = scaleClasses[scale];
|
|
1646
|
+
return /* @__PURE__ */ jsxs(
|
|
1647
|
+
"div",
|
|
1648
|
+
{
|
|
1649
|
+
"data-message-role": "tool",
|
|
1650
|
+
className: cn("flex ash-animate-fade-in pl-1", s.gap, className),
|
|
1651
|
+
children: [
|
|
1652
|
+
showAvatar && /* @__PURE__ */ jsx("div", { className: cn(s.avatar, "rounded-md bg-[var(--ash-avatar-assistant-bg)] flex items-center justify-center shrink-0 mt-0.5"), children: /* @__PURE__ */ jsx(BotIcon, { className: "w-3 h-3 text-[var(--ash-accent)]" }) }),
|
|
1653
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx(ToolCallCard, { toolCall: entry.entryType.toolCall, defaultExpanded }) })
|
|
1654
|
+
]
|
|
1655
|
+
}
|
|
1656
|
+
);
|
|
1439
1657
|
}
|
|
1440
|
-
function ErrorMessage({ entry, className }) {
|
|
1658
|
+
function ErrorMessage({ entry, scale = "compact", showAvatar = true, className }) {
|
|
1441
1659
|
if (entry.entryType.type !== "error") return null;
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1660
|
+
const s = scaleClasses[scale];
|
|
1661
|
+
return /* @__PURE__ */ jsxs(
|
|
1662
|
+
"div",
|
|
1663
|
+
{
|
|
1664
|
+
"data-message-role": "error",
|
|
1665
|
+
className: cn("flex ash-animate-fade-in pl-1", s.gap, className),
|
|
1666
|
+
children: [
|
|
1667
|
+
showAvatar && /* @__PURE__ */ jsx("div", { className: cn(s.avatar, "rounded-md bg-[var(--ash-avatar-error-bg)] flex items-center justify-center shrink-0 mt-0.5"), children: /* @__PURE__ */ jsx(AlertTriangleIcon, { className: "w-3 h-3 text-red-400" }) }),
|
|
1668
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: cn("rounded-lg bg-[var(--ash-error-bg)] border border-[var(--ash-error-border)]", s.padding), children: [
|
|
1669
|
+
/* @__PURE__ */ jsx("div", { className: "text-[10px] text-[var(--ash-error-text)] opacity-80 mb-1 font-medium uppercase tracking-wide", children: "Error" }),
|
|
1670
|
+
/* @__PURE__ */ jsx("p", { className: cn(s.text, "text-[var(--ash-error-text)] opacity-90"), children: entry.entryType.message }),
|
|
1671
|
+
entry.entryType.code && /* @__PURE__ */ jsxs("p", { className: "text-[11px] text-[var(--ash-error-text)] opacity-60 mt-1 font-mono", children: [
|
|
1672
|
+
"Code: ",
|
|
1673
|
+
entry.entryType.code
|
|
1674
|
+
] })
|
|
1675
|
+
] }) })
|
|
1676
|
+
]
|
|
1677
|
+
}
|
|
1678
|
+
);
|
|
1453
1679
|
}
|
|
1454
|
-
function MessageEntry({
|
|
1680
|
+
function MessageEntry({
|
|
1681
|
+
entry,
|
|
1682
|
+
onOptionSelect,
|
|
1683
|
+
defaultExpanded,
|
|
1684
|
+
richContentRenderers,
|
|
1685
|
+
markdownComponents,
|
|
1686
|
+
userVariant,
|
|
1687
|
+
assistantVariant,
|
|
1688
|
+
scale,
|
|
1689
|
+
showAvatars = true,
|
|
1690
|
+
showTimestamp = true,
|
|
1691
|
+
renderMetadata,
|
|
1692
|
+
metadata,
|
|
1693
|
+
className
|
|
1694
|
+
}) {
|
|
1455
1695
|
switch (entry.entryType.type) {
|
|
1456
1696
|
case "user_message":
|
|
1457
|
-
return /* @__PURE__ */ jsx(
|
|
1697
|
+
return /* @__PURE__ */ jsx(
|
|
1698
|
+
UserMessage,
|
|
1699
|
+
{
|
|
1700
|
+
entry,
|
|
1701
|
+
variant: userVariant,
|
|
1702
|
+
scale,
|
|
1703
|
+
showAvatar: showAvatars,
|
|
1704
|
+
showTimestamp,
|
|
1705
|
+
renderMetadata,
|
|
1706
|
+
metadata,
|
|
1707
|
+
className
|
|
1708
|
+
}
|
|
1709
|
+
);
|
|
1458
1710
|
case "assistant_message":
|
|
1459
|
-
return /* @__PURE__ */ jsx(
|
|
1711
|
+
return /* @__PURE__ */ jsx(
|
|
1712
|
+
AssistantMessage,
|
|
1713
|
+
{
|
|
1714
|
+
entry,
|
|
1715
|
+
variant: assistantVariant,
|
|
1716
|
+
scale,
|
|
1717
|
+
showAvatar: showAvatars,
|
|
1718
|
+
showTimestamp,
|
|
1719
|
+
onOptionSelect,
|
|
1720
|
+
richContentRenderers,
|
|
1721
|
+
markdownComponents,
|
|
1722
|
+
renderMetadata,
|
|
1723
|
+
metadata,
|
|
1724
|
+
className
|
|
1725
|
+
}
|
|
1726
|
+
);
|
|
1460
1727
|
case "thinking":
|
|
1461
|
-
return /* @__PURE__ */ jsx(ThinkingMessage, { entry, className });
|
|
1728
|
+
return /* @__PURE__ */ jsx(ThinkingMessage, { entry, scale, showAvatar: showAvatars, className });
|
|
1462
1729
|
case "tool_call":
|
|
1463
|
-
return /* @__PURE__ */ jsx(ToolCallMessage, { entry, defaultExpanded, className });
|
|
1730
|
+
return /* @__PURE__ */ jsx(ToolCallMessage, { entry, scale, showAvatar: showAvatars, defaultExpanded, className });
|
|
1464
1731
|
case "error":
|
|
1465
|
-
return /* @__PURE__ */ jsx(ErrorMessage, { entry, className });
|
|
1732
|
+
return /* @__PURE__ */ jsx(ErrorMessage, { entry, scale, showAvatar: showAvatars, className });
|
|
1466
1733
|
default:
|
|
1467
1734
|
return null;
|
|
1468
1735
|
}
|
|
@@ -2081,6 +2348,13 @@ var DEFAULT_DISPLAY_CONFIG = {
|
|
|
2081
2348
|
defaultExpanded: false,
|
|
2082
2349
|
animationDuration: 300
|
|
2083
2350
|
};
|
|
2351
|
+
var DEFAULT_STYLE_CONFIG = {
|
|
2352
|
+
userVariant: "bubble",
|
|
2353
|
+
assistantVariant: "bubble",
|
|
2354
|
+
scale: "compact",
|
|
2355
|
+
showTimestamp: true,
|
|
2356
|
+
showAvatars: true
|
|
2357
|
+
};
|
|
2084
2358
|
var DisplayModeContext = createContext(null);
|
|
2085
2359
|
function DisplayModeProvider({ children, initialConfig }) {
|
|
2086
2360
|
const [config, setConfigState] = useState({
|
|
@@ -2133,6 +2407,15 @@ function MessageList({
|
|
|
2133
2407
|
renderWidget,
|
|
2134
2408
|
onWidgetAction,
|
|
2135
2409
|
autoScroll = true,
|
|
2410
|
+
richContentRenderers,
|
|
2411
|
+
userVariant,
|
|
2412
|
+
assistantVariant,
|
|
2413
|
+
scale,
|
|
2414
|
+
showAvatars = true,
|
|
2415
|
+
showTimestamp = true,
|
|
2416
|
+
markdownComponents,
|
|
2417
|
+
renderMetadata,
|
|
2418
|
+
metadata,
|
|
2136
2419
|
className
|
|
2137
2420
|
}) {
|
|
2138
2421
|
const contextConfig = useDisplayConfig();
|
|
@@ -2167,7 +2450,8 @@ function MessageList({
|
|
|
2167
2450
|
}
|
|
2168
2451
|
return groupEntriesForCompactMode(entries, config);
|
|
2169
2452
|
}, [entries, config]);
|
|
2170
|
-
|
|
2453
|
+
const densityClass = scale ? `ash-density-${scale}` : void 0;
|
|
2454
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: cn("flex-1 overflow-y-auto px-3 py-2 space-y-1 ash-scrollbar", densityClass, className), children: [
|
|
2171
2455
|
groupedEntries.map((groupedEntry) => {
|
|
2172
2456
|
if (groupedEntry.type === "single") {
|
|
2173
2457
|
const entry = groupedEntry.entry;
|
|
@@ -2183,12 +2467,29 @@ function MessageList({
|
|
|
2183
2467
|
return /* @__PURE__ */ jsx("div", { className: "ash-animate-fade-in", children: widgetContent }, entry.id);
|
|
2184
2468
|
}
|
|
2185
2469
|
}
|
|
2186
|
-
return /* @__PURE__ */ jsx(
|
|
2470
|
+
return /* @__PURE__ */ jsx(
|
|
2471
|
+
MessageEntry,
|
|
2472
|
+
{
|
|
2473
|
+
entry,
|
|
2474
|
+
onOptionSelect,
|
|
2475
|
+
defaultExpanded: config.defaultExpanded,
|
|
2476
|
+
richContentRenderers,
|
|
2477
|
+
markdownComponents,
|
|
2478
|
+
userVariant,
|
|
2479
|
+
assistantVariant,
|
|
2480
|
+
scale,
|
|
2481
|
+
showAvatars,
|
|
2482
|
+
showTimestamp,
|
|
2483
|
+
renderMetadata,
|
|
2484
|
+
metadata
|
|
2485
|
+
},
|
|
2486
|
+
entry.id
|
|
2487
|
+
);
|
|
2187
2488
|
}
|
|
2188
2489
|
const toolCalls = extractToolCallsFromGroup(groupedEntry.entries);
|
|
2189
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex
|
|
2190
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
2191
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1", children: config.mode === "accordion" ? /* @__PURE__ */ jsx(
|
|
2490
|
+
return /* @__PURE__ */ jsxs("div", { className: "ash-message-row flex ash-animate-fade-in pl-1", style: { gap: "var(--ash-message-gap, 0.5rem)" }, children: [
|
|
2491
|
+
showAvatars && /* @__PURE__ */ jsx("div", { className: "ash-avatar rounded-md bg-[var(--ash-avatar-assistant-bg)] flex items-center justify-center shrink-0 mt-0.5", style: { width: "var(--ash-avatar-size, 1.25rem)", height: "var(--ash-avatar-size, 1.25rem)" }, children: /* @__PURE__ */ jsx(BotIcon, { className: "w-3 h-3 text-[var(--ash-accent)]" }) }),
|
|
2492
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: config.mode === "accordion" ? /* @__PURE__ */ jsx(
|
|
2192
2493
|
StepAccordion,
|
|
2193
2494
|
{
|
|
2194
2495
|
toolCalls,
|
|
@@ -2204,13 +2505,13 @@ function MessageList({
|
|
|
2204
2505
|
) })
|
|
2205
2506
|
] }, groupedEntry.id);
|
|
2206
2507
|
}),
|
|
2207
|
-
streamingContent && /* @__PURE__ */ jsxs("div", { className: "flex
|
|
2208
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
2209
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1
|
|
2508
|
+
streamingContent && /* @__PURE__ */ jsxs("div", { className: "ash-message-row flex ash-animate-fade-in pl-1", style: { gap: "var(--ash-message-gap, 0.5rem)" }, children: [
|
|
2509
|
+
showAvatars && /* @__PURE__ */ jsx("div", { className: "ash-avatar rounded-md bg-[var(--ash-avatar-assistant-bg)] flex items-center justify-center shrink-0 mt-0.5", style: { width: "var(--ash-avatar-size, 1.25rem)", height: "var(--ash-avatar-size, 1.25rem)" }, children: /* @__PURE__ */ jsx(BotIcon, { className: "w-3 h-3 text-[var(--ash-accent)]" }) }),
|
|
2510
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("div", { className: "ash-message-bubble rounded-lg bg-white/[0.03] text-white/80 leading-relaxed", style: { padding: "var(--ash-message-padding, 0.5rem 0.75rem)", fontSize: "var(--ash-font-size-base, 13px)" }, children: /* @__PURE__ */ jsx(StreamingText, { content: streamingContent, isStreaming: true }) }) })
|
|
2210
2511
|
] }),
|
|
2211
|
-
loading && !streamingContent && /* @__PURE__ */ jsxs("div", { className: "flex
|
|
2212
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
2213
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-
|
|
2512
|
+
loading && !streamingContent && /* @__PURE__ */ jsxs("div", { className: "ash-message-row flex ash-animate-fade-in pl-1", style: { gap: "var(--ash-message-gap, 0.5rem)" }, children: [
|
|
2513
|
+
showAvatars && /* @__PURE__ */ jsx("div", { className: "ash-avatar rounded-md bg-[var(--ash-avatar-assistant-bg)] flex items-center justify-center shrink-0 mt-0.5", style: { width: "var(--ash-avatar-size, 1.25rem)", height: "var(--ash-avatar-size, 1.25rem)" }, children: /* @__PURE__ */ jsx(BotIcon, { className: "w-3 h-3 text-[var(--ash-accent)]" }) }),
|
|
2514
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-lg px-3 py-1.5 bg-white/[0.03]", children: /* @__PURE__ */ jsx(LoadingIndicator, { variant: "dots" }) })
|
|
2214
2515
|
] }),
|
|
2215
2516
|
/* @__PURE__ */ jsx("div", { ref: messagesEndRef })
|
|
2216
2517
|
] });
|
|
@@ -3027,6 +3328,21 @@ var typography = {
|
|
|
3027
3328
|
relaxed: "1.75"
|
|
3028
3329
|
}
|
|
3029
3330
|
};
|
|
3331
|
+
var cssVars = {
|
|
3332
|
+
fontSize: {
|
|
3333
|
+
base: "--ash-font-size-base",
|
|
3334
|
+
sm: "--ash-font-size-sm",
|
|
3335
|
+
xs: "--ash-font-size-xs",
|
|
3336
|
+
code: "--ash-font-size-code"
|
|
3337
|
+
},
|
|
3338
|
+
accent: "--ash-accent",
|
|
3339
|
+
accentForeground: "--ash-accent-foreground",
|
|
3340
|
+
surfaceDark: "--ash-surface-dark",
|
|
3341
|
+
surfaceDarker: "--ash-surface-darker",
|
|
3342
|
+
surfaceCard: "--ash-surface-card",
|
|
3343
|
+
surfaceElevated: "--ash-surface-elevated",
|
|
3344
|
+
surfaceBorder: "--ash-surface-border"
|
|
3345
|
+
};
|
|
3030
3346
|
var keyframes = {
|
|
3031
3347
|
slideUp: {
|
|
3032
3348
|
from: { opacity: "0", transform: "translateY(20px)" },
|
|
@@ -3145,6 +3461,10 @@ function tokensToCssVariables(prefix = "ash") {
|
|
|
3145
3461
|
if (key !== "DEFAULT") vars[`--${prefix}-border-${key}`] = value;
|
|
3146
3462
|
else vars[`--${prefix}-border`] = value;
|
|
3147
3463
|
});
|
|
3464
|
+
vars[`--${prefix}-font-size-base`] = "14px";
|
|
3465
|
+
vars[`--${prefix}-font-size-sm`] = "12px";
|
|
3466
|
+
vars[`--${prefix}-font-size-xs`] = "11px";
|
|
3467
|
+
vars[`--${prefix}-font-size-code`] = "13px";
|
|
3148
3468
|
return vars;
|
|
3149
3469
|
}
|
|
3150
3470
|
var inlineStyles = {
|
|
@@ -3400,19 +3720,95 @@ function useFileUpload({
|
|
|
3400
3720
|
openFilePicker
|
|
3401
3721
|
};
|
|
3402
3722
|
}
|
|
3723
|
+
|
|
3724
|
+
// src/hooks/middleware.ts
|
|
3725
|
+
async function applyRequestMiddleware(middlewares, request) {
|
|
3726
|
+
let current = { ...request };
|
|
3727
|
+
for (const mw of middlewares) {
|
|
3728
|
+
if (mw.onRequest) {
|
|
3729
|
+
try {
|
|
3730
|
+
const result = await mw.onRequest(current);
|
|
3731
|
+
if (result?.error) {
|
|
3732
|
+
return { request: current, error: result.error };
|
|
3733
|
+
}
|
|
3734
|
+
if (result) {
|
|
3735
|
+
current = {
|
|
3736
|
+
...current,
|
|
3737
|
+
prompt: result.prompt ?? current.prompt,
|
|
3738
|
+
sessionContext: result.sessionContext ?? current.sessionContext,
|
|
3739
|
+
metadata: {
|
|
3740
|
+
...current.metadata,
|
|
3741
|
+
...result.metadata
|
|
3742
|
+
}
|
|
3743
|
+
};
|
|
3744
|
+
}
|
|
3745
|
+
} catch (err) {
|
|
3746
|
+
const errorMessage = err instanceof Error ? err.message : "Middleware error";
|
|
3747
|
+
return { request: current, error: errorMessage };
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
return { request: current };
|
|
3752
|
+
}
|
|
3753
|
+
async function applyEventMiddleware(middlewares, event) {
|
|
3754
|
+
let current = event;
|
|
3755
|
+
for (const mw of middlewares) {
|
|
3756
|
+
if (!current) break;
|
|
3757
|
+
if (mw.onEvent) {
|
|
3758
|
+
try {
|
|
3759
|
+
current = await mw.onEvent(current);
|
|
3760
|
+
} catch (err) {
|
|
3761
|
+
console.error("[middleware] onEvent error:", err);
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
return current;
|
|
3766
|
+
}
|
|
3767
|
+
async function callMiddlewareComplete(middlewares, sessionId) {
|
|
3768
|
+
for (const mw of middlewares) {
|
|
3769
|
+
if (mw.onComplete) {
|
|
3770
|
+
try {
|
|
3771
|
+
await mw.onComplete(sessionId);
|
|
3772
|
+
} catch (err) {
|
|
3773
|
+
console.error("[middleware] onComplete error:", err);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
async function callMiddlewareError(middlewares, error) {
|
|
3779
|
+
for (const mw of middlewares) {
|
|
3780
|
+
if (mw.onError) {
|
|
3781
|
+
try {
|
|
3782
|
+
await mw.onError(error);
|
|
3783
|
+
} catch (err) {
|
|
3784
|
+
console.error("[middleware] onError error:", err);
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3787
|
+
}
|
|
3788
|
+
}
|
|
3789
|
+
|
|
3790
|
+
// src/hooks/useAgentChat.ts
|
|
3403
3791
|
function useAgentChat(options) {
|
|
3404
3792
|
const {
|
|
3405
3793
|
createStream,
|
|
3794
|
+
subscribeToSession,
|
|
3406
3795
|
initialSessionId,
|
|
3407
3796
|
initialEntries = [],
|
|
3408
3797
|
onSessionStart,
|
|
3409
3798
|
onSessionEnd,
|
|
3410
3799
|
onError,
|
|
3411
|
-
onSandboxLog
|
|
3800
|
+
onSandboxLog,
|
|
3801
|
+
onReconnect,
|
|
3802
|
+
maxReconnectAttempts = 3,
|
|
3803
|
+
reconnectBaseDelay = 1e3,
|
|
3804
|
+
onBeforeSend,
|
|
3805
|
+
onEvent,
|
|
3806
|
+
middleware
|
|
3412
3807
|
} = options;
|
|
3413
3808
|
const [historyEntries, setHistoryEntries] = useState(initialEntries);
|
|
3414
3809
|
const [streamingEntries, setStreamingEntries] = useState([]);
|
|
3415
3810
|
const [isStreaming, setIsStreaming] = useState(false);
|
|
3811
|
+
const [isReconnecting, setIsReconnecting] = useState(false);
|
|
3416
3812
|
const [error, setError] = useState(null);
|
|
3417
3813
|
const [sessionId, setSessionId] = useState(initialSessionId || null);
|
|
3418
3814
|
const abortControllerRef = useRef(null);
|
|
@@ -3420,6 +3816,16 @@ function useAgentChat(options) {
|
|
|
3420
3816
|
const currentTextIdRef = useRef(null);
|
|
3421
3817
|
const pendingToolCallsRef = useRef(/* @__PURE__ */ new Map());
|
|
3422
3818
|
const hadToolCallSinceTextRef = useRef(false);
|
|
3819
|
+
const reconnectAttemptsRef = useRef(0);
|
|
3820
|
+
const eventCountRef = useRef(0);
|
|
3821
|
+
const sessionIdRef = useRef(sessionId);
|
|
3822
|
+
const streamingEntriesRef = useRef([]);
|
|
3823
|
+
useEffect(() => {
|
|
3824
|
+
sessionIdRef.current = sessionId;
|
|
3825
|
+
}, [sessionId]);
|
|
3826
|
+
useEffect(() => {
|
|
3827
|
+
streamingEntriesRef.current = streamingEntries;
|
|
3828
|
+
}, [streamingEntries]);
|
|
3423
3829
|
const entries = [...historyEntries, ...streamingEntries];
|
|
3424
3830
|
const emitStreamingEntries = useCallback((newEntries) => {
|
|
3425
3831
|
setStreamingEntries([...newEntries]);
|
|
@@ -3534,7 +3940,7 @@ function useAgentChat(options) {
|
|
|
3534
3940
|
setError(event.error);
|
|
3535
3941
|
onError?.(event.error);
|
|
3536
3942
|
newEntries.push({
|
|
3537
|
-
id: `error-${Date.now()}`,
|
|
3943
|
+
id: `error-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
3538
3944
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3539
3945
|
entryType: { type: "error", message: event.error, code: event.code },
|
|
3540
3946
|
content: event.error
|
|
@@ -3553,12 +3959,112 @@ function useAgentChat(options) {
|
|
|
3553
3959
|
}
|
|
3554
3960
|
return newEntries;
|
|
3555
3961
|
}, [sessionId, onSessionStart, onSessionEnd, onError, onSandboxLog, createTextEntry, resetStreamingState]);
|
|
3962
|
+
const attemptReconnect = useCallback(async (targetSessionId, currentEntries) => {
|
|
3963
|
+
if (!subscribeToSession) {
|
|
3964
|
+
return false;
|
|
3965
|
+
}
|
|
3966
|
+
const attempt = reconnectAttemptsRef.current + 1;
|
|
3967
|
+
if (attempt > maxReconnectAttempts) {
|
|
3968
|
+
console.warn(`[useAgentChat] Max reconnection attempts (${maxReconnectAttempts}) exceeded`);
|
|
3969
|
+
return false;
|
|
3970
|
+
}
|
|
3971
|
+
reconnectAttemptsRef.current = attempt;
|
|
3972
|
+
setIsReconnecting(true);
|
|
3973
|
+
onReconnect?.(attempt, targetSessionId);
|
|
3974
|
+
const delay = reconnectBaseDelay * Math.pow(2, attempt - 1);
|
|
3975
|
+
console.log(`[useAgentChat] Reconnection attempt ${attempt}/${maxReconnectAttempts} in ${delay}ms`);
|
|
3976
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
3977
|
+
const controller = new AbortController();
|
|
3978
|
+
abortControllerRef.current = controller;
|
|
3979
|
+
try {
|
|
3980
|
+
const stream = subscribeToSession(targetSessionId, controller.signal);
|
|
3981
|
+
let localStreamingEntries = [...currentEntries];
|
|
3982
|
+
for await (const event of stream) {
|
|
3983
|
+
if (controller.signal.aborted) break;
|
|
3984
|
+
eventCountRef.current++;
|
|
3985
|
+
localStreamingEntries = processEvent(event, localStreamingEntries);
|
|
3986
|
+
emitStreamingEntries(localStreamingEntries);
|
|
3987
|
+
if (event.type === "complete" || event.type === "session_end" || event.type === "error") {
|
|
3988
|
+
reconnectAttemptsRef.current = 0;
|
|
3989
|
+
setIsReconnecting(false);
|
|
3990
|
+
if (event.type === "complete" && localStreamingEntries.length > 0) {
|
|
3991
|
+
setHistoryEntries((prev) => [...prev, ...localStreamingEntries]);
|
|
3992
|
+
setStreamingEntries([]);
|
|
3993
|
+
}
|
|
3994
|
+
return true;
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
reconnectAttemptsRef.current = 0;
|
|
3998
|
+
setIsReconnecting(false);
|
|
3999
|
+
if (localStreamingEntries.length > 0) {
|
|
4000
|
+
setHistoryEntries((prev) => [...prev, ...localStreamingEntries]);
|
|
4001
|
+
setStreamingEntries([]);
|
|
4002
|
+
}
|
|
4003
|
+
return true;
|
|
4004
|
+
} catch (err) {
|
|
4005
|
+
const isAbort = err.name === "AbortError" || err.message?.includes("aborted") || err.message?.includes("BodyStreamBuffer");
|
|
4006
|
+
if (isAbort && !controller.signal.aborted) {
|
|
4007
|
+
console.log(`[useAgentChat] Reconnection stream interrupted, will retry...`);
|
|
4008
|
+
setIsReconnecting(false);
|
|
4009
|
+
return attemptReconnect(targetSessionId, streamingEntriesRef.current);
|
|
4010
|
+
}
|
|
4011
|
+
setIsReconnecting(false);
|
|
4012
|
+
if (!controller.signal.aborted) {
|
|
4013
|
+
const errorMessage = err instanceof Error ? err.message : "Reconnection failed";
|
|
4014
|
+
console.error(`[useAgentChat] Reconnection failed:`, errorMessage);
|
|
4015
|
+
}
|
|
4016
|
+
return false;
|
|
4017
|
+
}
|
|
4018
|
+
}, [subscribeToSession, maxReconnectAttempts, reconnectBaseDelay, onReconnect, processEvent, emitStreamingEntries]);
|
|
3556
4019
|
const send = useCallback(async (prompt) => {
|
|
3557
4020
|
if (isStreaming) return;
|
|
4021
|
+
let finalPrompt = prompt;
|
|
4022
|
+
let additionalMetadata = {};
|
|
4023
|
+
let additionalContext;
|
|
4024
|
+
if (onBeforeSend) {
|
|
4025
|
+
try {
|
|
4026
|
+
const result = await onBeforeSend({
|
|
4027
|
+
prompt,
|
|
4028
|
+
sessionId,
|
|
4029
|
+
entries: [...historyEntries, ...streamingEntries]
|
|
4030
|
+
});
|
|
4031
|
+
if (result?.cancel) {
|
|
4032
|
+
return;
|
|
4033
|
+
}
|
|
4034
|
+
if (result?.prompt !== void 0) finalPrompt = result.prompt;
|
|
4035
|
+
if (result?.metadata) additionalMetadata = result.metadata;
|
|
4036
|
+
if (result?.sessionContext) additionalContext = result.sessionContext;
|
|
4037
|
+
} catch (err) {
|
|
4038
|
+
const errorMessage = err instanceof Error ? err.message : "Send cancelled";
|
|
4039
|
+
setError(errorMessage);
|
|
4040
|
+
onError?.(errorMessage);
|
|
4041
|
+
return;
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
if (middleware?.length) {
|
|
4045
|
+
const middlewareRequest = {
|
|
4046
|
+
prompt: finalPrompt,
|
|
4047
|
+
sessionId,
|
|
4048
|
+
metadata: additionalMetadata,
|
|
4049
|
+
sessionContext: additionalContext
|
|
4050
|
+
};
|
|
4051
|
+
const { request, error: middlewareError } = await applyRequestMiddleware(middleware, middlewareRequest);
|
|
4052
|
+
if (middlewareError) {
|
|
4053
|
+
setError(middlewareError);
|
|
4054
|
+
onError?.(middlewareError);
|
|
4055
|
+
await callMiddlewareError(middleware, middlewareError);
|
|
4056
|
+
return;
|
|
4057
|
+
}
|
|
4058
|
+
finalPrompt = request.prompt;
|
|
4059
|
+
additionalMetadata = request.metadata || {};
|
|
4060
|
+
additionalContext = request.sessionContext;
|
|
4061
|
+
}
|
|
3558
4062
|
setIsStreaming(true);
|
|
3559
4063
|
setError(null);
|
|
4064
|
+
reconnectAttemptsRef.current = 0;
|
|
4065
|
+
eventCountRef.current = 0;
|
|
3560
4066
|
const userEntry = {
|
|
3561
|
-
id: `user-${Date.now()}`,
|
|
4067
|
+
id: `user-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
3562
4068
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3563
4069
|
entryType: { type: "user_message" },
|
|
3564
4070
|
content: prompt
|
|
@@ -3568,39 +4074,91 @@ function useAgentChat(options) {
|
|
|
3568
4074
|
const controller = new AbortController();
|
|
3569
4075
|
abortControllerRef.current = controller;
|
|
3570
4076
|
let localStreamingEntries = [];
|
|
4077
|
+
let completedSessionId = null;
|
|
3571
4078
|
try {
|
|
3572
|
-
const stream = createStream(
|
|
4079
|
+
const stream = createStream(finalPrompt, sessionId || void 0, {
|
|
4080
|
+
signal: controller.signal,
|
|
4081
|
+
metadata: Object.keys(additionalMetadata).length > 0 ? additionalMetadata : void 0,
|
|
4082
|
+
sessionContext: additionalContext
|
|
4083
|
+
});
|
|
3573
4084
|
for await (const event of stream) {
|
|
3574
4085
|
if (controller.signal.aborted) break;
|
|
3575
|
-
|
|
4086
|
+
eventCountRef.current++;
|
|
4087
|
+
if (event.type === "session_start" && event.sessionId) {
|
|
4088
|
+
completedSessionId = event.sessionId;
|
|
4089
|
+
}
|
|
4090
|
+
if (onEvent) {
|
|
4091
|
+
try {
|
|
4092
|
+
await onEvent(event);
|
|
4093
|
+
} catch (err) {
|
|
4094
|
+
console.error("[useAgentChat] onEvent error:", err);
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
let processedEvent = event;
|
|
4098
|
+
if (middleware?.length) {
|
|
4099
|
+
processedEvent = await applyEventMiddleware(middleware, event);
|
|
4100
|
+
}
|
|
4101
|
+
if (!processedEvent) continue;
|
|
4102
|
+
localStreamingEntries = processEvent(processedEvent, localStreamingEntries);
|
|
3576
4103
|
emitStreamingEntries(localStreamingEntries);
|
|
3577
4104
|
}
|
|
3578
4105
|
if (localStreamingEntries.length > 0) {
|
|
3579
4106
|
setHistoryEntries((prev) => [...prev, ...localStreamingEntries]);
|
|
3580
4107
|
setStreamingEntries([]);
|
|
3581
4108
|
}
|
|
4109
|
+
reconnectAttemptsRef.current = 0;
|
|
4110
|
+
if (middleware?.length && (completedSessionId || sessionIdRef.current)) {
|
|
4111
|
+
await callMiddlewareComplete(middleware, completedSessionId || sessionIdRef.current || "");
|
|
4112
|
+
}
|
|
3582
4113
|
} catch (err) {
|
|
3583
|
-
|
|
4114
|
+
const isAbort = err.name === "AbortError" || err.message?.includes("aborted") || err.message?.includes("BodyStreamBuffer");
|
|
4115
|
+
if (isAbort && !controller.signal.aborted) {
|
|
4116
|
+
const currentSessionId = sessionIdRef.current;
|
|
4117
|
+
const hadEvents = eventCountRef.current > 0;
|
|
4118
|
+
console.log(`[useAgentChat] Stream interrupted. sessionId=${currentSessionId}, events=${eventCountRef.current}`);
|
|
4119
|
+
if (currentSessionId && hadEvents && subscribeToSession) {
|
|
4120
|
+
console.log(`[useAgentChat] Attempting auto-reconnection...`);
|
|
4121
|
+
const reconnected = await attemptReconnect(currentSessionId, streamingEntriesRef.current);
|
|
4122
|
+
if (reconnected) {
|
|
4123
|
+
return;
|
|
4124
|
+
}
|
|
4125
|
+
const errorMsg = "Connection lost. Please try again.";
|
|
4126
|
+
setError(errorMsg);
|
|
4127
|
+
onError?.(errorMsg);
|
|
4128
|
+
if (middleware?.length) {
|
|
4129
|
+
await callMiddlewareError(middleware, errorMsg);
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
} else if (!isAbort) {
|
|
3584
4133
|
const errorMessage = err instanceof Error ? err.message : "Unknown error";
|
|
3585
4134
|
setError(errorMessage);
|
|
3586
4135
|
onError?.(errorMessage);
|
|
4136
|
+
if (middleware?.length) {
|
|
4137
|
+
await callMiddlewareError(middleware, errorMessage);
|
|
4138
|
+
}
|
|
3587
4139
|
}
|
|
3588
4140
|
} finally {
|
|
3589
4141
|
setIsStreaming(false);
|
|
4142
|
+
setIsReconnecting(false);
|
|
3590
4143
|
abortControllerRef.current = null;
|
|
3591
4144
|
resetStreamingState();
|
|
3592
4145
|
}
|
|
3593
|
-
}, [isStreaming, sessionId, createStream, processEvent, emitStreamingEntries, resetStreamingState, onError]);
|
|
4146
|
+
}, [isStreaming, sessionId, historyEntries, streamingEntries, createStream, subscribeToSession, processEvent, emitStreamingEntries, resetStreamingState, onError, attemptReconnect, onBeforeSend, onEvent, middleware]);
|
|
3594
4147
|
const stop = useCallback(() => {
|
|
4148
|
+
reconnectAttemptsRef.current = maxReconnectAttempts + 1;
|
|
4149
|
+
setIsReconnecting(false);
|
|
3595
4150
|
if (abortControllerRef.current) {
|
|
3596
4151
|
abortControllerRef.current.abort();
|
|
3597
4152
|
}
|
|
3598
|
-
}, []);
|
|
4153
|
+
}, [maxReconnectAttempts]);
|
|
3599
4154
|
const clear = useCallback(() => {
|
|
3600
4155
|
setHistoryEntries([]);
|
|
3601
4156
|
resetStreamingState();
|
|
3602
4157
|
setSessionId(initialSessionId || null);
|
|
3603
4158
|
setError(null);
|
|
4159
|
+
setIsReconnecting(false);
|
|
4160
|
+
reconnectAttemptsRef.current = 0;
|
|
4161
|
+
eventCountRef.current = 0;
|
|
3604
4162
|
}, [initialSessionId, resetStreamingState]);
|
|
3605
4163
|
const setEntries = useCallback((newEntries) => {
|
|
3606
4164
|
resetStreamingState();
|
|
@@ -3616,6 +4174,7 @@ function useAgentChat(options) {
|
|
|
3616
4174
|
return {
|
|
3617
4175
|
entries,
|
|
3618
4176
|
isStreaming,
|
|
4177
|
+
isReconnecting,
|
|
3619
4178
|
error,
|
|
3620
4179
|
sessionId,
|
|
3621
4180
|
send,
|
|
@@ -3697,6 +4256,6 @@ function useLongTextConversion({
|
|
|
3697
4256
|
};
|
|
3698
4257
|
}
|
|
3699
4258
|
|
|
3700
|
-
export { ActionIcon, AgentToolCard, AlertCircleIcon, AlertTriangleIcon, AssistantMessage, BotIcon, BrainIcon, BugIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon, ClipboardListIcon, ClockIcon, CodeBlock, CodeIcon, CompactToolRow, CompactToolStatusLine, CopyIcon, DEFAULT_DISPLAY_CONFIG, DisplayModeProvider, DisplayModeToggle, EditIcon, EnvVarsPanel, ErrorIcon, ErrorMessage, FileBadge, FileIcon, FilePlusIcon, FolderSearchIcon, GlobeIcon, InfoIcon, JsonDisplay, LazyMarkdown, 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, formatElapsedTime, formatFileSize, formatTimestamp, formatToolName, generateToolSummary, getActionIcon, getActionLabel, groupEntriesForCompactMode, inlineStyles, isAgentToolAction, 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 };
|
|
4259
|
+
export { ActionIcon, AgentToolCard, AlertCircleIcon, AlertTriangleIcon, ArrowUpIcon, AssistantMessage, BotIcon, BrainIcon, BugIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleIcon, ClipboardListIcon, ClockIcon, CodeBlock, CodeIcon, CompactToolRow, CompactToolStatusLine, CopyIcon, DEFAULT_DISPLAY_CONFIG, DEFAULT_STYLE_CONFIG, DisplayModeProvider, DisplayModeToggle, EditIcon, EnvVarsPanel, ErrorIcon, ErrorMessage, FileBadge, FileIcon, FilePlusIcon, FolderSearchIcon, GlobeIcon, HomeIcon, InfoIcon, JsonDisplay, LazyMarkdown, ListChecksIcon, LoaderIcon, LoadingIndicator, LogsPanel, MessageEntry, MessageList, MessageSquareIcon, MicrophoneIcon, MoonIcon, OptionCards, PaperclipIcon, PlugIcon, RichContentRenderer, SearchIcon, SendIcon, SparklesIcon, SpinnerIcon, StatusIndicator, StepAccordion, StopCircleIcon, StreamingText, SunIcon, TerminalIcon, ThemeProvider, ThinkingMessage, TodoPanel, ToolCallCard, ToolCallMessage, ToolExecutionGroup, ToolIcon, TypewriterText, UserIcon, UserMessage, XCircleIcon, XIcon, allKeyframesCss, applyEventMiddleware, applyRequestMiddleware, borderRadius, callMiddlewareComplete, callMiddlewareError, cn, colors, createToolCall, cssVars, extractTextContent, extractToolCallsFromGroup, formatElapsedTime, formatFileSize, formatTimestamp, formatToolName, generateToolSummary, getActionIcon, getActionLabel, groupEntriesForCompactMode, inlineStyles, isAgentToolAction, 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 };
|
|
3701
4260
|
//# sourceMappingURL=index.js.map
|
|
3702
4261
|
//# sourceMappingURL=index.js.map
|