@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.mjs
CHANGED
|
@@ -1320,42 +1320,84 @@ function getFileIcon(type) {
|
|
|
1320
1320
|
}
|
|
1321
1321
|
return File;
|
|
1322
1322
|
}
|
|
1323
|
-
var
|
|
1323
|
+
var statusBorderClass = {
|
|
1324
1324
|
pending: "border-silver/30",
|
|
1325
1325
|
uploading: "border-gold/50",
|
|
1326
|
-
|
|
1327
|
-
|
|
1326
|
+
uploaded: "border-info/50",
|
|
1327
|
+
analyzing: "border-info/50",
|
|
1328
|
+
analyzed: "border-success/50",
|
|
1329
|
+
upload_failed: "border-error/50",
|
|
1330
|
+
analysis_failed: "border-error/50"
|
|
1328
1331
|
};
|
|
1332
|
+
var statusHoverLabel = {
|
|
1333
|
+
pending: null,
|
|
1334
|
+
uploading: "Uploading...",
|
|
1335
|
+
uploaded: "Upload complete. Analyzing...",
|
|
1336
|
+
analyzing: "Upload complete. Analyzing...",
|
|
1337
|
+
analyzed: null,
|
|
1338
|
+
upload_failed: "Upload failed. Remove and try again.",
|
|
1339
|
+
analysis_failed: "Analysis failed. Provide a description in your next message."
|
|
1340
|
+
};
|
|
1341
|
+
function isErrorStatus(status) {
|
|
1342
|
+
return status === "upload_failed" || status === "analysis_failed";
|
|
1343
|
+
}
|
|
1329
1344
|
var FileChip = React15.forwardRef(
|
|
1330
1345
|
({
|
|
1331
1346
|
name,
|
|
1332
1347
|
size,
|
|
1333
1348
|
type,
|
|
1334
|
-
status = "
|
|
1349
|
+
status = "analyzed",
|
|
1335
1350
|
previewUrl,
|
|
1336
1351
|
onRemove,
|
|
1337
1352
|
removable = true,
|
|
1338
1353
|
error,
|
|
1354
|
+
artifactId,
|
|
1355
|
+
onOpen,
|
|
1339
1356
|
className,
|
|
1357
|
+
title,
|
|
1340
1358
|
...rest
|
|
1341
1359
|
}, ref) => {
|
|
1342
1360
|
const Icon = getFileIcon(type);
|
|
1343
1361
|
const isImage = type?.startsWith("image/");
|
|
1344
1362
|
const showPreview = isImage && previewUrl;
|
|
1363
|
+
const clickable = !!(artifactId && onOpen);
|
|
1364
|
+
const hoverLabel = statusHoverLabel[status];
|
|
1365
|
+
const tooltip = title ?? hoverLabel ?? name;
|
|
1366
|
+
const showError = isErrorStatus(status);
|
|
1367
|
+
const handleClick = () => {
|
|
1368
|
+
if (clickable) {
|
|
1369
|
+
onOpen(artifactId);
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
const handleKeyDown = (e) => {
|
|
1373
|
+
if (!clickable) {
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1377
|
+
e.preventDefault();
|
|
1378
|
+
onOpen(artifactId);
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1345
1381
|
return /* @__PURE__ */ React15.createElement(
|
|
1346
1382
|
"div",
|
|
1347
1383
|
{
|
|
1384
|
+
...rest,
|
|
1348
1385
|
ref,
|
|
1349
1386
|
className: cx(
|
|
1350
1387
|
"group relative inline-flex items-center gap-2 px-2 py-1.5",
|
|
1351
1388
|
"bg-charcoal border text-sm text-white",
|
|
1352
1389
|
"transition-colors duration-150",
|
|
1353
|
-
|
|
1354
|
-
|
|
1390
|
+
statusBorderClass[status],
|
|
1391
|
+
showError && "bg-error/10",
|
|
1392
|
+
clickable && "cursor-pointer hover:bg-graphite",
|
|
1355
1393
|
className
|
|
1356
1394
|
),
|
|
1357
|
-
role: "listitem",
|
|
1358
|
-
|
|
1395
|
+
role: clickable ? "button" : "listitem",
|
|
1396
|
+
tabIndex: clickable ? 0 : void 0,
|
|
1397
|
+
onClick: clickable ? handleClick : void 0,
|
|
1398
|
+
onKeyDown: clickable ? handleKeyDown : void 0,
|
|
1399
|
+
title: tooltip,
|
|
1400
|
+
"aria-label": hoverLabel ? `${name}: ${hoverLabel}` : name
|
|
1359
1401
|
},
|
|
1360
1402
|
showPreview ? /* @__PURE__ */ React15.createElement("div", { className: "w-8 h-8 flex-shrink-0 overflow-hidden bg-slate" }, /* @__PURE__ */ React15.createElement(
|
|
1361
1403
|
"img",
|
|
@@ -1366,10 +1408,11 @@ var FileChip = React15.forwardRef(
|
|
|
1366
1408
|
}
|
|
1367
1409
|
)) : /* @__PURE__ */ React15.createElement(Icon, { className: cx(
|
|
1368
1410
|
"w-4 h-4 flex-shrink-0",
|
|
1369
|
-
|
|
1411
|
+
showError ? "text-error" : "text-silver"
|
|
1370
1412
|
) }),
|
|
1371
|
-
/* @__PURE__ */ React15.createElement("div", { className: "flex flex-col min-w-0 flex-1" }, /* @__PURE__ */ React15.createElement("span", { className: "truncate max-w-40", title: name }, name), size !== void 0 &&
|
|
1413
|
+
/* @__PURE__ */ React15.createElement("div", { className: "flex flex-col min-w-0 flex-1" }, /* @__PURE__ */ React15.createElement("span", { className: "truncate max-w-40", title: name }, name), size !== void 0 && !showError && /* @__PURE__ */ React15.createElement("span", { className: "text-xs text-silver/60" }, formatBytes(size)), showError && error && /* @__PURE__ */ React15.createElement("span", { className: "text-xs text-error truncate", title: error }, error)),
|
|
1372
1414
|
status === "uploading" && /* @__PURE__ */ React15.createElement(Loader2, { className: "w-3.5 h-3.5 text-gold animate-spin flex-shrink-0" }),
|
|
1415
|
+
(status === "uploaded" || status === "analyzing") && /* @__PURE__ */ React15.createElement(Loader2, { className: "w-3.5 h-3.5 text-info animate-spin flex-shrink-0" }),
|
|
1373
1416
|
status === "pending" && /* @__PURE__ */ React15.createElement("div", { className: "w-2 h-2 rounded-full bg-silver/50 flex-shrink-0" }),
|
|
1374
1417
|
removable && onRemove && /* @__PURE__ */ React15.createElement(
|
|
1375
1418
|
"button",
|
|
@@ -1402,6 +1445,7 @@ var AttachmentPreview = React16.forwardRef(
|
|
|
1402
1445
|
onRemove,
|
|
1403
1446
|
removable = true,
|
|
1404
1447
|
maxVisible,
|
|
1448
|
+
onOpen,
|
|
1405
1449
|
className,
|
|
1406
1450
|
...rest
|
|
1407
1451
|
}, ref) => {
|
|
@@ -1430,7 +1474,9 @@ var AttachmentPreview = React16.forwardRef(
|
|
|
1430
1474
|
previewUrl: attachment.previewUrl,
|
|
1431
1475
|
error: attachment.error,
|
|
1432
1476
|
removable,
|
|
1433
|
-
onRemove: onRemove ? () => onRemove(attachment.id) : void 0
|
|
1477
|
+
onRemove: onRemove ? () => onRemove(attachment.id) : void 0,
|
|
1478
|
+
artifactId: attachment.artifactId,
|
|
1479
|
+
onOpen
|
|
1434
1480
|
}
|
|
1435
1481
|
)),
|
|
1436
1482
|
hiddenCount > 0 && /* @__PURE__ */ React16.createElement(
|
|
@@ -3890,6 +3936,8 @@ var Message = React55.forwardRef(
|
|
|
3890
3936
|
branchInfo,
|
|
3891
3937
|
actions,
|
|
3892
3938
|
hideActions,
|
|
3939
|
+
attachments,
|
|
3940
|
+
onAttachmentOpen,
|
|
3893
3941
|
...rest
|
|
3894
3942
|
}, ref) => {
|
|
3895
3943
|
const isUser = variant === "user";
|
|
@@ -3957,6 +4005,14 @@ var Message = React55.forwardRef(
|
|
|
3957
4005
|
),
|
|
3958
4006
|
...rest
|
|
3959
4007
|
},
|
|
4008
|
+
attachments && attachments.length > 0 && /* @__PURE__ */ React55.createElement("div", { className: cx("mb-1.5", isUser ? "self-end" : "self-start") }, /* @__PURE__ */ React55.createElement(
|
|
4009
|
+
AttachmentPreview,
|
|
4010
|
+
{
|
|
4011
|
+
attachments,
|
|
4012
|
+
removable: false,
|
|
4013
|
+
onOpen: onAttachmentOpen
|
|
4014
|
+
}
|
|
4015
|
+
)),
|
|
3960
4016
|
isUser && isEditing ? /* @__PURE__ */ React55.createElement("div", { className: "w-full max-w-11/12" }, /* @__PURE__ */ React55.createElement("div", { className: "relative bg-gold" }, /* @__PURE__ */ React55.createElement(
|
|
3961
4017
|
"textarea",
|
|
3962
4018
|
{
|
|
@@ -4207,6 +4263,7 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4207
4263
|
isVisible = true,
|
|
4208
4264
|
phraseInterval = 2500,
|
|
4209
4265
|
phrases = THINKING_PHRASES,
|
|
4266
|
+
manualLabel,
|
|
4210
4267
|
className,
|
|
4211
4268
|
...rest
|
|
4212
4269
|
}, ref) => {
|
|
@@ -4214,8 +4271,9 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4214
4271
|
() => Math.floor(Math.random() * phrases.length)
|
|
4215
4272
|
);
|
|
4216
4273
|
const [isTransitioning, setIsTransitioning] = useState13(false);
|
|
4274
|
+
const isManual = manualLabel !== void 0;
|
|
4217
4275
|
useEffect8(() => {
|
|
4218
|
-
if (!isVisible || phrases.length <= 1) {
|
|
4276
|
+
if (!isVisible || isManual || phrases.length <= 1) {
|
|
4219
4277
|
return;
|
|
4220
4278
|
}
|
|
4221
4279
|
let fadeTimeout = null;
|
|
@@ -4233,7 +4291,7 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4233
4291
|
clearTimeout(fadeTimeout);
|
|
4234
4292
|
}
|
|
4235
4293
|
};
|
|
4236
|
-
}, [isVisible, phrases.length, phraseInterval]);
|
|
4294
|
+
}, [isVisible, isManual, phrases.length, phraseInterval]);
|
|
4237
4295
|
if (!isVisible) {
|
|
4238
4296
|
return null;
|
|
4239
4297
|
}
|
|
@@ -4270,7 +4328,7 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4270
4328
|
style: { animationDelay: "300ms" }
|
|
4271
4329
|
}
|
|
4272
4330
|
)),
|
|
4273
|
-
/* @__PURE__ */ React57.createElement(
|
|
4331
|
+
isManual ? /* @__PURE__ */ React57.createElement("span", { className: "text-sm italic" }, manualLabel) : /* @__PURE__ */ React57.createElement(
|
|
4274
4332
|
"span",
|
|
4275
4333
|
{
|
|
4276
4334
|
className: cx(
|
|
@@ -4294,19 +4352,22 @@ import {
|
|
|
4294
4352
|
GitBranch as GitBranch2,
|
|
4295
4353
|
GitCommitVertical,
|
|
4296
4354
|
GitMerge,
|
|
4297
|
-
PencilLine
|
|
4355
|
+
PencilLine,
|
|
4356
|
+
Upload
|
|
4298
4357
|
} from "lucide-react";
|
|
4299
4358
|
var KIND_ICONS = {
|
|
4300
4359
|
task: GitBranch2,
|
|
4301
4360
|
submit: GitMerge,
|
|
4302
4361
|
rename: PencilLine,
|
|
4303
|
-
init: GitCommitVertical
|
|
4362
|
+
init: GitCommitVertical,
|
|
4363
|
+
ingest: Upload
|
|
4304
4364
|
};
|
|
4305
4365
|
var KIND_ARIA_LABELS = {
|
|
4306
4366
|
task: "Task checkpoint",
|
|
4307
4367
|
submit: "Submit checkpoint",
|
|
4308
4368
|
rename: "Rename checkpoint",
|
|
4309
|
-
init: "Project head checkpoint"
|
|
4369
|
+
init: "Project head checkpoint",
|
|
4370
|
+
ingest: "Upload batch checkpoint"
|
|
4310
4371
|
};
|
|
4311
4372
|
var Checkpoint = React58.forwardRef(
|
|
4312
4373
|
function Checkpoint2({ name, executionKind, status = "completed", isActive, muted, branchInfo, onJumpHere }, ref) {
|
|
@@ -4455,7 +4516,16 @@ GreyedDivider.displayName = "GreyedDivider";
|
|
|
4455
4516
|
|
|
4456
4517
|
// src/components/chat/ChatView.tsx
|
|
4457
4518
|
var ChatView = React60.forwardRef(
|
|
4458
|
-
function ChatView2({
|
|
4519
|
+
function ChatView2({
|
|
4520
|
+
items,
|
|
4521
|
+
latestUserMessageIndex,
|
|
4522
|
+
isStreaming,
|
|
4523
|
+
isThinking,
|
|
4524
|
+
thinkingLabel,
|
|
4525
|
+
onScroll,
|
|
4526
|
+
className,
|
|
4527
|
+
...rest
|
|
4528
|
+
}, ref) {
|
|
4459
4529
|
const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
|
|
4460
4530
|
behavior: "smooth",
|
|
4461
4531
|
block: "start"
|
|
@@ -4538,7 +4608,7 @@ var ChatView = React60.forwardRef(
|
|
|
4538
4608
|
}
|
|
4539
4609
|
)
|
|
4540
4610
|
);
|
|
4541
|
-
}), showThinking && /* @__PURE__ */ React60.createElement(ThinkingIndicator, { isVisible: true })),
|
|
4611
|
+
}), showThinking && /* @__PURE__ */ React60.createElement(ThinkingIndicator, { isVisible: true, manualLabel: thinkingLabel })),
|
|
4542
4612
|
/* @__PURE__ */ React60.createElement(
|
|
4543
4613
|
"div",
|
|
4544
4614
|
{
|
|
@@ -4723,8 +4793,8 @@ var ChatInput = React61.forwardRef(
|
|
|
4723
4793
|
);
|
|
4724
4794
|
const isCentered = position === "centered";
|
|
4725
4795
|
const hasAttachments = attachments.length > 0;
|
|
4726
|
-
const
|
|
4727
|
-
const canSubmit = value.trim() && !disabled && !isStreaming && !
|
|
4796
|
+
const isUploadIncomplete = attachments.some((a) => a.status === "pending" || a.status === "uploading" || a.status === "upload_failed");
|
|
4797
|
+
const canSubmit = value.trim() && !disabled && !isStreaming && !isUploadIncomplete;
|
|
4728
4798
|
return /* @__PURE__ */ React61.createElement(
|
|
4729
4799
|
"div",
|
|
4730
4800
|
{
|
|
@@ -4861,7 +4931,7 @@ var ChatInput = React61.forwardRef(
|
|
|
4861
4931
|
ChatInput.displayName = "ChatInput";
|
|
4862
4932
|
|
|
4863
4933
|
// src/components/chat/ArtifactsPanel.tsx
|
|
4864
|
-
import React71, { useCallback as
|
|
4934
|
+
import React71, { useCallback as useCallback18, useEffect as useEffect13, useRef as useRef12, useState as useState18 } from "react";
|
|
4865
4935
|
import { Image } from "lucide-react";
|
|
4866
4936
|
|
|
4867
4937
|
// src/components/ArtifactCard.tsx
|
|
@@ -5519,10 +5589,69 @@ var ArtifactVariantStack = React70.forwardRef(
|
|
|
5519
5589
|
);
|
|
5520
5590
|
ArtifactVariantStack.displayName = "ArtifactVariantStack";
|
|
5521
5591
|
|
|
5592
|
+
// src/components/chat/hooks/useResizable.ts
|
|
5593
|
+
import { useCallback as useCallback16, useEffect as useEffect12, useRef as useRef11, useState as useState16 } from "react";
|
|
5594
|
+
function useResizable({
|
|
5595
|
+
initialWidthPercent,
|
|
5596
|
+
minWidthPercent,
|
|
5597
|
+
maxWidthPercent,
|
|
5598
|
+
direction
|
|
5599
|
+
}) {
|
|
5600
|
+
const [widthPercent, setWidthPercent] = useState16(initialWidthPercent);
|
|
5601
|
+
const [isResizing, setIsResizing] = useState16(false);
|
|
5602
|
+
const lastX = useRef11(null);
|
|
5603
|
+
const startResizing = useCallback16((e) => {
|
|
5604
|
+
e.preventDefault();
|
|
5605
|
+
setIsResizing(true);
|
|
5606
|
+
lastX.current = e.clientX;
|
|
5607
|
+
}, []);
|
|
5608
|
+
const stopResizing = useCallback16(() => {
|
|
5609
|
+
setIsResizing(false);
|
|
5610
|
+
lastX.current = null;
|
|
5611
|
+
}, []);
|
|
5612
|
+
const resize = useCallback16(
|
|
5613
|
+
(e) => {
|
|
5614
|
+
if (!isResizing || lastX.current === null) {
|
|
5615
|
+
return;
|
|
5616
|
+
}
|
|
5617
|
+
const deltaX = e.clientX - lastX.current;
|
|
5618
|
+
const factor = direction === "right" ? 1 : -1;
|
|
5619
|
+
const deltaPercent = deltaX / window.innerWidth * 100;
|
|
5620
|
+
setWidthPercent((prevPercent) => {
|
|
5621
|
+
const newPercent = prevPercent + deltaPercent * factor;
|
|
5622
|
+
return Math.min(Math.max(newPercent, minWidthPercent), maxWidthPercent);
|
|
5623
|
+
});
|
|
5624
|
+
lastX.current = e.clientX;
|
|
5625
|
+
},
|
|
5626
|
+
[isResizing, direction, minWidthPercent, maxWidthPercent]
|
|
5627
|
+
);
|
|
5628
|
+
useEffect12(() => {
|
|
5629
|
+
if (isResizing) {
|
|
5630
|
+
window.addEventListener("mousemove", resize);
|
|
5631
|
+
window.addEventListener("mouseup", stopResizing);
|
|
5632
|
+
document.body.style.cursor = "col-resize";
|
|
5633
|
+
document.body.style.userSelect = "none";
|
|
5634
|
+
} else {
|
|
5635
|
+
window.removeEventListener("mousemove", resize);
|
|
5636
|
+
window.removeEventListener("mouseup", stopResizing);
|
|
5637
|
+
document.body.style.cursor = "";
|
|
5638
|
+
document.body.style.userSelect = "";
|
|
5639
|
+
}
|
|
5640
|
+
return () => {
|
|
5641
|
+
window.removeEventListener("mousemove", resize);
|
|
5642
|
+
window.removeEventListener("mouseup", stopResizing);
|
|
5643
|
+
document.body.style.cursor = "";
|
|
5644
|
+
document.body.style.userSelect = "";
|
|
5645
|
+
};
|
|
5646
|
+
}, [isResizing, resize, stopResizing]);
|
|
5647
|
+
const width = `${widthPercent}vw`;
|
|
5648
|
+
return { width, widthPercent, isResizing, startResizing };
|
|
5649
|
+
}
|
|
5650
|
+
|
|
5522
5651
|
// src/components/chat/hooks/useArtifactTreeNavigation.ts
|
|
5523
|
-
import { useCallback as
|
|
5652
|
+
import { useCallback as useCallback17, useMemo as useMemo2, useState as useState17 } from "react";
|
|
5524
5653
|
function useArtifactTreeNavigation(rootNodes) {
|
|
5525
|
-
const [stack, setStack] =
|
|
5654
|
+
const [stack, setStack] = useState17([]);
|
|
5526
5655
|
const currentNodes = useMemo2(() => {
|
|
5527
5656
|
if (stack.length === 0) return rootNodes;
|
|
5528
5657
|
return stack[stack.length - 1].children;
|
|
@@ -5535,13 +5664,13 @@ function useArtifactTreeNavigation(rootNodes) {
|
|
|
5535
5664
|
return entries;
|
|
5536
5665
|
}, [stack]);
|
|
5537
5666
|
const isAtRoot = stack.length === 0;
|
|
5538
|
-
const navigateInto =
|
|
5667
|
+
const navigateInto = useCallback17((node) => {
|
|
5539
5668
|
setStack((prev) => [...prev, node]);
|
|
5540
5669
|
}, []);
|
|
5541
|
-
const navigateTo =
|
|
5670
|
+
const navigateTo = useCallback17((index) => {
|
|
5542
5671
|
setStack((prev) => prev.slice(0, index));
|
|
5543
5672
|
}, []);
|
|
5544
|
-
const navigateBack =
|
|
5673
|
+
const navigateBack = useCallback17(() => {
|
|
5545
5674
|
setStack((prev) => prev.slice(0, -1));
|
|
5546
5675
|
}, []);
|
|
5547
5676
|
return {
|
|
@@ -5561,7 +5690,7 @@ function ArtifactModal({
|
|
|
5561
5690
|
onClose
|
|
5562
5691
|
}) {
|
|
5563
5692
|
useEscapeKey(onClose);
|
|
5564
|
-
const handleBackdropClick =
|
|
5693
|
+
const handleBackdropClick = useCallback18((e) => {
|
|
5565
5694
|
if (e.target === e.currentTarget) {
|
|
5566
5695
|
onClose();
|
|
5567
5696
|
}
|
|
@@ -5642,6 +5771,20 @@ function ArtifactModal({
|
|
|
5642
5771
|
)
|
|
5643
5772
|
);
|
|
5644
5773
|
}
|
|
5774
|
+
function findArtifactInNodes(nodes, artifactId) {
|
|
5775
|
+
for (const node of nodes) {
|
|
5776
|
+
if (node.type === "ARTIFACT" && node.artifact?.id === artifactId) {
|
|
5777
|
+
return node.artifact;
|
|
5778
|
+
}
|
|
5779
|
+
if (node.children && node.children.length > 0) {
|
|
5780
|
+
const found = findArtifactInNodes(node.children, artifactId);
|
|
5781
|
+
if (found) {
|
|
5782
|
+
return found;
|
|
5783
|
+
}
|
|
5784
|
+
}
|
|
5785
|
+
}
|
|
5786
|
+
return null;
|
|
5787
|
+
}
|
|
5645
5788
|
function NodeRenderer({
|
|
5646
5789
|
node,
|
|
5647
5790
|
loading,
|
|
@@ -5677,31 +5820,48 @@ var ArtifactsPanel = React71.forwardRef(
|
|
|
5677
5820
|
({
|
|
5678
5821
|
nodes,
|
|
5679
5822
|
loading,
|
|
5823
|
+
openArtifactId,
|
|
5824
|
+
onArtifactClosed,
|
|
5680
5825
|
className,
|
|
5681
5826
|
...rest
|
|
5682
5827
|
}, ref) => {
|
|
5683
|
-
const [expandedArtifact, setExpandedArtifact] =
|
|
5684
|
-
const [zoomIndex, setZoomIndex] =
|
|
5828
|
+
const [expandedArtifact, setExpandedArtifact] = useState18(null);
|
|
5829
|
+
const [zoomIndex, setZoomIndex] = useState18(ZOOM_LEVELS.length - 1);
|
|
5685
5830
|
const treeNav = useArtifactTreeNavigation(nodes || []);
|
|
5686
5831
|
const hasNodes = !!nodes && nodes.length > 0;
|
|
5687
|
-
const handleExpandArtifact =
|
|
5832
|
+
const handleExpandArtifact = useCallback18((artifact) => {
|
|
5688
5833
|
setExpandedArtifact(artifact);
|
|
5689
5834
|
}, []);
|
|
5690
|
-
const handleGroupClick =
|
|
5835
|
+
const handleGroupClick = useCallback18((node) => {
|
|
5691
5836
|
treeNav.navigateInto(node);
|
|
5692
5837
|
}, [treeNav]);
|
|
5693
|
-
|
|
5838
|
+
useEffect13(() => {
|
|
5839
|
+
if (!openArtifactId || !nodes) {
|
|
5840
|
+
return;
|
|
5841
|
+
}
|
|
5842
|
+
const found = findArtifactInNodes(nodes, openArtifactId);
|
|
5843
|
+
if (found) {
|
|
5844
|
+
setExpandedArtifact(found);
|
|
5845
|
+
}
|
|
5846
|
+
}, [openArtifactId, nodes]);
|
|
5847
|
+
const handleModalClose = useCallback18(() => {
|
|
5848
|
+
setExpandedArtifact(null);
|
|
5849
|
+
onArtifactClosed?.();
|
|
5850
|
+
}, [onArtifactClosed]);
|
|
5851
|
+
const zoomIn = useCallback18(() => {
|
|
5694
5852
|
setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
|
|
5695
5853
|
}, []);
|
|
5696
|
-
const zoomOut =
|
|
5854
|
+
const zoomOut = useCallback18(() => {
|
|
5697
5855
|
setZoomIndex((prev) => Math.max(prev - 1, 0));
|
|
5698
5856
|
}, []);
|
|
5699
5857
|
const currentZoom = ZOOM_LEVELS[zoomIndex];
|
|
5700
|
-
const contentRef =
|
|
5701
|
-
const [contentHeight, setContentHeight] =
|
|
5702
|
-
|
|
5858
|
+
const contentRef = useRef12(null);
|
|
5859
|
+
const [contentHeight, setContentHeight] = useState18(void 0);
|
|
5860
|
+
useEffect13(() => {
|
|
5703
5861
|
const el = contentRef.current;
|
|
5704
|
-
if (!el)
|
|
5862
|
+
if (!el) {
|
|
5863
|
+
return;
|
|
5864
|
+
}
|
|
5705
5865
|
const observer = new ResizeObserver(([entry]) => {
|
|
5706
5866
|
setContentHeight(entry.contentRect.height);
|
|
5707
5867
|
});
|
|
@@ -5745,7 +5905,15 @@ var ArtifactsPanel = React71.forwardRef(
|
|
|
5745
5905
|
},
|
|
5746
5906
|
"\u2212"
|
|
5747
5907
|
),
|
|
5748
|
-
/* @__PURE__ */ React71.createElement(
|
|
5908
|
+
/* @__PURE__ */ React71.createElement(
|
|
5909
|
+
"span",
|
|
5910
|
+
{
|
|
5911
|
+
className: "text-xs text-silver w-8 text-center tabular-nums",
|
|
5912
|
+
"data-testid": "zoom-level"
|
|
5913
|
+
},
|
|
5914
|
+
Math.round(currentZoom * 100),
|
|
5915
|
+
"%"
|
|
5916
|
+
),
|
|
5749
5917
|
/* @__PURE__ */ React71.createElement(
|
|
5750
5918
|
"button",
|
|
5751
5919
|
{
|
|
@@ -5820,7 +5988,7 @@ var ArtifactsPanel = React71.forwardRef(
|
|
|
5820
5988
|
ArtifactModal,
|
|
5821
5989
|
{
|
|
5822
5990
|
artifact: expandedArtifact,
|
|
5823
|
-
onClose:
|
|
5991
|
+
onClose: handleModalClose
|
|
5824
5992
|
}
|
|
5825
5993
|
));
|
|
5826
5994
|
}
|
|
@@ -5857,7 +6025,7 @@ var ArtifactsPanelToggle = React71.forwardRef(({ artifactCount = 0, onExpand, cl
|
|
|
5857
6025
|
ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
|
|
5858
6026
|
|
|
5859
6027
|
// src/components/chat/HistoryPanel.tsx
|
|
5860
|
-
import React72, { useCallback as
|
|
6028
|
+
import React72, { useCallback as useCallback19, useEffect as useEffect14, useMemo as useMemo3, useRef as useRef13, useState as useState19 } from "react";
|
|
5861
6029
|
import { ChevronDown as ChevronDown2, Pencil as Pencil2 } from "lucide-react";
|
|
5862
6030
|
function parseTimestamp(ts) {
|
|
5863
6031
|
if (ts == null) {
|
|
@@ -5900,9 +6068,9 @@ function ProjectFilter({
|
|
|
5900
6068
|
onChange,
|
|
5901
6069
|
className
|
|
5902
6070
|
}) {
|
|
5903
|
-
const [open, setOpen] =
|
|
5904
|
-
const ref =
|
|
5905
|
-
const closeFilter =
|
|
6071
|
+
const [open, setOpen] = useState19(false);
|
|
6072
|
+
const ref = useRef13(null);
|
|
6073
|
+
const closeFilter = useCallback19(() => setOpen(false), []);
|
|
5906
6074
|
useClickOutside(ref, closeFilter, open);
|
|
5907
6075
|
const label = value ?? "All projects";
|
|
5908
6076
|
return /* @__PURE__ */ React72.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ React72.createElement(
|
|
@@ -5977,28 +6145,28 @@ function ConversationRow({
|
|
|
5977
6145
|
onSelect,
|
|
5978
6146
|
onRename
|
|
5979
6147
|
}) {
|
|
5980
|
-
const [isEditing, setIsEditing] =
|
|
5981
|
-
const [draft, setDraft] =
|
|
5982
|
-
const inputRef =
|
|
5983
|
-
|
|
6148
|
+
const [isEditing, setIsEditing] = useState19(false);
|
|
6149
|
+
const [draft, setDraft] = useState19(conversation.title);
|
|
6150
|
+
const inputRef = useRef13(null);
|
|
6151
|
+
useEffect14(() => {
|
|
5984
6152
|
if (isEditing && inputRef.current) {
|
|
5985
6153
|
inputRef.current.focus();
|
|
5986
6154
|
inputRef.current.select();
|
|
5987
6155
|
}
|
|
5988
6156
|
}, [isEditing]);
|
|
5989
|
-
const startEdit =
|
|
6157
|
+
const startEdit = useCallback19((e) => {
|
|
5990
6158
|
e.stopPropagation();
|
|
5991
6159
|
setDraft(conversation.title);
|
|
5992
6160
|
setIsEditing(true);
|
|
5993
6161
|
}, [conversation.title]);
|
|
5994
|
-
const commit =
|
|
6162
|
+
const commit = useCallback19(() => {
|
|
5995
6163
|
const trimmed = draft.trim();
|
|
5996
6164
|
if (trimmed && trimmed !== conversation.title) {
|
|
5997
6165
|
onRename?.(conversation.id, trimmed);
|
|
5998
6166
|
}
|
|
5999
6167
|
setIsEditing(false);
|
|
6000
6168
|
}, [draft, conversation.id, conversation.title, onRename]);
|
|
6001
|
-
const cancel =
|
|
6169
|
+
const cancel = useCallback19(() => {
|
|
6002
6170
|
setDraft(conversation.title);
|
|
6003
6171
|
setIsEditing(false);
|
|
6004
6172
|
}, [conversation.title]);
|
|
@@ -6082,7 +6250,7 @@ function HistoryPanel({
|
|
|
6082
6250
|
onNewChat,
|
|
6083
6251
|
onRenameConversation
|
|
6084
6252
|
}) {
|
|
6085
|
-
const [projectFilter, setProjectFilter] =
|
|
6253
|
+
const [projectFilter, setProjectFilter] = useState19(null);
|
|
6086
6254
|
const projects = useMemo3(() => {
|
|
6087
6255
|
const set = /* @__PURE__ */ new Set();
|
|
6088
6256
|
for (const c of conversations) {
|
|
@@ -6092,7 +6260,7 @@ function HistoryPanel({
|
|
|
6092
6260
|
}
|
|
6093
6261
|
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
6094
6262
|
}, [conversations]);
|
|
6095
|
-
|
|
6263
|
+
useEffect14(() => {
|
|
6096
6264
|
if (projectFilter && !projects.includes(projectFilter)) {
|
|
6097
6265
|
setProjectFilter(null);
|
|
6098
6266
|
}
|
|
@@ -6148,7 +6316,7 @@ function HistoryPanel({
|
|
|
6148
6316
|
}
|
|
6149
6317
|
|
|
6150
6318
|
// src/components/chat/TodosList.tsx
|
|
6151
|
-
import React73, { useCallback as
|
|
6319
|
+
import React73, { useCallback as useCallback20, useMemo as useMemo4, useState as useState20 } from "react";
|
|
6152
6320
|
import { Loader2 as Loader22, Square as Square2 } from "lucide-react";
|
|
6153
6321
|
var TASK_STATUSES = {
|
|
6154
6322
|
PENDING: "pending",
|
|
@@ -6227,8 +6395,8 @@ function hasInProgressTask(tasks) {
|
|
|
6227
6395
|
var TodosList = React73.forwardRef(
|
|
6228
6396
|
({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
|
|
6229
6397
|
const sortedTasks = useMemo4(() => sortTasks(tasks), [tasks]);
|
|
6230
|
-
const [isStopping, setIsStopping] =
|
|
6231
|
-
const handleStopClick =
|
|
6398
|
+
const [isStopping, setIsStopping] = useState20(false);
|
|
6399
|
+
const handleStopClick = useCallback20(async () => {
|
|
6232
6400
|
if (!onStopAllTasks || isStopping) {
|
|
6233
6401
|
return;
|
|
6234
6402
|
}
|
|
@@ -6353,7 +6521,7 @@ var ToolSidebar = React74.forwardRef(
|
|
|
6353
6521
|
ToolSidebar.displayName = "ToolSidebar";
|
|
6354
6522
|
|
|
6355
6523
|
// src/components/chat/ToolPanelContainer.tsx
|
|
6356
|
-
import React75, { useCallback as
|
|
6524
|
+
import React75, { useCallback as useCallback21, useEffect as useEffect15, useRef as useRef14, useState as useState21 } from "react";
|
|
6357
6525
|
var ToolPanelContainer = React75.forwardRef(
|
|
6358
6526
|
({
|
|
6359
6527
|
topContent,
|
|
@@ -6365,21 +6533,21 @@ var ToolPanelContainer = React75.forwardRef(
|
|
|
6365
6533
|
initialTopPercent = 60,
|
|
6366
6534
|
...rest
|
|
6367
6535
|
}, ref) => {
|
|
6368
|
-
const [topPercent, setTopPercent] =
|
|
6369
|
-
const [isResizingHeight, setIsResizingHeight] =
|
|
6370
|
-
const containerRef =
|
|
6371
|
-
const lastY =
|
|
6536
|
+
const [topPercent, setTopPercent] = useState21(initialTopPercent);
|
|
6537
|
+
const [isResizingHeight, setIsResizingHeight] = useState21(false);
|
|
6538
|
+
const containerRef = useRef14(null);
|
|
6539
|
+
const lastY = useRef14(null);
|
|
6372
6540
|
const hasBoth = topContent !== null && bottomContent !== null;
|
|
6373
|
-
const startHeightResize =
|
|
6541
|
+
const startHeightResize = useCallback21((e) => {
|
|
6374
6542
|
e.preventDefault();
|
|
6375
6543
|
setIsResizingHeight(true);
|
|
6376
6544
|
lastY.current = e.clientY;
|
|
6377
6545
|
}, []);
|
|
6378
|
-
const stopHeightResize =
|
|
6546
|
+
const stopHeightResize = useCallback21(() => {
|
|
6379
6547
|
setIsResizingHeight(false);
|
|
6380
6548
|
lastY.current = null;
|
|
6381
6549
|
}, []);
|
|
6382
|
-
const resizeHeight =
|
|
6550
|
+
const resizeHeight = useCallback21(
|
|
6383
6551
|
(e) => {
|
|
6384
6552
|
if (!isResizingHeight || lastY.current === null || !containerRef.current) {
|
|
6385
6553
|
return;
|
|
@@ -6398,7 +6566,7 @@ var ToolPanelContainer = React75.forwardRef(
|
|
|
6398
6566
|
},
|
|
6399
6567
|
[isResizingHeight]
|
|
6400
6568
|
);
|
|
6401
|
-
|
|
6569
|
+
useEffect15(() => {
|
|
6402
6570
|
if (isResizingHeight) {
|
|
6403
6571
|
window.addEventListener("mousemove", resizeHeight);
|
|
6404
6572
|
window.addEventListener("mouseup", stopHeightResize);
|
|
@@ -6473,65 +6641,6 @@ var ToolPanelContainer = React75.forwardRef(
|
|
|
6473
6641
|
);
|
|
6474
6642
|
ToolPanelContainer.displayName = "ToolPanelContainer";
|
|
6475
6643
|
|
|
6476
|
-
// src/components/chat/hooks/useResizable.ts
|
|
6477
|
-
import { useCallback as useCallback21, useEffect as useEffect15, useRef as useRef14, useState as useState21 } from "react";
|
|
6478
|
-
function useResizable({
|
|
6479
|
-
initialWidthPercent,
|
|
6480
|
-
minWidthPercent,
|
|
6481
|
-
maxWidthPercent,
|
|
6482
|
-
direction
|
|
6483
|
-
}) {
|
|
6484
|
-
const [widthPercent, setWidthPercent] = useState21(initialWidthPercent);
|
|
6485
|
-
const [isResizing, setIsResizing] = useState21(false);
|
|
6486
|
-
const lastX = useRef14(null);
|
|
6487
|
-
const startResizing = useCallback21((e) => {
|
|
6488
|
-
e.preventDefault();
|
|
6489
|
-
setIsResizing(true);
|
|
6490
|
-
lastX.current = e.clientX;
|
|
6491
|
-
}, []);
|
|
6492
|
-
const stopResizing = useCallback21(() => {
|
|
6493
|
-
setIsResizing(false);
|
|
6494
|
-
lastX.current = null;
|
|
6495
|
-
}, []);
|
|
6496
|
-
const resize = useCallback21(
|
|
6497
|
-
(e) => {
|
|
6498
|
-
if (!isResizing || lastX.current === null) {
|
|
6499
|
-
return;
|
|
6500
|
-
}
|
|
6501
|
-
const deltaX = e.clientX - lastX.current;
|
|
6502
|
-
const factor = direction === "right" ? 1 : -1;
|
|
6503
|
-
const deltaPercent = deltaX / window.innerWidth * 100;
|
|
6504
|
-
setWidthPercent((prevPercent) => {
|
|
6505
|
-
const newPercent = prevPercent + deltaPercent * factor;
|
|
6506
|
-
return Math.min(Math.max(newPercent, minWidthPercent), maxWidthPercent);
|
|
6507
|
-
});
|
|
6508
|
-
lastX.current = e.clientX;
|
|
6509
|
-
},
|
|
6510
|
-
[isResizing, direction, minWidthPercent, maxWidthPercent]
|
|
6511
|
-
);
|
|
6512
|
-
useEffect15(() => {
|
|
6513
|
-
if (isResizing) {
|
|
6514
|
-
window.addEventListener("mousemove", resize);
|
|
6515
|
-
window.addEventListener("mouseup", stopResizing);
|
|
6516
|
-
document.body.style.cursor = "col-resize";
|
|
6517
|
-
document.body.style.userSelect = "none";
|
|
6518
|
-
} else {
|
|
6519
|
-
window.removeEventListener("mousemove", resize);
|
|
6520
|
-
window.removeEventListener("mouseup", stopResizing);
|
|
6521
|
-
document.body.style.cursor = "";
|
|
6522
|
-
document.body.style.userSelect = "";
|
|
6523
|
-
}
|
|
6524
|
-
return () => {
|
|
6525
|
-
window.removeEventListener("mousemove", resize);
|
|
6526
|
-
window.removeEventListener("mouseup", stopResizing);
|
|
6527
|
-
document.body.style.cursor = "";
|
|
6528
|
-
document.body.style.userSelect = "";
|
|
6529
|
-
};
|
|
6530
|
-
}, [isResizing, resize, stopResizing]);
|
|
6531
|
-
const width = `${widthPercent}vw`;
|
|
6532
|
-
return { width, widthPercent, isResizing, startResizing };
|
|
6533
|
-
}
|
|
6534
|
-
|
|
6535
6644
|
// src/components/chat/tree.ts
|
|
6536
6645
|
function createEmptyTree() {
|
|
6537
6646
|
return { nodes: {}, rootIds: [], activeLeafId: null, lastLeafId: null };
|
|
@@ -6692,6 +6801,7 @@ var ChatInterface = React76.forwardRef(
|
|
|
6692
6801
|
onRenameConversation,
|
|
6693
6802
|
isStreaming = false,
|
|
6694
6803
|
isThinking = false,
|
|
6804
|
+
thinkingLabel,
|
|
6695
6805
|
placeholder = "Send a message...",
|
|
6696
6806
|
emptyStateHelper = "Let's talk.",
|
|
6697
6807
|
emptyState,
|
|
@@ -6700,6 +6810,7 @@ var ChatInterface = React76.forwardRef(
|
|
|
6700
6810
|
attachments: propsAttachments,
|
|
6701
6811
|
onAttachmentsChange,
|
|
6702
6812
|
onAttachmentRemove,
|
|
6813
|
+
onAttachmentOpen,
|
|
6703
6814
|
artifactNodes,
|
|
6704
6815
|
isArtifactsPanelOpen,
|
|
6705
6816
|
onArtifactsPanelOpenChange,
|
|
@@ -6716,6 +6827,14 @@ var ChatInterface = React76.forwardRef(
|
|
|
6716
6827
|
}, ref) => {
|
|
6717
6828
|
const prevArtifactNodesRef = useRef15([]);
|
|
6718
6829
|
const prevTasksRef = useRef15([]);
|
|
6830
|
+
const [panelOpenArtifactId, setPanelOpenArtifactId] = useState22(null);
|
|
6831
|
+
const handleAttachmentOpen = useCallback22((artifactId) => {
|
|
6832
|
+
setPanelOpenArtifactId(artifactId);
|
|
6833
|
+
onAttachmentOpen?.(artifactId);
|
|
6834
|
+
}, [onAttachmentOpen]);
|
|
6835
|
+
const handleArtifactPanelClosed = useCallback22(() => {
|
|
6836
|
+
setPanelOpenArtifactId(null);
|
|
6837
|
+
}, []);
|
|
6719
6838
|
const [internalTools, setInternalTools] = useState22({
|
|
6720
6839
|
"top-left": "history",
|
|
6721
6840
|
"bottom-left": null,
|
|
@@ -6903,7 +7022,15 @@ var ChatInterface = React76.forwardRef(
|
|
|
6903
7022
|
isStreaming: node.isStreaming,
|
|
6904
7023
|
muted: opts.muted,
|
|
6905
7024
|
branchInfo,
|
|
6906
|
-
actions
|
|
7025
|
+
actions,
|
|
7026
|
+
attachments: node.attachments ? node.attachments.map((a) => ({
|
|
7027
|
+
id: a.id,
|
|
7028
|
+
file: { name: a.name, size: a.size ?? 0, type: a.type },
|
|
7029
|
+
previewUrl: a.previewUrl,
|
|
7030
|
+
artifactId: a.artifactId,
|
|
7031
|
+
status: a.status ?? "analyzed"
|
|
7032
|
+
})) : void 0,
|
|
7033
|
+
onAttachmentOpen: handleAttachmentOpen
|
|
6907
7034
|
};
|
|
6908
7035
|
},
|
|
6909
7036
|
[
|
|
@@ -6913,7 +7040,8 @@ var ChatInterface = React76.forwardRef(
|
|
|
6913
7040
|
onEditMessage,
|
|
6914
7041
|
onRetryMessage,
|
|
6915
7042
|
handleBranchSwitch,
|
|
6916
|
-
handleJumpToCheckpoint
|
|
7043
|
+
handleJumpToCheckpoint,
|
|
7044
|
+
handleAttachmentOpen
|
|
6917
7045
|
]
|
|
6918
7046
|
);
|
|
6919
7047
|
const displayItems = useMemo5(() => {
|
|
@@ -6982,6 +7110,8 @@ var ChatInterface = React76.forwardRef(
|
|
|
6982
7110
|
ArtifactsPanel,
|
|
6983
7111
|
{
|
|
6984
7112
|
nodes: artifactNodes,
|
|
7113
|
+
openArtifactId: panelOpenArtifactId,
|
|
7114
|
+
onArtifactClosed: handleArtifactPanelClosed,
|
|
6985
7115
|
className: "h-full"
|
|
6986
7116
|
}
|
|
6987
7117
|
);
|
|
@@ -7044,6 +7174,7 @@ var ChatInterface = React76.forwardRef(
|
|
|
7044
7174
|
latestUserMessageIndex,
|
|
7045
7175
|
isStreaming,
|
|
7046
7176
|
isThinking,
|
|
7177
|
+
thinkingLabel,
|
|
7047
7178
|
className: "flex-1"
|
|
7048
7179
|
}
|
|
7049
7180
|
)), /* @__PURE__ */ React76.createElement("div", { className: cx(
|