@lukeashford/aurelius 4.2.0 → 4.3.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 +347 -217
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +257 -126
- 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,84 @@ 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: "Upload complete. Analyzing...",
|
|
1503
|
+
analyzing: "Upload complete. Analyzing...",
|
|
1504
|
+
analyzed: null,
|
|
1505
|
+
upload_failed: "Upload failed. Remove and try again.",
|
|
1506
|
+
analysis_failed: "Analysis failed. Provide a description in your next message."
|
|
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;
|
|
1530
|
+
const clickable = !!(artifactId && onOpen);
|
|
1531
|
+
const hoverLabel = statusHoverLabel[status];
|
|
1532
|
+
const tooltip = title ?? hoverLabel ?? name;
|
|
1533
|
+
const showError = isErrorStatus(status);
|
|
1534
|
+
const handleClick = () => {
|
|
1535
|
+
if (clickable) {
|
|
1536
|
+
onOpen(artifactId);
|
|
1537
|
+
}
|
|
1538
|
+
};
|
|
1539
|
+
const handleKeyDown = (e) => {
|
|
1540
|
+
if (!clickable) {
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1544
|
+
e.preventDefault();
|
|
1545
|
+
onOpen(artifactId);
|
|
1546
|
+
}
|
|
1547
|
+
};
|
|
1512
1548
|
return /* @__PURE__ */ import_react16.default.createElement(
|
|
1513
1549
|
"div",
|
|
1514
1550
|
{
|
|
1551
|
+
...rest,
|
|
1515
1552
|
ref,
|
|
1516
1553
|
className: cx(
|
|
1517
1554
|
"group relative inline-flex items-center gap-2 px-2 py-1.5",
|
|
1518
1555
|
"bg-charcoal border text-sm text-white",
|
|
1519
1556
|
"transition-colors duration-150",
|
|
1520
|
-
|
|
1521
|
-
|
|
1557
|
+
statusBorderClass[status],
|
|
1558
|
+
showError && "bg-error/10",
|
|
1559
|
+
clickable && "cursor-pointer hover:bg-graphite",
|
|
1522
1560
|
className
|
|
1523
1561
|
),
|
|
1524
|
-
role: "listitem",
|
|
1525
|
-
|
|
1562
|
+
role: clickable ? "button" : "listitem",
|
|
1563
|
+
tabIndex: clickable ? 0 : void 0,
|
|
1564
|
+
onClick: clickable ? handleClick : void 0,
|
|
1565
|
+
onKeyDown: clickable ? handleKeyDown : void 0,
|
|
1566
|
+
title: tooltip,
|
|
1567
|
+
"aria-label": hoverLabel ? `${name}: ${hoverLabel}` : name
|
|
1526
1568
|
},
|
|
1527
1569
|
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
1570
|
"img",
|
|
@@ -1533,10 +1575,11 @@ var FileChip = import_react16.default.forwardRef(
|
|
|
1533
1575
|
}
|
|
1534
1576
|
)) : /* @__PURE__ */ import_react16.default.createElement(Icon, { className: cx(
|
|
1535
1577
|
"w-4 h-4 flex-shrink-0",
|
|
1536
|
-
|
|
1578
|
+
showError ? "text-error" : "text-silver"
|
|
1537
1579
|
) }),
|
|
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 &&
|
|
1580
|
+
/* @__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
1581
|
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" }),
|
|
1582
|
+
(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
1583
|
status === "pending" && /* @__PURE__ */ import_react16.default.createElement("div", { className: "w-2 h-2 rounded-full bg-silver/50 flex-shrink-0" }),
|
|
1541
1584
|
removable && onRemove && /* @__PURE__ */ import_react16.default.createElement(
|
|
1542
1585
|
"button",
|
|
@@ -1569,6 +1612,7 @@ var AttachmentPreview = import_react17.default.forwardRef(
|
|
|
1569
1612
|
onRemove,
|
|
1570
1613
|
removable = true,
|
|
1571
1614
|
maxVisible,
|
|
1615
|
+
onOpen,
|
|
1572
1616
|
className,
|
|
1573
1617
|
...rest
|
|
1574
1618
|
}, ref) => {
|
|
@@ -1597,7 +1641,9 @@ var AttachmentPreview = import_react17.default.forwardRef(
|
|
|
1597
1641
|
previewUrl: attachment.previewUrl,
|
|
1598
1642
|
error: attachment.error,
|
|
1599
1643
|
removable,
|
|
1600
|
-
onRemove: onRemove ? () => onRemove(attachment.id) : void 0
|
|
1644
|
+
onRemove: onRemove ? () => onRemove(attachment.id) : void 0,
|
|
1645
|
+
artifactId: attachment.artifactId,
|
|
1646
|
+
onOpen
|
|
1601
1647
|
}
|
|
1602
1648
|
)),
|
|
1603
1649
|
hiddenCount > 0 && /* @__PURE__ */ import_react17.default.createElement(
|
|
@@ -4049,6 +4095,8 @@ var Message = import_react56.default.forwardRef(
|
|
|
4049
4095
|
branchInfo,
|
|
4050
4096
|
actions,
|
|
4051
4097
|
hideActions,
|
|
4098
|
+
attachments,
|
|
4099
|
+
onAttachmentOpen,
|
|
4052
4100
|
...rest
|
|
4053
4101
|
}, ref) => {
|
|
4054
4102
|
const isUser = variant === "user";
|
|
@@ -4116,6 +4164,14 @@ var Message = import_react56.default.forwardRef(
|
|
|
4116
4164
|
),
|
|
4117
4165
|
...rest
|
|
4118
4166
|
},
|
|
4167
|
+
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(
|
|
4168
|
+
AttachmentPreview,
|
|
4169
|
+
{
|
|
4170
|
+
attachments,
|
|
4171
|
+
removable: false,
|
|
4172
|
+
onOpen: onAttachmentOpen
|
|
4173
|
+
}
|
|
4174
|
+
)),
|
|
4119
4175
|
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
4176
|
"textarea",
|
|
4121
4177
|
{
|
|
@@ -4366,6 +4422,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4366
4422
|
isVisible = true,
|
|
4367
4423
|
phraseInterval = 2500,
|
|
4368
4424
|
phrases = THINKING_PHRASES,
|
|
4425
|
+
manualLabel,
|
|
4369
4426
|
className,
|
|
4370
4427
|
...rest
|
|
4371
4428
|
}, ref) => {
|
|
@@ -4373,8 +4430,9 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4373
4430
|
() => Math.floor(Math.random() * phrases.length)
|
|
4374
4431
|
);
|
|
4375
4432
|
const [isTransitioning, setIsTransitioning] = (0, import_react60.useState)(false);
|
|
4433
|
+
const isManual = manualLabel !== void 0;
|
|
4376
4434
|
(0, import_react60.useEffect)(() => {
|
|
4377
|
-
if (!isVisible || phrases.length <= 1) {
|
|
4435
|
+
if (!isVisible || isManual || phrases.length <= 1) {
|
|
4378
4436
|
return;
|
|
4379
4437
|
}
|
|
4380
4438
|
let fadeTimeout = null;
|
|
@@ -4392,7 +4450,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4392
4450
|
clearTimeout(fadeTimeout);
|
|
4393
4451
|
}
|
|
4394
4452
|
};
|
|
4395
|
-
}, [isVisible, phrases.length, phraseInterval]);
|
|
4453
|
+
}, [isVisible, isManual, phrases.length, phraseInterval]);
|
|
4396
4454
|
if (!isVisible) {
|
|
4397
4455
|
return null;
|
|
4398
4456
|
}
|
|
@@ -4429,7 +4487,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4429
4487
|
style: { animationDelay: "300ms" }
|
|
4430
4488
|
}
|
|
4431
4489
|
)),
|
|
4432
|
-
/* @__PURE__ */ import_react60.default.createElement(
|
|
4490
|
+
isManual ? /* @__PURE__ */ import_react60.default.createElement("span", { className: "text-sm italic" }, manualLabel) : /* @__PURE__ */ import_react60.default.createElement(
|
|
4433
4491
|
"span",
|
|
4434
4492
|
{
|
|
4435
4493
|
className: cx(
|
|
@@ -4451,13 +4509,15 @@ var KIND_ICONS = {
|
|
|
4451
4509
|
task: import_lucide_react12.GitBranch,
|
|
4452
4510
|
submit: import_lucide_react12.GitMerge,
|
|
4453
4511
|
rename: import_lucide_react12.PencilLine,
|
|
4454
|
-
init: import_lucide_react12.GitCommitVertical
|
|
4512
|
+
init: import_lucide_react12.GitCommitVertical,
|
|
4513
|
+
ingest: import_lucide_react12.Upload
|
|
4455
4514
|
};
|
|
4456
4515
|
var KIND_ARIA_LABELS = {
|
|
4457
4516
|
task: "Task checkpoint",
|
|
4458
4517
|
submit: "Submit checkpoint",
|
|
4459
4518
|
rename: "Rename checkpoint",
|
|
4460
|
-
init: "Project head checkpoint"
|
|
4519
|
+
init: "Project head checkpoint",
|
|
4520
|
+
ingest: "Upload batch checkpoint"
|
|
4461
4521
|
};
|
|
4462
4522
|
var Checkpoint = import_react61.default.forwardRef(
|
|
4463
4523
|
function Checkpoint2({ name, executionKind, status = "completed", isActive, muted, branchInfo, onJumpHere }, ref) {
|
|
@@ -4606,7 +4666,16 @@ GreyedDivider.displayName = "GreyedDivider";
|
|
|
4606
4666
|
|
|
4607
4667
|
// src/components/chat/ChatView.tsx
|
|
4608
4668
|
var ChatView = import_react63.default.forwardRef(
|
|
4609
|
-
function ChatView2({
|
|
4669
|
+
function ChatView2({
|
|
4670
|
+
items,
|
|
4671
|
+
latestUserMessageIndex,
|
|
4672
|
+
isStreaming,
|
|
4673
|
+
isThinking,
|
|
4674
|
+
thinkingLabel,
|
|
4675
|
+
onScroll,
|
|
4676
|
+
className,
|
|
4677
|
+
...rest
|
|
4678
|
+
}, ref) {
|
|
4610
4679
|
const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
|
|
4611
4680
|
behavior: "smooth",
|
|
4612
4681
|
block: "start"
|
|
@@ -4689,7 +4758,7 @@ var ChatView = import_react63.default.forwardRef(
|
|
|
4689
4758
|
}
|
|
4690
4759
|
)
|
|
4691
4760
|
);
|
|
4692
|
-
}), showThinking && /* @__PURE__ */ import_react63.default.createElement(ThinkingIndicator, { isVisible: true })),
|
|
4761
|
+
}), showThinking && /* @__PURE__ */ import_react63.default.createElement(ThinkingIndicator, { isVisible: true, manualLabel: thinkingLabel })),
|
|
4693
4762
|
/* @__PURE__ */ import_react63.default.createElement(
|
|
4694
4763
|
"div",
|
|
4695
4764
|
{
|
|
@@ -4874,8 +4943,8 @@ var ChatInput = import_react64.default.forwardRef(
|
|
|
4874
4943
|
);
|
|
4875
4944
|
const isCentered = position === "centered";
|
|
4876
4945
|
const hasAttachments = attachments.length > 0;
|
|
4877
|
-
const
|
|
4878
|
-
const canSubmit = value.trim() && !disabled && !isStreaming && !
|
|
4946
|
+
const isUploadIncomplete = attachments.some((a) => a.status === "pending" || a.status === "uploading" || a.status === "upload_failed");
|
|
4947
|
+
const canSubmit = value.trim() && !disabled && !isStreaming && !isUploadIncomplete;
|
|
4879
4948
|
return /* @__PURE__ */ import_react64.default.createElement(
|
|
4880
4949
|
"div",
|
|
4881
4950
|
{
|
|
@@ -5012,7 +5081,7 @@ var ChatInput = import_react64.default.forwardRef(
|
|
|
5012
5081
|
ChatInput.displayName = "ChatInput";
|
|
5013
5082
|
|
|
5014
5083
|
// src/components/chat/ArtifactsPanel.tsx
|
|
5015
|
-
var
|
|
5084
|
+
var import_react76 = __toESM(require("react"));
|
|
5016
5085
|
var import_lucide_react17 = require("lucide-react");
|
|
5017
5086
|
|
|
5018
5087
|
// src/components/ArtifactCard.tsx
|
|
@@ -5670,15 +5739,74 @@ var ArtifactVariantStack = import_react73.default.forwardRef(
|
|
|
5670
5739
|
);
|
|
5671
5740
|
ArtifactVariantStack.displayName = "ArtifactVariantStack";
|
|
5672
5741
|
|
|
5673
|
-
// src/components/chat/hooks/
|
|
5742
|
+
// src/components/chat/hooks/useResizable.ts
|
|
5674
5743
|
var import_react74 = require("react");
|
|
5744
|
+
function useResizable({
|
|
5745
|
+
initialWidthPercent,
|
|
5746
|
+
minWidthPercent,
|
|
5747
|
+
maxWidthPercent,
|
|
5748
|
+
direction
|
|
5749
|
+
}) {
|
|
5750
|
+
const [widthPercent, setWidthPercent] = (0, import_react74.useState)(initialWidthPercent);
|
|
5751
|
+
const [isResizing, setIsResizing] = (0, import_react74.useState)(false);
|
|
5752
|
+
const lastX = (0, import_react74.useRef)(null);
|
|
5753
|
+
const startResizing = (0, import_react74.useCallback)((e) => {
|
|
5754
|
+
e.preventDefault();
|
|
5755
|
+
setIsResizing(true);
|
|
5756
|
+
lastX.current = e.clientX;
|
|
5757
|
+
}, []);
|
|
5758
|
+
const stopResizing = (0, import_react74.useCallback)(() => {
|
|
5759
|
+
setIsResizing(false);
|
|
5760
|
+
lastX.current = null;
|
|
5761
|
+
}, []);
|
|
5762
|
+
const resize = (0, import_react74.useCallback)(
|
|
5763
|
+
(e) => {
|
|
5764
|
+
if (!isResizing || lastX.current === null) {
|
|
5765
|
+
return;
|
|
5766
|
+
}
|
|
5767
|
+
const deltaX = e.clientX - lastX.current;
|
|
5768
|
+
const factor = direction === "right" ? 1 : -1;
|
|
5769
|
+
const deltaPercent = deltaX / window.innerWidth * 100;
|
|
5770
|
+
setWidthPercent((prevPercent) => {
|
|
5771
|
+
const newPercent = prevPercent + deltaPercent * factor;
|
|
5772
|
+
return Math.min(Math.max(newPercent, minWidthPercent), maxWidthPercent);
|
|
5773
|
+
});
|
|
5774
|
+
lastX.current = e.clientX;
|
|
5775
|
+
},
|
|
5776
|
+
[isResizing, direction, minWidthPercent, maxWidthPercent]
|
|
5777
|
+
);
|
|
5778
|
+
(0, import_react74.useEffect)(() => {
|
|
5779
|
+
if (isResizing) {
|
|
5780
|
+
window.addEventListener("mousemove", resize);
|
|
5781
|
+
window.addEventListener("mouseup", stopResizing);
|
|
5782
|
+
document.body.style.cursor = "col-resize";
|
|
5783
|
+
document.body.style.userSelect = "none";
|
|
5784
|
+
} else {
|
|
5785
|
+
window.removeEventListener("mousemove", resize);
|
|
5786
|
+
window.removeEventListener("mouseup", stopResizing);
|
|
5787
|
+
document.body.style.cursor = "";
|
|
5788
|
+
document.body.style.userSelect = "";
|
|
5789
|
+
}
|
|
5790
|
+
return () => {
|
|
5791
|
+
window.removeEventListener("mousemove", resize);
|
|
5792
|
+
window.removeEventListener("mouseup", stopResizing);
|
|
5793
|
+
document.body.style.cursor = "";
|
|
5794
|
+
document.body.style.userSelect = "";
|
|
5795
|
+
};
|
|
5796
|
+
}, [isResizing, resize, stopResizing]);
|
|
5797
|
+
const width = `${widthPercent}vw`;
|
|
5798
|
+
return { width, widthPercent, isResizing, startResizing };
|
|
5799
|
+
}
|
|
5800
|
+
|
|
5801
|
+
// src/components/chat/hooks/useArtifactTreeNavigation.ts
|
|
5802
|
+
var import_react75 = require("react");
|
|
5675
5803
|
function useArtifactTreeNavigation(rootNodes) {
|
|
5676
|
-
const [stack, setStack] = (0,
|
|
5677
|
-
const currentNodes = (0,
|
|
5804
|
+
const [stack, setStack] = (0, import_react75.useState)([]);
|
|
5805
|
+
const currentNodes = (0, import_react75.useMemo)(() => {
|
|
5678
5806
|
if (stack.length === 0) return rootNodes;
|
|
5679
5807
|
return stack[stack.length - 1].children;
|
|
5680
5808
|
}, [rootNodes, stack]);
|
|
5681
|
-
const breadcrumbs = (0,
|
|
5809
|
+
const breadcrumbs = (0, import_react75.useMemo)(() => {
|
|
5682
5810
|
const entries = [{ label: "Project", node: null }];
|
|
5683
5811
|
for (const node of stack) {
|
|
5684
5812
|
entries.push({ label: node.label, node });
|
|
@@ -5686,13 +5814,13 @@ function useArtifactTreeNavigation(rootNodes) {
|
|
|
5686
5814
|
return entries;
|
|
5687
5815
|
}, [stack]);
|
|
5688
5816
|
const isAtRoot = stack.length === 0;
|
|
5689
|
-
const navigateInto = (0,
|
|
5817
|
+
const navigateInto = (0, import_react75.useCallback)((node) => {
|
|
5690
5818
|
setStack((prev) => [...prev, node]);
|
|
5691
5819
|
}, []);
|
|
5692
|
-
const navigateTo = (0,
|
|
5820
|
+
const navigateTo = (0, import_react75.useCallback)((index) => {
|
|
5693
5821
|
setStack((prev) => prev.slice(0, index));
|
|
5694
5822
|
}, []);
|
|
5695
|
-
const navigateBack = (0,
|
|
5823
|
+
const navigateBack = (0, import_react75.useCallback)(() => {
|
|
5696
5824
|
setStack((prev) => prev.slice(0, -1));
|
|
5697
5825
|
}, []);
|
|
5698
5826
|
return {
|
|
@@ -5712,46 +5840,46 @@ function ArtifactModal({
|
|
|
5712
5840
|
onClose
|
|
5713
5841
|
}) {
|
|
5714
5842
|
useEscapeKey(onClose);
|
|
5715
|
-
const handleBackdropClick = (0,
|
|
5843
|
+
const handleBackdropClick = (0, import_react76.useCallback)((e) => {
|
|
5716
5844
|
if (e.target === e.currentTarget) {
|
|
5717
5845
|
onClose();
|
|
5718
5846
|
}
|
|
5719
5847
|
}, [onClose]);
|
|
5720
|
-
return /* @__PURE__ */
|
|
5848
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5721
5849
|
"div",
|
|
5722
5850
|
{
|
|
5723
5851
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
|
|
5724
5852
|
onClick: handleBackdropClick
|
|
5725
5853
|
},
|
|
5726
|
-
/* @__PURE__ */
|
|
5854
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5727
5855
|
"div",
|
|
5728
5856
|
{
|
|
5729
5857
|
className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
|
|
5730
5858
|
},
|
|
5731
|
-
/* @__PURE__ */
|
|
5859
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5732
5860
|
"div",
|
|
5733
5861
|
{
|
|
5734
5862
|
className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
|
|
5735
5863
|
},
|
|
5736
|
-
/* @__PURE__ */
|
|
5737
|
-
/* @__PURE__ */
|
|
5864
|
+
/* @__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)),
|
|
5865
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5738
5866
|
"button",
|
|
5739
5867
|
{
|
|
5740
5868
|
onClick: onClose,
|
|
5741
5869
|
className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
|
|
5742
5870
|
"aria-label": "Close modal"
|
|
5743
5871
|
},
|
|
5744
|
-
/* @__PURE__ */
|
|
5872
|
+
/* @__PURE__ */ import_react76.default.createElement(CloseIcon, { className: "w-5 h-5" })
|
|
5745
5873
|
)
|
|
5746
5874
|
),
|
|
5747
|
-
/* @__PURE__ */
|
|
5875
|
+
/* @__PURE__ */ import_react76.default.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5748
5876
|
"img",
|
|
5749
5877
|
{
|
|
5750
5878
|
src: artifact.url,
|
|
5751
5879
|
alt: artifact.alt || "Artifact image",
|
|
5752
5880
|
className: "max-w-full max-h-full object-contain mx-auto"
|
|
5753
5881
|
}
|
|
5754
|
-
), artifact.type === "VIDEO" && /* @__PURE__ */
|
|
5882
|
+
), artifact.type === "VIDEO" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5755
5883
|
VideoCard,
|
|
5756
5884
|
{
|
|
5757
5885
|
src: artifact.url || "",
|
|
@@ -5759,20 +5887,20 @@ function ArtifactModal({
|
|
|
5759
5887
|
controls: true,
|
|
5760
5888
|
className: "max-w-full max-h-full mx-auto"
|
|
5761
5889
|
}
|
|
5762
|
-
), artifact.type === "AUDIO" && /* @__PURE__ */
|
|
5890
|
+
), artifact.type === "AUDIO" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5763
5891
|
AudioCard,
|
|
5764
5892
|
{
|
|
5765
5893
|
src: artifact.url || "",
|
|
5766
5894
|
controls: true,
|
|
5767
5895
|
className: "max-w-xl mx-auto"
|
|
5768
5896
|
}
|
|
5769
|
-
), artifact.type === "PDF" && /* @__PURE__ */
|
|
5897
|
+
), artifact.type === "PDF" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5770
5898
|
PdfCard,
|
|
5771
5899
|
{
|
|
5772
5900
|
src: artifact.url || "",
|
|
5773
5901
|
className: "h-full border-0"
|
|
5774
5902
|
}
|
|
5775
|
-
), artifact.type === "TEXT" && /* @__PURE__ */
|
|
5903
|
+
), artifact.type === "TEXT" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5776
5904
|
MarkdownContent,
|
|
5777
5905
|
{
|
|
5778
5906
|
content: artifact.inlineContent || "",
|
|
@@ -5782,7 +5910,7 @@ function ArtifactModal({
|
|
|
5782
5910
|
artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
|
|
5783
5911
|
)
|
|
5784
5912
|
}
|
|
5785
|
-
), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */
|
|
5913
|
+
), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react76.default.createElement(
|
|
5786
5914
|
ScriptCard,
|
|
5787
5915
|
{
|
|
5788
5916
|
elements: artifact.scriptElements,
|
|
@@ -5793,6 +5921,20 @@ function ArtifactModal({
|
|
|
5793
5921
|
)
|
|
5794
5922
|
);
|
|
5795
5923
|
}
|
|
5924
|
+
function findArtifactInNodes(nodes, artifactId) {
|
|
5925
|
+
for (const node of nodes) {
|
|
5926
|
+
if (node.type === "ARTIFACT" && node.artifact?.id === artifactId) {
|
|
5927
|
+
return node.artifact;
|
|
5928
|
+
}
|
|
5929
|
+
if (node.children && node.children.length > 0) {
|
|
5930
|
+
const found = findArtifactInNodes(node.children, artifactId);
|
|
5931
|
+
if (found) {
|
|
5932
|
+
return found;
|
|
5933
|
+
}
|
|
5934
|
+
}
|
|
5935
|
+
}
|
|
5936
|
+
return null;
|
|
5937
|
+
}
|
|
5796
5938
|
function NodeRenderer({
|
|
5797
5939
|
node,
|
|
5798
5940
|
loading,
|
|
@@ -5800,7 +5942,7 @@ function NodeRenderer({
|
|
|
5800
5942
|
onGroupClick
|
|
5801
5943
|
}) {
|
|
5802
5944
|
if (node.type === "ARTIFACT" && node.artifact) {
|
|
5803
|
-
return /* @__PURE__ */
|
|
5945
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5804
5946
|
ArtifactCard,
|
|
5805
5947
|
{
|
|
5806
5948
|
artifact: node.artifact,
|
|
@@ -5810,10 +5952,10 @@ function NodeRenderer({
|
|
|
5810
5952
|
);
|
|
5811
5953
|
}
|
|
5812
5954
|
if (node.type === "GROUP") {
|
|
5813
|
-
return /* @__PURE__ */
|
|
5955
|
+
return /* @__PURE__ */ import_react76.default.createElement(ArtifactGroup, { node, onClick: onGroupClick });
|
|
5814
5956
|
}
|
|
5815
5957
|
if (node.type === "VARIANT_SET") {
|
|
5816
|
-
return /* @__PURE__ */
|
|
5958
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5817
5959
|
ArtifactVariantStack,
|
|
5818
5960
|
{
|
|
5819
5961
|
node,
|
|
@@ -5824,42 +5966,59 @@ function NodeRenderer({
|
|
|
5824
5966
|
}
|
|
5825
5967
|
return null;
|
|
5826
5968
|
}
|
|
5827
|
-
var ArtifactsPanel =
|
|
5969
|
+
var ArtifactsPanel = import_react76.default.forwardRef(
|
|
5828
5970
|
({
|
|
5829
5971
|
nodes,
|
|
5830
5972
|
loading,
|
|
5973
|
+
openArtifactId,
|
|
5974
|
+
onArtifactClosed,
|
|
5831
5975
|
className,
|
|
5832
5976
|
...rest
|
|
5833
5977
|
}, ref) => {
|
|
5834
|
-
const [expandedArtifact, setExpandedArtifact] = (0,
|
|
5835
|
-
const [zoomIndex, setZoomIndex] = (0,
|
|
5978
|
+
const [expandedArtifact, setExpandedArtifact] = (0, import_react76.useState)(null);
|
|
5979
|
+
const [zoomIndex, setZoomIndex] = (0, import_react76.useState)(ZOOM_LEVELS.length - 1);
|
|
5836
5980
|
const treeNav = useArtifactTreeNavigation(nodes || []);
|
|
5837
5981
|
const hasNodes = !!nodes && nodes.length > 0;
|
|
5838
|
-
const handleExpandArtifact = (0,
|
|
5982
|
+
const handleExpandArtifact = (0, import_react76.useCallback)((artifact) => {
|
|
5839
5983
|
setExpandedArtifact(artifact);
|
|
5840
5984
|
}, []);
|
|
5841
|
-
const handleGroupClick = (0,
|
|
5985
|
+
const handleGroupClick = (0, import_react76.useCallback)((node) => {
|
|
5842
5986
|
treeNav.navigateInto(node);
|
|
5843
5987
|
}, [treeNav]);
|
|
5844
|
-
|
|
5988
|
+
(0, import_react76.useEffect)(() => {
|
|
5989
|
+
if (!openArtifactId || !nodes) {
|
|
5990
|
+
return;
|
|
5991
|
+
}
|
|
5992
|
+
const found = findArtifactInNodes(nodes, openArtifactId);
|
|
5993
|
+
if (found) {
|
|
5994
|
+
setExpandedArtifact(found);
|
|
5995
|
+
}
|
|
5996
|
+
}, [openArtifactId, nodes]);
|
|
5997
|
+
const handleModalClose = (0, import_react76.useCallback)(() => {
|
|
5998
|
+
setExpandedArtifact(null);
|
|
5999
|
+
onArtifactClosed?.();
|
|
6000
|
+
}, [onArtifactClosed]);
|
|
6001
|
+
const zoomIn = (0, import_react76.useCallback)(() => {
|
|
5845
6002
|
setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
|
|
5846
6003
|
}, []);
|
|
5847
|
-
const zoomOut = (0,
|
|
6004
|
+
const zoomOut = (0, import_react76.useCallback)(() => {
|
|
5848
6005
|
setZoomIndex((prev) => Math.max(prev - 1, 0));
|
|
5849
6006
|
}, []);
|
|
5850
6007
|
const currentZoom = ZOOM_LEVELS[zoomIndex];
|
|
5851
|
-
const contentRef = (0,
|
|
5852
|
-
const [contentHeight, setContentHeight] = (0,
|
|
5853
|
-
(0,
|
|
6008
|
+
const contentRef = (0, import_react76.useRef)(null);
|
|
6009
|
+
const [contentHeight, setContentHeight] = (0, import_react76.useState)(void 0);
|
|
6010
|
+
(0, import_react76.useEffect)(() => {
|
|
5854
6011
|
const el = contentRef.current;
|
|
5855
|
-
if (!el)
|
|
6012
|
+
if (!el) {
|
|
6013
|
+
return;
|
|
6014
|
+
}
|
|
5856
6015
|
const observer = new ResizeObserver(([entry]) => {
|
|
5857
6016
|
setContentHeight(entry.contentRect.height);
|
|
5858
6017
|
});
|
|
5859
6018
|
observer.observe(el);
|
|
5860
6019
|
return () => observer.disconnect();
|
|
5861
6020
|
}, []);
|
|
5862
|
-
return /* @__PURE__ */
|
|
6021
|
+
return /* @__PURE__ */ import_react76.default.createElement(import_react76.default.Fragment, null, /* @__PURE__ */ import_react76.default.createElement(
|
|
5863
6022
|
"div",
|
|
5864
6023
|
{
|
|
5865
6024
|
ref,
|
|
@@ -5870,19 +6029,19 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5870
6029
|
),
|
|
5871
6030
|
...rest
|
|
5872
6031
|
},
|
|
5873
|
-
/* @__PURE__ */
|
|
6032
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5874
6033
|
"div",
|
|
5875
6034
|
{
|
|
5876
6035
|
className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
|
|
5877
6036
|
},
|
|
5878
|
-
/* @__PURE__ */
|
|
5879
|
-
hasNodes && /* @__PURE__ */
|
|
6037
|
+
/* @__PURE__ */ import_react76.default.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
|
|
6038
|
+
hasNodes && /* @__PURE__ */ import_react76.default.createElement(
|
|
5880
6039
|
"div",
|
|
5881
6040
|
{
|
|
5882
6041
|
className: "flex items-center gap-0.5",
|
|
5883
6042
|
"data-testid": "zoom-controls"
|
|
5884
6043
|
},
|
|
5885
|
-
/* @__PURE__ */
|
|
6044
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5886
6045
|
"button",
|
|
5887
6046
|
{
|
|
5888
6047
|
onClick: zoomOut,
|
|
@@ -5896,8 +6055,16 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5896
6055
|
},
|
|
5897
6056
|
"\u2212"
|
|
5898
6057
|
),
|
|
5899
|
-
/* @__PURE__ */
|
|
5900
|
-
|
|
6058
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
6059
|
+
"span",
|
|
6060
|
+
{
|
|
6061
|
+
className: "text-xs text-silver w-8 text-center tabular-nums",
|
|
6062
|
+
"data-testid": "zoom-level"
|
|
6063
|
+
},
|
|
6064
|
+
Math.round(currentZoom * 100),
|
|
6065
|
+
"%"
|
|
6066
|
+
),
|
|
6067
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5901
6068
|
"button",
|
|
5902
6069
|
{
|
|
5903
6070
|
onClick: zoomIn,
|
|
@@ -5913,7 +6080,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5913
6080
|
)
|
|
5914
6081
|
)
|
|
5915
6082
|
),
|
|
5916
|
-
hasNodes && !treeNav.isAtRoot && /* @__PURE__ */
|
|
6083
|
+
hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ import_react76.default.createElement(
|
|
5917
6084
|
"nav",
|
|
5918
6085
|
{
|
|
5919
6086
|
className: "flex items-center gap-1 px-4 py-2 border-b border-ash/40 shrink-0 overflow-x-auto text-xs",
|
|
@@ -5922,7 +6089,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5922
6089
|
},
|
|
5923
6090
|
treeNav.breadcrumbs.map((crumb, i) => {
|
|
5924
6091
|
const isLast = i === treeNav.breadcrumbs.length - 1;
|
|
5925
|
-
return /* @__PURE__ */
|
|
6092
|
+
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
6093
|
"button",
|
|
5927
6094
|
{
|
|
5928
6095
|
onClick: () => treeNav.navigateTo(i),
|
|
@@ -5932,18 +6099,18 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5932
6099
|
));
|
|
5933
6100
|
})
|
|
5934
6101
|
),
|
|
5935
|
-
/* @__PURE__ */
|
|
6102
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5936
6103
|
"div",
|
|
5937
6104
|
{
|
|
5938
6105
|
className: "flex-1 overflow-auto relative",
|
|
5939
6106
|
"data-testid": "artifacts-scroll-area"
|
|
5940
6107
|
},
|
|
5941
|
-
/* @__PURE__ */
|
|
6108
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5942
6109
|
"div",
|
|
5943
6110
|
{
|
|
5944
6111
|
style: currentZoom !== 1 && contentHeight !== void 0 ? { height: contentHeight * currentZoom } : void 0
|
|
5945
6112
|
},
|
|
5946
|
-
/* @__PURE__ */
|
|
6113
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5947
6114
|
"div",
|
|
5948
6115
|
{
|
|
5949
6116
|
ref: contentRef,
|
|
@@ -5954,7 +6121,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5954
6121
|
transformOrigin: "top center"
|
|
5955
6122
|
} : void 0
|
|
5956
6123
|
},
|
|
5957
|
-
treeNav.currentNodes.length === 0 ? /* @__PURE__ */
|
|
6124
|
+
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
6125
|
NodeRenderer,
|
|
5959
6126
|
{
|
|
5960
6127
|
key: node.id,
|
|
@@ -5967,18 +6134,18 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5967
6134
|
)
|
|
5968
6135
|
)
|
|
5969
6136
|
)
|
|
5970
|
-
), expandedArtifact && /* @__PURE__ */
|
|
6137
|
+
), expandedArtifact && /* @__PURE__ */ import_react76.default.createElement(
|
|
5971
6138
|
ArtifactModal,
|
|
5972
6139
|
{
|
|
5973
6140
|
artifact: expandedArtifact,
|
|
5974
|
-
onClose:
|
|
6141
|
+
onClose: handleModalClose
|
|
5975
6142
|
}
|
|
5976
6143
|
));
|
|
5977
6144
|
}
|
|
5978
6145
|
);
|
|
5979
6146
|
ArtifactsPanel.displayName = "ArtifactsPanel";
|
|
5980
|
-
var ArtifactsPanelToggle =
|
|
5981
|
-
return /* @__PURE__ */
|
|
6147
|
+
var ArtifactsPanelToggle = import_react76.default.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
|
|
6148
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5982
6149
|
"button",
|
|
5983
6150
|
{
|
|
5984
6151
|
ref,
|
|
@@ -5995,8 +6162,8 @@ var ArtifactsPanelToggle = import_react75.default.forwardRef(({ artifactCount =
|
|
|
5995
6162
|
"aria-label": "Expand artifacts panel",
|
|
5996
6163
|
...rest
|
|
5997
6164
|
},
|
|
5998
|
-
/* @__PURE__ */
|
|
5999
|
-
artifactCount > 0 && /* @__PURE__ */
|
|
6165
|
+
/* @__PURE__ */ import_react76.default.createElement(import_lucide_react17.Image, { className: "w-5 h-5", "aria-hidden": true }),
|
|
6166
|
+
artifactCount > 0 && /* @__PURE__ */ import_react76.default.createElement(
|
|
6000
6167
|
"span",
|
|
6001
6168
|
{
|
|
6002
6169
|
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 +6175,7 @@ var ArtifactsPanelToggle = import_react75.default.forwardRef(({ artifactCount =
|
|
|
6008
6175
|
ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
|
|
6009
6176
|
|
|
6010
6177
|
// src/components/chat/HistoryPanel.tsx
|
|
6011
|
-
var
|
|
6178
|
+
var import_react77 = __toESM(require("react"));
|
|
6012
6179
|
var import_lucide_react18 = require("lucide-react");
|
|
6013
6180
|
function parseTimestamp(ts) {
|
|
6014
6181
|
if (ts == null) {
|
|
@@ -6051,12 +6218,12 @@ function ProjectFilter({
|
|
|
6051
6218
|
onChange,
|
|
6052
6219
|
className
|
|
6053
6220
|
}) {
|
|
6054
|
-
const [open, setOpen] = (0,
|
|
6055
|
-
const ref = (0,
|
|
6056
|
-
const closeFilter = (0,
|
|
6221
|
+
const [open, setOpen] = (0, import_react77.useState)(false);
|
|
6222
|
+
const ref = (0, import_react77.useRef)(null);
|
|
6223
|
+
const closeFilter = (0, import_react77.useCallback)(() => setOpen(false), []);
|
|
6057
6224
|
useClickOutside(ref, closeFilter, open);
|
|
6058
6225
|
const label = value ?? "All projects";
|
|
6059
|
-
return /* @__PURE__ */
|
|
6226
|
+
return /* @__PURE__ */ import_react77.default.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ import_react77.default.createElement(
|
|
6060
6227
|
"button",
|
|
6061
6228
|
{
|
|
6062
6229
|
type: "button",
|
|
@@ -6072,9 +6239,9 @@ function ProjectFilter({
|
|
|
6072
6239
|
"transition-colors duration-150 min-w-0"
|
|
6073
6240
|
)
|
|
6074
6241
|
},
|
|
6075
|
-
/* @__PURE__ */
|
|
6076
|
-
/* @__PURE__ */
|
|
6077
|
-
), open && /* @__PURE__ */
|
|
6242
|
+
/* @__PURE__ */ import_react77.default.createElement("span", { className: "truncate" }, label),
|
|
6243
|
+
/* @__PURE__ */ import_react77.default.createElement(import_lucide_react18.ChevronDown, { className: "w-3 h-3 shrink-0", "aria-hidden": true })
|
|
6244
|
+
), open && /* @__PURE__ */ import_react77.default.createElement(
|
|
6078
6245
|
"div",
|
|
6079
6246
|
{
|
|
6080
6247
|
role: "listbox",
|
|
@@ -6084,7 +6251,7 @@ function ProjectFilter({
|
|
|
6084
6251
|
"max-h-60 overflow-y-auto"
|
|
6085
6252
|
)
|
|
6086
6253
|
},
|
|
6087
|
-
/* @__PURE__ */
|
|
6254
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6088
6255
|
"button",
|
|
6089
6256
|
{
|
|
6090
6257
|
type: "button",
|
|
@@ -6102,7 +6269,7 @@ function ProjectFilter({
|
|
|
6102
6269
|
},
|
|
6103
6270
|
"All projects"
|
|
6104
6271
|
),
|
|
6105
|
-
projects.map((p) => /* @__PURE__ */
|
|
6272
|
+
projects.map((p) => /* @__PURE__ */ import_react77.default.createElement(
|
|
6106
6273
|
"button",
|
|
6107
6274
|
{
|
|
6108
6275
|
key: p,
|
|
@@ -6128,33 +6295,33 @@ function ConversationRow({
|
|
|
6128
6295
|
onSelect,
|
|
6129
6296
|
onRename
|
|
6130
6297
|
}) {
|
|
6131
|
-
const [isEditing, setIsEditing] = (0,
|
|
6132
|
-
const [draft, setDraft] = (0,
|
|
6133
|
-
const inputRef = (0,
|
|
6134
|
-
(0,
|
|
6298
|
+
const [isEditing, setIsEditing] = (0, import_react77.useState)(false);
|
|
6299
|
+
const [draft, setDraft] = (0, import_react77.useState)(conversation.title);
|
|
6300
|
+
const inputRef = (0, import_react77.useRef)(null);
|
|
6301
|
+
(0, import_react77.useEffect)(() => {
|
|
6135
6302
|
if (isEditing && inputRef.current) {
|
|
6136
6303
|
inputRef.current.focus();
|
|
6137
6304
|
inputRef.current.select();
|
|
6138
6305
|
}
|
|
6139
6306
|
}, [isEditing]);
|
|
6140
|
-
const startEdit = (0,
|
|
6307
|
+
const startEdit = (0, import_react77.useCallback)((e) => {
|
|
6141
6308
|
e.stopPropagation();
|
|
6142
6309
|
setDraft(conversation.title);
|
|
6143
6310
|
setIsEditing(true);
|
|
6144
6311
|
}, [conversation.title]);
|
|
6145
|
-
const commit = (0,
|
|
6312
|
+
const commit = (0, import_react77.useCallback)(() => {
|
|
6146
6313
|
const trimmed = draft.trim();
|
|
6147
6314
|
if (trimmed && trimmed !== conversation.title) {
|
|
6148
6315
|
onRename?.(conversation.id, trimmed);
|
|
6149
6316
|
}
|
|
6150
6317
|
setIsEditing(false);
|
|
6151
6318
|
}, [draft, conversation.id, conversation.title, onRename]);
|
|
6152
|
-
const cancel = (0,
|
|
6319
|
+
const cancel = (0, import_react77.useCallback)(() => {
|
|
6153
6320
|
setDraft(conversation.title);
|
|
6154
6321
|
setIsEditing(false);
|
|
6155
6322
|
}, [conversation.title]);
|
|
6156
6323
|
if (isEditing) {
|
|
6157
|
-
return /* @__PURE__ */
|
|
6324
|
+
return /* @__PURE__ */ import_react77.default.createElement(
|
|
6158
6325
|
"div",
|
|
6159
6326
|
{
|
|
6160
6327
|
className: cx(
|
|
@@ -6162,7 +6329,7 @@ function ConversationRow({
|
|
|
6162
6329
|
conversation.isActive ? "bg-ash/40" : "bg-ash/20"
|
|
6163
6330
|
)
|
|
6164
6331
|
},
|
|
6165
|
-
/* @__PURE__ */
|
|
6332
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6166
6333
|
"input",
|
|
6167
6334
|
{
|
|
6168
6335
|
ref: inputRef,
|
|
@@ -6187,10 +6354,10 @@ function ConversationRow({
|
|
|
6187
6354
|
"aria-label": "Conversation title"
|
|
6188
6355
|
}
|
|
6189
6356
|
),
|
|
6190
|
-
conversation.project && /* @__PURE__ */
|
|
6357
|
+
conversation.project && /* @__PURE__ */ import_react77.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-1" }, conversation.project)
|
|
6191
6358
|
);
|
|
6192
6359
|
}
|
|
6193
|
-
return /* @__PURE__ */
|
|
6360
|
+
return /* @__PURE__ */ import_react77.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react77.default.createElement(
|
|
6194
6361
|
"button",
|
|
6195
6362
|
{
|
|
6196
6363
|
onClick: () => onSelect?.(conversation.id),
|
|
@@ -6200,7 +6367,7 @@ function ConversationRow({
|
|
|
6200
6367
|
conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
|
|
6201
6368
|
)
|
|
6202
6369
|
},
|
|
6203
|
-
/* @__PURE__ */
|
|
6370
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6204
6371
|
"p",
|
|
6205
6372
|
{
|
|
6206
6373
|
className: cx(
|
|
@@ -6210,8 +6377,8 @@ function ConversationRow({
|
|
|
6210
6377
|
},
|
|
6211
6378
|
conversation.title
|
|
6212
6379
|
),
|
|
6213
|
-
conversation.project && /* @__PURE__ */
|
|
6214
|
-
), onRename && /* @__PURE__ */
|
|
6380
|
+
conversation.project && /* @__PURE__ */ import_react77.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.project)
|
|
6381
|
+
), onRename && /* @__PURE__ */ import_react77.default.createElement(
|
|
6215
6382
|
"button",
|
|
6216
6383
|
{
|
|
6217
6384
|
type: "button",
|
|
@@ -6224,7 +6391,7 @@ function ConversationRow({
|
|
|
6224
6391
|
"transition-opacity duration-150"
|
|
6225
6392
|
)
|
|
6226
6393
|
},
|
|
6227
|
-
/* @__PURE__ */
|
|
6394
|
+
/* @__PURE__ */ import_react77.default.createElement(import_lucide_react18.Pencil, { className: "w-3.5 h-3.5", "aria-hidden": true })
|
|
6228
6395
|
));
|
|
6229
6396
|
}
|
|
6230
6397
|
function HistoryPanel({
|
|
@@ -6233,8 +6400,8 @@ function HistoryPanel({
|
|
|
6233
6400
|
onNewChat,
|
|
6234
6401
|
onRenameConversation
|
|
6235
6402
|
}) {
|
|
6236
|
-
const [projectFilter, setProjectFilter] = (0,
|
|
6237
|
-
const projects = (0,
|
|
6403
|
+
const [projectFilter, setProjectFilter] = (0, import_react77.useState)(null);
|
|
6404
|
+
const projects = (0, import_react77.useMemo)(() => {
|
|
6238
6405
|
const set = /* @__PURE__ */ new Set();
|
|
6239
6406
|
for (const c of conversations) {
|
|
6240
6407
|
if (c.project) {
|
|
@@ -6243,23 +6410,23 @@ function HistoryPanel({
|
|
|
6243
6410
|
}
|
|
6244
6411
|
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
6245
6412
|
}, [conversations]);
|
|
6246
|
-
(0,
|
|
6413
|
+
(0, import_react77.useEffect)(() => {
|
|
6247
6414
|
if (projectFilter && !projects.includes(projectFilter)) {
|
|
6248
6415
|
setProjectFilter(null);
|
|
6249
6416
|
}
|
|
6250
6417
|
}, [projects, projectFilter]);
|
|
6251
|
-
const filteredConversations = (0,
|
|
6418
|
+
const filteredConversations = (0, import_react77.useMemo)(() => {
|
|
6252
6419
|
if (!projectFilter) {
|
|
6253
6420
|
return conversations;
|
|
6254
6421
|
}
|
|
6255
6422
|
return conversations.filter((c) => c.project === projectFilter);
|
|
6256
6423
|
}, [conversations, projectFilter]);
|
|
6257
|
-
const groups = (0,
|
|
6424
|
+
const groups = (0, import_react77.useMemo)(
|
|
6258
6425
|
() => groupConversations(filteredConversations),
|
|
6259
6426
|
[filteredConversations]
|
|
6260
6427
|
);
|
|
6261
6428
|
const hasFilter = projects.length > 0;
|
|
6262
|
-
return /* @__PURE__ */
|
|
6429
|
+
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
6430
|
ProjectFilter,
|
|
6264
6431
|
{
|
|
6265
6432
|
projects,
|
|
@@ -6267,7 +6434,7 @@ function HistoryPanel({
|
|
|
6267
6434
|
onChange: setProjectFilter,
|
|
6268
6435
|
className: "flex-1"
|
|
6269
6436
|
}
|
|
6270
|
-
)), onNewChat && /* @__PURE__ */
|
|
6437
|
+
)), 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
6438
|
"button",
|
|
6272
6439
|
{
|
|
6273
6440
|
onClick: onNewChat,
|
|
@@ -6279,15 +6446,15 @@ function HistoryPanel({
|
|
|
6279
6446
|
"transition-colors duration-200"
|
|
6280
6447
|
)
|
|
6281
6448
|
},
|
|
6282
|
-
/* @__PURE__ */
|
|
6283
|
-
/* @__PURE__ */
|
|
6284
|
-
)))), /* @__PURE__ */
|
|
6449
|
+
/* @__PURE__ */ import_react77.default.createElement(PlusIcon, { className: "w-4 h-4" }),
|
|
6450
|
+
/* @__PURE__ */ import_react77.default.createElement("span", { className: "truncate" }, "New Chat")
|
|
6451
|
+
)))), /* @__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
6452
|
"span",
|
|
6286
6453
|
{
|
|
6287
6454
|
className: "text-xs font-medium uppercase tracking-wider text-gold/70"
|
|
6288
6455
|
},
|
|
6289
6456
|
group.label
|
|
6290
|
-
), /* @__PURE__ */
|
|
6457
|
+
), /* @__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
6458
|
ConversationRow,
|
|
6292
6459
|
{
|
|
6293
6460
|
key: conversation.id,
|
|
@@ -6299,7 +6466,7 @@ function HistoryPanel({
|
|
|
6299
6466
|
}
|
|
6300
6467
|
|
|
6301
6468
|
// src/components/chat/TodosList.tsx
|
|
6302
|
-
var
|
|
6469
|
+
var import_react78 = __toESM(require("react"));
|
|
6303
6470
|
var import_lucide_react19 = require("lucide-react");
|
|
6304
6471
|
var TASK_STATUSES = {
|
|
6305
6472
|
PENDING: "pending",
|
|
@@ -6311,16 +6478,16 @@ var TASK_STATUSES = {
|
|
|
6311
6478
|
function TaskIcon({ status }) {
|
|
6312
6479
|
switch (status) {
|
|
6313
6480
|
case "done":
|
|
6314
|
-
return /* @__PURE__ */
|
|
6481
|
+
return /* @__PURE__ */ import_react78.default.createElement(CheckSquareIcon, null);
|
|
6315
6482
|
case "in_progress":
|
|
6316
|
-
return /* @__PURE__ */
|
|
6483
|
+
return /* @__PURE__ */ import_react78.default.createElement(SquareLoaderIcon, null);
|
|
6317
6484
|
case "cancelled":
|
|
6318
|
-
return /* @__PURE__ */
|
|
6485
|
+
return /* @__PURE__ */ import_react78.default.createElement(CrossSquareIcon, { variant: "cancelled" });
|
|
6319
6486
|
case "failed":
|
|
6320
|
-
return /* @__PURE__ */
|
|
6487
|
+
return /* @__PURE__ */ import_react78.default.createElement(CrossSquareIcon, { variant: "failed" });
|
|
6321
6488
|
case "pending":
|
|
6322
6489
|
default:
|
|
6323
|
-
return /* @__PURE__ */
|
|
6490
|
+
return /* @__PURE__ */ import_react78.default.createElement(EmptySquareIcon, null);
|
|
6324
6491
|
}
|
|
6325
6492
|
}
|
|
6326
6493
|
function sortTasks(tasks) {
|
|
@@ -6340,14 +6507,14 @@ function TaskItem({ task, depth = 0 }) {
|
|
|
6340
6507
|
const isSubtle = task.status === "cancelled" || task.status === "failed";
|
|
6341
6508
|
const showSubtasks = task.subtasks && task.subtasks.length > 0;
|
|
6342
6509
|
const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
|
|
6343
|
-
return /* @__PURE__ */
|
|
6510
|
+
return /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react78.default.createElement(
|
|
6344
6511
|
"div",
|
|
6345
6512
|
{
|
|
6346
6513
|
className: "flex items-center gap-2 py-1",
|
|
6347
6514
|
style: { paddingLeft: `${depth * 1.5}rem` }
|
|
6348
6515
|
},
|
|
6349
|
-
/* @__PURE__ */
|
|
6350
|
-
/* @__PURE__ */
|
|
6516
|
+
/* @__PURE__ */ import_react78.default.createElement(TaskIcon, { status: task.status }),
|
|
6517
|
+
/* @__PURE__ */ import_react78.default.createElement(
|
|
6351
6518
|
"span",
|
|
6352
6519
|
{
|
|
6353
6520
|
className: cx(
|
|
@@ -6359,10 +6526,10 @@ function TaskItem({ task, depth = 0 }) {
|
|
|
6359
6526
|
)
|
|
6360
6527
|
},
|
|
6361
6528
|
task.label,
|
|
6362
|
-
task.status === "cancelled" && /* @__PURE__ */
|
|
6363
|
-
task.status === "failed" && /* @__PURE__ */
|
|
6529
|
+
task.status === "cancelled" && /* @__PURE__ */ import_react78.default.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
|
|
6530
|
+
task.status === "failed" && /* @__PURE__ */ import_react78.default.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
|
|
6364
6531
|
)
|
|
6365
|
-
), showSubtasks && /* @__PURE__ */
|
|
6532
|
+
), 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
6533
|
}
|
|
6367
6534
|
function hasInProgressTask(tasks) {
|
|
6368
6535
|
return tasks.some((t) => {
|
|
@@ -6375,11 +6542,11 @@ function hasInProgressTask(tasks) {
|
|
|
6375
6542
|
return false;
|
|
6376
6543
|
});
|
|
6377
6544
|
}
|
|
6378
|
-
var TodosList =
|
|
6545
|
+
var TodosList = import_react78.default.forwardRef(
|
|
6379
6546
|
({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
|
|
6380
|
-
const sortedTasks = (0,
|
|
6381
|
-
const [isStopping, setIsStopping] = (0,
|
|
6382
|
-
const handleStopClick = (0,
|
|
6547
|
+
const sortedTasks = (0, import_react78.useMemo)(() => sortTasks(tasks), [tasks]);
|
|
6548
|
+
const [isStopping, setIsStopping] = (0, import_react78.useState)(false);
|
|
6549
|
+
const handleStopClick = (0, import_react78.useCallback)(async () => {
|
|
6383
6550
|
if (!onStopAllTasks || isStopping) {
|
|
6384
6551
|
return;
|
|
6385
6552
|
}
|
|
@@ -6400,7 +6567,7 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6400
6567
|
if (tasks.length === 0) {
|
|
6401
6568
|
return null;
|
|
6402
6569
|
}
|
|
6403
|
-
return /* @__PURE__ */
|
|
6570
|
+
return /* @__PURE__ */ import_react78.default.createElement(
|
|
6404
6571
|
"div",
|
|
6405
6572
|
{
|
|
6406
6573
|
ref,
|
|
@@ -6411,16 +6578,16 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6411
6578
|
),
|
|
6412
6579
|
...rest
|
|
6413
6580
|
},
|
|
6414
|
-
/* @__PURE__ */
|
|
6581
|
+
/* @__PURE__ */ import_react78.default.createElement(
|
|
6415
6582
|
"div",
|
|
6416
6583
|
{
|
|
6417
6584
|
className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
|
|
6418
6585
|
},
|
|
6419
|
-
/* @__PURE__ */
|
|
6420
|
-
/* @__PURE__ */
|
|
6586
|
+
/* @__PURE__ */ import_react78.default.createElement("h4", { className: "text-xs font-medium text-white" }, title),
|
|
6587
|
+
/* @__PURE__ */ import_react78.default.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
|
|
6421
6588
|
),
|
|
6422
|
-
/* @__PURE__ */
|
|
6423
|
-
showStopButton && /* @__PURE__ */
|
|
6589
|
+
/* @__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 }))),
|
|
6590
|
+
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
6591
|
"button",
|
|
6425
6592
|
{
|
|
6426
6593
|
type: "button",
|
|
@@ -6437,7 +6604,7 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6437
6604
|
isStopping ? "cursor-not-allowed opacity-70" : "hover:bg-error/20"
|
|
6438
6605
|
)
|
|
6439
6606
|
},
|
|
6440
|
-
isStopping ? /* @__PURE__ */
|
|
6607
|
+
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
6608
|
))
|
|
6442
6609
|
);
|
|
6443
6610
|
}
|
|
@@ -6457,8 +6624,8 @@ function areAllTasksSettled(tasks) {
|
|
|
6457
6624
|
}
|
|
6458
6625
|
|
|
6459
6626
|
// src/components/chat/ToolSidebar.tsx
|
|
6460
|
-
var
|
|
6461
|
-
var ToolSidebar =
|
|
6627
|
+
var import_react79 = __toESM(require("react"));
|
|
6628
|
+
var ToolSidebar = import_react79.default.forwardRef(
|
|
6462
6629
|
({ tools, activeTools, onToggleTool, side, className, ...rest }, ref) => {
|
|
6463
6630
|
const topTools = tools.filter((t) => t.group === `top-${side}`);
|
|
6464
6631
|
const bottomTools = tools.filter((t) => t.group === `bottom-${side}`);
|
|
@@ -6469,7 +6636,7 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6469
6636
|
};
|
|
6470
6637
|
const renderButton = (tool) => {
|
|
6471
6638
|
const active = isActive(tool.id);
|
|
6472
|
-
return /* @__PURE__ */
|
|
6639
|
+
return /* @__PURE__ */ import_react79.default.createElement(
|
|
6473
6640
|
"button",
|
|
6474
6641
|
{
|
|
6475
6642
|
key: tool.id,
|
|
@@ -6481,10 +6648,10 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6481
6648
|
"aria-label": tool.label,
|
|
6482
6649
|
"aria-pressed": active
|
|
6483
6650
|
},
|
|
6484
|
-
/* @__PURE__ */
|
|
6651
|
+
/* @__PURE__ */ import_react79.default.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
|
|
6485
6652
|
);
|
|
6486
6653
|
};
|
|
6487
|
-
return /* @__PURE__ */
|
|
6654
|
+
return /* @__PURE__ */ import_react79.default.createElement(
|
|
6488
6655
|
"div",
|
|
6489
6656
|
{
|
|
6490
6657
|
ref,
|
|
@@ -6495,17 +6662,17 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6495
6662
|
),
|
|
6496
6663
|
...rest
|
|
6497
6664
|
},
|
|
6498
|
-
/* @__PURE__ */
|
|
6499
|
-
/* @__PURE__ */
|
|
6500
|
-
/* @__PURE__ */
|
|
6665
|
+
/* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
|
|
6666
|
+
/* @__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" })),
|
|
6667
|
+
/* @__PURE__ */ import_react79.default.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
|
|
6501
6668
|
);
|
|
6502
6669
|
}
|
|
6503
6670
|
);
|
|
6504
6671
|
ToolSidebar.displayName = "ToolSidebar";
|
|
6505
6672
|
|
|
6506
6673
|
// src/components/chat/ToolPanelContainer.tsx
|
|
6507
|
-
var
|
|
6508
|
-
var ToolPanelContainer =
|
|
6674
|
+
var import_react80 = __toESM(require("react"));
|
|
6675
|
+
var ToolPanelContainer = import_react80.default.forwardRef(
|
|
6509
6676
|
({
|
|
6510
6677
|
topContent,
|
|
6511
6678
|
bottomContent,
|
|
@@ -6516,21 +6683,21 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6516
6683
|
initialTopPercent = 60,
|
|
6517
6684
|
...rest
|
|
6518
6685
|
}, ref) => {
|
|
6519
|
-
const [topPercent, setTopPercent] = (0,
|
|
6520
|
-
const [isResizingHeight, setIsResizingHeight] = (0,
|
|
6521
|
-
const containerRef = (0,
|
|
6522
|
-
const lastY = (0,
|
|
6686
|
+
const [topPercent, setTopPercent] = (0, import_react80.useState)(initialTopPercent);
|
|
6687
|
+
const [isResizingHeight, setIsResizingHeight] = (0, import_react80.useState)(false);
|
|
6688
|
+
const containerRef = (0, import_react80.useRef)(null);
|
|
6689
|
+
const lastY = (0, import_react80.useRef)(null);
|
|
6523
6690
|
const hasBoth = topContent !== null && bottomContent !== null;
|
|
6524
|
-
const startHeightResize = (0,
|
|
6691
|
+
const startHeightResize = (0, import_react80.useCallback)((e) => {
|
|
6525
6692
|
e.preventDefault();
|
|
6526
6693
|
setIsResizingHeight(true);
|
|
6527
6694
|
lastY.current = e.clientY;
|
|
6528
6695
|
}, []);
|
|
6529
|
-
const stopHeightResize = (0,
|
|
6696
|
+
const stopHeightResize = (0, import_react80.useCallback)(() => {
|
|
6530
6697
|
setIsResizingHeight(false);
|
|
6531
6698
|
lastY.current = null;
|
|
6532
6699
|
}, []);
|
|
6533
|
-
const resizeHeight = (0,
|
|
6700
|
+
const resizeHeight = (0, import_react80.useCallback)(
|
|
6534
6701
|
(e) => {
|
|
6535
6702
|
if (!isResizingHeight || lastY.current === null || !containerRef.current) {
|
|
6536
6703
|
return;
|
|
@@ -6549,7 +6716,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6549
6716
|
},
|
|
6550
6717
|
[isResizingHeight]
|
|
6551
6718
|
);
|
|
6552
|
-
(0,
|
|
6719
|
+
(0, import_react80.useEffect)(() => {
|
|
6553
6720
|
if (isResizingHeight) {
|
|
6554
6721
|
window.addEventListener("mousemove", resizeHeight);
|
|
6555
6722
|
window.addEventListener("mouseup", stopHeightResize);
|
|
@@ -6568,7 +6735,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6568
6735
|
document.body.style.userSelect = "";
|
|
6569
6736
|
};
|
|
6570
6737
|
}, [isResizingHeight, resizeHeight, stopHeightResize]);
|
|
6571
|
-
return /* @__PURE__ */
|
|
6738
|
+
return /* @__PURE__ */ import_react80.default.createElement(
|
|
6572
6739
|
"div",
|
|
6573
6740
|
{
|
|
6574
6741
|
ref: composeRefs(containerRef, ref),
|
|
@@ -6580,7 +6747,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6580
6747
|
style: width ? { width } : void 0,
|
|
6581
6748
|
...rest
|
|
6582
6749
|
},
|
|
6583
|
-
/* @__PURE__ */
|
|
6750
|
+
/* @__PURE__ */ import_react80.default.createElement(
|
|
6584
6751
|
"div",
|
|
6585
6752
|
{
|
|
6586
6753
|
onMouseDown: onResizeStart,
|
|
@@ -6591,7 +6758,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6591
6758
|
)
|
|
6592
6759
|
}
|
|
6593
6760
|
),
|
|
6594
|
-
topContent !== null && /* @__PURE__ */
|
|
6761
|
+
topContent !== null && /* @__PURE__ */ import_react80.default.createElement(
|
|
6595
6762
|
"div",
|
|
6596
6763
|
{
|
|
6597
6764
|
className: "min-h-0 overflow-hidden flex flex-col",
|
|
@@ -6599,7 +6766,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6599
6766
|
},
|
|
6600
6767
|
topContent
|
|
6601
6768
|
),
|
|
6602
|
-
hasBoth && /* @__PURE__ */
|
|
6769
|
+
hasBoth && /* @__PURE__ */ import_react80.default.createElement(
|
|
6603
6770
|
"div",
|
|
6604
6771
|
{
|
|
6605
6772
|
onMouseDown: startHeightResize,
|
|
@@ -6611,7 +6778,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6611
6778
|
)
|
|
6612
6779
|
}
|
|
6613
6780
|
),
|
|
6614
|
-
bottomContent !== null && /* @__PURE__ */
|
|
6781
|
+
bottomContent !== null && /* @__PURE__ */ import_react80.default.createElement(
|
|
6615
6782
|
"div",
|
|
6616
6783
|
{
|
|
6617
6784
|
className: "min-h-0 overflow-hidden flex flex-col",
|
|
@@ -6624,65 +6791,6 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6624
6791
|
);
|
|
6625
6792
|
ToolPanelContainer.displayName = "ToolPanelContainer";
|
|
6626
6793
|
|
|
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
6794
|
// src/components/chat/tree.ts
|
|
6687
6795
|
function createEmptyTree() {
|
|
6688
6796
|
return { nodes: {}, rootIds: [], activeLeafId: null, lastLeafId: null };
|
|
@@ -6843,6 +6951,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6843
6951
|
onRenameConversation,
|
|
6844
6952
|
isStreaming = false,
|
|
6845
6953
|
isThinking = false,
|
|
6954
|
+
thinkingLabel,
|
|
6846
6955
|
placeholder = "Send a message...",
|
|
6847
6956
|
emptyStateHelper = "Let's talk.",
|
|
6848
6957
|
emptyState,
|
|
@@ -6851,6 +6960,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6851
6960
|
attachments: propsAttachments,
|
|
6852
6961
|
onAttachmentsChange,
|
|
6853
6962
|
onAttachmentRemove,
|
|
6963
|
+
onAttachmentOpen,
|
|
6854
6964
|
artifactNodes,
|
|
6855
6965
|
isArtifactsPanelOpen,
|
|
6856
6966
|
onArtifactsPanelOpenChange,
|
|
@@ -6867,6 +6977,14 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6867
6977
|
}, ref) => {
|
|
6868
6978
|
const prevArtifactNodesRef = (0, import_react81.useRef)([]);
|
|
6869
6979
|
const prevTasksRef = (0, import_react81.useRef)([]);
|
|
6980
|
+
const [panelOpenArtifactId, setPanelOpenArtifactId] = (0, import_react81.useState)(null);
|
|
6981
|
+
const handleAttachmentOpen = (0, import_react81.useCallback)((artifactId) => {
|
|
6982
|
+
setPanelOpenArtifactId(artifactId);
|
|
6983
|
+
onAttachmentOpen?.(artifactId);
|
|
6984
|
+
}, [onAttachmentOpen]);
|
|
6985
|
+
const handleArtifactPanelClosed = (0, import_react81.useCallback)(() => {
|
|
6986
|
+
setPanelOpenArtifactId(null);
|
|
6987
|
+
}, []);
|
|
6870
6988
|
const [internalTools, setInternalTools] = (0, import_react81.useState)({
|
|
6871
6989
|
"top-left": "history",
|
|
6872
6990
|
"bottom-left": null,
|
|
@@ -7054,7 +7172,15 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7054
7172
|
isStreaming: node.isStreaming,
|
|
7055
7173
|
muted: opts.muted,
|
|
7056
7174
|
branchInfo,
|
|
7057
|
-
actions
|
|
7175
|
+
actions,
|
|
7176
|
+
attachments: node.attachments ? node.attachments.map((a) => ({
|
|
7177
|
+
id: a.id,
|
|
7178
|
+
file: { name: a.name, size: a.size ?? 0, type: a.type },
|
|
7179
|
+
previewUrl: a.previewUrl,
|
|
7180
|
+
artifactId: a.artifactId,
|
|
7181
|
+
status: a.status ?? "analyzed"
|
|
7182
|
+
})) : void 0,
|
|
7183
|
+
onAttachmentOpen: handleAttachmentOpen
|
|
7058
7184
|
};
|
|
7059
7185
|
},
|
|
7060
7186
|
[
|
|
@@ -7064,7 +7190,8 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7064
7190
|
onEditMessage,
|
|
7065
7191
|
onRetryMessage,
|
|
7066
7192
|
handleBranchSwitch,
|
|
7067
|
-
handleJumpToCheckpoint
|
|
7193
|
+
handleJumpToCheckpoint,
|
|
7194
|
+
handleAttachmentOpen
|
|
7068
7195
|
]
|
|
7069
7196
|
);
|
|
7070
7197
|
const displayItems = (0, import_react81.useMemo)(() => {
|
|
@@ -7133,6 +7260,8 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7133
7260
|
ArtifactsPanel,
|
|
7134
7261
|
{
|
|
7135
7262
|
nodes: artifactNodes,
|
|
7263
|
+
openArtifactId: panelOpenArtifactId,
|
|
7264
|
+
onArtifactClosed: handleArtifactPanelClosed,
|
|
7136
7265
|
className: "h-full"
|
|
7137
7266
|
}
|
|
7138
7267
|
);
|
|
@@ -7195,6 +7324,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7195
7324
|
latestUserMessageIndex,
|
|
7196
7325
|
isStreaming,
|
|
7197
7326
|
isThinking,
|
|
7327
|
+
thinkingLabel,
|
|
7198
7328
|
className: "flex-1"
|
|
7199
7329
|
}
|
|
7200
7330
|
)), /* @__PURE__ */ import_react81.default.createElement("div", { className: cx(
|