@invergent/agent-chat-react 2.1.4 → 2.1.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 +173 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +173 -74
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -882,7 +882,7 @@ var ConversationEmptyState = ({
|
|
|
882
882
|
icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center size-14 rounded-2xl bg-muted/60 text-muted-foreground/60", children: icon }),
|
|
883
883
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
884
884
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-base text-foreground/80", children: title }),
|
|
885
|
-
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-
|
|
885
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-foreground/60 text-sm max-w-sm", children: description })
|
|
886
886
|
] })
|
|
887
887
|
] })
|
|
888
888
|
}
|
|
@@ -5281,12 +5281,16 @@ var PromptInput = ({
|
|
|
5281
5281
|
const formData = new FormData(form);
|
|
5282
5282
|
return formData.get("message") || "";
|
|
5283
5283
|
})();
|
|
5284
|
+
const submittedFiles = files;
|
|
5284
5285
|
if (!usingProvider) {
|
|
5285
5286
|
form.reset();
|
|
5287
|
+
} else {
|
|
5288
|
+
controller.textInput.clear();
|
|
5286
5289
|
}
|
|
5290
|
+
clear();
|
|
5287
5291
|
try {
|
|
5288
5292
|
const convertedFiles = await Promise.all(
|
|
5289
|
-
|
|
5293
|
+
submittedFiles.map(async (entry) => {
|
|
5290
5294
|
const isBlob = entry.url?.startsWith("blob:");
|
|
5291
5295
|
const isImage = entry.mediaType?.startsWith("image/");
|
|
5292
5296
|
if (isBlob && isImage && entry.url) {
|
|
@@ -5299,22 +5303,7 @@ var PromptInput = ({
|
|
|
5299
5303
|
return entry;
|
|
5300
5304
|
})
|
|
5301
5305
|
);
|
|
5302
|
-
|
|
5303
|
-
if (result instanceof Promise) {
|
|
5304
|
-
try {
|
|
5305
|
-
await result;
|
|
5306
|
-
clear();
|
|
5307
|
-
if (usingProvider) {
|
|
5308
|
-
controller.textInput.clear();
|
|
5309
|
-
}
|
|
5310
|
-
} catch {
|
|
5311
|
-
}
|
|
5312
|
-
} else {
|
|
5313
|
-
clear();
|
|
5314
|
-
if (usingProvider) {
|
|
5315
|
-
controller.textInput.clear();
|
|
5316
|
-
}
|
|
5317
|
-
}
|
|
5306
|
+
await onSubmit({ files: convertedFiles, text }, event);
|
|
5318
5307
|
} catch {
|
|
5319
5308
|
}
|
|
5320
5309
|
},
|
|
@@ -6392,36 +6381,6 @@ function ChatComposerInner({
|
|
|
6392
6381
|
}
|
|
6393
6382
|
)
|
|
6394
6383
|
] }),
|
|
6395
|
-
onViewModeChange && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6396
|
-
"div",
|
|
6397
|
-
{
|
|
6398
|
-
role: "group",
|
|
6399
|
-
"aria-label": "Chat view mode",
|
|
6400
|
-
className: "inline-flex overflow-hidden rounded-md border border-border",
|
|
6401
|
-
children: [
|
|
6402
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6403
|
-
"button",
|
|
6404
|
-
{
|
|
6405
|
-
type: "button",
|
|
6406
|
-
"aria-pressed": viewMode === "simple",
|
|
6407
|
-
onClick: () => onViewModeChange("simple"),
|
|
6408
|
-
className: viewMode === "simple" ? "bg-accent px-2 py-1 text-xs text-foreground" : "px-2 py-1 text-xs text-muted-foreground hover:text-foreground",
|
|
6409
|
-
children: "Simple"
|
|
6410
|
-
}
|
|
6411
|
-
),
|
|
6412
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6413
|
-
"button",
|
|
6414
|
-
{
|
|
6415
|
-
type: "button",
|
|
6416
|
-
"aria-pressed": viewMode === "expert",
|
|
6417
|
-
onClick: () => onViewModeChange("expert"),
|
|
6418
|
-
className: viewMode === "expert" ? "bg-accent px-2 py-1 text-xs text-foreground" : "px-2 py-1 text-xs text-muted-foreground hover:text-foreground",
|
|
6419
|
-
children: "Expert"
|
|
6420
|
-
}
|
|
6421
|
-
)
|
|
6422
|
-
]
|
|
6423
|
-
}
|
|
6424
|
-
),
|
|
6425
6384
|
canShowBrowser && onToggleBrowser && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6426
6385
|
PromptInputButton,
|
|
6427
6386
|
{
|
|
@@ -6501,7 +6460,46 @@ function ChatComposerInner({
|
|
|
6501
6460
|
}
|
|
6502
6461
|
)
|
|
6503
6462
|
] }),
|
|
6504
|
-
/* @__PURE__ */ jsxRuntime.
|
|
6463
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
6464
|
+
onViewModeChange && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6465
|
+
"div",
|
|
6466
|
+
{
|
|
6467
|
+
role: "group",
|
|
6468
|
+
"aria-label": "Chat view mode",
|
|
6469
|
+
className: "inline-flex overflow-hidden rounded-md border border-border",
|
|
6470
|
+
children: [
|
|
6471
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6472
|
+
"button",
|
|
6473
|
+
{
|
|
6474
|
+
type: "button",
|
|
6475
|
+
"aria-pressed": viewMode === "simple",
|
|
6476
|
+
onClick: () => onViewModeChange("simple"),
|
|
6477
|
+
className: viewMode === "simple" ? "bg-accent px-2 py-1 text-xs text-foreground" : "px-2 py-1 text-xs text-muted-foreground hover:text-foreground",
|
|
6478
|
+
children: "Simple"
|
|
6479
|
+
}
|
|
6480
|
+
),
|
|
6481
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6482
|
+
"button",
|
|
6483
|
+
{
|
|
6484
|
+
type: "button",
|
|
6485
|
+
"aria-pressed": viewMode === "expert",
|
|
6486
|
+
onClick: () => onViewModeChange("expert"),
|
|
6487
|
+
className: viewMode === "expert" ? "bg-accent px-2 py-1 text-xs text-foreground" : "px-2 py-1 text-xs text-muted-foreground hover:text-foreground",
|
|
6488
|
+
children: "Advanced"
|
|
6489
|
+
}
|
|
6490
|
+
)
|
|
6491
|
+
]
|
|
6492
|
+
}
|
|
6493
|
+
),
|
|
6494
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6495
|
+
PromptInputSubmit,
|
|
6496
|
+
{
|
|
6497
|
+
status,
|
|
6498
|
+
onStop,
|
|
6499
|
+
className: "md:size-8"
|
|
6500
|
+
}
|
|
6501
|
+
)
|
|
6502
|
+
] })
|
|
6505
6503
|
] })
|
|
6506
6504
|
]
|
|
6507
6505
|
}
|
|
@@ -6678,7 +6676,7 @@ function TurnFeedback({ msg }) {
|
|
|
6678
6676
|
{
|
|
6679
6677
|
type: "button",
|
|
6680
6678
|
variant: "ghost",
|
|
6681
|
-
size: "icon-
|
|
6679
|
+
size: "icon-sm",
|
|
6682
6680
|
"aria-label": "Good response",
|
|
6683
6681
|
title: alreadyRated && rating === "up" ? "Good response (recorded)" : "Good response",
|
|
6684
6682
|
disabled: pending !== null || alreadyRated,
|
|
@@ -6686,7 +6684,7 @@ function TurnFeedback({ msg }) {
|
|
|
6686
6684
|
className: cn(
|
|
6687
6685
|
rating === "up" ? "text-foreground" : "text-muted-foreground/60"
|
|
6688
6686
|
),
|
|
6689
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ThumbsUpIcon, { className: "size-
|
|
6687
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ThumbsUpIcon, { className: "size-4.5" })
|
|
6690
6688
|
}
|
|
6691
6689
|
),
|
|
6692
6690
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6694,7 +6692,7 @@ function TurnFeedback({ msg }) {
|
|
|
6694
6692
|
{
|
|
6695
6693
|
type: "button",
|
|
6696
6694
|
variant: "ghost",
|
|
6697
|
-
size: "icon-
|
|
6695
|
+
size: "icon-sm",
|
|
6698
6696
|
"aria-label": "Poor response",
|
|
6699
6697
|
title: alreadyRated && rating === "down" ? "Poor response (recorded)" : "Poor response",
|
|
6700
6698
|
disabled: pending !== null || reasonDraft !== null || alreadyRated,
|
|
@@ -6702,7 +6700,7 @@ function TurnFeedback({ msg }) {
|
|
|
6702
6700
|
className: cn(
|
|
6703
6701
|
rating === "down" ? "text-foreground" : "text-muted-foreground/60"
|
|
6704
6702
|
),
|
|
6705
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ThumbsDownIcon, { className: "size-
|
|
6703
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ThumbsDownIcon, { className: "size-4.5" })
|
|
6706
6704
|
}
|
|
6707
6705
|
),
|
|
6708
6706
|
alreadyRated && msg.userFeedback?.reason && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -7472,7 +7470,8 @@ function FileViewer({
|
|
|
7472
7470
|
error,
|
|
7473
7471
|
downloadUrl,
|
|
7474
7472
|
onDelete,
|
|
7475
|
-
onClose
|
|
7473
|
+
onClose,
|
|
7474
|
+
hideHeader = false
|
|
7476
7475
|
}) {
|
|
7477
7476
|
const visible = loading || file !== null || error !== null;
|
|
7478
7477
|
if (!visible) return null;
|
|
@@ -7482,7 +7481,7 @@ function FileViewer({
|
|
|
7482
7481
|
const isImage = file?.encoding === "base64" && !isPdf;
|
|
7483
7482
|
const HeaderIcon = isImage ? lucideReact.ImageIcon : lucideReact.FileTextIcon;
|
|
7484
7483
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col border-t border-line", children: [
|
|
7485
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b border-line px-3 py-2", children: [
|
|
7484
|
+
!hideHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b border-line px-3 py-2", children: [
|
|
7486
7485
|
/* @__PURE__ */ jsxRuntime.jsx(HeaderIcon, { className: "size-3.5 shrink-0 text-muted-foreground" }),
|
|
7487
7486
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
7488
7487
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-xs font-medium", children: fileName2 }),
|
|
@@ -7527,7 +7526,12 @@ function FileViewer({
|
|
|
7527
7526
|
}
|
|
7528
7527
|
)
|
|
7529
7528
|
] }),
|
|
7530
|
-
|
|
7529
|
+
file && isPdf && file.encoding === "base64" ? (
|
|
7530
|
+
// PDF has its own scrollable container — bypass ScrollArea so
|
|
7531
|
+
// it can grow with the parent's flex height (Radix Viewport's
|
|
7532
|
+
// internal table wrapper sizes to content and breaks h-full).
|
|
7533
|
+
/* @__PURE__ */ jsxRuntime.jsx(PdfPreview, { file, fileName: fileName2 })
|
|
7534
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(ScrollArea, { className: "min-h-0 flex-1", children: [
|
|
7531
7535
|
loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5 p-3", children: Array.from({ length: 10 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7532
7536
|
Skeleton,
|
|
7533
7537
|
{
|
|
@@ -7543,7 +7547,6 @@ function FileViewer({
|
|
|
7543
7547
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: error })
|
|
7544
7548
|
] }),
|
|
7545
7549
|
file && isPdf && file.encoding !== "base64" && /* @__PURE__ */ jsxRuntime.jsx(FileViewerError, { message: "PDF preview requires base64 file content." }),
|
|
7546
|
-
file && isPdf && file.encoding === "base64" && /* @__PURE__ */ jsxRuntime.jsx(PdfPreview, { file, fileName: fileName2 }),
|
|
7547
7550
|
file && isImage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7548
7551
|
"img",
|
|
7549
7552
|
{
|
|
@@ -7807,7 +7810,7 @@ function PdfPreview({
|
|
|
7807
7810
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
7808
7811
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: error })
|
|
7809
7812
|
] }),
|
|
7810
|
-
!error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative
|
|
7813
|
+
!error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative min-h-105 flex-1 bg-muted/20", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7811
7814
|
"div",
|
|
7812
7815
|
{
|
|
7813
7816
|
ref: containerRef,
|
|
@@ -8008,8 +8011,23 @@ function WorkspaceFilePreviewDialog({
|
|
|
8008
8011
|
cancelled = true;
|
|
8009
8012
|
};
|
|
8010
8013
|
}, [adapter, sessionId, path, open]);
|
|
8011
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "flex h-[
|
|
8012
|
-
/* @__PURE__ */ jsxRuntime.
|
|
8014
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "flex h-[85vh] w-[95vw] max-w-350! flex-col gap-0 overflow-hidden p-0", children: [
|
|
8015
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { className: "flex flex-row items-center gap-2 border-b border-line px-4 py-3", children: [
|
|
8016
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "min-w-0 flex-1 truncate text-sm", children: _basename(path) }),
|
|
8017
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
8018
|
+
"a",
|
|
8019
|
+
{
|
|
8020
|
+
href: downloadUrl,
|
|
8021
|
+
download: _basename(path),
|
|
8022
|
+
className: "mr-8 inline-flex shrink-0 items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1 text-xs font-medium text-foreground transition-colors hover:bg-muted",
|
|
8023
|
+
"aria-label": `Download ${_basename(path)}`,
|
|
8024
|
+
children: [
|
|
8025
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, { className: "size-3.5", "aria-hidden": true }),
|
|
8026
|
+
"Download"
|
|
8027
|
+
]
|
|
8028
|
+
}
|
|
8029
|
+
)
|
|
8030
|
+
] }),
|
|
8013
8031
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8014
8032
|
FileViewer,
|
|
8015
8033
|
{
|
|
@@ -8018,7 +8036,8 @@ function WorkspaceFilePreviewDialog({
|
|
|
8018
8036
|
error,
|
|
8019
8037
|
downloadUrl,
|
|
8020
8038
|
onDelete: null,
|
|
8021
|
-
onClose: () => onOpenChange(false)
|
|
8039
|
+
onClose: () => onOpenChange(false),
|
|
8040
|
+
hideHeader: true
|
|
8022
8041
|
}
|
|
8023
8042
|
) })
|
|
8024
8043
|
] }) });
|
|
@@ -8045,7 +8064,8 @@ function TurnSummaryCard({
|
|
|
8045
8064
|
const hasRecap = summary.recap.trim().length > 0;
|
|
8046
8065
|
const hasArtifacts = summary.artifacts.length > 0;
|
|
8047
8066
|
if (!hasRecap && !hasArtifacts) return null;
|
|
8048
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 rounded border border-border bg-muted/
|
|
8067
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 rounded border border-border bg-muted/50 px-3 py-2 text-sm", children: [
|
|
8068
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-xs font-semibold uppercase tracking-wide", children: "Summary" }),
|
|
8049
8069
|
hasRecap && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 whitespace-pre-wrap text-foreground", children: summary.recap }),
|
|
8050
8070
|
hasArtifacts && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: summary.artifacts.map((artifact, i) => {
|
|
8051
8071
|
const key = `${artifact.kind}:${artifact.ref}:${i}`;
|
|
@@ -8099,6 +8119,16 @@ function TurnSummaryCard({
|
|
|
8099
8119
|
}) })
|
|
8100
8120
|
] });
|
|
8101
8121
|
}
|
|
8122
|
+
function TurnSummaryPending() {
|
|
8123
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 rounded border border-border bg-muted/50 px-3 py-2 text-sm", children: [
|
|
8124
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-xs font-semibold uppercase tracking-wide", children: "Summary" }),
|
|
8125
|
+
/* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 3, spread: 3, className: "mb-2 text-sm", children: "Summarizing conversation..." }),
|
|
8126
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
8127
|
+
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
8128
|
+
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 w-2/3" })
|
|
8129
|
+
] })
|
|
8130
|
+
] });
|
|
8131
|
+
}
|
|
8102
8132
|
function ArtifactRow({
|
|
8103
8133
|
artifact,
|
|
8104
8134
|
sessionId,
|
|
@@ -8835,7 +8865,7 @@ function IterationGroup({
|
|
|
8835
8865
|
type: "button",
|
|
8836
8866
|
onClick: () => setOpen((prev) => !prev),
|
|
8837
8867
|
"aria-expanded": open,
|
|
8838
|
-
className: "flex w-full items-center gap-2 rounded
|
|
8868
|
+
className: "flex w-full items-center gap-2 rounded py-0.5 text-left text-sm hover:bg-muted/40",
|
|
8839
8869
|
children: [
|
|
8840
8870
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("flex-1 truncate", labelTone), children: label }),
|
|
8841
8871
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8863,6 +8893,18 @@ function IterationGroup({
|
|
|
8863
8893
|
] });
|
|
8864
8894
|
}
|
|
8865
8895
|
function deriveFileArtifactsFromMessages(messages) {
|
|
8896
|
+
const terminalCommands = [];
|
|
8897
|
+
for (const msg of messages) {
|
|
8898
|
+
if (msg.role !== "assistant" || !msg.toolCalls) continue;
|
|
8899
|
+
for (const tc of msg.toolCalls) {
|
|
8900
|
+
if (tc.toolName !== "terminal") continue;
|
|
8901
|
+
const status = effectiveStatus(tc);
|
|
8902
|
+
if (status === "error" || status === "cancelled") continue;
|
|
8903
|
+
const args = parseArgs(tc.args);
|
|
8904
|
+
const cmd = typeof args?.command === "string" ? args.command : "";
|
|
8905
|
+
if (cmd) terminalCommands.push(cmd);
|
|
8906
|
+
}
|
|
8907
|
+
}
|
|
8866
8908
|
const seen = /* @__PURE__ */ new Set();
|
|
8867
8909
|
const out = [];
|
|
8868
8910
|
for (const msg of messages) {
|
|
@@ -8875,6 +8917,8 @@ function deriveFileArtifactsFromMessages(messages) {
|
|
|
8875
8917
|
if (tc.toolName === "write_file" || tc.toolName === "patch") {
|
|
8876
8918
|
const path = typeof args.path === "string" ? args.path : typeof args.file_path === "string" ? args.file_path : "";
|
|
8877
8919
|
if (!path || seen.has(`file:${path}`)) continue;
|
|
8920
|
+
const executed = terminalCommands.some((cmd) => cmd.includes(path));
|
|
8921
|
+
if (executed) continue;
|
|
8878
8922
|
seen.add(`file:${path}`);
|
|
8879
8923
|
out.push({
|
|
8880
8924
|
kind: "file",
|
|
@@ -8915,11 +8959,13 @@ function SimpleAssistantGroup({
|
|
|
8915
8959
|
const isTailGroup = lastGlobalIndex === totalMessages - 1;
|
|
8916
8960
|
const showThinkingShim = isTailGroup && isRunning && (!tail && messages.some((m) => m.role !== "assistant") || tailIsTextOnly && tail.status === "streaming" && !tail.content);
|
|
8917
8961
|
const showErrorInfo = !!tail && tail.status === "error" && !!tail.errorInfo;
|
|
8962
|
+
const turnComplete = !isRunning && tail?.status === "complete";
|
|
8918
8963
|
const effectiveTurnSummary = (() => {
|
|
8919
8964
|
const fromHarness = tail?.turnSummary;
|
|
8920
8965
|
if (fromHarness && fromHarness.artifacts.length > 0) {
|
|
8921
8966
|
return fromHarness;
|
|
8922
8967
|
}
|
|
8968
|
+
if (!turnComplete) return fromHarness;
|
|
8923
8969
|
const derived = deriveFileArtifactsFromMessages(messages);
|
|
8924
8970
|
if (derived.length === 0) return fromHarness;
|
|
8925
8971
|
return {
|
|
@@ -8960,7 +9006,7 @@ function SimpleAssistantGroup({
|
|
|
8960
9006
|
/* @__PURE__ */ jsxRuntime.jsx(MessageResponse, { children: finalText }),
|
|
8961
9007
|
tail?.status === "complete" && /* @__PURE__ */ jsxRuntime.jsx(TurnFeedback, { msg: tail })
|
|
8962
9008
|
] }),
|
|
8963
|
-
effectiveTurnSummary
|
|
9009
|
+
effectiveTurnSummary ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
8964
9010
|
TurnSummaryCard,
|
|
8965
9011
|
{
|
|
8966
9012
|
summary: effectiveTurnSummary,
|
|
@@ -8968,6 +9014,14 @@ function SimpleAssistantGroup({
|
|
|
8968
9014
|
messages,
|
|
8969
9015
|
onFileSelect
|
|
8970
9016
|
}
|
|
9017
|
+
) : (
|
|
9018
|
+
// The harness summarizer runs after the last assistant
|
|
9019
|
+
// response and before ``session.complete``. Show a pending
|
|
9020
|
+
// placeholder during that window so users aren't surprised
|
|
9021
|
+
// when the Summary card pops in. Gated on the tail group +
|
|
9022
|
+
// a complete final answer + still-running session so the
|
|
9023
|
+
// placeholder doesn't show on historic turns or mid-stream.
|
|
9024
|
+
isTailGroup && isRunning && !!finalText && tail?.status === "complete" && /* @__PURE__ */ jsxRuntime.jsx(TurnSummaryPending, {})
|
|
8971
9025
|
),
|
|
8972
9026
|
showErrorInfo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage, { errorInfo: tail.errorInfo, onRetry }) })
|
|
8973
9027
|
] }) });
|
|
@@ -9419,6 +9473,27 @@ function findEntry(entries, path) {
|
|
|
9419
9473
|
}
|
|
9420
9474
|
return null;
|
|
9421
9475
|
}
|
|
9476
|
+
var FILENAME_MAX_CHARS = 42;
|
|
9477
|
+
function truncateFilename(name, max) {
|
|
9478
|
+
if (name.length <= max) return name;
|
|
9479
|
+
const dot = name.lastIndexOf(".");
|
|
9480
|
+
if (dot > 0 && name.length - dot <= 12) {
|
|
9481
|
+
const ext = name.slice(dot);
|
|
9482
|
+
const head = name.slice(0, Math.max(1, max - ext.length - 1));
|
|
9483
|
+
return `${head}\u2026${ext}`;
|
|
9484
|
+
}
|
|
9485
|
+
return `${name.slice(0, max - 1)}\u2026`;
|
|
9486
|
+
}
|
|
9487
|
+
function TruncatedFileName({ name }) {
|
|
9488
|
+
const truncated = truncateFilename(name, FILENAME_MAX_CHARS);
|
|
9489
|
+
const isTruncated = truncated !== name;
|
|
9490
|
+
const node = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: truncated });
|
|
9491
|
+
if (!isTruncated) return node;
|
|
9492
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
9493
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: node }),
|
|
9494
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", className: "max-w-md break-all", children: name })
|
|
9495
|
+
] });
|
|
9496
|
+
}
|
|
9422
9497
|
function RenderEntries({
|
|
9423
9498
|
entries,
|
|
9424
9499
|
onDelete,
|
|
@@ -9438,7 +9513,7 @@ function RenderEntries({
|
|
|
9438
9513
|
const fileName2 = entry.name;
|
|
9439
9514
|
return /* @__PURE__ */ jsxRuntime.jsxs(FileTreeFile, { name: entry.name, path: entry.path, children: [
|
|
9440
9515
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-4 shrink-0" }),
|
|
9441
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9516
|
+
/* @__PURE__ */ jsxRuntime.jsx(TruncatedFileName, { name: entry.name }),
|
|
9442
9517
|
entry.size != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 shrink-0 text-xs text-muted-foreground/60", children: formatFileSize(entry.size) }),
|
|
9443
9518
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-1 flex shrink-0 items-center gap-0 opacity-100 transition-opacity md:opacity-0 md:group-hover:opacity-100", children: [
|
|
9444
9519
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9482,7 +9557,6 @@ function WorkspacePanel({
|
|
|
9482
9557
|
}) {
|
|
9483
9558
|
const fileInputRef = react.useRef(null);
|
|
9484
9559
|
const [entries, setEntries] = react.useState([]);
|
|
9485
|
-
const [rootName, setRootName] = react.useState("workspace");
|
|
9486
9560
|
const [treeLoading, setTreeLoading] = react.useState(false);
|
|
9487
9561
|
const [treeError, setTreeError] = react.useState(null);
|
|
9488
9562
|
const [file, setFile] = react.useState(null);
|
|
@@ -9501,7 +9575,6 @@ function WorkspacePanel({
|
|
|
9501
9575
|
const fetchTree = react.useCallback(async () => {
|
|
9502
9576
|
if (!sessionId) {
|
|
9503
9577
|
setEntries([]);
|
|
9504
|
-
setRootName("workspace");
|
|
9505
9578
|
setExpandedPaths(/* @__PURE__ */ new Set());
|
|
9506
9579
|
setTreeLoading(false);
|
|
9507
9580
|
setTreeError(null);
|
|
@@ -9516,12 +9589,10 @@ function WorkspacePanel({
|
|
|
9516
9589
|
});
|
|
9517
9590
|
if (sessionIdRef.current !== requestedSessionId) return;
|
|
9518
9591
|
setEntries(tree.entries);
|
|
9519
|
-
setRootName(tree.root || "workspace");
|
|
9520
9592
|
setExpandedPaths(new Set(collectExpandedPaths(tree.entries)));
|
|
9521
9593
|
} catch (error) {
|
|
9522
9594
|
if (sessionIdRef.current !== requestedSessionId) return;
|
|
9523
9595
|
setEntries([]);
|
|
9524
|
-
setRootName("workspace");
|
|
9525
9596
|
setTreeError(error.message);
|
|
9526
9597
|
} finally {
|
|
9527
9598
|
if (sessionIdRef.current === requestedSessionId) {
|
|
@@ -9711,10 +9782,7 @@ function WorkspacePanel({
|
|
|
9711
9782
|
),
|
|
9712
9783
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-14 items-center gap-2 border-b border-line px-3 py-3", children: [
|
|
9713
9784
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderOpenIcon, { className: "size-4 shrink-0 text-amber-500" }),
|
|
9714
|
-
/* @__PURE__ */ jsxRuntime.
|
|
9715
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm font-medium text-foreground", children: rootName }),
|
|
9716
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-xs text-faint", children: disabled ? "Workspace - Read-only" : "Workspace" })
|
|
9717
|
-
] }),
|
|
9785
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm font-medium text-foreground", children: disabled ? "Workspace - Read-only" : "Workspace" }) }),
|
|
9718
9786
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
9719
9787
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9720
9788
|
Button,
|
|
@@ -10834,6 +10902,7 @@ function readTurnMeta(data) {
|
|
|
10834
10902
|
|
|
10835
10903
|
// src/runtime/use-agent-chat-runtime.ts
|
|
10836
10904
|
var VIEW_MODE_KEY = "@invergent/agent-chat-react:viewMode";
|
|
10905
|
+
var VIEW_MODE_EVENT = "@invergent/agent-chat-react:viewMode:change";
|
|
10837
10906
|
function readPersistedViewMode() {
|
|
10838
10907
|
if (typeof window === "undefined") return null;
|
|
10839
10908
|
try {
|
|
@@ -10849,6 +10918,36 @@ function writePersistedViewMode(mode) {
|
|
|
10849
10918
|
window.localStorage.setItem(VIEW_MODE_KEY, mode);
|
|
10850
10919
|
} catch {
|
|
10851
10920
|
}
|
|
10921
|
+
try {
|
|
10922
|
+
window.dispatchEvent(
|
|
10923
|
+
new CustomEvent(VIEW_MODE_EVENT, { detail: mode })
|
|
10924
|
+
);
|
|
10925
|
+
} catch {
|
|
10926
|
+
}
|
|
10927
|
+
}
|
|
10928
|
+
function useChatViewMode() {
|
|
10929
|
+
const [mode, setMode] = react.useState(
|
|
10930
|
+
() => readPersistedViewMode() ?? "simple"
|
|
10931
|
+
);
|
|
10932
|
+
react.useEffect(() => {
|
|
10933
|
+
if (typeof window === "undefined") return;
|
|
10934
|
+
const onSameTab = (event) => {
|
|
10935
|
+
const detail = event.detail;
|
|
10936
|
+
if (detail === "simple" || detail === "expert") setMode(detail);
|
|
10937
|
+
};
|
|
10938
|
+
const onCrossTab = (event) => {
|
|
10939
|
+
if (event.key !== VIEW_MODE_KEY) return;
|
|
10940
|
+
const next = event.newValue;
|
|
10941
|
+
if (next === "simple" || next === "expert") setMode(next);
|
|
10942
|
+
};
|
|
10943
|
+
window.addEventListener(VIEW_MODE_EVENT, onSameTab);
|
|
10944
|
+
window.addEventListener("storage", onCrossTab);
|
|
10945
|
+
return () => {
|
|
10946
|
+
window.removeEventListener(VIEW_MODE_EVENT, onSameTab);
|
|
10947
|
+
window.removeEventListener("storage", onCrossTab);
|
|
10948
|
+
};
|
|
10949
|
+
}, []);
|
|
10950
|
+
return mode;
|
|
10852
10951
|
}
|
|
10853
10952
|
function useAgentChatRuntime({
|
|
10854
10953
|
adapter,
|
|
@@ -13905,6 +14004,7 @@ exports.isTerminalMissionStatus = isTerminalMissionStatus;
|
|
|
13905
14004
|
exports.missionTaskBucket = missionTaskBucket;
|
|
13906
14005
|
exports.useAgentChatAdapterContext = useAgentChatAdapterContext;
|
|
13907
14006
|
exports.useAgentChatRuntime = useAgentChatRuntime;
|
|
14007
|
+
exports.useChatViewMode = useChatViewMode;
|
|
13908
14008
|
exports.useInboxUnreadCount = useInboxUnreadCount;
|
|
13909
14009
|
//# sourceMappingURL=index.cjs.map
|
|
13910
14010
|
//# sourceMappingURL=index.cjs.map
|