@lukeashford/aurelius 4.1.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 +359 -224
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +269 -133
- 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(
|
|
@@ -3871,12 +3917,14 @@ var import_lucide_react11 = require("lucide-react");
|
|
|
3871
3917
|
var import_react55 = __toESM(require("react"));
|
|
3872
3918
|
var import_dompurify = __toESM(require("dompurify"));
|
|
3873
3919
|
var import_marked = require("marked");
|
|
3874
|
-
import_dompurify.default.addHook
|
|
3875
|
-
|
|
3876
|
-
node.
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
}
|
|
3920
|
+
if (typeof window !== "undefined" && typeof import_dompurify.default.addHook === "function") {
|
|
3921
|
+
import_dompurify.default.addHook("afterSanitizeAttributes", (node) => {
|
|
3922
|
+
if (node.tagName === "A") {
|
|
3923
|
+
node.setAttribute("target", "_blank");
|
|
3924
|
+
node.setAttribute("rel", "noopener noreferrer");
|
|
3925
|
+
}
|
|
3926
|
+
});
|
|
3927
|
+
}
|
|
3880
3928
|
var DEFAULT_SANITIZE_CONFIG = {
|
|
3881
3929
|
ALLOWED_TAGS: [
|
|
3882
3930
|
"h1",
|
|
@@ -3953,6 +4001,9 @@ function injectStreamingCursor(html, cursorClassName) {
|
|
|
3953
4001
|
CURSOR_BASE_CLASSES,
|
|
3954
4002
|
cursorClassName
|
|
3955
4003
|
)}" aria-hidden="true"></span>`;
|
|
4004
|
+
if (typeof DOMParser === "undefined") {
|
|
4005
|
+
return html + cursorHtml;
|
|
4006
|
+
}
|
|
3956
4007
|
const parser = new DOMParser();
|
|
3957
4008
|
const doc = parser.parseFromString(`<div>${html}</div>`, "text/html");
|
|
3958
4009
|
const container = doc.body.firstChild;
|
|
@@ -3989,7 +4040,7 @@ var MarkdownContent = import_react55.default.forwardRef(
|
|
|
3989
4040
|
} else {
|
|
3990
4041
|
htmlContent = content;
|
|
3991
4042
|
}
|
|
3992
|
-
const sanitized = htmlContent ? import_dompurify.default.sanitize(htmlContent, config) : "";
|
|
4043
|
+
const sanitized = htmlContent && typeof import_dompurify.default.sanitize === "function" ? import_dompurify.default.sanitize(htmlContent, config) : htmlContent || "";
|
|
3993
4044
|
if (isStreaming) {
|
|
3994
4045
|
return injectStreamingCursor(sanitized, cursorClassName);
|
|
3995
4046
|
}
|
|
@@ -4044,6 +4095,8 @@ var Message = import_react56.default.forwardRef(
|
|
|
4044
4095
|
branchInfo,
|
|
4045
4096
|
actions,
|
|
4046
4097
|
hideActions,
|
|
4098
|
+
attachments,
|
|
4099
|
+
onAttachmentOpen,
|
|
4047
4100
|
...rest
|
|
4048
4101
|
}, ref) => {
|
|
4049
4102
|
const isUser = variant === "user";
|
|
@@ -4111,6 +4164,14 @@ var Message = import_react56.default.forwardRef(
|
|
|
4111
4164
|
),
|
|
4112
4165
|
...rest
|
|
4113
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
|
+
)),
|
|
4114
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(
|
|
4115
4176
|
"textarea",
|
|
4116
4177
|
{
|
|
@@ -4361,6 +4422,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4361
4422
|
isVisible = true,
|
|
4362
4423
|
phraseInterval = 2500,
|
|
4363
4424
|
phrases = THINKING_PHRASES,
|
|
4425
|
+
manualLabel,
|
|
4364
4426
|
className,
|
|
4365
4427
|
...rest
|
|
4366
4428
|
}, ref) => {
|
|
@@ -4368,8 +4430,9 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4368
4430
|
() => Math.floor(Math.random() * phrases.length)
|
|
4369
4431
|
);
|
|
4370
4432
|
const [isTransitioning, setIsTransitioning] = (0, import_react60.useState)(false);
|
|
4433
|
+
const isManual = manualLabel !== void 0;
|
|
4371
4434
|
(0, import_react60.useEffect)(() => {
|
|
4372
|
-
if (!isVisible || phrases.length <= 1) {
|
|
4435
|
+
if (!isVisible || isManual || phrases.length <= 1) {
|
|
4373
4436
|
return;
|
|
4374
4437
|
}
|
|
4375
4438
|
let fadeTimeout = null;
|
|
@@ -4387,7 +4450,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4387
4450
|
clearTimeout(fadeTimeout);
|
|
4388
4451
|
}
|
|
4389
4452
|
};
|
|
4390
|
-
}, [isVisible, phrases.length, phraseInterval]);
|
|
4453
|
+
}, [isVisible, isManual, phrases.length, phraseInterval]);
|
|
4391
4454
|
if (!isVisible) {
|
|
4392
4455
|
return null;
|
|
4393
4456
|
}
|
|
@@ -4424,7 +4487,7 @@ var ThinkingIndicator = import_react60.default.forwardRef(
|
|
|
4424
4487
|
style: { animationDelay: "300ms" }
|
|
4425
4488
|
}
|
|
4426
4489
|
)),
|
|
4427
|
-
/* @__PURE__ */ import_react60.default.createElement(
|
|
4490
|
+
isManual ? /* @__PURE__ */ import_react60.default.createElement("span", { className: "text-sm italic" }, manualLabel) : /* @__PURE__ */ import_react60.default.createElement(
|
|
4428
4491
|
"span",
|
|
4429
4492
|
{
|
|
4430
4493
|
className: cx(
|
|
@@ -4446,13 +4509,15 @@ var KIND_ICONS = {
|
|
|
4446
4509
|
task: import_lucide_react12.GitBranch,
|
|
4447
4510
|
submit: import_lucide_react12.GitMerge,
|
|
4448
4511
|
rename: import_lucide_react12.PencilLine,
|
|
4449
|
-
init: import_lucide_react12.GitCommitVertical
|
|
4512
|
+
init: import_lucide_react12.GitCommitVertical,
|
|
4513
|
+
ingest: import_lucide_react12.Upload
|
|
4450
4514
|
};
|
|
4451
4515
|
var KIND_ARIA_LABELS = {
|
|
4452
4516
|
task: "Task checkpoint",
|
|
4453
4517
|
submit: "Submit checkpoint",
|
|
4454
4518
|
rename: "Rename checkpoint",
|
|
4455
|
-
init: "Project head checkpoint"
|
|
4519
|
+
init: "Project head checkpoint",
|
|
4520
|
+
ingest: "Upload batch checkpoint"
|
|
4456
4521
|
};
|
|
4457
4522
|
var Checkpoint = import_react61.default.forwardRef(
|
|
4458
4523
|
function Checkpoint2({ name, executionKind, status = "completed", isActive, muted, branchInfo, onJumpHere }, ref) {
|
|
@@ -4601,7 +4666,16 @@ GreyedDivider.displayName = "GreyedDivider";
|
|
|
4601
4666
|
|
|
4602
4667
|
// src/components/chat/ChatView.tsx
|
|
4603
4668
|
var ChatView = import_react63.default.forwardRef(
|
|
4604
|
-
function ChatView2({
|
|
4669
|
+
function ChatView2({
|
|
4670
|
+
items,
|
|
4671
|
+
latestUserMessageIndex,
|
|
4672
|
+
isStreaming,
|
|
4673
|
+
isThinking,
|
|
4674
|
+
thinkingLabel,
|
|
4675
|
+
onScroll,
|
|
4676
|
+
className,
|
|
4677
|
+
...rest
|
|
4678
|
+
}, ref) {
|
|
4605
4679
|
const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
|
|
4606
4680
|
behavior: "smooth",
|
|
4607
4681
|
block: "start"
|
|
@@ -4684,7 +4758,7 @@ var ChatView = import_react63.default.forwardRef(
|
|
|
4684
4758
|
}
|
|
4685
4759
|
)
|
|
4686
4760
|
);
|
|
4687
|
-
}), showThinking && /* @__PURE__ */ import_react63.default.createElement(ThinkingIndicator, { isVisible: true })),
|
|
4761
|
+
}), showThinking && /* @__PURE__ */ import_react63.default.createElement(ThinkingIndicator, { isVisible: true, manualLabel: thinkingLabel })),
|
|
4688
4762
|
/* @__PURE__ */ import_react63.default.createElement(
|
|
4689
4763
|
"div",
|
|
4690
4764
|
{
|
|
@@ -4869,8 +4943,8 @@ var ChatInput = import_react64.default.forwardRef(
|
|
|
4869
4943
|
);
|
|
4870
4944
|
const isCentered = position === "centered";
|
|
4871
4945
|
const hasAttachments = attachments.length > 0;
|
|
4872
|
-
const
|
|
4873
|
-
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;
|
|
4874
4948
|
return /* @__PURE__ */ import_react64.default.createElement(
|
|
4875
4949
|
"div",
|
|
4876
4950
|
{
|
|
@@ -5007,7 +5081,7 @@ var ChatInput = import_react64.default.forwardRef(
|
|
|
5007
5081
|
ChatInput.displayName = "ChatInput";
|
|
5008
5082
|
|
|
5009
5083
|
// src/components/chat/ArtifactsPanel.tsx
|
|
5010
|
-
var
|
|
5084
|
+
var import_react76 = __toESM(require("react"));
|
|
5011
5085
|
var import_lucide_react17 = require("lucide-react");
|
|
5012
5086
|
|
|
5013
5087
|
// src/components/ArtifactCard.tsx
|
|
@@ -5665,15 +5739,74 @@ var ArtifactVariantStack = import_react73.default.forwardRef(
|
|
|
5665
5739
|
);
|
|
5666
5740
|
ArtifactVariantStack.displayName = "ArtifactVariantStack";
|
|
5667
5741
|
|
|
5668
|
-
// src/components/chat/hooks/
|
|
5742
|
+
// src/components/chat/hooks/useResizable.ts
|
|
5669
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");
|
|
5670
5803
|
function useArtifactTreeNavigation(rootNodes) {
|
|
5671
|
-
const [stack, setStack] = (0,
|
|
5672
|
-
const currentNodes = (0,
|
|
5804
|
+
const [stack, setStack] = (0, import_react75.useState)([]);
|
|
5805
|
+
const currentNodes = (0, import_react75.useMemo)(() => {
|
|
5673
5806
|
if (stack.length === 0) return rootNodes;
|
|
5674
5807
|
return stack[stack.length - 1].children;
|
|
5675
5808
|
}, [rootNodes, stack]);
|
|
5676
|
-
const breadcrumbs = (0,
|
|
5809
|
+
const breadcrumbs = (0, import_react75.useMemo)(() => {
|
|
5677
5810
|
const entries = [{ label: "Project", node: null }];
|
|
5678
5811
|
for (const node of stack) {
|
|
5679
5812
|
entries.push({ label: node.label, node });
|
|
@@ -5681,13 +5814,13 @@ function useArtifactTreeNavigation(rootNodes) {
|
|
|
5681
5814
|
return entries;
|
|
5682
5815
|
}, [stack]);
|
|
5683
5816
|
const isAtRoot = stack.length === 0;
|
|
5684
|
-
const navigateInto = (0,
|
|
5817
|
+
const navigateInto = (0, import_react75.useCallback)((node) => {
|
|
5685
5818
|
setStack((prev) => [...prev, node]);
|
|
5686
5819
|
}, []);
|
|
5687
|
-
const navigateTo = (0,
|
|
5820
|
+
const navigateTo = (0, import_react75.useCallback)((index) => {
|
|
5688
5821
|
setStack((prev) => prev.slice(0, index));
|
|
5689
5822
|
}, []);
|
|
5690
|
-
const navigateBack = (0,
|
|
5823
|
+
const navigateBack = (0, import_react75.useCallback)(() => {
|
|
5691
5824
|
setStack((prev) => prev.slice(0, -1));
|
|
5692
5825
|
}, []);
|
|
5693
5826
|
return {
|
|
@@ -5707,46 +5840,46 @@ function ArtifactModal({
|
|
|
5707
5840
|
onClose
|
|
5708
5841
|
}) {
|
|
5709
5842
|
useEscapeKey(onClose);
|
|
5710
|
-
const handleBackdropClick = (0,
|
|
5843
|
+
const handleBackdropClick = (0, import_react76.useCallback)((e) => {
|
|
5711
5844
|
if (e.target === e.currentTarget) {
|
|
5712
5845
|
onClose();
|
|
5713
5846
|
}
|
|
5714
5847
|
}, [onClose]);
|
|
5715
|
-
return /* @__PURE__ */
|
|
5848
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5716
5849
|
"div",
|
|
5717
5850
|
{
|
|
5718
5851
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
|
|
5719
5852
|
onClick: handleBackdropClick
|
|
5720
5853
|
},
|
|
5721
|
-
/* @__PURE__ */
|
|
5854
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5722
5855
|
"div",
|
|
5723
5856
|
{
|
|
5724
5857
|
className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
|
|
5725
5858
|
},
|
|
5726
|
-
/* @__PURE__ */
|
|
5859
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5727
5860
|
"div",
|
|
5728
5861
|
{
|
|
5729
5862
|
className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
|
|
5730
5863
|
},
|
|
5731
|
-
/* @__PURE__ */
|
|
5732
|
-
/* @__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(
|
|
5733
5866
|
"button",
|
|
5734
5867
|
{
|
|
5735
5868
|
onClick: onClose,
|
|
5736
5869
|
className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
|
|
5737
5870
|
"aria-label": "Close modal"
|
|
5738
5871
|
},
|
|
5739
|
-
/* @__PURE__ */
|
|
5872
|
+
/* @__PURE__ */ import_react76.default.createElement(CloseIcon, { className: "w-5 h-5" })
|
|
5740
5873
|
)
|
|
5741
5874
|
),
|
|
5742
|
-
/* @__PURE__ */
|
|
5875
|
+
/* @__PURE__ */ import_react76.default.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5743
5876
|
"img",
|
|
5744
5877
|
{
|
|
5745
5878
|
src: artifact.url,
|
|
5746
5879
|
alt: artifact.alt || "Artifact image",
|
|
5747
5880
|
className: "max-w-full max-h-full object-contain mx-auto"
|
|
5748
5881
|
}
|
|
5749
|
-
), artifact.type === "VIDEO" && /* @__PURE__ */
|
|
5882
|
+
), artifact.type === "VIDEO" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5750
5883
|
VideoCard,
|
|
5751
5884
|
{
|
|
5752
5885
|
src: artifact.url || "",
|
|
@@ -5754,20 +5887,20 @@ function ArtifactModal({
|
|
|
5754
5887
|
controls: true,
|
|
5755
5888
|
className: "max-w-full max-h-full mx-auto"
|
|
5756
5889
|
}
|
|
5757
|
-
), artifact.type === "AUDIO" && /* @__PURE__ */
|
|
5890
|
+
), artifact.type === "AUDIO" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5758
5891
|
AudioCard,
|
|
5759
5892
|
{
|
|
5760
5893
|
src: artifact.url || "",
|
|
5761
5894
|
controls: true,
|
|
5762
5895
|
className: "max-w-xl mx-auto"
|
|
5763
5896
|
}
|
|
5764
|
-
), artifact.type === "PDF" && /* @__PURE__ */
|
|
5897
|
+
), artifact.type === "PDF" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5765
5898
|
PdfCard,
|
|
5766
5899
|
{
|
|
5767
5900
|
src: artifact.url || "",
|
|
5768
5901
|
className: "h-full border-0"
|
|
5769
5902
|
}
|
|
5770
|
-
), artifact.type === "TEXT" && /* @__PURE__ */
|
|
5903
|
+
), artifact.type === "TEXT" && /* @__PURE__ */ import_react76.default.createElement(
|
|
5771
5904
|
MarkdownContent,
|
|
5772
5905
|
{
|
|
5773
5906
|
content: artifact.inlineContent || "",
|
|
@@ -5777,7 +5910,7 @@ function ArtifactModal({
|
|
|
5777
5910
|
artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
|
|
5778
5911
|
)
|
|
5779
5912
|
}
|
|
5780
|
-
), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */
|
|
5913
|
+
), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react76.default.createElement(
|
|
5781
5914
|
ScriptCard,
|
|
5782
5915
|
{
|
|
5783
5916
|
elements: artifact.scriptElements,
|
|
@@ -5788,6 +5921,20 @@ function ArtifactModal({
|
|
|
5788
5921
|
)
|
|
5789
5922
|
);
|
|
5790
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
|
+
}
|
|
5791
5938
|
function NodeRenderer({
|
|
5792
5939
|
node,
|
|
5793
5940
|
loading,
|
|
@@ -5795,7 +5942,7 @@ function NodeRenderer({
|
|
|
5795
5942
|
onGroupClick
|
|
5796
5943
|
}) {
|
|
5797
5944
|
if (node.type === "ARTIFACT" && node.artifact) {
|
|
5798
|
-
return /* @__PURE__ */
|
|
5945
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5799
5946
|
ArtifactCard,
|
|
5800
5947
|
{
|
|
5801
5948
|
artifact: node.artifact,
|
|
@@ -5805,10 +5952,10 @@ function NodeRenderer({
|
|
|
5805
5952
|
);
|
|
5806
5953
|
}
|
|
5807
5954
|
if (node.type === "GROUP") {
|
|
5808
|
-
return /* @__PURE__ */
|
|
5955
|
+
return /* @__PURE__ */ import_react76.default.createElement(ArtifactGroup, { node, onClick: onGroupClick });
|
|
5809
5956
|
}
|
|
5810
5957
|
if (node.type === "VARIANT_SET") {
|
|
5811
|
-
return /* @__PURE__ */
|
|
5958
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5812
5959
|
ArtifactVariantStack,
|
|
5813
5960
|
{
|
|
5814
5961
|
node,
|
|
@@ -5819,42 +5966,59 @@ function NodeRenderer({
|
|
|
5819
5966
|
}
|
|
5820
5967
|
return null;
|
|
5821
5968
|
}
|
|
5822
|
-
var ArtifactsPanel =
|
|
5969
|
+
var ArtifactsPanel = import_react76.default.forwardRef(
|
|
5823
5970
|
({
|
|
5824
5971
|
nodes,
|
|
5825
5972
|
loading,
|
|
5973
|
+
openArtifactId,
|
|
5974
|
+
onArtifactClosed,
|
|
5826
5975
|
className,
|
|
5827
5976
|
...rest
|
|
5828
5977
|
}, ref) => {
|
|
5829
|
-
const [expandedArtifact, setExpandedArtifact] = (0,
|
|
5830
|
-
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);
|
|
5831
5980
|
const treeNav = useArtifactTreeNavigation(nodes || []);
|
|
5832
5981
|
const hasNodes = !!nodes && nodes.length > 0;
|
|
5833
|
-
const handleExpandArtifact = (0,
|
|
5982
|
+
const handleExpandArtifact = (0, import_react76.useCallback)((artifact) => {
|
|
5834
5983
|
setExpandedArtifact(artifact);
|
|
5835
5984
|
}, []);
|
|
5836
|
-
const handleGroupClick = (0,
|
|
5985
|
+
const handleGroupClick = (0, import_react76.useCallback)((node) => {
|
|
5837
5986
|
treeNav.navigateInto(node);
|
|
5838
5987
|
}, [treeNav]);
|
|
5839
|
-
|
|
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)(() => {
|
|
5840
6002
|
setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
|
|
5841
6003
|
}, []);
|
|
5842
|
-
const zoomOut = (0,
|
|
6004
|
+
const zoomOut = (0, import_react76.useCallback)(() => {
|
|
5843
6005
|
setZoomIndex((prev) => Math.max(prev - 1, 0));
|
|
5844
6006
|
}, []);
|
|
5845
6007
|
const currentZoom = ZOOM_LEVELS[zoomIndex];
|
|
5846
|
-
const contentRef = (0,
|
|
5847
|
-
const [contentHeight, setContentHeight] = (0,
|
|
5848
|
-
(0,
|
|
6008
|
+
const contentRef = (0, import_react76.useRef)(null);
|
|
6009
|
+
const [contentHeight, setContentHeight] = (0, import_react76.useState)(void 0);
|
|
6010
|
+
(0, import_react76.useEffect)(() => {
|
|
5849
6011
|
const el = contentRef.current;
|
|
5850
|
-
if (!el)
|
|
6012
|
+
if (!el) {
|
|
6013
|
+
return;
|
|
6014
|
+
}
|
|
5851
6015
|
const observer = new ResizeObserver(([entry]) => {
|
|
5852
6016
|
setContentHeight(entry.contentRect.height);
|
|
5853
6017
|
});
|
|
5854
6018
|
observer.observe(el);
|
|
5855
6019
|
return () => observer.disconnect();
|
|
5856
6020
|
}, []);
|
|
5857
|
-
return /* @__PURE__ */
|
|
6021
|
+
return /* @__PURE__ */ import_react76.default.createElement(import_react76.default.Fragment, null, /* @__PURE__ */ import_react76.default.createElement(
|
|
5858
6022
|
"div",
|
|
5859
6023
|
{
|
|
5860
6024
|
ref,
|
|
@@ -5865,19 +6029,19 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5865
6029
|
),
|
|
5866
6030
|
...rest
|
|
5867
6031
|
},
|
|
5868
|
-
/* @__PURE__ */
|
|
6032
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5869
6033
|
"div",
|
|
5870
6034
|
{
|
|
5871
6035
|
className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
|
|
5872
6036
|
},
|
|
5873
|
-
/* @__PURE__ */
|
|
5874
|
-
hasNodes && /* @__PURE__ */
|
|
6037
|
+
/* @__PURE__ */ import_react76.default.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
|
|
6038
|
+
hasNodes && /* @__PURE__ */ import_react76.default.createElement(
|
|
5875
6039
|
"div",
|
|
5876
6040
|
{
|
|
5877
6041
|
className: "flex items-center gap-0.5",
|
|
5878
6042
|
"data-testid": "zoom-controls"
|
|
5879
6043
|
},
|
|
5880
|
-
/* @__PURE__ */
|
|
6044
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5881
6045
|
"button",
|
|
5882
6046
|
{
|
|
5883
6047
|
onClick: zoomOut,
|
|
@@ -5891,8 +6055,16 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5891
6055
|
},
|
|
5892
6056
|
"\u2212"
|
|
5893
6057
|
),
|
|
5894
|
-
/* @__PURE__ */
|
|
5895
|
-
|
|
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(
|
|
5896
6068
|
"button",
|
|
5897
6069
|
{
|
|
5898
6070
|
onClick: zoomIn,
|
|
@@ -5908,7 +6080,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5908
6080
|
)
|
|
5909
6081
|
)
|
|
5910
6082
|
),
|
|
5911
|
-
hasNodes && !treeNav.isAtRoot && /* @__PURE__ */
|
|
6083
|
+
hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ import_react76.default.createElement(
|
|
5912
6084
|
"nav",
|
|
5913
6085
|
{
|
|
5914
6086
|
className: "flex items-center gap-1 px-4 py-2 border-b border-ash/40 shrink-0 overflow-x-auto text-xs",
|
|
@@ -5917,7 +6089,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5917
6089
|
},
|
|
5918
6090
|
treeNav.breadcrumbs.map((crumb, i) => {
|
|
5919
6091
|
const isLast = i === treeNav.breadcrumbs.length - 1;
|
|
5920
|
-
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(
|
|
5921
6093
|
"button",
|
|
5922
6094
|
{
|
|
5923
6095
|
onClick: () => treeNav.navigateTo(i),
|
|
@@ -5927,18 +6099,18 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5927
6099
|
));
|
|
5928
6100
|
})
|
|
5929
6101
|
),
|
|
5930
|
-
/* @__PURE__ */
|
|
6102
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5931
6103
|
"div",
|
|
5932
6104
|
{
|
|
5933
6105
|
className: "flex-1 overflow-auto relative",
|
|
5934
6106
|
"data-testid": "artifacts-scroll-area"
|
|
5935
6107
|
},
|
|
5936
|
-
/* @__PURE__ */
|
|
6108
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5937
6109
|
"div",
|
|
5938
6110
|
{
|
|
5939
6111
|
style: currentZoom !== 1 && contentHeight !== void 0 ? { height: contentHeight * currentZoom } : void 0
|
|
5940
6112
|
},
|
|
5941
|
-
/* @__PURE__ */
|
|
6113
|
+
/* @__PURE__ */ import_react76.default.createElement(
|
|
5942
6114
|
"div",
|
|
5943
6115
|
{
|
|
5944
6116
|
ref: contentRef,
|
|
@@ -5949,7 +6121,7 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5949
6121
|
transformOrigin: "top center"
|
|
5950
6122
|
} : void 0
|
|
5951
6123
|
},
|
|
5952
|
-
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(
|
|
5953
6125
|
NodeRenderer,
|
|
5954
6126
|
{
|
|
5955
6127
|
key: node.id,
|
|
@@ -5962,18 +6134,18 @@ var ArtifactsPanel = import_react75.default.forwardRef(
|
|
|
5962
6134
|
)
|
|
5963
6135
|
)
|
|
5964
6136
|
)
|
|
5965
|
-
), expandedArtifact && /* @__PURE__ */
|
|
6137
|
+
), expandedArtifact && /* @__PURE__ */ import_react76.default.createElement(
|
|
5966
6138
|
ArtifactModal,
|
|
5967
6139
|
{
|
|
5968
6140
|
artifact: expandedArtifact,
|
|
5969
|
-
onClose:
|
|
6141
|
+
onClose: handleModalClose
|
|
5970
6142
|
}
|
|
5971
6143
|
));
|
|
5972
6144
|
}
|
|
5973
6145
|
);
|
|
5974
6146
|
ArtifactsPanel.displayName = "ArtifactsPanel";
|
|
5975
|
-
var ArtifactsPanelToggle =
|
|
5976
|
-
return /* @__PURE__ */
|
|
6147
|
+
var ArtifactsPanelToggle = import_react76.default.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
|
|
6148
|
+
return /* @__PURE__ */ import_react76.default.createElement(
|
|
5977
6149
|
"button",
|
|
5978
6150
|
{
|
|
5979
6151
|
ref,
|
|
@@ -5990,8 +6162,8 @@ var ArtifactsPanelToggle = import_react75.default.forwardRef(({ artifactCount =
|
|
|
5990
6162
|
"aria-label": "Expand artifacts panel",
|
|
5991
6163
|
...rest
|
|
5992
6164
|
},
|
|
5993
|
-
/* @__PURE__ */
|
|
5994
|
-
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(
|
|
5995
6167
|
"span",
|
|
5996
6168
|
{
|
|
5997
6169
|
className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center"
|
|
@@ -6003,7 +6175,7 @@ var ArtifactsPanelToggle = import_react75.default.forwardRef(({ artifactCount =
|
|
|
6003
6175
|
ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
|
|
6004
6176
|
|
|
6005
6177
|
// src/components/chat/HistoryPanel.tsx
|
|
6006
|
-
var
|
|
6178
|
+
var import_react77 = __toESM(require("react"));
|
|
6007
6179
|
var import_lucide_react18 = require("lucide-react");
|
|
6008
6180
|
function parseTimestamp(ts) {
|
|
6009
6181
|
if (ts == null) {
|
|
@@ -6046,12 +6218,12 @@ function ProjectFilter({
|
|
|
6046
6218
|
onChange,
|
|
6047
6219
|
className
|
|
6048
6220
|
}) {
|
|
6049
|
-
const [open, setOpen] = (0,
|
|
6050
|
-
const ref = (0,
|
|
6051
|
-
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), []);
|
|
6052
6224
|
useClickOutside(ref, closeFilter, open);
|
|
6053
6225
|
const label = value ?? "All projects";
|
|
6054
|
-
return /* @__PURE__ */
|
|
6226
|
+
return /* @__PURE__ */ import_react77.default.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ import_react77.default.createElement(
|
|
6055
6227
|
"button",
|
|
6056
6228
|
{
|
|
6057
6229
|
type: "button",
|
|
@@ -6067,9 +6239,9 @@ function ProjectFilter({
|
|
|
6067
6239
|
"transition-colors duration-150 min-w-0"
|
|
6068
6240
|
)
|
|
6069
6241
|
},
|
|
6070
|
-
/* @__PURE__ */
|
|
6071
|
-
/* @__PURE__ */
|
|
6072
|
-
), 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(
|
|
6073
6245
|
"div",
|
|
6074
6246
|
{
|
|
6075
6247
|
role: "listbox",
|
|
@@ -6079,7 +6251,7 @@ function ProjectFilter({
|
|
|
6079
6251
|
"max-h-60 overflow-y-auto"
|
|
6080
6252
|
)
|
|
6081
6253
|
},
|
|
6082
|
-
/* @__PURE__ */
|
|
6254
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6083
6255
|
"button",
|
|
6084
6256
|
{
|
|
6085
6257
|
type: "button",
|
|
@@ -6097,7 +6269,7 @@ function ProjectFilter({
|
|
|
6097
6269
|
},
|
|
6098
6270
|
"All projects"
|
|
6099
6271
|
),
|
|
6100
|
-
projects.map((p) => /* @__PURE__ */
|
|
6272
|
+
projects.map((p) => /* @__PURE__ */ import_react77.default.createElement(
|
|
6101
6273
|
"button",
|
|
6102
6274
|
{
|
|
6103
6275
|
key: p,
|
|
@@ -6123,33 +6295,33 @@ function ConversationRow({
|
|
|
6123
6295
|
onSelect,
|
|
6124
6296
|
onRename
|
|
6125
6297
|
}) {
|
|
6126
|
-
const [isEditing, setIsEditing] = (0,
|
|
6127
|
-
const [draft, setDraft] = (0,
|
|
6128
|
-
const inputRef = (0,
|
|
6129
|
-
(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)(() => {
|
|
6130
6302
|
if (isEditing && inputRef.current) {
|
|
6131
6303
|
inputRef.current.focus();
|
|
6132
6304
|
inputRef.current.select();
|
|
6133
6305
|
}
|
|
6134
6306
|
}, [isEditing]);
|
|
6135
|
-
const startEdit = (0,
|
|
6307
|
+
const startEdit = (0, import_react77.useCallback)((e) => {
|
|
6136
6308
|
e.stopPropagation();
|
|
6137
6309
|
setDraft(conversation.title);
|
|
6138
6310
|
setIsEditing(true);
|
|
6139
6311
|
}, [conversation.title]);
|
|
6140
|
-
const commit = (0,
|
|
6312
|
+
const commit = (0, import_react77.useCallback)(() => {
|
|
6141
6313
|
const trimmed = draft.trim();
|
|
6142
6314
|
if (trimmed && trimmed !== conversation.title) {
|
|
6143
6315
|
onRename?.(conversation.id, trimmed);
|
|
6144
6316
|
}
|
|
6145
6317
|
setIsEditing(false);
|
|
6146
6318
|
}, [draft, conversation.id, conversation.title, onRename]);
|
|
6147
|
-
const cancel = (0,
|
|
6319
|
+
const cancel = (0, import_react77.useCallback)(() => {
|
|
6148
6320
|
setDraft(conversation.title);
|
|
6149
6321
|
setIsEditing(false);
|
|
6150
6322
|
}, [conversation.title]);
|
|
6151
6323
|
if (isEditing) {
|
|
6152
|
-
return /* @__PURE__ */
|
|
6324
|
+
return /* @__PURE__ */ import_react77.default.createElement(
|
|
6153
6325
|
"div",
|
|
6154
6326
|
{
|
|
6155
6327
|
className: cx(
|
|
@@ -6157,7 +6329,7 @@ function ConversationRow({
|
|
|
6157
6329
|
conversation.isActive ? "bg-ash/40" : "bg-ash/20"
|
|
6158
6330
|
)
|
|
6159
6331
|
},
|
|
6160
|
-
/* @__PURE__ */
|
|
6332
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6161
6333
|
"input",
|
|
6162
6334
|
{
|
|
6163
6335
|
ref: inputRef,
|
|
@@ -6182,10 +6354,10 @@ function ConversationRow({
|
|
|
6182
6354
|
"aria-label": "Conversation title"
|
|
6183
6355
|
}
|
|
6184
6356
|
),
|
|
6185
|
-
conversation.project && /* @__PURE__ */
|
|
6357
|
+
conversation.project && /* @__PURE__ */ import_react77.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-1" }, conversation.project)
|
|
6186
6358
|
);
|
|
6187
6359
|
}
|
|
6188
|
-
return /* @__PURE__ */
|
|
6360
|
+
return /* @__PURE__ */ import_react77.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react77.default.createElement(
|
|
6189
6361
|
"button",
|
|
6190
6362
|
{
|
|
6191
6363
|
onClick: () => onSelect?.(conversation.id),
|
|
@@ -6195,7 +6367,7 @@ function ConversationRow({
|
|
|
6195
6367
|
conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
|
|
6196
6368
|
)
|
|
6197
6369
|
},
|
|
6198
|
-
/* @__PURE__ */
|
|
6370
|
+
/* @__PURE__ */ import_react77.default.createElement(
|
|
6199
6371
|
"p",
|
|
6200
6372
|
{
|
|
6201
6373
|
className: cx(
|
|
@@ -6205,8 +6377,8 @@ function ConversationRow({
|
|
|
6205
6377
|
},
|
|
6206
6378
|
conversation.title
|
|
6207
6379
|
),
|
|
6208
|
-
conversation.project && /* @__PURE__ */
|
|
6209
|
-
), 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(
|
|
6210
6382
|
"button",
|
|
6211
6383
|
{
|
|
6212
6384
|
type: "button",
|
|
@@ -6219,7 +6391,7 @@ function ConversationRow({
|
|
|
6219
6391
|
"transition-opacity duration-150"
|
|
6220
6392
|
)
|
|
6221
6393
|
},
|
|
6222
|
-
/* @__PURE__ */
|
|
6394
|
+
/* @__PURE__ */ import_react77.default.createElement(import_lucide_react18.Pencil, { className: "w-3.5 h-3.5", "aria-hidden": true })
|
|
6223
6395
|
));
|
|
6224
6396
|
}
|
|
6225
6397
|
function HistoryPanel({
|
|
@@ -6228,8 +6400,8 @@ function HistoryPanel({
|
|
|
6228
6400
|
onNewChat,
|
|
6229
6401
|
onRenameConversation
|
|
6230
6402
|
}) {
|
|
6231
|
-
const [projectFilter, setProjectFilter] = (0,
|
|
6232
|
-
const projects = (0,
|
|
6403
|
+
const [projectFilter, setProjectFilter] = (0, import_react77.useState)(null);
|
|
6404
|
+
const projects = (0, import_react77.useMemo)(() => {
|
|
6233
6405
|
const set = /* @__PURE__ */ new Set();
|
|
6234
6406
|
for (const c of conversations) {
|
|
6235
6407
|
if (c.project) {
|
|
@@ -6238,23 +6410,23 @@ function HistoryPanel({
|
|
|
6238
6410
|
}
|
|
6239
6411
|
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
6240
6412
|
}, [conversations]);
|
|
6241
|
-
(0,
|
|
6413
|
+
(0, import_react77.useEffect)(() => {
|
|
6242
6414
|
if (projectFilter && !projects.includes(projectFilter)) {
|
|
6243
6415
|
setProjectFilter(null);
|
|
6244
6416
|
}
|
|
6245
6417
|
}, [projects, projectFilter]);
|
|
6246
|
-
const filteredConversations = (0,
|
|
6418
|
+
const filteredConversations = (0, import_react77.useMemo)(() => {
|
|
6247
6419
|
if (!projectFilter) {
|
|
6248
6420
|
return conversations;
|
|
6249
6421
|
}
|
|
6250
6422
|
return conversations.filter((c) => c.project === projectFilter);
|
|
6251
6423
|
}, [conversations, projectFilter]);
|
|
6252
|
-
const groups = (0,
|
|
6424
|
+
const groups = (0, import_react77.useMemo)(
|
|
6253
6425
|
() => groupConversations(filteredConversations),
|
|
6254
6426
|
[filteredConversations]
|
|
6255
6427
|
);
|
|
6256
6428
|
const hasFilter = projects.length > 0;
|
|
6257
|
-
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(
|
|
6258
6430
|
ProjectFilter,
|
|
6259
6431
|
{
|
|
6260
6432
|
projects,
|
|
@@ -6262,7 +6434,7 @@ function HistoryPanel({
|
|
|
6262
6434
|
onChange: setProjectFilter,
|
|
6263
6435
|
className: "flex-1"
|
|
6264
6436
|
}
|
|
6265
|
-
)), 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(
|
|
6266
6438
|
"button",
|
|
6267
6439
|
{
|
|
6268
6440
|
onClick: onNewChat,
|
|
@@ -6274,15 +6446,15 @@ function HistoryPanel({
|
|
|
6274
6446
|
"transition-colors duration-200"
|
|
6275
6447
|
)
|
|
6276
6448
|
},
|
|
6277
|
-
/* @__PURE__ */
|
|
6278
|
-
/* @__PURE__ */
|
|
6279
|
-
)))), /* @__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(
|
|
6280
6452
|
"span",
|
|
6281
6453
|
{
|
|
6282
6454
|
className: "text-xs font-medium uppercase tracking-wider text-gold/70"
|
|
6283
6455
|
},
|
|
6284
6456
|
group.label
|
|
6285
|
-
), /* @__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(
|
|
6286
6458
|
ConversationRow,
|
|
6287
6459
|
{
|
|
6288
6460
|
key: conversation.id,
|
|
@@ -6294,7 +6466,7 @@ function HistoryPanel({
|
|
|
6294
6466
|
}
|
|
6295
6467
|
|
|
6296
6468
|
// src/components/chat/TodosList.tsx
|
|
6297
|
-
var
|
|
6469
|
+
var import_react78 = __toESM(require("react"));
|
|
6298
6470
|
var import_lucide_react19 = require("lucide-react");
|
|
6299
6471
|
var TASK_STATUSES = {
|
|
6300
6472
|
PENDING: "pending",
|
|
@@ -6306,16 +6478,16 @@ var TASK_STATUSES = {
|
|
|
6306
6478
|
function TaskIcon({ status }) {
|
|
6307
6479
|
switch (status) {
|
|
6308
6480
|
case "done":
|
|
6309
|
-
return /* @__PURE__ */
|
|
6481
|
+
return /* @__PURE__ */ import_react78.default.createElement(CheckSquareIcon, null);
|
|
6310
6482
|
case "in_progress":
|
|
6311
|
-
return /* @__PURE__ */
|
|
6483
|
+
return /* @__PURE__ */ import_react78.default.createElement(SquareLoaderIcon, null);
|
|
6312
6484
|
case "cancelled":
|
|
6313
|
-
return /* @__PURE__ */
|
|
6485
|
+
return /* @__PURE__ */ import_react78.default.createElement(CrossSquareIcon, { variant: "cancelled" });
|
|
6314
6486
|
case "failed":
|
|
6315
|
-
return /* @__PURE__ */
|
|
6487
|
+
return /* @__PURE__ */ import_react78.default.createElement(CrossSquareIcon, { variant: "failed" });
|
|
6316
6488
|
case "pending":
|
|
6317
6489
|
default:
|
|
6318
|
-
return /* @__PURE__ */
|
|
6490
|
+
return /* @__PURE__ */ import_react78.default.createElement(EmptySquareIcon, null);
|
|
6319
6491
|
}
|
|
6320
6492
|
}
|
|
6321
6493
|
function sortTasks(tasks) {
|
|
@@ -6335,14 +6507,14 @@ function TaskItem({ task, depth = 0 }) {
|
|
|
6335
6507
|
const isSubtle = task.status === "cancelled" || task.status === "failed";
|
|
6336
6508
|
const showSubtasks = task.subtasks && task.subtasks.length > 0;
|
|
6337
6509
|
const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
|
|
6338
|
-
return /* @__PURE__ */
|
|
6510
|
+
return /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react78.default.createElement(
|
|
6339
6511
|
"div",
|
|
6340
6512
|
{
|
|
6341
6513
|
className: "flex items-center gap-2 py-1",
|
|
6342
6514
|
style: { paddingLeft: `${depth * 1.5}rem` }
|
|
6343
6515
|
},
|
|
6344
|
-
/* @__PURE__ */
|
|
6345
|
-
/* @__PURE__ */
|
|
6516
|
+
/* @__PURE__ */ import_react78.default.createElement(TaskIcon, { status: task.status }),
|
|
6517
|
+
/* @__PURE__ */ import_react78.default.createElement(
|
|
6346
6518
|
"span",
|
|
6347
6519
|
{
|
|
6348
6520
|
className: cx(
|
|
@@ -6354,10 +6526,10 @@ function TaskItem({ task, depth = 0 }) {
|
|
|
6354
6526
|
)
|
|
6355
6527
|
},
|
|
6356
6528
|
task.label,
|
|
6357
|
-
task.status === "cancelled" && /* @__PURE__ */
|
|
6358
|
-
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)")
|
|
6359
6531
|
)
|
|
6360
|
-
), 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 }))));
|
|
6361
6533
|
}
|
|
6362
6534
|
function hasInProgressTask(tasks) {
|
|
6363
6535
|
return tasks.some((t) => {
|
|
@@ -6370,11 +6542,11 @@ function hasInProgressTask(tasks) {
|
|
|
6370
6542
|
return false;
|
|
6371
6543
|
});
|
|
6372
6544
|
}
|
|
6373
|
-
var TodosList =
|
|
6545
|
+
var TodosList = import_react78.default.forwardRef(
|
|
6374
6546
|
({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
|
|
6375
|
-
const sortedTasks = (0,
|
|
6376
|
-
const [isStopping, setIsStopping] = (0,
|
|
6377
|
-
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 () => {
|
|
6378
6550
|
if (!onStopAllTasks || isStopping) {
|
|
6379
6551
|
return;
|
|
6380
6552
|
}
|
|
@@ -6395,7 +6567,7 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6395
6567
|
if (tasks.length === 0) {
|
|
6396
6568
|
return null;
|
|
6397
6569
|
}
|
|
6398
|
-
return /* @__PURE__ */
|
|
6570
|
+
return /* @__PURE__ */ import_react78.default.createElement(
|
|
6399
6571
|
"div",
|
|
6400
6572
|
{
|
|
6401
6573
|
ref,
|
|
@@ -6406,16 +6578,16 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6406
6578
|
),
|
|
6407
6579
|
...rest
|
|
6408
6580
|
},
|
|
6409
|
-
/* @__PURE__ */
|
|
6581
|
+
/* @__PURE__ */ import_react78.default.createElement(
|
|
6410
6582
|
"div",
|
|
6411
6583
|
{
|
|
6412
6584
|
className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
|
|
6413
6585
|
},
|
|
6414
|
-
/* @__PURE__ */
|
|
6415
|
-
/* @__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))
|
|
6416
6588
|
),
|
|
6417
|
-
/* @__PURE__ */
|
|
6418
|
-
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(
|
|
6419
6591
|
"button",
|
|
6420
6592
|
{
|
|
6421
6593
|
type: "button",
|
|
@@ -6432,7 +6604,7 @@ var TodosList = import_react77.default.forwardRef(
|
|
|
6432
6604
|
isStopping ? "cursor-not-allowed opacity-70" : "hover:bg-error/20"
|
|
6433
6605
|
)
|
|
6434
6606
|
},
|
|
6435
|
-
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")
|
|
6436
6608
|
))
|
|
6437
6609
|
);
|
|
6438
6610
|
}
|
|
@@ -6452,8 +6624,8 @@ function areAllTasksSettled(tasks) {
|
|
|
6452
6624
|
}
|
|
6453
6625
|
|
|
6454
6626
|
// src/components/chat/ToolSidebar.tsx
|
|
6455
|
-
var
|
|
6456
|
-
var ToolSidebar =
|
|
6627
|
+
var import_react79 = __toESM(require("react"));
|
|
6628
|
+
var ToolSidebar = import_react79.default.forwardRef(
|
|
6457
6629
|
({ tools, activeTools, onToggleTool, side, className, ...rest }, ref) => {
|
|
6458
6630
|
const topTools = tools.filter((t) => t.group === `top-${side}`);
|
|
6459
6631
|
const bottomTools = tools.filter((t) => t.group === `bottom-${side}`);
|
|
@@ -6464,7 +6636,7 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6464
6636
|
};
|
|
6465
6637
|
const renderButton = (tool) => {
|
|
6466
6638
|
const active = isActive(tool.id);
|
|
6467
|
-
return /* @__PURE__ */
|
|
6639
|
+
return /* @__PURE__ */ import_react79.default.createElement(
|
|
6468
6640
|
"button",
|
|
6469
6641
|
{
|
|
6470
6642
|
key: tool.id,
|
|
@@ -6476,10 +6648,10 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6476
6648
|
"aria-label": tool.label,
|
|
6477
6649
|
"aria-pressed": active
|
|
6478
6650
|
},
|
|
6479
|
-
/* @__PURE__ */
|
|
6651
|
+
/* @__PURE__ */ import_react79.default.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
|
|
6480
6652
|
);
|
|
6481
6653
|
};
|
|
6482
|
-
return /* @__PURE__ */
|
|
6654
|
+
return /* @__PURE__ */ import_react79.default.createElement(
|
|
6483
6655
|
"div",
|
|
6484
6656
|
{
|
|
6485
6657
|
ref,
|
|
@@ -6490,17 +6662,17 @@ var ToolSidebar = import_react78.default.forwardRef(
|
|
|
6490
6662
|
),
|
|
6491
6663
|
...rest
|
|
6492
6664
|
},
|
|
6493
|
-
/* @__PURE__ */
|
|
6494
|
-
/* @__PURE__ */
|
|
6495
|
-
/* @__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))
|
|
6496
6668
|
);
|
|
6497
6669
|
}
|
|
6498
6670
|
);
|
|
6499
6671
|
ToolSidebar.displayName = "ToolSidebar";
|
|
6500
6672
|
|
|
6501
6673
|
// src/components/chat/ToolPanelContainer.tsx
|
|
6502
|
-
var
|
|
6503
|
-
var ToolPanelContainer =
|
|
6674
|
+
var import_react80 = __toESM(require("react"));
|
|
6675
|
+
var ToolPanelContainer = import_react80.default.forwardRef(
|
|
6504
6676
|
({
|
|
6505
6677
|
topContent,
|
|
6506
6678
|
bottomContent,
|
|
@@ -6511,21 +6683,21 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6511
6683
|
initialTopPercent = 60,
|
|
6512
6684
|
...rest
|
|
6513
6685
|
}, ref) => {
|
|
6514
|
-
const [topPercent, setTopPercent] = (0,
|
|
6515
|
-
const [isResizingHeight, setIsResizingHeight] = (0,
|
|
6516
|
-
const containerRef = (0,
|
|
6517
|
-
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);
|
|
6518
6690
|
const hasBoth = topContent !== null && bottomContent !== null;
|
|
6519
|
-
const startHeightResize = (0,
|
|
6691
|
+
const startHeightResize = (0, import_react80.useCallback)((e) => {
|
|
6520
6692
|
e.preventDefault();
|
|
6521
6693
|
setIsResizingHeight(true);
|
|
6522
6694
|
lastY.current = e.clientY;
|
|
6523
6695
|
}, []);
|
|
6524
|
-
const stopHeightResize = (0,
|
|
6696
|
+
const stopHeightResize = (0, import_react80.useCallback)(() => {
|
|
6525
6697
|
setIsResizingHeight(false);
|
|
6526
6698
|
lastY.current = null;
|
|
6527
6699
|
}, []);
|
|
6528
|
-
const resizeHeight = (0,
|
|
6700
|
+
const resizeHeight = (0, import_react80.useCallback)(
|
|
6529
6701
|
(e) => {
|
|
6530
6702
|
if (!isResizingHeight || lastY.current === null || !containerRef.current) {
|
|
6531
6703
|
return;
|
|
@@ -6544,7 +6716,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6544
6716
|
},
|
|
6545
6717
|
[isResizingHeight]
|
|
6546
6718
|
);
|
|
6547
|
-
(0,
|
|
6719
|
+
(0, import_react80.useEffect)(() => {
|
|
6548
6720
|
if (isResizingHeight) {
|
|
6549
6721
|
window.addEventListener("mousemove", resizeHeight);
|
|
6550
6722
|
window.addEventListener("mouseup", stopHeightResize);
|
|
@@ -6563,7 +6735,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6563
6735
|
document.body.style.userSelect = "";
|
|
6564
6736
|
};
|
|
6565
6737
|
}, [isResizingHeight, resizeHeight, stopHeightResize]);
|
|
6566
|
-
return /* @__PURE__ */
|
|
6738
|
+
return /* @__PURE__ */ import_react80.default.createElement(
|
|
6567
6739
|
"div",
|
|
6568
6740
|
{
|
|
6569
6741
|
ref: composeRefs(containerRef, ref),
|
|
@@ -6575,7 +6747,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6575
6747
|
style: width ? { width } : void 0,
|
|
6576
6748
|
...rest
|
|
6577
6749
|
},
|
|
6578
|
-
/* @__PURE__ */
|
|
6750
|
+
/* @__PURE__ */ import_react80.default.createElement(
|
|
6579
6751
|
"div",
|
|
6580
6752
|
{
|
|
6581
6753
|
onMouseDown: onResizeStart,
|
|
@@ -6586,7 +6758,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6586
6758
|
)
|
|
6587
6759
|
}
|
|
6588
6760
|
),
|
|
6589
|
-
topContent !== null && /* @__PURE__ */
|
|
6761
|
+
topContent !== null && /* @__PURE__ */ import_react80.default.createElement(
|
|
6590
6762
|
"div",
|
|
6591
6763
|
{
|
|
6592
6764
|
className: "min-h-0 overflow-hidden flex flex-col",
|
|
@@ -6594,7 +6766,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6594
6766
|
},
|
|
6595
6767
|
topContent
|
|
6596
6768
|
),
|
|
6597
|
-
hasBoth && /* @__PURE__ */
|
|
6769
|
+
hasBoth && /* @__PURE__ */ import_react80.default.createElement(
|
|
6598
6770
|
"div",
|
|
6599
6771
|
{
|
|
6600
6772
|
onMouseDown: startHeightResize,
|
|
@@ -6606,7 +6778,7 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6606
6778
|
)
|
|
6607
6779
|
}
|
|
6608
6780
|
),
|
|
6609
|
-
bottomContent !== null && /* @__PURE__ */
|
|
6781
|
+
bottomContent !== null && /* @__PURE__ */ import_react80.default.createElement(
|
|
6610
6782
|
"div",
|
|
6611
6783
|
{
|
|
6612
6784
|
className: "min-h-0 overflow-hidden flex flex-col",
|
|
@@ -6619,65 +6791,6 @@ var ToolPanelContainer = import_react79.default.forwardRef(
|
|
|
6619
6791
|
);
|
|
6620
6792
|
ToolPanelContainer.displayName = "ToolPanelContainer";
|
|
6621
6793
|
|
|
6622
|
-
// src/components/chat/hooks/useResizable.ts
|
|
6623
|
-
var import_react80 = require("react");
|
|
6624
|
-
function useResizable({
|
|
6625
|
-
initialWidthPercent,
|
|
6626
|
-
minWidthPercent,
|
|
6627
|
-
maxWidthPercent,
|
|
6628
|
-
direction
|
|
6629
|
-
}) {
|
|
6630
|
-
const [widthPercent, setWidthPercent] = (0, import_react80.useState)(initialWidthPercent);
|
|
6631
|
-
const [isResizing, setIsResizing] = (0, import_react80.useState)(false);
|
|
6632
|
-
const lastX = (0, import_react80.useRef)(null);
|
|
6633
|
-
const startResizing = (0, import_react80.useCallback)((e) => {
|
|
6634
|
-
e.preventDefault();
|
|
6635
|
-
setIsResizing(true);
|
|
6636
|
-
lastX.current = e.clientX;
|
|
6637
|
-
}, []);
|
|
6638
|
-
const stopResizing = (0, import_react80.useCallback)(() => {
|
|
6639
|
-
setIsResizing(false);
|
|
6640
|
-
lastX.current = null;
|
|
6641
|
-
}, []);
|
|
6642
|
-
const resize = (0, import_react80.useCallback)(
|
|
6643
|
-
(e) => {
|
|
6644
|
-
if (!isResizing || lastX.current === null) {
|
|
6645
|
-
return;
|
|
6646
|
-
}
|
|
6647
|
-
const deltaX = e.clientX - lastX.current;
|
|
6648
|
-
const factor = direction === "right" ? 1 : -1;
|
|
6649
|
-
const deltaPercent = deltaX / window.innerWidth * 100;
|
|
6650
|
-
setWidthPercent((prevPercent) => {
|
|
6651
|
-
const newPercent = prevPercent + deltaPercent * factor;
|
|
6652
|
-
return Math.min(Math.max(newPercent, minWidthPercent), maxWidthPercent);
|
|
6653
|
-
});
|
|
6654
|
-
lastX.current = e.clientX;
|
|
6655
|
-
},
|
|
6656
|
-
[isResizing, direction, minWidthPercent, maxWidthPercent]
|
|
6657
|
-
);
|
|
6658
|
-
(0, import_react80.useEffect)(() => {
|
|
6659
|
-
if (isResizing) {
|
|
6660
|
-
window.addEventListener("mousemove", resize);
|
|
6661
|
-
window.addEventListener("mouseup", stopResizing);
|
|
6662
|
-
document.body.style.cursor = "col-resize";
|
|
6663
|
-
document.body.style.userSelect = "none";
|
|
6664
|
-
} else {
|
|
6665
|
-
window.removeEventListener("mousemove", resize);
|
|
6666
|
-
window.removeEventListener("mouseup", stopResizing);
|
|
6667
|
-
document.body.style.cursor = "";
|
|
6668
|
-
document.body.style.userSelect = "";
|
|
6669
|
-
}
|
|
6670
|
-
return () => {
|
|
6671
|
-
window.removeEventListener("mousemove", resize);
|
|
6672
|
-
window.removeEventListener("mouseup", stopResizing);
|
|
6673
|
-
document.body.style.cursor = "";
|
|
6674
|
-
document.body.style.userSelect = "";
|
|
6675
|
-
};
|
|
6676
|
-
}, [isResizing, resize, stopResizing]);
|
|
6677
|
-
const width = `${widthPercent}vw`;
|
|
6678
|
-
return { width, widthPercent, isResizing, startResizing };
|
|
6679
|
-
}
|
|
6680
|
-
|
|
6681
6794
|
// src/components/chat/tree.ts
|
|
6682
6795
|
function createEmptyTree() {
|
|
6683
6796
|
return { nodes: {}, rootIds: [], activeLeafId: null, lastLeafId: null };
|
|
@@ -6838,6 +6951,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6838
6951
|
onRenameConversation,
|
|
6839
6952
|
isStreaming = false,
|
|
6840
6953
|
isThinking = false,
|
|
6954
|
+
thinkingLabel,
|
|
6841
6955
|
placeholder = "Send a message...",
|
|
6842
6956
|
emptyStateHelper = "Let's talk.",
|
|
6843
6957
|
emptyState,
|
|
@@ -6846,6 +6960,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6846
6960
|
attachments: propsAttachments,
|
|
6847
6961
|
onAttachmentsChange,
|
|
6848
6962
|
onAttachmentRemove,
|
|
6963
|
+
onAttachmentOpen,
|
|
6849
6964
|
artifactNodes,
|
|
6850
6965
|
isArtifactsPanelOpen,
|
|
6851
6966
|
onArtifactsPanelOpenChange,
|
|
@@ -6862,6 +6977,14 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
6862
6977
|
}, ref) => {
|
|
6863
6978
|
const prevArtifactNodesRef = (0, import_react81.useRef)([]);
|
|
6864
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
|
+
}, []);
|
|
6865
6988
|
const [internalTools, setInternalTools] = (0, import_react81.useState)({
|
|
6866
6989
|
"top-left": "history",
|
|
6867
6990
|
"bottom-left": null,
|
|
@@ -7049,7 +7172,15 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7049
7172
|
isStreaming: node.isStreaming,
|
|
7050
7173
|
muted: opts.muted,
|
|
7051
7174
|
branchInfo,
|
|
7052
|
-
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
|
|
7053
7184
|
};
|
|
7054
7185
|
},
|
|
7055
7186
|
[
|
|
@@ -7059,7 +7190,8 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7059
7190
|
onEditMessage,
|
|
7060
7191
|
onRetryMessage,
|
|
7061
7192
|
handleBranchSwitch,
|
|
7062
|
-
handleJumpToCheckpoint
|
|
7193
|
+
handleJumpToCheckpoint,
|
|
7194
|
+
handleAttachmentOpen
|
|
7063
7195
|
]
|
|
7064
7196
|
);
|
|
7065
7197
|
const displayItems = (0, import_react81.useMemo)(() => {
|
|
@@ -7128,6 +7260,8 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7128
7260
|
ArtifactsPanel,
|
|
7129
7261
|
{
|
|
7130
7262
|
nodes: artifactNodes,
|
|
7263
|
+
openArtifactId: panelOpenArtifactId,
|
|
7264
|
+
onArtifactClosed: handleArtifactPanelClosed,
|
|
7131
7265
|
className: "h-full"
|
|
7132
7266
|
}
|
|
7133
7267
|
);
|
|
@@ -7190,6 +7324,7 @@ var ChatInterface = import_react81.default.forwardRef(
|
|
|
7190
7324
|
latestUserMessageIndex,
|
|
7191
7325
|
isStreaming,
|
|
7192
7326
|
isThinking,
|
|
7327
|
+
thinkingLabel,
|
|
7193
7328
|
className: "flex-1"
|
|
7194
7329
|
}
|
|
7195
7330
|
)), /* @__PURE__ */ import_react81.default.createElement("div", { className: cx(
|