@lukeashford/aurelius 4.2.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +124 -25
- package/dist/index.d.ts +124 -25
- package/dist/index.js +359 -218
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +309 -167
- package/dist/index.mjs.map +1 -1
- package/llms.md +23 -11
- package/package.json +10 -6
package/dist/index.js
CHANGED
|
@@ -1487,42 +1487,91 @@ function getFileIcon(type) {
|
|
|
1487
1487
|
}
|
|
1488
1488
|
return import_lucide_react2.File;
|
|
1489
1489
|
}
|
|
1490
|
-
var
|
|
1490
|
+
var statusBorderClass = {
|
|
1491
1491
|
pending: "border-silver/30",
|
|
1492
1492
|
uploading: "border-gold/50",
|
|
1493
|
-
|
|
1494
|
-
|
|
1493
|
+
uploaded: "border-info/50",
|
|
1494
|
+
analyzing: "border-info/50",
|
|
1495
|
+
analyzed: "border-success/50",
|
|
1496
|
+
upload_failed: "border-error/50",
|
|
1497
|
+
analysis_failed: "border-error/50"
|
|
1495
1498
|
};
|
|
1499
|
+
var statusHoverLabel = {
|
|
1500
|
+
pending: null,
|
|
1501
|
+
uploading: "Uploading",
|
|
1502
|
+
uploaded: "Analyzing",
|
|
1503
|
+
analyzing: "Analyzing",
|
|
1504
|
+
analyzed: null,
|
|
1505
|
+
upload_failed: "Upload failed",
|
|
1506
|
+
analysis_failed: "Couldn't process this file"
|
|
1507
|
+
};
|
|
1508
|
+
function isErrorStatus(status) {
|
|
1509
|
+
return status === "upload_failed" || status === "analysis_failed";
|
|
1510
|
+
}
|
|
1496
1511
|
var FileChip = import_react16.default.forwardRef(
|
|
1497
1512
|
({
|
|
1498
1513
|
name,
|
|
1499
1514
|
size,
|
|
1500
1515
|
type,
|
|
1501
|
-
status = "
|
|
1516
|
+
status = "analyzed",
|
|
1502
1517
|
previewUrl,
|
|
1503
1518
|
onRemove,
|
|
1504
1519
|
removable = true,
|
|
1505
1520
|
error,
|
|
1521
|
+
artifactId,
|
|
1522
|
+
onOpen,
|
|
1506
1523
|
className,
|
|
1524
|
+
title,
|
|
1507
1525
|
...rest
|
|
1508
1526
|
}, ref) => {
|
|
1509
1527
|
const Icon = getFileIcon(type);
|
|
1510
1528
|
const isImage = type?.startsWith("image/");
|
|
1511
1529
|
const showPreview = isImage && previewUrl;
|
|
1512
|
-
|
|
1530
|
+
const clickable = !!(artifactId && onOpen);
|
|
1531
|
+
const hoverLabel = statusHoverLabel[status];
|
|
1532
|
+
const tooltipContent = isErrorStatus(status) ? error ?? hoverLabel ?? null : hoverLabel;
|
|
1533
|
+
const [hovered, setHovered] = (0, import_react16.useState)(false);
|
|
1534
|
+
const [focused, setFocused] = (0, import_react16.useState)(false);
|
|
1535
|
+
const showError = isErrorStatus(status);
|
|
1536
|
+
const handleClick = () => {
|
|
1537
|
+
if (clickable) {
|
|
1538
|
+
onOpen(artifactId);
|
|
1539
|
+
}
|
|
1540
|
+
};
|
|
1541
|
+
const handleKeyDown = (e) => {
|
|
1542
|
+
if (!clickable) {
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1546
|
+
e.preventDefault();
|
|
1547
|
+
onOpen(artifactId);
|
|
1548
|
+
}
|
|
1549
|
+
};
|
|
1550
|
+
const tooltipOpen = tooltipContent !== null && (hovered || focused);
|
|
1551
|
+
const chip = /* @__PURE__ */ import_react16.default.createElement(
|
|
1513
1552
|
"div",
|
|
1514
1553
|
{
|
|
1554
|
+
...rest,
|
|
1515
1555
|
ref,
|
|
1516
1556
|
className: cx(
|
|
1517
1557
|
"group relative inline-flex items-center gap-2 px-2 py-1.5",
|
|
1518
1558
|
"bg-charcoal border text-sm text-white",
|
|
1519
1559
|
"transition-colors duration-150",
|
|
1520
|
-
|
|
1521
|
-
|
|
1560
|
+
statusBorderClass[status],
|
|
1561
|
+
showError && "bg-error/10",
|
|
1562
|
+
clickable && "cursor-pointer hover:bg-graphite",
|
|
1522
1563
|
className
|
|
1523
1564
|
),
|
|
1524
|
-
role: "listitem",
|
|
1525
|
-
|
|
1565
|
+
role: clickable ? "button" : "listitem",
|
|
1566
|
+
tabIndex: clickable ? 0 : void 0,
|
|
1567
|
+
onClick: clickable ? handleClick : void 0,
|
|
1568
|
+
onKeyDown: clickable ? handleKeyDown : void 0,
|
|
1569
|
+
onMouseEnter: () => setHovered(true),
|
|
1570
|
+
onMouseLeave: () => setHovered(false),
|
|
1571
|
+
onFocus: () => setFocused(true),
|
|
1572
|
+
onBlur: () => setFocused(false),
|
|
1573
|
+
title,
|
|
1574
|
+
"aria-label": hoverLabel ? `${name}: ${hoverLabel}` : name
|
|
1526
1575
|
},
|
|
1527
1576
|
showPreview ? /* @__PURE__ */ import_react16.default.createElement("div", { className: "w-8 h-8 flex-shrink-0 overflow-hidden bg-slate" }, /* @__PURE__ */ import_react16.default.createElement(
|
|
1528
1577
|
"img",
|
|
@@ -1533,10 +1582,11 @@ var FileChip = import_react16.default.forwardRef(
|
|
|
1533
1582
|
}
|
|
1534
1583
|
)) : /* @__PURE__ */ import_react16.default.createElement(Icon, { className: cx(
|
|
1535
1584
|
"w-4 h-4 flex-shrink-0",
|
|
1536
|
-
|
|
1585
|
+
showError ? "text-error" : "text-silver"
|
|
1537
1586
|
) }),
|
|
1538
|
-
/* @__PURE__ */ import_react16.default.createElement("div", { className: "flex flex-col min-w-0 flex-1" }, /* @__PURE__ */ import_react16.default.createElement("span", { className: "truncate max-w-40", title: name }, name), size !== void 0 &&
|
|
1587
|
+
/* @__PURE__ */ import_react16.default.createElement("div", { className: "flex flex-col min-w-0 flex-1" }, /* @__PURE__ */ import_react16.default.createElement("span", { className: "truncate max-w-40", title: name }, name), size !== void 0 && !showError && /* @__PURE__ */ import_react16.default.createElement("span", { className: "text-xs text-silver/60" }, formatBytes(size)), showError && error && /* @__PURE__ */ import_react16.default.createElement("span", { className: "text-xs text-error truncate", title: error }, error)),
|
|
1539
1588
|
status === "uploading" && /* @__PURE__ */ import_react16.default.createElement(import_lucide_react2.Loader2, { className: "w-3.5 h-3.5 text-gold animate-spin flex-shrink-0" }),
|
|
1589
|
+
(status === "uploaded" || status === "analyzing") && /* @__PURE__ */ import_react16.default.createElement(import_lucide_react2.Loader2, { className: "w-3.5 h-3.5 text-info animate-spin flex-shrink-0" }),
|
|
1540
1590
|
status === "pending" && /* @__PURE__ */ import_react16.default.createElement("div", { className: "w-2 h-2 rounded-full bg-silver/50 flex-shrink-0" }),
|
|
1541
1591
|
removable && onRemove && /* @__PURE__ */ import_react16.default.createElement(
|
|
1542
1592
|
"button",
|
|
@@ -1557,6 +1607,10 @@ var FileChip = import_react16.default.forwardRef(
|
|
|
1557
1607
|
/* @__PURE__ */ import_react16.default.createElement(import_lucide_react2.X, { className: "w-3.5 h-3.5" })
|
|
1558
1608
|
)
|
|
1559
1609
|
);
|
|
1610
|
+
if (tooltipContent === null) {
|
|
1611
|
+
return chip;
|
|
1612
|
+
}
|
|
1613
|
+
return /* @__PURE__ */ import_react16.default.createElement(Tooltip, { content: tooltipContent, open: tooltipOpen, side: "top" }, chip);
|
|
1560
1614
|
}
|
|
1561
1615
|
);
|
|
1562
1616
|
FileChip.displayName = "FileChip";
|
|
@@ -1569,6 +1623,7 @@ var AttachmentPreview = import_react17.default.forwardRef(
|
|
|
1569
1623
|
onRemove,
|
|
1570
1624
|
removable = true,
|
|
1571
1625
|
maxVisible,
|
|
1626
|
+
onOpen,
|
|
1572
1627
|
className,
|
|
1573
1628
|
...rest
|
|
1574
1629
|
}, ref) => {
|
|
@@ -1597,7 +1652,9 @@ var AttachmentPreview = import_react17.default.forwardRef(
|
|
|
1597
1652
|
previewUrl: attachment.previewUrl,
|
|
1598
1653
|
error: attachment.error,
|
|
1599
1654
|
removable,
|
|
1600
|
-
onRemove: onRemove ? () => onRemove(attachment.id) : void 0
|
|
1655
|
+
onRemove: onRemove ? () => onRemove(attachment.id) : void 0,
|
|
1656
|
+
artifactId: attachment.artifactId,
|
|
1657
|
+
onOpen
|
|
1601
1658
|
}
|
|
1602
1659
|
)),
|
|
1603
1660
|
hiddenCount > 0 && /* @__PURE__ */ import_react17.default.createElement(
|
|
@@ -4049,6 +4106,8 @@ var Message = import_react56.default.forwardRef(
|
|
|
4049
4106
|
branchInfo,
|
|
4050
4107
|
actions,
|
|
4051
4108
|
hideActions,
|
|
4109
|
+
attachments,
|
|
4110
|
+
onAttachmentOpen,
|
|
4052
4111
|
...rest
|
|
4053
4112
|
}, ref) => {
|
|
4054
4113
|
const isUser = variant === "user";
|
|
@@ -4116,6 +4175,14 @@ var Message = import_react56.default.forwardRef(
|
|
|
4116
4175
|
),
|
|
4117
4176
|
...rest
|
|
4118
4177
|
},
|
|
4178
|
+
attachments && attachments.length > 0 && /* @__PURE__ */ import_react56.default.createElement("div", { className: cx("mb-1.5", isUser ? "self-end" : "self-start") }, /* @__PURE__ */ import_react56.default.createElement(
|
|
4179
|
+
AttachmentPreview,
|
|
4180
|
+
{
|
|
4181
|
+
attachments,
|
|
4182
|
+
removable: false,
|
|
4183
|
+
onOpen: onAttachmentOpen
|
|
4184
|
+
}
|
|
4185
|
+
)),
|
|
4119
4186
|
isUser && isEditing ? /* @__PURE__ */ import_react56.default.createElement("div", { className: "w-full max-w-11/12" }, /* @__PURE__ */ import_react56.default.createElement("div", { className: "relative bg-gold" }, /* @__PURE__ */ import_react56.default.createElement(
|
|
4120
4187
|
"textarea",
|
|
4121
4188
|
{
|
|
@@ -4366,6 +4433,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4366
4433
|
isVisible = true,
|
|
4367
4434
|
phraseInterval = 2500,
|
|
4368
4435
|
phrases = THINKING_PHRASES,
|
|
4436
|
+
manualLabel,
|
|
4369
4437
|
className,
|
|
4370
4438
|
...rest
|
|
4371
4439
|
}, ref) => {
|
|
@@ -4373,8 +4441,9 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4373
4441
|
() => Math.floor(Math.random() * phrases.length)
|
|
4374
4442
|
);
|
|
4375
4443
|
const [isTransitioning, setIsTransitioning] = (0, import_react60.useState)(false);
|
|
4444
|
+
const isManual = manualLabel !== void 0;
|
|
4376
4445
|
(0, import_react60.useEffect)(() => {
|
|
4377
|
-
if (!isVisible || phrases.length <= 1) {
|
|
4446
|
+
if (!isVisible || isManual || phrases.length <= 1) {
|
|
4378
4447
|
return;
|
|
4379
4448
|
}
|
|
4380
4449
|
let fadeTimeout = null;
|
|
@@ -4392,7 +4461,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4392
4461
|
clearTimeout(fadeTimeout);
|
|
4393
4462
|
}
|
|
4394
4463
|
};
|
|
4395
|
-
}, [isVisible, phrases.length, phraseInterval]);
|
|
4464
|
+
}, [isVisible, isManual, phrases.length, phraseInterval]);
|
|
4396
4465
|
if (!isVisible) {
|
|
4397
4466
|
return null;
|
|
4398
4467
|
}
|
|
@@ -4429,7 +4498,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4429
4498
|
style: { animationDelay: "300ms" }
|
|
4430
4499
|
}
|
|
4431
4500
|
)),
|
|
4432
|
-
/* @__PURE__ */ import_react60.default.createElement(
|
|
4501
|
+
isManual ? /* @__PURE__ */ import_react60.default.createElement("span", { className: "text-sm italic" }, manualLabel) : /* @__PURE__ */ import_react60.default.createElement(
|
|
4433
4502
|
"span",
|
|
4434
4503
|
{
|
|
4435
4504
|
className: cx(
|
|
@@ -4451,13 +4520,15 @@ var KIND_ICONS = {
|
|
|
4451
4520
|
task: import_lucide_react12.GitBranch,
|
|
4452
4521
|
submit: import_lucide_react12.GitMerge,
|
|
4453
4522
|
rename: import_lucide_react12.PencilLine,
|
|
4454
|
-
init: import_lucide_react12.GitCommitVertical
|
|
4523
|
+
init: import_lucide_react12.GitCommitVertical,
|
|
4524
|
+
ingest: import_lucide_react12.Upload
|
|
4455
4525
|
};
|
|
4456
4526
|
var KIND_ARIA_LABELS = {
|
|
4457
4527
|
task: "Task checkpoint",
|
|
4458
4528
|
submit: "Submit checkpoint",
|
|
4459
4529
|
rename: "Rename checkpoint",
|
|
4460
|
-
init: "Project head checkpoint"
|
|
4530
|
+
init: "Project head checkpoint",
|
|
4531
|
+
ingest: "Upload batch checkpoint"
|
|
4461
4532
|
};
|
|
4462
4533
|
var Checkpoint = import_react61.default.forwardRef(
|
|
4463
4534
|
function Checkpoint2({ name, executionKind, status = "completed", isActive, muted, branchInfo, onJumpHere }, ref) {
|
|
@@ -4606,7 +4677,16 @@ GreyedDivider.displayName = "GreyedDivider";
|
|
|
4606
4677
|
|
|
4607
4678
|
// src/components/chat/ChatView.tsx
|
|
4608
4679
|
var ChatView = import_react63.default.forwardRef(
|
|
4609
|
-
function ChatView2({
|
|
4680
|
+
function ChatView2({
|
|
4681
|
+
items,
|
|
4682
|
+
latestUserMessageIndex,
|
|
4683
|
+
isStreaming,
|
|
4684
|
+
isThinking,
|
|
4685
|
+
thinkingLabel,
|
|
4686
|
+
onScroll,
|
|
4687
|
+
className,
|
|
4688
|
+
...rest
|
|
4689
|
+
}, ref) {
|
|
4610
4690
|
const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
|
|
4611
4691
|
behavior: "smooth",
|
|
4612
4692
|
block: "start"
|
|
@@ -4689,7 +4769,7 @@ var ChatView = import_react63.default.forwardRef(
|
|
|
4689
4769
|
}
|
|
4690
4770
|
)
|
|
4691
4771
|
);
|
|
4692
|
-
}), showThinking && /* @__PURE__ */ import_react63.default.createElement(ThinkingIndicator, { isVisible: true })),
|
|
4772
|
+
}), showThinking && /* @__PURE__ */ import_react63.default.createElement(ThinkingIndicator, { isVisible: true, manualLabel: thinkingLabel })),
|
|
4693
4773
|
/* @__PURE__ */ import_react63.default.createElement(
|
|
4694
4774
|
"div",
|
|
4695
4775
|
{
|
|
@@ -4874,8 +4954,8 @@ var ChatInput = import_react64.default.forwardRef(
|
|
|
4874
4954
|
);
|
|
4875
4955
|
const isCentered = position === "centered";
|
|
4876
4956
|
const hasAttachments = attachments.length > 0;
|
|
4877
|
-
const
|
|
4878
|
-
const canSubmit = value.trim() && !disabled && !isStreaming && !
|
|
4957
|
+
const isUploadIncomplete = attachments.some((a) => a.status === "pending" || a.status === "uploading" || a.status === "upload_failed");
|
|
4958
|
+
const canSubmit = value.trim() && !disabled && !isStreaming && !isUploadIncomplete;
|
|
4879
4959
|
return /* @__PURE__ */ import_react64.default.createElement(
|
|
4880
4960
|
"div",
|
|
4881
4961
|
{
|
|
@@ -5012,7 +5092,7 @@ var ChatInput = import_react64.default.forwardRef(
|
|
|
5012
5092
|
ChatInput.displayName = "ChatInput";
|
|
5013
5093
|
|
|
5014
5094
|
// src/components/chat/ArtifactsPanel.tsx
|
|
5015
|
-
var
|
|
5095
|
+
var import_react76 = __toESM(require("react"));
|
|
5016
5096
|
var import_lucide_react17 = require("lucide-react");
|
|
5017
5097
|
|
|
5018
5098
|
// src/components/ArtifactCard.tsx
|
|
@@ -5670,15 +5750,74 @@ var ArtifactVariantStack = import_react73.default.forwardRef(
|
|
|
5670
5750
|
);
|
|
5671
5751
|
ArtifactVariantStack.displayName = "ArtifactVariantStack";
|
|
5672
5752
|
|
|
5673
|
-
// src/components/chat/hooks/
|
|
5753
|
+
// src/components/chat/hooks/useResizable.ts
|
|
5674
5754
|
var import_react74 = require("react");
|
|
5755
|
+
function useResizable({
|
|
5756
|
+
initialWidthPercent,
|
|
5757
|
+
minWidthPercent,
|
|
5758
|
+
maxWidthPercent,
|
|
5759
|
+
direction
|
|
5760
|
+
}) {
|
|
5761
|
+
const [widthPercent, setWidthPercent] = (0, import_react74.useState)(initialWidthPercent);
|
|
5762
|
+
const [isResizing, setIsResizing] = (0, import_react74.useState)(false);
|
|
5763
|
+
const lastX = (0, import_react74.useRef)(null);
|
|
5764
|
+
const startResizing = (0, import_react74.useCallback)((e) => {
|
|
5765
|
+
e.preventDefault();
|
|
5766
|
+
setIsResizing(true);
|
|
5767
|
+
lastX.current = e.clientX;
|
|
5768
|
+
}, []);
|
|
5769
|
+
const stopResizing = (0, import_react74.useCallback)(() => {
|
|
5770
|
+
setIsResizing(false);
|
|
5771
|
+
lastX.current = null;
|
|
5772
|
+
}, []);
|
|
5773
|
+
const resize = (0, import_react74.useCallback)(
|
|
5774
|
+
(e) => {
|
|
5775
|
+
if (!isResizing || lastX.current === null) {
|
|
5776
|
+
return;
|
|
5777
|
+
}
|
|
5778
|
+
const deltaX = e.clientX - lastX.current;
|
|
5779
|
+
const factor = direction === "right" ? 1 : -1;
|
|
5780
|
+
const deltaPercent = deltaX / window.innerWidth * 100;
|
|
5781
|
+
setWidthPercent((prevPercent) => {
|
|
5782
|
+
const newPercent = prevPercent + deltaPercent * factor;
|
|
5783
|
+
return Math.min(Math.max(newPercent, minWidthPercent), maxWidthPercent);
|
|
5784
|
+
});
|
|
5785
|
+
lastX.current = e.clientX;
|
|
5786
|
+
},
|
|
5787
|
+
[isResizing, direction, minWidthPercent, maxWidthPercent]
|
|
5788
|
+
);
|
|
5789
|
+
(0, import_react74.useEffect)(() => {
|
|
5790
|
+
if (isResizing) {
|
|
5791
|
+
window.addEventListener("mousemove", resize);
|
|
5792
|
+
window.addEventListener("mouseup", stopResizing);
|
|
5793
|
+
document.body.style.cursor = "col-resize";
|
|
5794
|
+
document.body.style.userSelect = "none";
|
|
5795
|
+
} else {
|
|
5796
|
+
window.removeEventListener("mousemove", resize);
|
|
5797
|
+
window.removeEventListener("mouseup", stopResizing);
|
|
5798
|
+
document.body.style.cursor = "";
|
|
5799
|
+
document.body.style.userSelect = "";
|
|
5800
|
+
}
|
|
5801
|
+
return () => {
|
|
5802
|
+
window.removeEventListener("mousemove", resize);
|
|
5803
|
+
window.removeEventListener("mouseup", stopResizing);
|
|
5804
|
+
document.body.style.cursor = "";
|
|
5805
|
+
document.body.style.userSelect = "";
|
|
5806
|
+
};
|
|
5807
|
+
}, [isResizing, resize, stopResizing]);
|
|
5808
|
+
const width = `${widthPercent}vw`;
|
|
5809
|
+
return { width, widthPercent, isResizing, startResizing };
|
|
5810
|
+
}
|
|
5811
|
+
|
|
5812
|
+
// src/components/chat/hooks/useArtifactTreeNavigation.ts
|
|
5813
|
+
var import_react75 = require("react");
|
|
5675
5814
|
function useArtifactTreeNavigation(rootNodes) {
|
|
5676
|
-
const [stack, setStack] = (0,
|
|
5677
|
-
const currentNodes = (0,
|
|
5815
|
+
const [stack, setStack] = (0, import_react75.useState)([]);
|
|
5816
|
+
const currentNodes = (0, import_react75.useMemo)(() => {
|
|
5678
5817
|
if (stack.length === 0) return rootNodes;
|
|
5679
5818
|
return stack[stack.length - 1].children;
|
|
5680
5819
|
}, [rootNodes, stack]);
|
|
5681
|
-
const breadcrumbs = (0,
|
|
5820
|
+
const breadcrumbs = (0, import_react75.useMemo)(() => {
|
|
5682
5821
|
const entries = [{ label: "Project", node: null }];
|
|
5683
5822
|
for (const node of stack) {
|
|
5684
5823
|
entries.push({ label: node.label, node });
|
|
@@ -5686,13 +5825,13 @@ function useArtifactTreeNavigation(rootNodes) {
|
|
|
5686
5825
|
return entries;
|
|
5687
5826
|
}, [stack]);
|
|
5688
5827
|
const isAtRoot = stack.length === 0;
|
|
5689
|
-
const navigateInto = (0,
|
|
5828
|
+
const navigateInto = (0, import_react75.useCallback)((node) => {
|
|
5690
5829
|
setStack((prev) => [...prev, node]);
|
|
5691
5830
|
}, []);
|
|
5692
|
-
const navigateTo = (0,
|
|
5831
|
+
const navigateTo = (0, import_react75.useCallback)((index) => {
|
|
5693
5832
|
setStack((prev) => prev.slice(0, index));
|
|
5694
5833
|
}, []);
|
|
5695
|
-
const navigateBack = (0,
|
|
5834
|
+
const navigateBack = (0, import_react75.useCallback)(() => {
|
|
5696
5835
|
setStack((prev) => prev.slice(0, -1));
|
|
5697
5836
|
}, []);
|
|
5698
5837
|
return {
|
|
@@ -5712,46 +5851,46 @@ function ArtifactModal({
|
|
|
5712
5851
|
onClose
|
|
5713
5852
|
}) {
|
|
5714
5853
|
useEscapeKey(onClose);
|
|
5715
|
-
const handleBackdropClick = (0,
|
|
5854
|
+
const handleBackdropClick = (0, import_react76.useCallback)((e) => {
|
|
5716
5855
|
if (e.target === e.currentTarget) {
|
|
5717
5856
|
onClose();
|
|
5718
5857
|
}
|
|
5719
5858
|
}, [onClose]);
|
|
5720
|
-
return /* @__PURE__ */
|
|
5859
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5721
5860
|
"div",
|
|
5722
5861
|
{
|
|
5723
5862
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
|
|
5724
5863
|
onClick: handleBackdropClick
|
|
5725
5864
|
},
|
|
5726
|
-
/* @__PURE__ */
|
|
5865
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5727
5866
|
"div",
|
|
5728
5867
|
{
|
|
5729
5868
|
className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
|
|
5730
5869
|
},
|
|
5731
|
-
/* @__PURE__ */
|
|
5870
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5732
5871
|
"div",
|
|
5733
5872
|
{
|
|
5734
5873
|
className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
|
|
5735
5874
|
},
|
|
5736
|
-
/* @__PURE__ */
|
|
5737
|
-
/* @__PURE__ */
|
|
5875
|
+
/* @__PURE__ */ import_react76.default.createElement("div", null, artifact.title && /* @__PURE__ */ import_react76.default.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ import_react76.default.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
|
|
5876
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5738
5877
|
"button",
|
|
5739
5878
|
{
|
|
5740
5879
|
onClick: onClose,
|
|
5741
5880
|
className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
|
|
5742
5881
|
"aria-label": "Close modal"
|
|
5743
5882
|
},
|
|
5744
|
-
/* @__PURE__ */
|
|
5883
|
+
/* @__PURE__ */ import_react76.default.createElement(CloseIcon, { className: "w-5 h-5" })
|
|
5745
5884
|
)
|
|
5746
5885
|
),
|
|
5747
|
-
/* @__PURE__ */
|
|
5886
|
+
/* @__PURE__ */ import_react76.default.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5748
5887
|
"img",
|
|
5749
5888
|
{
|
|
5750
5889
|
src: artifact.url,
|
|
5751
5890
|
alt: artifact.alt || "Artifact image",
|
|
5752
5891
|
className: "max-w-full max-h-full object-contain mx-auto"
|
|
5753
5892
|
}
|
|
5754
|
-
), artifact.type === "VIDEO" && /* @__PURE__ */
|
|
5893
|
+
), artifact.type === "VIDEO" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5755
5894
|
VideoCard,
|
|
5756
5895
|
{
|
|
5757
5896
|
src: artifact.url || "",
|
|
@@ -5759,20 +5898,20 @@ function ArtifactModal({
|
|
|
5759
5898
|
controls: true,
|
|
5760
5899
|
className: "max-w-full max-h-full mx-auto"
|
|
5761
5900
|
}
|
|
5762
|
-
), artifact.type === "AUDIO" && /* @__PURE__ */
|
|
5901
|
+
), artifact.type === "AUDIO" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5763
5902
|
AudioCard,
|
|
5764
5903
|
{
|
|
5765
5904
|
src: artifact.url || "",
|
|
5766
5905
|
controls: true,
|
|
5767
5906
|
className: "max-w-xl mx-auto"
|
|
5768
5907
|
}
|
|
5769
|
-
), artifact.type === "PDF" && /* @__PURE__ */
|
|
5908
|
+
), artifact.type === "PDF" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5770
5909
|
PdfCard,
|
|
5771
5910
|
{
|
|
5772
5911
|
src: artifact.url || "",
|
|
5773
5912
|
className: "h-full border-0"
|
|
5774
5913
|
}
|
|
5775
|
-
), artifact.type === "TEXT" && /* @__PURE__ */
|
|
5914
|
+
), artifact.type === "TEXT" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5776
5915
|
MarkdownContent,
|
|
5777
5916
|
{
|
|
5778
5917
|
content: artifact.inlineContent || "",
|
|
@@ -5782,7 +5921,7 @@ function ArtifactModal({
|
|
|
5782
5921
|
artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
|
|
5783
5922
|
)
|
|
5784
5923
|
}
|
|
5785
|
-
), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */
|
|
5924
|
+
), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react76.default.createElement(
|
|
5786
5925
|
ScriptCard,
|
|
5787
5926
|
{
|
|
5788
5927
|
elements: artifact.scriptElements,
|
|
@@ -5793,6 +5932,20 @@ function ArtifactModal({
|
|
|
5793
5932
|
)
|
|
5794
5933
|
);
|
|
5795
5934
|
}
|
|
5935
|
+
function findArtifactInNodes(nodes, artifactId) {
|
|
5936
|
+
for (const node of nodes) {
|
|
5937
|
+
if (node.type === "ARTIFACT" && node.artifact?.id === artifactId) {
|
|
5938
|
+
return node.artifact;
|
|
5939
|
+
}
|
|
5940
|
+
if (node.children && node.children.length > 0) {
|
|
5941
|
+
const found = findArtifactInNodes(node.children, artifactId);
|
|
5942
|
+
if (found) {
|
|
5943
|
+
return found;
|
|
5944
|
+
}
|
|
5945
|
+
}
|
|
5946
|
+
}
|
|
5947
|
+
return null;
|
|
5948
|
+
}
|
|
5796
5949
|
function NodeRenderer({
|
|
5797
5950
|
node,
|
|
5798
5951
|
loading,
|
|
@@ -5800,7 +5953,7 @@ function NodeRenderer({
|
|
|
5800
5953
|
onGroupClick
|
|
5801
5954
|
}) {
|
|
5802
5955
|
if (node.type === "ARTIFACT" && node.artifact) {
|
|
5803
|
-
return /* @__PURE__ */
|
|
5956
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5804
5957
|
ArtifactCard,
|
|
5805
5958
|
{
|
|
5806
5959
|
artifact: node.artifact,
|
|
@@ -5810,10 +5963,10 @@ function NodeRenderer({
|
|
|
5810
5963
|
);
|
|
5811
5964
|
}
|
|
5812
5965
|
if (node.type === "GROUP") {
|
|
5813
|
-
return /* @__PURE__ */
|
|
5966
|
+
return /* @__PURE__ */ import_react76.default.createElement(ArtifactGroup, { node, onClick: onGroupClick });
|
|
5814
5967
|
}
|
|
5815
5968
|
if (node.type === "VARIANT_SET") {
|
|
5816
|
-
return /* @__PURE__ */
|
|
5969
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5817
5970
|
ArtifactVariantStack,
|
|
5818
5971
|
{
|
|
5819
5972
|
node,
|
|
@@ -5824,42 +5977,59 @@ function NodeRenderer({
|
|
|
5824
5977
|
}
|
|
5825
5978
|
return null;
|
|
5826
5979
|
}
|
|
5827
|
-
var ArtifactsPanel =
|
|
5980
|
+
var ArtifactsPanel = import_react76.default.forwardRef(
|
|
5828
5981
|
({
|
|
5829
5982
|
nodes,
|
|
5830
5983
|
loading,
|
|
5984
|
+
openArtifactId,
|
|
5985
|
+
onArtifactClosed,
|
|
5831
5986
|
className,
|
|
5832
5987
|
...rest
|
|
5833
5988
|
}, ref) => {
|
|
5834
|
-
const [expandedArtifact, setExpandedArtifact] = (0,
|
|
5835
|
-
const [zoomIndex, setZoomIndex] = (0,
|
|
5989
|
+
const [expandedArtifact, setExpandedArtifact] = (0, import_react76.useState)(null);
|
|
5990
|
+
const [zoomIndex, setZoomIndex] = (0, import_react76.useState)(ZOOM_LEVELS.length - 1);
|
|
5836
5991
|
const treeNav = useArtifactTreeNavigation(nodes || []);
|
|
5837
5992
|
const hasNodes = !!nodes && nodes.length > 0;
|
|
5838
|
-
const handleExpandArtifact = (0,
|
|
5993
|
+
const handleExpandArtifact = (0, import_react76.useCallback)((artifact) => {
|
|
5839
5994
|
setExpandedArtifact(artifact);
|
|
5840
5995
|
}, []);
|
|
5841
|
-
const handleGroupClick = (0,
|
|
5996
|
+
const handleGroupClick = (0, import_react76.useCallback)((node) => {
|
|
5842
5997
|
treeNav.navigateInto(node);
|
|
5843
5998
|
}, [treeNav]);
|
|
5844
|
-
|
|
5999
|
+
(0, import_react76.useEffect)(() => {
|
|
6000
|
+
if (!openArtifactId || !nodes) {
|
|
6001
|
+
return;
|
|
6002
|
+
}
|
|
6003
|
+
const found = findArtifactInNodes(nodes, openArtifactId);
|
|
6004
|
+
if (found) {
|
|
6005
|
+
setExpandedArtifact(found);
|
|
6006
|
+
}
|
|
6007
|
+
}, [openArtifactId, nodes]);
|
|
6008
|
+
const handleModalClose = (0, import_react76.useCallback)(() => {
|
|
6009
|
+
setExpandedArtifact(null);
|
|
6010
|
+
onArtifactClosed?.();
|
|
6011
|
+
}, [onArtifactClosed]);
|
|
6012
|
+
const zoomIn = (0, import_react76.useCallback)(() => {
|
|
5845
6013
|
setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
|
|
5846
6014
|
}, []);
|
|
5847
|
-
const zoomOut = (0,
|
|
6015
|
+
const zoomOut = (0, import_react76.useCallback)(() => {
|
|
5848
6016
|
setZoomIndex((prev) => Math.max(prev - 1, 0));
|
|
5849
6017
|
}, []);
|
|
5850
6018
|
const currentZoom = ZOOM_LEVELS[zoomIndex];
|
|
5851
|
-
const contentRef = (0,
|
|
5852
|
-
const [contentHeight, setContentHeight] = (0,
|
|
5853
|
-
(0,
|
|
6019
|
+
const contentRef = (0, import_react76.useRef)(null);
|
|
6020
|
+
const [contentHeight, setContentHeight] = (0, import_react76.useState)(void 0);
|
|
6021
|
+
(0, import_react76.useEffect)(() => {
|
|
5854
6022
|
const el = contentRef.current;
|
|
5855
|
-
if (!el)
|
|
6023
|
+
if (!el) {
|
|
6024
|
+
return;
|
|
6025
|
+
}
|
|
5856
6026
|
const observer = new ResizeObserver(([entry]) => {
|
|
5857
6027
|
setContentHeight(entry.contentRect.height);
|
|
5858
6028
|
});
|
|
5859
6029
|
observer.observe(el);
|
|
5860
6030
|
return () => observer.disconnect();
|
|
5861
6031
|
}, []);
|
|
5862
|
-
return /* @__PURE__ */
|
|
6032
|
+
return /* @__PURE__ */ import_react76.default.createElement(import_react76.default.Fragment, null, /* @__PURE__ */ import_react76.default.createElement(
|
|
5863
6033
|
"div",
|
|
5864
6034
|
{
|
|
5865
6035
|
ref,
|
|
@@ -5870,19 +6040,19 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5870
6040
|
),
|
|
5871
6041
|
...rest
|
|
5872
6042
|
},
|
|
5873
|
-
/* @__PURE__ */
|
|
6043
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5874
6044
|
"div",
|
|
5875
6045
|
{
|
|
5876
6046
|
className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
|
|
5877
6047
|
},
|
|
5878
|
-
/* @__PURE__ */
|
|
5879
|
-
hasNodes && /* @__PURE__ */
|
|
6048
|
+
/* @__PURE__ */ import_react76.default.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
|
|
6049
|
+
hasNodes && /* @__PURE__ */ import_react76.default.createElement(
|
|
5880
6050
|
"div",
|
|
5881
6051
|
{
|
|
5882
6052
|
className: "flex items-center gap-0.5",
|
|
5883
6053
|
"data-testid": "zoom-controls"
|
|
5884
6054
|
},
|
|
5885
|
-
/* @__PURE__ */
|
|
6055
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5886
6056
|
"button",
|
|
5887
6057
|
{
|
|
5888
6058
|
onClick: zoomOut,
|
|
@@ -5896,8 +6066,16 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5896
6066
|
},
|
|
5897
6067
|
"\u2212"
|
|
5898
6068
|
),
|
|
5899
|
-
/* @__PURE__ */
|
|
5900
|
-
|
|
6069
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
6070
|
+
"span",
|
|
6071
|
+
{
|
|
6072
|
+
className: "text-xs text-silver w-8 text-center tabular-nums",
|
|
6073
|
+
"data-testid": "zoom-level"
|
|
6074
|
+
},
|
|
6075
|
+
Math.round(currentZoom * 100),
|
|
6076
|
+
"%"
|
|
6077
|
+
),
|
|
6078
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5901
6079
|
"button",
|
|
5902
6080
|
{
|
|
5903
6081
|
onClick: zoomIn,
|
|
@@ -5913,7 +6091,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5913
6091
|
)
|
|
5914
6092
|
)
|
|
5915
6093
|
),
|
|
5916
|
-
hasNodes && !treeNav.isAtRoot && /* @__PURE__ */
|
|
6094
|
+
hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ import_react76.default.createElement(
|
|
5917
6095
|
"nav",
|
|
5918
6096
|
{
|
|
5919
6097
|
className: "flex items-center gap-1 px-4 py-2 border-b border-ash/40 shrink-0 overflow-x-auto text-xs",
|
|
@@ -5922,7 +6100,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5922
6100
|
},
|
|
5923
6101
|
treeNav.breadcrumbs.map((crumb, i) => {
|
|
5924
6102
|
const isLast = i === treeNav.breadcrumbs.length - 1;
|
|
5925
|
-
return /* @__PURE__ */
|
|
6103
|
+
return /* @__PURE__ */ import_react76.default.createElement("span", { key: i, className: "flex items-center gap-1 shrink-0" }, i > 0 && /* @__PURE__ */ import_react76.default.createElement(ChevronRightIcon, { className: "w-3 h-3 text-silver/50", "aria-hidden": true }), isLast ? /* @__PURE__ */ import_react76.default.createElement("span", { className: "text-gold font-medium" }, crumb.label) : /* @__PURE__ */ import_react76.default.createElement(
|
|
5926
6104
|
"button",
|
|
5927
6105
|
{
|
|
5928
6106
|
onClick: () => treeNav.navigateTo(i),
|
|
@@ -5932,18 +6110,18 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5932
6110
|
));
|
|
5933
6111
|
})
|
|
5934
6112
|
),
|
|
5935
|
-
/* @__PURE__ */
|
|
6113
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5936
6114
|
"div",
|
|
5937
6115
|
{
|
|
5938
6116
|
className: "flex-1 overflow-auto relative",
|
|
5939
6117
|
"data-testid": "artifacts-scroll-area"
|
|
5940
6118
|
},
|
|
5941
|
-
/* @__PURE__ */
|
|
6119
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5942
6120
|
"div",
|
|
5943
6121
|
{
|
|
5944
6122
|
style: currentZoom !== 1 && contentHeight !== void 0 ? { height: contentHeight * currentZoom } : void 0
|
|
5945
6123
|
},
|
|
5946
|
-
/* @__PURE__ */
|
|
6124
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5947
6125
|
"div",
|
|
5948
6126
|
{
|
|
5949
6127
|
ref: contentRef,
|
|
@@ -5954,7 +6132,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5954
6132
|
transformOrigin: "top center"
|
|
5955
6133
|
} : void 0
|
|
5956
6134
|
},
|
|
5957
|
-
treeNav.currentNodes.length === 0 ? /* @__PURE__ */
|
|
6135
|
+
treeNav.currentNodes.length === 0 ? /* @__PURE__ */ import_react76.default.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, hasNodes ? "Empty group" : "No artifacts to display") : treeNav.currentNodes.map((node) => /* @__PURE__ */ import_react76.default.createElement(
|
|
5958
6136
|
NodeRenderer,
|
|
5959
6137
|
{
|
|
5960
6138
|
key: node.id,
|
|
@@ -5967,18 +6145,18 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5967
6145
|
)
|
|
5968
6146
|
)
|
|
5969
6147
|
)
|
|
5970
|
-
), expandedArtifact && /* @__PURE__ */
|
|
6148
|
+
), expandedArtifact && /* @__PURE__ */ import_react76.default.createElement(
|
|
5971
6149
|
ArtifactModal,
|
|
5972
6150
|
{
|
|
5973
6151
|
artifact: expandedArtifact,
|
|
5974
|
-
onClose:
|
|
6152
|
+
onClose: handleModalClose
|
|
5975
6153
|
}
|
|
5976
6154
|
));
|
|
5977
6155
|
}
|
|
5978
6156
|
);
|
|
5979
6157
|
ArtifactsPanel.displayName = "ArtifactsPanel";
|
|
5980
|
-
var ArtifactsPanelToggle =
|
|
5981
|
-
return /* @__PURE__ */
|
|
6158
|
+
var ArtifactsPanelToggle = import_react76.default.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
|
|
6159
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5982
6160
|
"button",
|
|
5983
6161
|
{
|
|
5984
6162
|
ref,
|
|
@@ -5995,8 +6173,8 @@ var ArtifactsPanelToggle = import_react75.default.forwardRef(({ artifactCount =
|
|
|
5995
6173
|
"aria-label": "Expand artifacts panel",
|
|
5996
6174
|
...rest
|
|
5997
6175
|
},
|
|
5998
|
-
/* @__PURE__ */
|
|
5999
|
-
artifactCount > 0 && /* @__PURE__ */
|
|
6176
|
+
/* @__PURE__ */ import_react76.default.createElement(import_lucide_react17.Image, { className: "w-5 h-5", "aria-hidden": true }),
|
|
6177
|
+
artifactCount > 0 && /* @__PURE__ */ import_react76.default.createElement(
|
|
6000
6178
|
"span",
|
|
6001
6179
|
{
|
|
6002
6180
|
className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center"
|
|
@@ -6008,7 +6186,7 @@ var ArtifactsPanelToggle = import_react75.default.forwardRef(({ artifactCount =
|
|
|
6008
6186
|
ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
|
|
6009
6187
|
|
|
6010
6188
|
// src/components/chat/HistoryPanel.tsx
|
|
6011
|
-
var
|
|
6189
|
+
var import_react77 = __toESM(require("react"));
|
|
6012
6190
|
var import_lucide_react18 = require("lucide-react");
|
|
6013
6191
|
function parseTimestamp(ts) {
|
|
6014
6192
|
if (ts == null) {
|
|
@@ -6051,12 +6229,12 @@ function ProjectFilter({
|
|
|
6051
6229
|
onChange,
|
|
6052
6230
|
className
|
|
6053
6231
|
}) {
|
|
6054
|
-
const [open, setOpen] = (0,
|
|
6055
|
-
const ref = (0,
|
|
6056
|
-
const closeFilter = (0,
|
|
6232
|
+
const [open, setOpen] = (0, import_react77.useState)(false);
|
|
6233
|
+
const ref = (0, import_react77.useRef)(null);
|
|
6234
|
+
const closeFilter = (0, import_react77.useCallback)(() => setOpen(false), []);
|
|
6057
6235
|
useClickOutside(ref, closeFilter, open);
|
|
6058
6236
|
const label = value ?? "All projects";
|
|
6059
|
-
return /* @__PURE__ */
|
|
6237
|
+
return /* @__PURE__ */ import_react77.default.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ import_react77.default.createElement(
|
|
6060
6238
|
"button",
|
|
6061
6239
|
{
|
|
6062
6240
|
type: "button",
|
|
@@ -6072,9 +6250,9 @@ function ProjectFilter({
|
|
|
6072
6250
|
"transition-colors duration-150 min-w-0"
|
|
6073
6251
|
)
|
|
6074
6252
|
},
|
|
6075
|
-
/* @__PURE__ */
|
|
6076
|
-
/* @__PURE__ */
|
|
6077
|
-
), open && /* @__PURE__ */
|
|
6253
|
+
/* @__PURE__ */ import_react77.default.createElement("span", { className: "truncate" }, label),
|
|
6254
|
+
/* @__PURE__ */ import_react77.default.createElement(import_lucide_react18.ChevronDown, { className: "w-3 h-3 shrink-0", "aria-hidden": true })
|
|
6255
|
+
), open && /* @__PURE__ */ import_react77.default.createElement(
|
|
6078
6256
|
"div",
|
|
6079
6257
|
{
|
|
6080
6258
|
role: "listbox",
|
|
@@ -6084,7 +6262,7 @@ function ProjectFilter({
|
|
|
6084
6262
|
"max-h-60 overflow-y-auto"
|
|
6085
6263
|
)
|
|
6086
6264
|
},
|
|
6087
|
-
/* @__PURE__ */
|
|
6265
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6088
6266
|
"button",
|
|
6089
6267
|
{
|
|
6090
6268
|
type: "button",
|
|
@@ -6102,7 +6280,7 @@ function ProjectFilter({
|
|
|
6102
6280
|
},
|
|
6103
6281
|
"All projects"
|
|
6104
6282
|
),
|
|
6105
|
-
projects.map((p) => /* @__PURE__ */
|
|
6283
|
+
projects.map((p) => /* @__PURE__ */ import_react77.default.createElement(
|
|
6106
6284
|
"button",
|
|
6107
6285
|
{
|
|
6108
6286
|
key: p,
|
|
@@ -6128,33 +6306,33 @@ function ConversationRow({
|
|
|
6128
6306
|
onSelect,
|
|
6129
6307
|
onRename
|
|
6130
6308
|
}) {
|
|
6131
|
-
const [isEditing, setIsEditing] = (0,
|
|
6132
|
-
const [draft, setDraft] = (0,
|
|
6133
|
-
const inputRef = (0,
|
|
6134
|
-
(0,
|
|
6309
|
+
const [isEditing, setIsEditing] = (0, import_react77.useState)(false);
|
|
6310
|
+
const [draft, setDraft] = (0, import_react77.useState)(conversation.title);
|
|
6311
|
+
const inputRef = (0, import_react77.useRef)(null);
|
|
6312
|
+
(0, import_react77.useEffect)(() => {
|
|
6135
6313
|
if (isEditing && inputRef.current) {
|
|
6136
6314
|
inputRef.current.focus();
|
|
6137
6315
|
inputRef.current.select();
|
|
6138
6316
|
}
|
|
6139
6317
|
}, [isEditing]);
|
|
6140
|
-
const startEdit = (0,
|
|
6318
|
+
const startEdit = (0, import_react77.useCallback)((e) => {
|
|
6141
6319
|
e.stopPropagation();
|
|
6142
6320
|
setDraft(conversation.title);
|
|
6143
6321
|
setIsEditing(true);
|
|
6144
6322
|
}, [conversation.title]);
|
|
6145
|
-
const commit = (0,
|
|
6323
|
+
const commit = (0, import_react77.useCallback)(() => {
|
|
6146
6324
|
const trimmed = draft.trim();
|
|
6147
6325
|
if (trimmed && trimmed !== conversation.title) {
|
|
6148
6326
|
onRename?.(conversation.id, trimmed);
|
|
6149
6327
|
}
|
|
6150
6328
|
setIsEditing(false);
|
|
6151
6329
|
}, [draft, conversation.id, conversation.title, onRename]);
|
|
6152
|
-
const cancel = (0,
|
|
6330
|
+
const cancel = (0, import_react77.useCallback)(() => {
|
|
6153
6331
|
setDraft(conversation.title);
|
|
6154
6332
|
setIsEditing(false);
|
|
6155
6333
|
}, [conversation.title]);
|
|
6156
6334
|
if (isEditing) {
|
|
6157
|
-
return /* @__PURE__ */
|
|
6335
|
+
return /* @__PURE__ */ import_react77.default.createElement(
|
|
6158
6336
|
"div",
|
|
6159
6337
|
{
|
|
6160
6338
|
className: cx(
|
|
@@ -6162,7 +6340,7 @@ function ConversationRow({
|
|
|
6162
6340
|
conversation.isActive ? "bg-ash/40" : "bg-ash/20"
|
|
6163
6341
|
)
|
|
6164
6342
|
},
|
|
6165
|
-
/* @__PURE__ */
|
|
6343
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6166
6344
|
"input",
|
|
6167
6345
|
{
|
|
6168
6346
|
ref: inputRef,
|
|
@@ -6187,10 +6365,10 @@ function ConversationRow({
|
|
|
6187
6365
|
"aria-label": "Conversation title"
|
|
6188
6366
|
}
|
|
6189
6367
|
),
|
|
6190
|
-
conversation.project && /* @__PURE__ */
|
|
6368
|
+
conversation.project && /* @__PURE__ */ import_react77.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-1" }, conversation.project)
|
|
6191
6369
|
);
|
|
6192
6370
|
}
|
|
6193
|
-
return /* @__PURE__ */
|
|
6371
|
+
return /* @__PURE__ */ import_react77.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react77.default.createElement(
|
|
6194
6372
|
"button",
|
|
6195
6373
|
{
|
|
6196
6374
|
onClick: () => onSelect?.(conversation.id),
|
|
@@ -6200,7 +6378,7 @@ function ConversationRow({
|
|
|
6200
6378
|
conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
|
|
6201
6379
|
)
|
|
6202
6380
|
},
|
|
6203
|
-
/* @__PURE__ */
|
|
6381
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6204
6382
|
"p",
|
|
6205
6383
|
{
|
|
6206
6384
|
className: cx(
|
|
@@ -6210,8 +6388,8 @@ function ConversationRow({
|
|
|
6210
6388
|
},
|
|
6211
6389
|
conversation.title
|
|
6212
6390
|
),
|
|
6213
|
-
conversation.project && /* @__PURE__ */
|
|
6214
|
-
), onRename && /* @__PURE__ */
|
|
6391
|
+
conversation.project && /* @__PURE__ */ import_react77.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.project)
|
|
6392
|
+
), onRename && /* @__PURE__ */ import_react77.default.createElement(
|
|
6215
6393
|
"button",
|
|
6216
6394
|
{
|
|
6217
6395
|
type: "button",
|
|
@@ -6224,7 +6402,7 @@ function ConversationRow({
|
|
|
6224
6402
|
"transition-opacity duration-150"
|
|
6225
6403
|
)
|
|
6226
6404
|
},
|
|
6227
|
-
/* @__PURE__ */
|
|
6405
|
+
/* @__PURE__ */ import_react77.default.createElement(import_lucide_react18.Pencil, { className: "w-3.5 h-3.5", "aria-hidden": true })
|
|
6228
6406
|
));
|
|
6229
6407
|
}
|
|
6230
6408
|
function HistoryPanel({
|
|
@@ -6233,8 +6411,8 @@ function HistoryPanel({
|
|
|
6233
6411
|
onNewChat,
|
|
6234
6412
|
onRenameConversation
|
|
6235
6413
|
}) {
|
|
6236
|
-
const [projectFilter, setProjectFilter] = (0,
|
|
6237
|
-
const projects = (0,
|
|
6414
|
+
const [projectFilter, setProjectFilter] = (0, import_react77.useState)(null);
|
|
6415
|
+
const projects = (0, import_react77.useMemo)(() => {
|
|
6238
6416
|
const set = /* @__PURE__ */ new Set();
|
|
6239
6417
|
for (const c of conversations) {
|
|
6240
6418
|
if (c.project) {
|
|
@@ -6243,23 +6421,23 @@ function HistoryPanel({
|
|
|
6243
6421
|
}
|
|
6244
6422
|
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
6245
6423
|
}, [conversations]);
|
|
6246
|
-
(0,
|
|
6424
|
+
(0, import_react77.useEffect)(() => {
|
|
6247
6425
|
if (projectFilter && !projects.includes(projectFilter)) {
|
|
6248
6426
|
setProjectFilter(null);
|
|
6249
6427
|
}
|
|
6250
6428
|
}, [projects, projectFilter]);
|
|
6251
|
-
const filteredConversations = (0,
|
|
6429
|
+
const filteredConversations = (0, import_react77.useMemo)(() => {
|
|
6252
6430
|
if (!projectFilter) {
|
|
6253
6431
|
return conversations;
|
|
6254
6432
|
}
|
|
6255
6433
|
return conversations.filter((c) => c.project === projectFilter);
|
|
6256
6434
|
}, [conversations, projectFilter]);
|
|
6257
|
-
const groups = (0,
|
|
6435
|
+
const groups = (0, import_react77.useMemo)(
|
|
6258
6436
|
() => groupConversations(filteredConversations),
|
|
6259
6437
|
[filteredConversations]
|
|
6260
6438
|
);
|
|
6261
6439
|
const hasFilter = projects.length > 0;
|
|
6262
|
-
return /* @__PURE__ */
|
|
6440
|
+
return /* @__PURE__ */ import_react77.default.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ import_react77.default.createElement("div", { className: "px-4 py-3 border-b border-ash/40 shrink-0 flex items-center gap-2" }, /* @__PURE__ */ import_react77.default.createElement("h3", { className: "text-xs font-medium text-white shrink-0" }, "History"), (hasFilter || onNewChat) && /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex items-center gap-2 flex-1 min-w-0" }, hasFilter && /* @__PURE__ */ import_react77.default.createElement(import_react77.default.Fragment, null, /* @__PURE__ */ import_react77.default.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ import_react77.default.createElement(
|
|
6263
6441
|
ProjectFilter,
|
|
6264
6442
|
{
|
|
6265
6443
|
projects,
|
|
@@ -6267,7 +6445,7 @@ function HistoryPanel({
|
|
|
6267
6445
|
onChange: setProjectFilter,
|
|
6268
6446
|
className: "flex-1"
|
|
6269
6447
|
}
|
|
6270
|
-
)), onNewChat && /* @__PURE__ */
|
|
6448
|
+
)), onNewChat && /* @__PURE__ */ import_react77.default.createElement(import_react77.default.Fragment, null, /* @__PURE__ */ import_react77.default.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ import_react77.default.createElement(
|
|
6271
6449
|
"button",
|
|
6272
6450
|
{
|
|
6273
6451
|
onClick: onNewChat,
|
|
@@ -6279,15 +6457,15 @@ function HistoryPanel({
|
|
|
6279
6457
|
"transition-colors duration-200"
|
|
6280
6458
|
)
|
|
6281
6459
|
},
|
|
6282
|
-
/* @__PURE__ */
|
|
6283
|
-
/* @__PURE__ */
|
|
6284
|
-
)))), /* @__PURE__ */
|
|
6460
|
+
/* @__PURE__ */ import_react77.default.createElement(PlusIcon, { className: "w-4 h-4" }),
|
|
6461
|
+
/* @__PURE__ */ import_react77.default.createElement("span", { className: "truncate" }, "New Chat")
|
|
6462
|
+
)))), /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ import_react77.default.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations yet") : groups.length === 0 ? /* @__PURE__ */ import_react77.default.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations match this filter") : /* @__PURE__ */ import_react77.default.createElement("div", null, groups.map((group, index) => /* @__PURE__ */ import_react77.default.createElement("section", { key: group.key, className: cx(index > 0 && "mt-3") }, /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex items-center gap-2 px-3 pb-2" }, /* @__PURE__ */ import_react77.default.createElement(
|
|
6285
6463
|
"span",
|
|
6286
6464
|
{
|
|
6287
6465
|
className: "text-xs font-medium uppercase tracking-wider text-gold/70"
|
|
6288
6466
|
},
|
|
6289
6467
|
group.label
|
|
6290
|
-
), /* @__PURE__ */
|
|
6468
|
+
), /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex-1 h-px bg-gold/20" })), /* @__PURE__ */ import_react77.default.createElement("div", { className: "space-y-1 px-2" }, group.conversations.map((conversation) => /* @__PURE__ */ import_react77.default.createElement(
|
|
6291
6469
|
ConversationRow,
|
|
6292
6470
|
{
|
|
6293
6471
|
key: conversation.id,
|
|
@@ -6299,7 +6477,7 @@ function HistoryPanel({
|
|
|
6299
6477
|
}
|
|
6300
6478
|
|
|
6301
6479
|
// src/components/chat/TodosList.tsx
|
|
6302
|
-
var
|
|
6480
|
+
var import_react78 = __toESM(require("react"));
|
|
6303
6481
|
var import_lucide_react19 = require("lucide-react");
|
|
6304
6482
|
var TASK_STATUSES = {
|
|
6305
6483
|
PENDING: "pending",
|
|
@@ -6311,16 +6489,16 @@ var TASK_STATUSES = {
|
|
|
6311
6489
|
function TaskIcon({ status }) {
|
|
6312
6490
|
switch (status) {
|
|
6313
6491
|
case "done":
|
|
6314
|
-
return /* @__PURE__ */
|
|
6492
|
+
return /* @__PURE__ */ import_react78.default.createElement(CheckSquareIcon, null);
|
|
6315
6493
|
case "in_progress":
|
|
6316
|
-
return /* @__PURE__ */
|
|
6494
|
+
return /* @__PURE__ */ import_react78.default.createElement(SquareLoaderIcon, null);
|
|
6317
6495
|
case "cancelled":
|
|
6318
|
-
return /* @__PURE__ */
|
|
6496
|
+
return /* @__PURE__ */ import_react78.default.createElement(CrossSquareIcon, { variant: "cancelled" });
|
|
6319
6497
|
case "failed":
|
|
6320
|
-
return /* @__PURE__ */
|
|
6498
|
+
return /* @__PURE__ */ import_react78.default.createElement(CrossSquareIcon, { variant: "failed" });
|
|
6321
6499
|
case "pending":
|
|
6322
6500
|
default:
|
|
6323
|
-
return /* @__PURE__ */
|
|
6501
|
+
return /* @__PURE__ */ import_react78.default.createElement(EmptySquareIcon, null);
|
|
6324
6502
|
}
|
|
6325
6503
|
}
|
|
6326
6504
|
function sortTasks(tasks) {
|
|
@@ -6340,14 +6518,14 @@ function TaskItem({ task, depth = 0 }) {
|
|
|
6340
6518
|
const isSubtle = task.status === "cancelled" || task.status === "failed";
|
|
6341
6519
|
const showSubtasks = task.subtasks && task.subtasks.length > 0;
|
|
6342
6520
|
const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
|
|
6343
|
-
return /* @__PURE__ */
|
|
6521
|
+
return /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react78.default.createElement(
|
|
6344
6522
|
"div",
|
|
6345
6523
|
{
|
|
6346
6524
|
className: "flex items-center gap-2 py-1",
|
|
6347
6525
|
style: { paddingLeft: `${depth * 1.5}rem` }
|
|
6348
6526
|
},
|
|
6349
|
-
/* @__PURE__ */
|
|
6350
|
-
/* @__PURE__ */
|
|
6527
|
+
/* @__PURE__ */ import_react78.default.createElement(TaskIcon, { status: task.status }),
|
|
6528
|
+
/* @__PURE__ */ import_react78.default.createElement(
|
|
6351
6529
|
"span",
|
|
6352
6530
|
{
|
|
6353
6531
|
className: cx(
|
|
@@ -6359,10 +6537,10 @@ function TaskItem({ task, depth = 0 }) {
|
|
|
6359
6537
|
)
|
|
6360
6538
|
},
|
|
6361
6539
|
task.label,
|
|
6362
|
-
task.status === "cancelled" && /* @__PURE__ */
|
|
6363
|
-
task.status === "failed" && /* @__PURE__ */
|
|
6540
|
+
task.status === "cancelled" && /* @__PURE__ */ import_react78.default.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
|
|
6541
|
+
task.status === "failed" && /* @__PURE__ */ import_react78.default.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
|
|
6364
6542
|
)
|
|
6365
|
-
), showSubtasks && /* @__PURE__ */
|
|
6543
|
+
), showSubtasks && /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ import_react78.default.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
|
|
6366
6544
|
}
|
|
6367
6545
|
function hasInProgressTask(tasks) {
|
|
6368
6546
|
return tasks.some((t) => {
|
|
@@ -6375,11 +6553,11 @@ function hasInProgressTask(tasks) {
|
|
|
6375
6553
|
return false;
|
|
6376
6554
|
});
|
|
6377
6555
|
}
|
|
6378
|
-
var TodosList =
|
|
6556
|
+
var TodosList = import_react78.default.forwardRef(
|
|
6379
6557
|
({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
|
|
6380
|
-
const sortedTasks = (0,
|
|
6381
|
-
const [isStopping, setIsStopping] = (0,
|
|
6382
|
-
const handleStopClick = (0,
|
|
6558
|
+
const sortedTasks = (0, import_react78.useMemo)(() => sortTasks(tasks), [tasks]);
|
|
6559
|
+
const [isStopping, setIsStopping] = (0, import_react78.useState)(false);
|
|
6560
|
+
const handleStopClick = (0, import_react78.useCallback)(async () => {
|
|
6383
6561
|
if (!onStopAllTasks || isStopping) {
|
|
6384
6562
|
return;
|
|
6385
6563
|
}
|
|
@@ -6400,7 +6578,7 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6400
6578
|
if (tasks.length === 0) {
|
|
6401
6579
|
return null;
|
|
6402
6580
|
}
|
|
6403
|
-
return /* @__PURE__ */
|
|
6581
|
+
return /* @__PURE__ */ import_react78.default.createElement(
|
|
6404
6582
|
"div",
|
|
6405
6583
|
{
|
|
6406
6584
|
ref,
|
|
@@ -6411,16 +6589,16 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6411
6589
|
),
|
|
6412
6590
|
...rest
|
|
6413
6591
|
},
|
|
6414
|
-
/* @__PURE__ */
|
|
6592
|
+
/* @__PURE__ */ import_react78.default.createElement(
|
|
6415
6593
|
"div",
|
|
6416
6594
|
{
|
|
6417
6595
|
className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
|
|
6418
6596
|
},
|
|
6419
|
-
/* @__PURE__ */
|
|
6420
|
-
/* @__PURE__ */
|
|
6597
|
+
/* @__PURE__ */ import_react78.default.createElement("h4", { className: "text-xs font-medium text-white" }, title),
|
|
6598
|
+
/* @__PURE__ */ import_react78.default.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
|
|
6421
6599
|
),
|
|
6422
|
-
/* @__PURE__ */
|
|
6423
|
-
showStopButton && /* @__PURE__ */
|
|
6600
|
+
/* @__PURE__ */ import_react78.default.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ import_react78.default.createElement(TaskItem, { key: task.id, task }))),
|
|
6601
|
+
showStopButton && /* @__PURE__ */ import_react78.default.createElement("div", { className: "px-4 py-2 border-t border-ash/40 flex-shrink-0" }, /* @__PURE__ */ import_react78.default.createElement(
|
|
6424
6602
|
"button",
|
|
6425
6603
|
{
|
|
6426
6604
|
type: "button",
|
|
@@ -6437,7 +6615,7 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6437
6615
|
isStopping ? "cursor-not-allowed opacity-70" : "hover:bg-error/20"
|
|
6438
6616
|
)
|
|
6439
6617
|
},
|
|
6440
|
-
isStopping ? /* @__PURE__ */
|
|
6618
|
+
isStopping ? /* @__PURE__ */ import_react78.default.createElement(import_react78.default.Fragment, null, /* @__PURE__ */ import_react78.default.createElement(import_lucide_react19.Loader2, { className: "w-3 h-3 animate-spin" }), "Stopping tasks") : /* @__PURE__ */ import_react78.default.createElement(import_react78.default.Fragment, null, /* @__PURE__ */ import_react78.default.createElement(import_lucide_react19.Square, { className: "w-3 h-3 fill-current" }), "Stop All Tasks")
|
|
6441
6619
|
))
|
|
6442
6620
|
);
|
|
6443
6621
|
}
|
|
@@ -6457,8 +6635,8 @@ function areAllTasksSettled(tasks) {
|
|
|
6457
6635
|
}
|
|
6458
6636
|
|
|
6459
6637
|
// src/components/chat/ToolSidebar.tsx
|
|
6460
|
-
var
|
|
6461
|
-
var ToolSidebar =
|
|
6638
|
+
var import_react79 = __toESM(require("react"));
|
|
6639
|
+
var ToolSidebar = import_react79.default.forwardRef(
|
|
6462
6640
|
({ tools, activeTools, onToggleTool, side, className, ...rest }, ref) => {
|
|
6463
6641
|
const topTools = tools.filter((t) => t.group === `top-${side}`);
|
|
6464
6642
|
const bottomTools = tools.filter((t) => t.group === `bottom-${side}`);
|
|
@@ -6469,7 +6647,7 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6469
6647
|
};
|
|
6470
6648
|
const renderButton = (tool) => {
|
|
6471
6649
|
const active = isActive(tool.id);
|
|
6472
|
-
return /* @__PURE__ */
|
|
6650
|
+
return /* @__PURE__ */ import_react79.default.createElement(
|
|
6473
6651
|
"button",
|
|
6474
6652
|
{
|
|
6475
6653
|
key: tool.id,
|
|
@@ -6481,10 +6659,10 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6481
6659
|
"aria-label": tool.label,
|
|
6482
6660
|
"aria-pressed": active
|
|
6483
6661
|
},
|
|
6484
|
-
/* @__PURE__ */
|
|
6662
|
+
/* @__PURE__ */ import_react79.default.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
|
|
6485
6663
|
);
|
|
6486
6664
|
};
|
|
6487
|
-
return /* @__PURE__ */
|
|
6665
|
+
return /* @__PURE__ */ import_react79.default.createElement(
|
|
6488
6666
|
"div",
|
|
6489
6667
|
{
|
|
6490
6668
|
ref,
|
|
@@ -6495,17 +6673,17 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6495
6673
|
),
|
|
6496
6674
|
...rest
|
|
6497
6675
|
},
|
|
6498
|
-
/* @__PURE__ */
|
|
6499
|
-
/* @__PURE__ */
|
|
6500
|
-
/* @__PURE__ */
|
|
6676
|
+
/* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
|
|
6677
|
+
/* @__PURE__ */ import_react79.default.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "w-5 border-t border-ash/30" })),
|
|
6678
|
+
/* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
|
|
6501
6679
|
);
|
|
6502
6680
|
}
|
|
6503
6681
|
);
|
|
6504
6682
|
ToolSidebar.displayName = "ToolSidebar";
|
|
6505
6683
|
|
|
6506
6684
|
// src/components/chat/ToolPanelContainer.tsx
|
|
6507
|
-
var
|
|
6508
|
-
var ToolPanelContainer =
|
|
6685
|
+
var import_react80 = __toESM(require("react"));
|
|
6686
|
+
var ToolPanelContainer = import_react80.default.forwardRef(
|
|
6509
6687
|
({
|
|
6510
6688
|
topContent,
|
|
6511
6689
|
bottomContent,
|
|
@@ -6516,21 +6694,21 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6516
6694
|
initialTopPercent = 60,
|
|
6517
6695
|
...rest
|
|
6518
6696
|
}, ref) => {
|
|
6519
|
-
const [topPercent, setTopPercent] = (0,
|
|
6520
|
-
const [isResizingHeight, setIsResizingHeight] = (0,
|
|
6521
|
-
const containerRef = (0,
|
|
6522
|
-
const lastY = (0,
|
|
6697
|
+
const [topPercent, setTopPercent] = (0, import_react80.useState)(initialTopPercent);
|
|
6698
|
+
const [isResizingHeight, setIsResizingHeight] = (0, import_react80.useState)(false);
|
|
6699
|
+
const containerRef = (0, import_react80.useRef)(null);
|
|
6700
|
+
const lastY = (0, import_react80.useRef)(null);
|
|
6523
6701
|
const hasBoth = topContent !== null && bottomContent !== null;
|
|
6524
|
-
const startHeightResize = (0,
|
|
6702
|
+
const startHeightResize = (0, import_react80.useCallback)((e) => {
|
|
6525
6703
|
e.preventDefault();
|
|
6526
6704
|
setIsResizingHeight(true);
|
|
6527
6705
|
lastY.current = e.clientY;
|
|
6528
6706
|
}, []);
|
|
6529
|
-
const stopHeightResize = (0,
|
|
6707
|
+
const stopHeightResize = (0, import_react80.useCallback)(() => {
|
|
6530
6708
|
setIsResizingHeight(false);
|
|
6531
6709
|
lastY.current = null;
|
|
6532
6710
|
}, []);
|
|
6533
|
-
const resizeHeight = (0,
|
|
6711
|
+
const resizeHeight = (0, import_react80.useCallback)(
|
|
6534
6712
|
(e) => {
|
|
6535
6713
|
if (!isResizingHeight || lastY.current === null || !containerRef.current) {
|
|
6536
6714
|
return;
|
|
@@ -6549,7 +6727,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6549
6727
|
},
|
|
6550
6728
|
[isResizingHeight]
|
|
6551
6729
|
);
|
|
6552
|
-
(0,
|
|
6730
|
+
(0, import_react80.useEffect)(() => {
|
|
6553
6731
|
if (isResizingHeight) {
|
|
6554
6732
|
window.addEventListener("mousemove", resizeHeight);
|
|
6555
6733
|
window.addEventListener("mouseup", stopHeightResize);
|
|
@@ -6568,7 +6746,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6568
6746
|
document.body.style.userSelect = "";
|
|
6569
6747
|
};
|
|
6570
6748
|
}, [isResizingHeight, resizeHeight, stopHeightResize]);
|
|
6571
|
-
return /* @__PURE__ */
|
|
6749
|
+
return /* @__PURE__ */ import_react80.default.createElement(
|
|
6572
6750
|
"div",
|
|
6573
6751
|
{
|
|
6574
6752
|
ref: composeRefs(containerRef, ref),
|
|
@@ -6580,7 +6758,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6580
6758
|
style: width ? { width } : void 0,
|
|
6581
6759
|
...rest
|
|
6582
6760
|
},
|
|
6583
|
-
/* @__PURE__ */
|
|
6761
|
+
/* @__PURE__ */ import_react80.default.createElement(
|
|
6584
6762
|
"div",
|
|
6585
6763
|
{
|
|
6586
6764
|
onMouseDown: onResizeStart,
|
|
@@ -6591,7 +6769,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6591
6769
|
)
|
|
6592
6770
|
}
|
|
6593
6771
|
),
|
|
6594
|
-
topContent !== null && /* @__PURE__ */
|
|
6772
|
+
topContent !== null && /* @__PURE__ */ import_react80.default.createElement(
|
|
6595
6773
|
"div",
|
|
6596
6774
|
{
|
|
6597
6775
|
className: "min-h-0 overflow-hidden flex flex-col",
|
|
@@ -6599,7 +6777,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6599
6777
|
},
|
|
6600
6778
|
topContent
|
|
6601
6779
|
),
|
|
6602
|
-
hasBoth && /* @__PURE__ */
|
|
6780
|
+
hasBoth && /* @__PURE__ */ import_react80.default.createElement(
|
|
6603
6781
|
"div",
|
|
6604
6782
|
{
|
|
6605
6783
|
onMouseDown: startHeightResize,
|
|
@@ -6611,7 +6789,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6611
6789
|
)
|
|
6612
6790
|
}
|
|
6613
6791
|
),
|
|
6614
|
-
bottomContent !== null && /* @__PURE__ */
|
|
6792
|
+
bottomContent !== null && /* @__PURE__ */ import_react80.default.createElement(
|
|
6615
6793
|
"div",
|
|
6616
6794
|
{
|
|
6617
6795
|
className: "min-h-0 overflow-hidden flex flex-col",
|
|
@@ -6624,65 +6802,6 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6624
6802
|
);
|
|
6625
6803
|
ToolPanelContainer.displayName = "ToolPanelContainer";
|
|
6626
6804
|
|
|
6627
|
-
// src/components/chat/hooks/useResizable.ts
|
|
6628
|
-
var import_react80 = require("react");
|
|
6629
|
-
function useResizable({
|
|
6630
|
-
initialWidthPercent,
|
|
6631
|
-
minWidthPercent,
|
|
6632
|
-
maxWidthPercent,
|
|
6633
|
-
direction
|
|
6634
|
-
}) {
|
|
6635
|
-
const [widthPercent, setWidthPercent] = (0, import_react80.useState)(initialWidthPercent);
|
|
6636
|
-
const [isResizing, setIsResizing] = (0, import_react80.useState)(false);
|
|
6637
|
-
const lastX = (0, import_react80.useRef)(null);
|
|
6638
|
-
const startResizing = (0, import_react80.useCallback)((e) => {
|
|
6639
|
-
e.preventDefault();
|
|
6640
|
-
setIsResizing(true);
|
|
6641
|
-
lastX.current = e.clientX;
|
|
6642
|
-
}, []);
|
|
6643
|
-
const stopResizing = (0, import_react80.useCallback)(() => {
|
|
6644
|
-
setIsResizing(false);
|
|
6645
|
-
lastX.current = null;
|
|
6646
|
-
}, []);
|
|
6647
|
-
const resize = (0, import_react80.useCallback)(
|
|
6648
|
-
(e) => {
|
|
6649
|
-
if (!isResizing || lastX.current === null) {
|
|
6650
|
-
return;
|
|
6651
|
-
}
|
|
6652
|
-
const deltaX = e.clientX - lastX.current;
|
|
6653
|
-
const factor = direction === "right" ? 1 : -1;
|
|
6654
|
-
const deltaPercent = deltaX / window.innerWidth * 100;
|
|
6655
|
-
setWidthPercent((prevPercent) => {
|
|
6656
|
-
const newPercent = prevPercent + deltaPercent * factor;
|
|
6657
|
-
return Math.min(Math.max(newPercent, minWidthPercent), maxWidthPercent);
|
|
6658
|
-
});
|
|
6659
|
-
lastX.current = e.clientX;
|
|
6660
|
-
},
|
|
6661
|
-
[isResizing, direction, minWidthPercent, maxWidthPercent]
|
|
6662
|
-
);
|
|
6663
|
-
(0, import_react80.useEffect)(() => {
|
|
6664
|
-
if (isResizing) {
|
|
6665
|
-
window.addEventListener("mousemove", resize);
|
|
6666
|
-
window.addEventListener("mouseup", stopResizing);
|
|
6667
|
-
document.body.style.cursor = "col-resize";
|
|
6668
|
-
document.body.style.userSelect = "none";
|
|
6669
|
-
} else {
|
|
6670
|
-
window.removeEventListener("mousemove", resize);
|
|
6671
|
-
window.removeEventListener("mouseup", stopResizing);
|
|
6672
|
-
document.body.style.cursor = "";
|
|
6673
|
-
document.body.style.userSelect = "";
|
|
6674
|
-
}
|
|
6675
|
-
return () => {
|
|
6676
|
-
window.removeEventListener("mousemove", resize);
|
|
6677
|
-
window.removeEventListener("mouseup", stopResizing);
|
|
6678
|
-
document.body.style.cursor = "";
|
|
6679
|
-
document.body.style.userSelect = "";
|
|
6680
|
-
};
|
|
6681
|
-
}, [isResizing, resize, stopResizing]);
|
|
6682
|
-
const width = `${widthPercent}vw`;
|
|
6683
|
-
return { width, widthPercent, isResizing, startResizing };
|
|
6684
|
-
}
|
|
6685
|
-
|
|
6686
6805
|
// src/components/chat/tree.ts
|
|
6687
6806
|
function createEmptyTree() {
|
|
6688
6807
|
return { nodes: {}, rootIds: [], activeLeafId: null, lastLeafId: null };
|
|
@@ -6843,6 +6962,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6843
6962
|
onRenameConversation,
|
|
6844
6963
|
isStreaming = false,
|
|
6845
6964
|
isThinking = false,
|
|
6965
|
+
thinkingLabel,
|
|
6846
6966
|
placeholder = "Send a message...",
|
|
6847
6967
|
emptyStateHelper = "Let's talk.",
|
|
6848
6968
|
emptyState,
|
|
@@ -6851,6 +6971,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6851
6971
|
attachments: propsAttachments,
|
|
6852
6972
|
onAttachmentsChange,
|
|
6853
6973
|
onAttachmentRemove,
|
|
6974
|
+
onAttachmentOpen,
|
|
6854
6975
|
artifactNodes,
|
|
6855
6976
|
isArtifactsPanelOpen,
|
|
6856
6977
|
onArtifactsPanelOpenChange,
|
|
@@ -6867,6 +6988,14 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6867
6988
|
}, ref) => {
|
|
6868
6989
|
const prevArtifactNodesRef = (0, import_react81.useRef)([]);
|
|
6869
6990
|
const prevTasksRef = (0, import_react81.useRef)([]);
|
|
6991
|
+
const [panelOpenArtifactId, setPanelOpenArtifactId] = (0, import_react81.useState)(null);
|
|
6992
|
+
const handleAttachmentOpen = (0, import_react81.useCallback)((artifactId) => {
|
|
6993
|
+
setPanelOpenArtifactId(artifactId);
|
|
6994
|
+
onAttachmentOpen?.(artifactId);
|
|
6995
|
+
}, [onAttachmentOpen]);
|
|
6996
|
+
const handleArtifactPanelClosed = (0, import_react81.useCallback)(() => {
|
|
6997
|
+
setPanelOpenArtifactId(null);
|
|
6998
|
+
}, []);
|
|
6870
6999
|
const [internalTools, setInternalTools] = (0, import_react81.useState)({
|
|
6871
7000
|
"top-left": "history",
|
|
6872
7001
|
"bottom-left": null,
|
|
@@ -7054,7 +7183,15 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7054
7183
|
isStreaming: node.isStreaming,
|
|
7055
7184
|
muted: opts.muted,
|
|
7056
7185
|
branchInfo,
|
|
7057
|
-
actions
|
|
7186
|
+
actions,
|
|
7187
|
+
attachments: node.attachments ? node.attachments.map((a) => ({
|
|
7188
|
+
id: a.id,
|
|
7189
|
+
file: { name: a.name, size: a.size ?? 0, type: a.type },
|
|
7190
|
+
previewUrl: a.previewUrl,
|
|
7191
|
+
artifactId: a.artifactId,
|
|
7192
|
+
status: a.status ?? "analyzed"
|
|
7193
|
+
})) : void 0,
|
|
7194
|
+
onAttachmentOpen: handleAttachmentOpen
|
|
7058
7195
|
};
|
|
7059
7196
|
},
|
|
7060
7197
|
[
|
|
@@ -7064,7 +7201,8 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7064
7201
|
onEditMessage,
|
|
7065
7202
|
onRetryMessage,
|
|
7066
7203
|
handleBranchSwitch,
|
|
7067
|
-
handleJumpToCheckpoint
|
|
7204
|
+
handleJumpToCheckpoint,
|
|
7205
|
+
handleAttachmentOpen
|
|
7068
7206
|
]
|
|
7069
7207
|
);
|
|
7070
7208
|
const displayItems = (0, import_react81.useMemo)(() => {
|
|
@@ -7133,6 +7271,8 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7133
7271
|
ArtifactsPanel,
|
|
7134
7272
|
{
|
|
7135
7273
|
nodes: artifactNodes,
|
|
7274
|
+
openArtifactId: panelOpenArtifactId,
|
|
7275
|
+
onArtifactClosed: handleArtifactPanelClosed,
|
|
7136
7276
|
className: "h-full"
|
|
7137
7277
|
}
|
|
7138
7278
|
);
|
|
@@ -7195,6 +7335,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7195
7335
|
latestUserMessageIndex,
|
|
7196
7336
|
isStreaming,
|
|
7197
7337
|
isThinking,
|
|
7338
|
+
thinkingLabel,
|
|
7198
7339
|
className: "flex-1"
|
|
7199
7340
|
}
|
|
7200
7341
|
)), /* @__PURE__ */ import_react81.default.createElement("div", { className: cx(
|