@hachej/boring-agent 0.1.92 → 0.1.94
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/{chunk-IWBC6SF7.js → chunk-2TMS2RU2.js} +15 -2
- package/dist/{chunk-CJ2BW2W2.js → chunk-EOMY2HDT.js} +1 -0
- package/dist/{chunk-V3ZD3T3G.js → chunk-N4AATPH7.js} +258 -76
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +1 -1
- package/dist/{createHarness-PMYRKDE4.js → createHarness-UCD74XXK.js} +1 -1
- package/dist/{errors-C38f6pol.d.ts → errors-G6T6S7PQ.d.ts} +2 -0
- package/dist/front/index.d.ts +71 -8
- package/dist/front/index.js +910 -619
- package/dist/front/styles.css +253 -109
- package/dist/{lease-BqeCLGPL.d.ts → lease-CusB-uLg.d.ts} +3 -1
- package/dist/{piChatSessionService-BrPqKrpY.d.ts → piChatSessionService-C0KbcGw9.d.ts} +7 -1
- package/dist/server/agent-host/testing/gatewayConformance.d.ts +3 -3
- package/dist/server/agent-host/testing/gatewayConformance.js +77 -0
- package/dist/server/index.d.ts +44 -5
- package/dist/server/index.js +3 -3
- package/dist/server/worker/index.js +3 -3
- package/dist/shared/index.d.ts +4 -4
- package/dist/{types-uQozUhGt.d.ts → types-C-Eroi__.d.ts} +2 -2
- package/docs/AGENT_GATEWAY_V0.md +152 -0
- package/package.json +4 -4
package/dist/front/index.js
CHANGED
|
@@ -68,7 +68,7 @@ function rawWorkspaceFileUrl(path, opts) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
// src/front/chat/PiChatPanel.tsx
|
|
71
|
-
import { lazy, Suspense, useCallback as useCallback18, useEffect as useEffect21, useMemo as
|
|
71
|
+
import { lazy, Suspense, useCallback as useCallback18, useEffect as useEffect21, useMemo as useMemo16, useRef as useRef18, useState as useState20 } from "react";
|
|
72
72
|
|
|
73
73
|
// src/front/ArtifactOpenContext.tsx
|
|
74
74
|
import { createContext, useContext } from "react";
|
|
@@ -279,6 +279,7 @@ var builtinCommands = [
|
|
|
279
279
|
{
|
|
280
280
|
name: "reload",
|
|
281
281
|
description: "Reload agent plugins",
|
|
282
|
+
clickBehavior: "execute",
|
|
282
283
|
handler(_, ctx) {
|
|
283
284
|
if (ctx.pluginUpdate) return ctx.pluginUpdate.run();
|
|
284
285
|
return ctx.reloadAgentPlugins();
|
|
@@ -345,7 +346,7 @@ var lineClass = {
|
|
|
345
346
|
" ": ""
|
|
346
347
|
};
|
|
347
348
|
var prefixMap = { "+": "+", "-": "-", " ": " " };
|
|
348
|
-
function DiffView({ oldString, newString, path, replaceAll }) {
|
|
349
|
+
function DiffView({ oldString, newString, path, replaceAll, actions }) {
|
|
349
350
|
const [expanded, setExpanded] = useState(false);
|
|
350
351
|
if (oldString === newString) {
|
|
351
352
|
return /* @__PURE__ */ jsx3("div", { "data-testid": "diff-no-change", className: "py-2 italic opacity-60", children: "No changes" });
|
|
@@ -355,9 +356,12 @@ function DiffView({ oldString, newString, path, replaceAll }) {
|
|
|
355
356
|
const collapsed = !expanded && lines.length > COLLAPSE_THRESHOLD;
|
|
356
357
|
const visible = collapsed ? lines.slice(0, COLLAPSE_THRESHOLD) : lines;
|
|
357
358
|
return /* @__PURE__ */ jsxs2("div", { "data-testid": "diff-view", children: [
|
|
358
|
-
/* @__PURE__ */ jsxs2("div", { className: "px-
|
|
359
|
-
|
|
360
|
-
|
|
359
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex min-h-7 items-center justify-between gap-2 px-2 py-0.5 font-[family-name:var(--boring-agent-font-mono,monospace)] text-xs opacity-70", children: [
|
|
360
|
+
/* @__PURE__ */ jsxs2("span", { className: "min-w-0 truncate", children: [
|
|
361
|
+
path,
|
|
362
|
+
replaceAll ? " (replace all)" : ""
|
|
363
|
+
] }),
|
|
364
|
+
actions ? /* @__PURE__ */ jsx3("span", { className: "flex shrink-0 items-center gap-0.5", children: actions }) : null
|
|
361
365
|
] }),
|
|
362
366
|
/* @__PURE__ */ jsx3("pre", { className: "m-0 overflow-auto py-2 font-[family-name:var(--boring-agent-font-mono,monospace)] text-[0.8125rem] leading-relaxed", children: visible.map((line, i) => /* @__PURE__ */ jsxs2("div", { className: cn("px-3", lineClass[line.type]), children: [
|
|
363
367
|
/* @__PURE__ */ jsx3("span", { className: "inline-block w-[1.5ch] select-none opacity-50", children: prefixMap[line.type] }),
|
|
@@ -1263,9 +1267,9 @@ var statusIcons = {
|
|
|
1263
1267
|
"output-error": /* @__PURE__ */ jsx9(XCircleIcon, { className: "size-4 text-destructive" }),
|
|
1264
1268
|
aborted: /* @__PURE__ */ jsx9(XCircleIcon, { className: "size-4 text-muted-foreground" })
|
|
1265
1269
|
};
|
|
1266
|
-
var getStatusBadge = (status) => /* @__PURE__ */ jsxs8(Badge, { className: "shrink-0 gap-1.5 rounded-full text-xs", variant: "secondary", children: [
|
|
1270
|
+
var getStatusBadge = (status, label = statusLabels[status]) => /* @__PURE__ */ jsxs8(Badge, { className: "shrink-0 gap-1.5 rounded-full text-xs", variant: "secondary", children: [
|
|
1267
1271
|
statusIcons[status],
|
|
1268
|
-
|
|
1272
|
+
label
|
|
1269
1273
|
] });
|
|
1270
1274
|
var ToolHeader = ({
|
|
1271
1275
|
className,
|
|
@@ -1274,6 +1278,7 @@ var ToolHeader = ({
|
|
|
1274
1278
|
state,
|
|
1275
1279
|
icon,
|
|
1276
1280
|
toolName,
|
|
1281
|
+
statusLabel,
|
|
1277
1282
|
...props
|
|
1278
1283
|
}) => {
|
|
1279
1284
|
const derivedName = type === "dynamic-tool" || type === "tool-call" ? toolName : type.split("-").slice(1).join("-");
|
|
@@ -1290,7 +1295,7 @@ var ToolHeader = ({
|
|
|
1290
1295
|
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
1291
1296
|
icon ?? /* @__PURE__ */ jsx9(WrenchIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
|
|
1292
1297
|
/* @__PURE__ */ jsx9("span", { "data-boring-agent-part": "tool-title", className: "min-w-0 flex-1 truncate text-sm font-medium", children: title ?? derivedName }),
|
|
1293
|
-
getStatusBadge(state)
|
|
1298
|
+
getStatusBadge(state, statusLabel)
|
|
1294
1299
|
] }),
|
|
1295
1300
|
/* @__PURE__ */ jsx9(
|
|
1296
1301
|
ChevronDownIcon,
|
|
@@ -1356,7 +1361,7 @@ var ToolOutput = ({
|
|
|
1356
1361
|
|
|
1357
1362
|
// src/front/toolRenderers.tsx
|
|
1358
1363
|
import { CollapsibleTrigger as CollapsibleTrigger2 } from "@hachej/boring-ui-kit";
|
|
1359
|
-
import { ChevronDownIcon as ChevronDownIcon2, ExternalLinkIcon, FileDiffIcon, FilePlus2Icon, FileTextIcon, SearchIcon, SquareTerminalIcon, ZapIcon } from "lucide-react";
|
|
1364
|
+
import { ChevronDownIcon as ChevronDownIcon2, CopyIcon as CopyIcon2, DownloadIcon, ExternalLinkIcon, FileDiffIcon, FilePlus2Icon, FileTextIcon, SearchIcon, SquareTerminalIcon, ZapIcon } from "lucide-react";
|
|
1360
1365
|
|
|
1361
1366
|
// src/front/primitives/artifact.tsx
|
|
1362
1367
|
import { Button as Button6 } from "@hachej/boring-ui-kit";
|
|
@@ -1368,44 +1373,6 @@ import {
|
|
|
1368
1373
|
} from "@hachej/boring-ui-kit";
|
|
1369
1374
|
import { XIcon } from "lucide-react";
|
|
1370
1375
|
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1371
|
-
var Artifact = ({ className, ...props }) => /* @__PURE__ */ jsx10(
|
|
1372
|
-
"div",
|
|
1373
|
-
{
|
|
1374
|
-
className: cn(
|
|
1375
|
-
"flex flex-col overflow-hidden rounded-lg border bg-background shadow-sm",
|
|
1376
|
-
className
|
|
1377
|
-
),
|
|
1378
|
-
...props
|
|
1379
|
-
}
|
|
1380
|
-
);
|
|
1381
|
-
var ArtifactHeader = ({
|
|
1382
|
-
className,
|
|
1383
|
-
...props
|
|
1384
|
-
}) => /* @__PURE__ */ jsx10(
|
|
1385
|
-
"div",
|
|
1386
|
-
{
|
|
1387
|
-
className: cn(
|
|
1388
|
-
"flex items-center justify-between border-b bg-muted/50 px-4 py-3",
|
|
1389
|
-
className
|
|
1390
|
-
),
|
|
1391
|
-
...props
|
|
1392
|
-
}
|
|
1393
|
-
);
|
|
1394
|
-
var ArtifactTitle = ({ className, ...props }) => /* @__PURE__ */ jsx10(
|
|
1395
|
-
"p",
|
|
1396
|
-
{
|
|
1397
|
-
className: cn("font-medium text-foreground text-sm", className),
|
|
1398
|
-
...props
|
|
1399
|
-
}
|
|
1400
|
-
);
|
|
1401
|
-
var ArtifactDescription = ({
|
|
1402
|
-
className,
|
|
1403
|
-
...props
|
|
1404
|
-
}) => /* @__PURE__ */ jsx10("p", { className: cn("text-muted-foreground text-sm", className), ...props });
|
|
1405
|
-
var ArtifactActions = ({
|
|
1406
|
-
className,
|
|
1407
|
-
...props
|
|
1408
|
-
}) => /* @__PURE__ */ jsx10("div", { className: cn("flex items-center gap-1", className), ...props });
|
|
1409
1376
|
var ArtifactAction = ({
|
|
1410
1377
|
tooltip,
|
|
1411
1378
|
label,
|
|
@@ -1441,13 +1408,6 @@ var ArtifactAction = ({
|
|
|
1441
1408
|
}
|
|
1442
1409
|
return button;
|
|
1443
1410
|
};
|
|
1444
|
-
var ArtifactContent = ({
|
|
1445
|
-
className,
|
|
1446
|
-
...props
|
|
1447
|
-
}) => /* @__PURE__ */ jsx10("div", { className: cn("flex-1 overflow-auto p-4", className), ...props });
|
|
1448
|
-
|
|
1449
|
-
// src/front/toolRenderers.tsx
|
|
1450
|
-
import { CopyIcon as CopyIcon2, DownloadIcon } from "lucide-react";
|
|
1451
1411
|
|
|
1452
1412
|
// src/front/runtimeReadinessStatus.ts
|
|
1453
1413
|
var COPY = {
|
|
@@ -1513,7 +1473,7 @@ function getWorkspaceNotReadyStatus(output) {
|
|
|
1513
1473
|
}
|
|
1514
1474
|
|
|
1515
1475
|
// src/front/toolRenderers.tsx
|
|
1516
|
-
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1476
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1517
1477
|
function asRecord2(value) {
|
|
1518
1478
|
return typeof value === "object" && value !== null ? value : {};
|
|
1519
1479
|
}
|
|
@@ -1671,59 +1631,44 @@ function renderWrite2(part) {
|
|
|
1671
1631
|
const path = typeof input.path === "string" ? input.path : "";
|
|
1672
1632
|
const filesystem = typeof input.filesystem === "string" ? input.filesystem : void 0;
|
|
1673
1633
|
const content = typeof input.content === "string" ? input.content : "";
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
" ",
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
label: "Copy",
|
|
1696
|
-
onClick: () => {
|
|
1697
|
-
void copyTextToClipboard(content);
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
),
|
|
1701
|
-
/* @__PURE__ */ jsx11(
|
|
1702
|
-
ArtifactAction,
|
|
1703
|
-
{
|
|
1704
|
-
icon: DownloadIcon,
|
|
1705
|
-
tooltip: "Download file",
|
|
1706
|
-
label: "Download",
|
|
1707
|
-
onClick: () => {
|
|
1708
|
-
try {
|
|
1634
|
+
return /* @__PURE__ */ jsxs10(Tool2, { defaultOpen: part.state === "output-available", children: [
|
|
1635
|
+
/* @__PURE__ */ jsx11(ToolHeader, { className: "p-2", icon: /* @__PURE__ */ jsx11(FilePlus2Icon, { className: "size-4 shrink-0 text-muted-foreground" }), title: pathTitle("write", path, filesystem), ...toHeaderProps(part) }),
|
|
1636
|
+
/* @__PURE__ */ jsxs10(ToolContent, { className: "p-1.5", children: [
|
|
1637
|
+
/* @__PURE__ */ jsx11("div", { className: "max-h-80 overflow-auto overscroll-contain rounded-sm", children: content ? /* @__PURE__ */ jsx11(
|
|
1638
|
+
DiffView,
|
|
1639
|
+
{
|
|
1640
|
+
oldString: "",
|
|
1641
|
+
newString: content,
|
|
1642
|
+
path,
|
|
1643
|
+
actions: /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
1644
|
+
/* @__PURE__ */ jsx11(ArtifactAction, { className: "size-6", icon: CopyIcon2, tooltip: "Copy contents", label: "Copy", onClick: () => {
|
|
1645
|
+
void copyTextToClipboard(content);
|
|
1646
|
+
} }),
|
|
1647
|
+
/* @__PURE__ */ jsx11(
|
|
1648
|
+
ArtifactAction,
|
|
1649
|
+
{
|
|
1650
|
+
className: "size-6",
|
|
1651
|
+
icon: DownloadIcon,
|
|
1652
|
+
tooltip: "Download file",
|
|
1653
|
+
label: "Download",
|
|
1654
|
+
onClick: () => {
|
|
1709
1655
|
const blob = new Blob([content], { type: "text/plain" });
|
|
1710
1656
|
const url = URL.createObjectURL(blob);
|
|
1711
|
-
const
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
document.body.appendChild(
|
|
1715
|
-
|
|
1716
|
-
|
|
1657
|
+
const anchor = document.createElement("a");
|
|
1658
|
+
anchor.href = url;
|
|
1659
|
+
anchor.download = path.split("/").pop() || "artifact.txt";
|
|
1660
|
+
document.body.appendChild(anchor);
|
|
1661
|
+
anchor.click();
|
|
1662
|
+
anchor.remove();
|
|
1717
1663
|
URL.revokeObjectURL(url);
|
|
1718
|
-
} catch {
|
|
1719
1664
|
}
|
|
1720
1665
|
}
|
|
1721
|
-
|
|
1722
|
-
)
|
|
1723
|
-
|
|
1724
|
-
] }),
|
|
1725
|
-
|
|
1726
|
-
] })
|
|
1666
|
+
)
|
|
1667
|
+
] })
|
|
1668
|
+
}
|
|
1669
|
+
) : /* @__PURE__ */ jsx11("p", { className: "px-2 py-1 text-[12px] text-muted-foreground", children: "No file content was included with this tool call." }) }),
|
|
1670
|
+
part.errorText || part.state === "output-error" || part.state === "output-denied" ? /* @__PURE__ */ jsx11(ToolOutput, { output: part.output, errorText: part.errorText }) : null
|
|
1671
|
+
] })
|
|
1727
1672
|
] });
|
|
1728
1673
|
}
|
|
1729
1674
|
function renderEdit2(part) {
|
|
@@ -1732,25 +1677,26 @@ function renderEdit2(part) {
|
|
|
1732
1677
|
const input = asRecord2(part.input);
|
|
1733
1678
|
const path = typeof input.path === "string" ? input.path : "";
|
|
1734
1679
|
const filesystem = typeof input.filesystem === "string" ? input.filesystem : void 0;
|
|
1735
|
-
const
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
] })
|
|
1752
|
-
|
|
1753
|
-
/* @__PURE__ */ jsx11(
|
|
1680
|
+
const edits = Array.isArray(input.edits) ? input.edits.flatMap((value) => {
|
|
1681
|
+
const edit = asRecord2(value);
|
|
1682
|
+
const oldText = typeof edit.oldText === "string" ? edit.oldText : "";
|
|
1683
|
+
const newText = typeof edit.newText === "string" ? edit.newText : "";
|
|
1684
|
+
return oldText || newText ? [{ oldText, newText }] : [];
|
|
1685
|
+
}) : [];
|
|
1686
|
+
const legacyOldText = typeof input.oldString === "string" ? input.oldString : typeof input.oldText === "string" ? input.oldText : "";
|
|
1687
|
+
const legacyNewText = typeof input.newString === "string" ? input.newString : typeof input.newText === "string" ? input.newText : "";
|
|
1688
|
+
const visibleEdits = edits.length > 0 ? edits : legacyOldText || legacyNewText ? [{ oldText: legacyOldText, newText: legacyNewText }] : [];
|
|
1689
|
+
return /* @__PURE__ */ jsxs10(Tool2, { defaultOpen: part.state === "output-available", children: [
|
|
1690
|
+
/* @__PURE__ */ jsx11(ToolHeader, { className: "p-2", icon: /* @__PURE__ */ jsx11(FileDiffIcon, { className: "size-4 shrink-0 text-muted-foreground" }), title: pathTitle("edit", path, filesystem), ...toHeaderProps(part) }),
|
|
1691
|
+
/* @__PURE__ */ jsxs10(ToolContent, { className: "space-y-2 p-2", children: [
|
|
1692
|
+
/* @__PURE__ */ jsx11("div", { className: "max-h-80 space-y-2 overflow-auto overscroll-contain rounded-sm", children: visibleEdits.length > 0 ? visibleEdits.map((edit, index) => /* @__PURE__ */ jsxs10("div", { children: [
|
|
1693
|
+
visibleEdits.length > 1 ? /* @__PURE__ */ jsxs10("div", { className: "mb-1 px-1 text-[11px] text-muted-foreground", children: [
|
|
1694
|
+
"Change ",
|
|
1695
|
+
index + 1
|
|
1696
|
+
] }) : null,
|
|
1697
|
+
/* @__PURE__ */ jsx11(DiffView, { oldString: edit.oldText, newString: edit.newText, path })
|
|
1698
|
+
] }, `${index}:${edit.oldText.length}:${edit.newText.length}`)) : /* @__PURE__ */ jsx11("p", { className: "px-2 py-1 text-[12px] text-muted-foreground", children: "Diff details were not included with this tool call." }) }),
|
|
1699
|
+
part.errorText || part.state === "output-error" || part.state === "output-denied" ? /* @__PURE__ */ jsx11(ToolOutput, { output: part.output, errorText: part.errorText }) : null
|
|
1754
1700
|
] })
|
|
1755
1701
|
] });
|
|
1756
1702
|
}
|
|
@@ -2026,7 +1972,7 @@ function usePickerKeyboard({
|
|
|
2026
1972
|
}
|
|
2027
1973
|
|
|
2028
1974
|
// src/front/primitives/mention-picker.tsx
|
|
2029
|
-
import { Fragment as
|
|
1975
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2030
1976
|
var mentionSearchGlob = toFileSearchGlob;
|
|
2031
1977
|
function highlight(text, query) {
|
|
2032
1978
|
if (!query) return null;
|
|
@@ -2089,7 +2035,7 @@ function MentionPicker({
|
|
|
2089
2035
|
onSelect(path);
|
|
2090
2036
|
},
|
|
2091
2037
|
children: [
|
|
2092
|
-
/* @__PURE__ */ jsx12("span", { className: "font-medium", children: hl ? /* @__PURE__ */ jsxs11(
|
|
2038
|
+
/* @__PURE__ */ jsx12("span", { className: "font-medium", children: hl ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
2093
2039
|
hl.before,
|
|
2094
2040
|
/* @__PURE__ */ jsx12("mark", { className: "bg-transparent text-[color:var(--accent)]", children: hl.match }),
|
|
2095
2041
|
hl.after
|
|
@@ -2495,10 +2441,11 @@ var PiComposerPolicyController = class {
|
|
|
2495
2441
|
}));
|
|
2496
2442
|
}
|
|
2497
2443
|
async runLocalCommand(commandName, args) {
|
|
2498
|
-
|
|
2444
|
+
const command = this.options.registry.get(commandName);
|
|
2445
|
+
if (isPiChatBusy(this.options.session.getState().status) && command?.allowWhileBusy?.(args) !== true) {
|
|
2499
2446
|
return this.block("busy-slash-command", "Slash commands are not queued while the agent is responding.");
|
|
2500
2447
|
}
|
|
2501
|
-
const result = await Promise.resolve(
|
|
2448
|
+
const result = await Promise.resolve(command?.handler(args, this.options.slashContext));
|
|
2502
2449
|
const message = typeof result === "string" ? result : result && typeof result === "object" ? result.message : void 0;
|
|
2503
2450
|
const preserveDraft = Boolean(result && typeof result === "object" && result.preserveDraft === true);
|
|
2504
2451
|
if (message) this.options.onCommandResult?.(message);
|
|
@@ -2911,6 +2858,25 @@ function composerNoticeForRuntimeDependencies(status) {
|
|
|
2911
2858
|
return null;
|
|
2912
2859
|
}
|
|
2913
2860
|
|
|
2861
|
+
// src/front/chat/composerContributions.tsx
|
|
2862
|
+
import { createContext as createContext3, useContext as useContext3, useMemo as useMemo3 } from "react";
|
|
2863
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
2864
|
+
var ComposerContributionContext = createContext3([]);
|
|
2865
|
+
function ComposerContributionProvider({
|
|
2866
|
+
contribution,
|
|
2867
|
+
children
|
|
2868
|
+
}) {
|
|
2869
|
+
const parent = useContext3(ComposerContributionContext);
|
|
2870
|
+
const contributions = useMemo3(
|
|
2871
|
+
() => [contribution, ...parent.filter((entry) => entry.id !== contribution.id)],
|
|
2872
|
+
[contribution, parent]
|
|
2873
|
+
);
|
|
2874
|
+
return /* @__PURE__ */ jsx13(ComposerContributionContext.Provider, { value: contributions, children });
|
|
2875
|
+
}
|
|
2876
|
+
function useComposerContributions() {
|
|
2877
|
+
return useContext3(ComposerContributionContext);
|
|
2878
|
+
}
|
|
2879
|
+
|
|
2914
2880
|
// src/front/chat/pi/piChatMessageMetadata.ts
|
|
2915
2881
|
function earliestCreatedAt(left, right) {
|
|
2916
2882
|
if (!left) return right;
|
|
@@ -5158,7 +5124,7 @@ function resolveStorage2(storage) {
|
|
|
5158
5124
|
}
|
|
5159
5125
|
|
|
5160
5126
|
// src/front/chat/session/usePiSessions.ts
|
|
5161
|
-
import { useCallback as useCallback7, useEffect as useEffect8, useMemo as
|
|
5127
|
+
import { useCallback as useCallback7, useEffect as useEffect8, useMemo as useMemo4, useRef as useRef8, useState as useState10 } from "react";
|
|
5162
5128
|
var DEFAULT_SESSIONS_API_PATH = "/api/v1/agent/pi-chat/sessions";
|
|
5163
5129
|
var SESSION_PAGE_SIZE = 50;
|
|
5164
5130
|
var DEFAULT_MAX_RETRIES = 60;
|
|
@@ -5179,16 +5145,16 @@ function usePiSessions(options = {}) {
|
|
|
5179
5145
|
const addressed = typeof options.agentTypeId === "string" && options.agentTypeId.length > 0;
|
|
5180
5146
|
const sessionsApiPath = options.sessionsApiPath ?? (addressed ? `/api/v1/agents/${encodeURIComponent(options.agentTypeId)}/sessions` : DEFAULT_SESSIONS_API_PATH);
|
|
5181
5147
|
const storageScope = options.storageScope ?? "default";
|
|
5182
|
-
const fetchImpl =
|
|
5148
|
+
const fetchImpl = useMemo4(() => options.fetch ?? globalThis.fetch.bind(globalThis), [options.fetch]);
|
|
5183
5149
|
const createRemoteSession = options.createRemoteSession ?? createRemotePiSession;
|
|
5184
5150
|
const connectActiveSession = options.connectActiveSession ?? true;
|
|
5185
5151
|
const retryMaxRetries = options.retry?.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
5186
5152
|
const retryBaseMs = options.retry?.baseMs ?? DEFAULT_RETRY_BASE_MS;
|
|
5187
5153
|
const retryMaxMs = options.retry?.maxMs ?? DEFAULT_RETRY_MAX_MS;
|
|
5188
|
-
const headersKey =
|
|
5189
|
-
const normalizedHeaders =
|
|
5190
|
-
const requestScopeKey =
|
|
5191
|
-
const dataSourceKey =
|
|
5154
|
+
const headersKey = useMemo4(() => headersScopeKey(options.requestHeaders, storageScope), [options.requestHeaders, storageScope]);
|
|
5155
|
+
const normalizedHeaders = useMemo4(() => buildRequestHeaders(options.requestHeaders, storageScope), [headersKey, storageScope]);
|
|
5156
|
+
const requestScopeKey = useMemo4(() => requestScopeIdentity(apiBaseUrl, sessionsApiPath, storageScope, headersKey), [apiBaseUrl, headersKey, sessionsApiPath, storageScope]);
|
|
5157
|
+
const dataSourceKey = useMemo4(() => dataSourceIdentity(apiBaseUrl, sessionsApiPath, storageScope), [apiBaseUrl, sessionsApiPath, storageScope]);
|
|
5192
5158
|
const [sessions, setSessions] = useState10([]);
|
|
5193
5159
|
const [dataStorageScope, setDataStorageScope] = useState10(storageScope);
|
|
5194
5160
|
const [activeSessionId, setActiveSessionId] = useState10(() => options.initialActiveSessionId ?? readActiveSessionId({ storageScope, storage: options.storage }));
|
|
@@ -5215,7 +5181,7 @@ function usePiSessions(options = {}) {
|
|
|
5215
5181
|
requestScopeRef.current = requestScopeKey;
|
|
5216
5182
|
const remoteSessionOptionsRef = useRef8(options.remoteSessionOptions);
|
|
5217
5183
|
remoteSessionOptionsRef.current = options.remoteSessionOptions;
|
|
5218
|
-
const remoteSessionOptionsKey =
|
|
5184
|
+
const remoteSessionOptionsKey = useMemo4(
|
|
5219
5185
|
() => remoteSessionOptionsIdentity(options.remoteSessionOptions),
|
|
5220
5186
|
[options.remoteSessionOptions]
|
|
5221
5187
|
);
|
|
@@ -5657,10 +5623,10 @@ function clearRetryTimer(ref) {
|
|
|
5657
5623
|
}
|
|
5658
5624
|
|
|
5659
5625
|
// src/front/chat/session/SessionList.tsx
|
|
5660
|
-
import { useMemo as
|
|
5626
|
+
import { useMemo as useMemo5 } from "react";
|
|
5661
5627
|
import { ChevronLeftIcon, PlusIcon, Trash2Icon } from "lucide-react";
|
|
5662
5628
|
import { IconButton } from "@hachej/boring-ui-kit";
|
|
5663
|
-
import { Fragment as
|
|
5629
|
+
import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5664
5630
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
5665
5631
|
function SessionList({
|
|
5666
5632
|
sessions,
|
|
@@ -5675,7 +5641,7 @@ function SessionList({
|
|
|
5675
5641
|
onClose,
|
|
5676
5642
|
className
|
|
5677
5643
|
}) {
|
|
5678
|
-
const groups =
|
|
5644
|
+
const groups = useMemo5(() => groupSessions(sessions), [sessions]);
|
|
5679
5645
|
return /* @__PURE__ */ jsxs12(
|
|
5680
5646
|
"div",
|
|
5681
5647
|
{
|
|
@@ -5686,26 +5652,26 @@ function SessionList({
|
|
|
5686
5652
|
"aria-busy": loading ? "true" : void 0,
|
|
5687
5653
|
children: [
|
|
5688
5654
|
/* @__PURE__ */ jsxs12("div", { className: "flex h-11 items-center justify-between border-b border-border/60 px-3.5", children: [
|
|
5689
|
-
/* @__PURE__ */
|
|
5655
|
+
/* @__PURE__ */ jsx14("span", { className: "text-[12px] font-medium tracking-tight text-foreground/70", children: "Sessions" }),
|
|
5690
5656
|
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-0.5", children: [
|
|
5691
|
-
onCreate ? /* @__PURE__ */
|
|
5692
|
-
onClose ? /* @__PURE__ */
|
|
5657
|
+
onCreate ? /* @__PURE__ */ jsx14(IconButton, { type: "button", variant: "ghost", size: "icon-xs", onClick: onCreate, "aria-label": "New session", title: "New chat", children: /* @__PURE__ */ jsx14(PlusIcon, { className: "h-3.5 w-3.5", strokeWidth: 1.75 }) }) : null,
|
|
5658
|
+
onClose ? /* @__PURE__ */ jsx14(IconButton, { type: "button", variant: "ghost", size: "icon-xs", onClick: onClose, "aria-label": "Close sessions", title: "Close sessions", children: /* @__PURE__ */ jsx14(ChevronLeftIcon, { className: "h-4 w-4", strokeWidth: 1.75 }) }) : null
|
|
5693
5659
|
] })
|
|
5694
5660
|
] }),
|
|
5695
5661
|
/* @__PURE__ */ jsxs12("div", { className: "flex-1 overflow-y-auto py-2.5", children: [
|
|
5696
5662
|
sessions.length === 0 ? /* @__PURE__ */ jsxs12("div", { "data-boring-agent-part": "session-list-empty", className: "px-3 py-8 text-center text-[13px] text-muted-foreground", children: [
|
|
5697
5663
|
loading ? "Loading sessions\u2026" : "No sessions yet.",
|
|
5698
|
-
!loading ? /* @__PURE__ */ jsxs12(
|
|
5699
|
-
/* @__PURE__ */
|
|
5664
|
+
!loading ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
|
|
5665
|
+
/* @__PURE__ */ jsx14("br", {}),
|
|
5700
5666
|
"Start a new chat to begin."
|
|
5701
5667
|
] }) : null
|
|
5702
5668
|
] }) : null,
|
|
5703
5669
|
groups.map((group, index) => /* @__PURE__ */ jsxs12("section", { className: cn(index > 0 && "mt-4"), children: [
|
|
5704
5670
|
/* @__PURE__ */ jsxs12("div", { className: "flex items-baseline justify-between gap-2 px-3.5 pb-2 pt-2 text-[11px] font-medium tracking-tight text-muted-foreground/75", children: [
|
|
5705
|
-
/* @__PURE__ */
|
|
5706
|
-
/* @__PURE__ */
|
|
5671
|
+
/* @__PURE__ */ jsx14("span", { children: group.label }),
|
|
5672
|
+
/* @__PURE__ */ jsx14("span", { "aria-hidden": "true", className: "text-[10.5px] tabular-nums text-muted-foreground/40", children: group.items.length })
|
|
5707
5673
|
] }),
|
|
5708
|
-
/* @__PURE__ */
|
|
5674
|
+
/* @__PURE__ */ jsx14("ul", { role: "list", className: "flex flex-col", children: group.items.map((session) => /* @__PURE__ */ jsx14(
|
|
5709
5675
|
SessionRow,
|
|
5710
5676
|
{
|
|
5711
5677
|
session,
|
|
@@ -5716,7 +5682,7 @@ function SessionList({
|
|
|
5716
5682
|
session.id
|
|
5717
5683
|
)) })
|
|
5718
5684
|
] }, group.key)),
|
|
5719
|
-
hasMore && onLoadMore ? /* @__PURE__ */
|
|
5685
|
+
hasMore && onLoadMore ? /* @__PURE__ */ jsx14("div", { className: "px-3 py-3", children: /* @__PURE__ */ jsx14(
|
|
5720
5686
|
"button",
|
|
5721
5687
|
{
|
|
5722
5688
|
type: "button",
|
|
@@ -5748,10 +5714,10 @@ function SessionRow({ session, active, onSwitch, onDelete }) {
|
|
|
5748
5714
|
onClick: () => onSwitch?.(session.id),
|
|
5749
5715
|
children: [
|
|
5750
5716
|
/* @__PURE__ */ jsxs12("span", { className: "min-w-0 flex-1 truncate leading-5", title: session.title, children: [
|
|
5751
|
-
/* @__PURE__ */
|
|
5752
|
-
time ? /* @__PURE__ */
|
|
5717
|
+
/* @__PURE__ */ jsx14("span", { className: cn(active ? "font-medium text-foreground" : "text-foreground/90"), children: session.title || "Untitled" }),
|
|
5718
|
+
time ? /* @__PURE__ */ jsx14("span", { className: cn("ml-1.5 tabular-nums text-[11px]", active ? "text-[color:var(--accent)]" : "text-muted-foreground/60"), children: time }) : null
|
|
5753
5719
|
] }),
|
|
5754
|
-
onDelete ? /* @__PURE__ */
|
|
5720
|
+
onDelete ? /* @__PURE__ */ jsx14(
|
|
5755
5721
|
IconButton,
|
|
5756
5722
|
{
|
|
5757
5723
|
type: "button",
|
|
@@ -5763,7 +5729,7 @@ function SessionRow({ session, active, onSwitch, onDelete }) {
|
|
|
5763
5729
|
onDelete(session.id);
|
|
5764
5730
|
},
|
|
5765
5731
|
"aria-label": `Delete ${session.title || "session"}`,
|
|
5766
|
-
children: /* @__PURE__ */
|
|
5732
|
+
children: /* @__PURE__ */ jsx14(Trash2Icon, { className: "h-3 w-3" })
|
|
5767
5733
|
}
|
|
5768
5734
|
) : null
|
|
5769
5735
|
]
|
|
@@ -6010,7 +5976,7 @@ function searchPiSessions(sessions, query, options = {}) {
|
|
|
6010
5976
|
|
|
6011
5977
|
// src/front/chat/components/PiConversationSurface.tsx
|
|
6012
5978
|
import { Loader2 as Loader22 } from "lucide-react";
|
|
6013
|
-
import { useCallback as useCallback14, useEffect as useEffect14, useLayoutEffect, useRef as
|
|
5979
|
+
import { useCallback as useCallback14, useEffect as useEffect14, useLayoutEffect, useRef as useRef11, useState as useState15 } from "react";
|
|
6014
5980
|
import { useStickToBottomContext as useStickToBottomContext2 } from "use-stick-to-bottom";
|
|
6015
5981
|
|
|
6016
5982
|
// src/front/primitives/conversation.tsx
|
|
@@ -6018,7 +5984,7 @@ import { Button as Button7 } from "@hachej/boring-ui-kit";
|
|
|
6018
5984
|
import { ArrowDownIcon, DownloadIcon as DownloadIcon2 } from "lucide-react";
|
|
6019
5985
|
import { useCallback as useCallback8, useEffect as useEffect9 } from "react";
|
|
6020
5986
|
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
6021
|
-
import { Fragment as
|
|
5987
|
+
import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
6022
5988
|
var ConversationScrollController = ({
|
|
6023
5989
|
onScrollToBottomReady
|
|
6024
5990
|
}) => {
|
|
@@ -6044,7 +6010,7 @@ var Conversation = ({
|
|
|
6044
6010
|
role: "log",
|
|
6045
6011
|
...props,
|
|
6046
6012
|
children: [
|
|
6047
|
-
/* @__PURE__ */
|
|
6013
|
+
/* @__PURE__ */ jsx15(ConversationScrollController, { onScrollToBottomReady }),
|
|
6048
6014
|
children
|
|
6049
6015
|
]
|
|
6050
6016
|
}
|
|
@@ -6052,7 +6018,7 @@ var Conversation = ({
|
|
|
6052
6018
|
var ConversationContent = ({
|
|
6053
6019
|
className,
|
|
6054
6020
|
...props
|
|
6055
|
-
}) => /* @__PURE__ */
|
|
6021
|
+
}) => /* @__PURE__ */ jsx15(
|
|
6056
6022
|
StickToBottom.Content,
|
|
6057
6023
|
{
|
|
6058
6024
|
className: cn("flex flex-col gap-8 p-4", className),
|
|
@@ -6067,7 +6033,7 @@ var ConversationScrollButton = ({
|
|
|
6067
6033
|
const handleScrollToBottom = useCallback8(() => {
|
|
6068
6034
|
scrollToBottom();
|
|
6069
6035
|
}, [scrollToBottom]);
|
|
6070
|
-
return !isAtBottom && /* @__PURE__ */
|
|
6036
|
+
return !isAtBottom && /* @__PURE__ */ jsx15(
|
|
6071
6037
|
Button7,
|
|
6072
6038
|
{
|
|
6073
6039
|
className: cn(
|
|
@@ -6080,7 +6046,7 @@ var ConversationScrollButton = ({
|
|
|
6080
6046
|
variant: "outline",
|
|
6081
6047
|
"aria-label": "Scroll to latest message",
|
|
6082
6048
|
...props,
|
|
6083
|
-
children: /* @__PURE__ */
|
|
6049
|
+
children: /* @__PURE__ */ jsx15(ArrowDownIcon, { className: "size-4" })
|
|
6084
6050
|
}
|
|
6085
6051
|
);
|
|
6086
6052
|
};
|
|
@@ -6116,16 +6082,16 @@ function noticeTextClass(className) {
|
|
|
6116
6082
|
import { memo as memo2 } from "react";
|
|
6117
6083
|
import { AlertTriangleIcon, InfoIcon, Loader2Icon, PlugZapIcon, RefreshCwIcon, XIcon as XIcon2 } from "lucide-react";
|
|
6118
6084
|
import { Button as Button8 } from "@hachej/boring-ui-kit";
|
|
6119
|
-
import { jsx as
|
|
6085
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
6120
6086
|
var RuntimeNotices = memo2(({ notices, onDismiss, onAction, renderAction, className, ...props }) => {
|
|
6121
6087
|
if (notices.length === 0) return null;
|
|
6122
|
-
return /* @__PURE__ */
|
|
6088
|
+
return /* @__PURE__ */ jsx16(
|
|
6123
6089
|
"div",
|
|
6124
6090
|
{
|
|
6125
6091
|
"data-boring-agent-part": "runtime-notices",
|
|
6126
6092
|
className: cn("flex flex-col gap-2 px-4 py-2", className),
|
|
6127
6093
|
...props,
|
|
6128
|
-
children: notices.map((notice) => /* @__PURE__ */
|
|
6094
|
+
children: notices.map((notice) => /* @__PURE__ */ jsx16(RuntimeNoticeRow, { notice, onDismiss, onAction, renderAction }, notice.id))
|
|
6129
6095
|
}
|
|
6130
6096
|
);
|
|
6131
6097
|
});
|
|
@@ -6149,11 +6115,11 @@ function RuntimeNoticeRow({ notice, onDismiss, onAction, renderAction }) {
|
|
|
6149
6115
|
"flex items-start gap-2.5 motion-reduce:transition-none"
|
|
6150
6116
|
),
|
|
6151
6117
|
children: [
|
|
6152
|
-
/* @__PURE__ */
|
|
6153
|
-
/* @__PURE__ */
|
|
6118
|
+
/* @__PURE__ */ jsx16(Icon, { className: cn(noticeIconClass(notice.level), kind === "retry" && "animate-spin motion-reduce:animate-none"), "aria-hidden": "true" }),
|
|
6119
|
+
/* @__PURE__ */ jsx16("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx16("p", { className: noticeTextClass(), children: notice.text }) }),
|
|
6154
6120
|
hostAction ?? null,
|
|
6155
|
-
actionLabel && onAction ? /* @__PURE__ */
|
|
6156
|
-
notice.dismissible && onDismiss ? /* @__PURE__ */
|
|
6121
|
+
actionLabel && onAction ? /* @__PURE__ */ jsx16(Button8, { type: "button", variant: "ghost", size: "sm", onClick: () => onAction(notice.id), children: actionLabel }) : null,
|
|
6122
|
+
notice.dismissible && onDismiss ? /* @__PURE__ */ jsx16(
|
|
6157
6123
|
Button8,
|
|
6158
6124
|
{
|
|
6159
6125
|
type: "button",
|
|
@@ -6162,7 +6128,7 @@ function RuntimeNoticeRow({ notice, onDismiss, onAction, renderAction }) {
|
|
|
6162
6128
|
"aria-label": "Dismiss notice",
|
|
6163
6129
|
onClick: () => onDismiss(notice.id),
|
|
6164
6130
|
className: "-mr-1 -mt-1 shrink-0 text-muted-foreground/70 hover:bg-muted hover:text-foreground",
|
|
6165
|
-
children: /* @__PURE__ */
|
|
6131
|
+
children: /* @__PURE__ */ jsx16(XIcon2, { className: "size-3" })
|
|
6166
6132
|
}
|
|
6167
6133
|
) : null
|
|
6168
6134
|
]
|
|
@@ -6191,7 +6157,7 @@ function defaultActionLabel(kind) {
|
|
|
6191
6157
|
}
|
|
6192
6158
|
|
|
6193
6159
|
// src/front/chat/components/ChatNotices.tsx
|
|
6194
|
-
import { jsx as
|
|
6160
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
6195
6161
|
function RuntimeNoticeMessages({
|
|
6196
6162
|
notices,
|
|
6197
6163
|
onDismiss,
|
|
@@ -6201,7 +6167,7 @@ function RuntimeNoticeMessages({
|
|
|
6201
6167
|
(notice) => notice.level === "error" || notice.level === "warning" || notice.id === "connection-reconnecting" || notice.id === "auto-retry" || notice.id === "large-state-warning" || notice.id.startsWith("command:") || notice.id.startsWith("composer-warning:")
|
|
6202
6168
|
);
|
|
6203
6169
|
if (visible.length === 0) return null;
|
|
6204
|
-
return /* @__PURE__ */
|
|
6170
|
+
return /* @__PURE__ */ jsx17(
|
|
6205
6171
|
RuntimeNotices,
|
|
6206
6172
|
{
|
|
6207
6173
|
notices: visible,
|
|
@@ -6213,7 +6179,7 @@ function RuntimeNoticeMessages({
|
|
|
6213
6179
|
}
|
|
6214
6180
|
function ComposerRuntimeNotice({ notice }) {
|
|
6215
6181
|
const level = notice.code === ErrorCode.enum.AGENT_RUNTIME_NOT_READY ? "info" : "error";
|
|
6216
|
-
return /* @__PURE__ */
|
|
6182
|
+
return /* @__PURE__ */ jsx17(
|
|
6217
6183
|
"div",
|
|
6218
6184
|
{
|
|
6219
6185
|
"data-testid": "chat-composer-runtime-notice",
|
|
@@ -6221,17 +6187,17 @@ function ComposerRuntimeNotice({ notice }) {
|
|
|
6221
6187
|
"aria-live": "polite",
|
|
6222
6188
|
className: noticeSurfaceClass(level, "mx-auto mb-2 w-full max-w-3xl text-xs"),
|
|
6223
6189
|
children: /* @__PURE__ */ jsxs15("div", { className: "flex items-start gap-2", children: [
|
|
6224
|
-
notice.code === ErrorCode.enum.AGENT_RUNTIME_NOT_READY ? /* @__PURE__ */
|
|
6190
|
+
notice.code === ErrorCode.enum.AGENT_RUNTIME_NOT_READY ? /* @__PURE__ */ jsx17(Loader2, { "aria-hidden": "true", className: "mt-0.5 size-3.5 shrink-0 animate-spin text-muted-foreground" }) : /* @__PURE__ */ jsx17(AlertCircleIcon, { "aria-hidden": "true", className: "mt-0.5 size-3.5 shrink-0 text-destructive" }),
|
|
6225
6191
|
/* @__PURE__ */ jsxs15("div", { className: "min-w-0", children: [
|
|
6226
|
-
/* @__PURE__ */
|
|
6227
|
-
notice.detail ? /* @__PURE__ */
|
|
6192
|
+
/* @__PURE__ */ jsx17("div", { className: "font-medium", children: notice.title }),
|
|
6193
|
+
notice.detail ? /* @__PURE__ */ jsx17(NoticeText, { className: "mt-0.5 text-muted-foreground", children: notice.detail }) : null
|
|
6228
6194
|
] })
|
|
6229
6195
|
] })
|
|
6230
6196
|
}
|
|
6231
6197
|
);
|
|
6232
6198
|
}
|
|
6233
6199
|
function NoticeText({ className, children }) {
|
|
6234
|
-
return /* @__PURE__ */
|
|
6200
|
+
return /* @__PURE__ */ jsx17("div", { className: noticeTextClass(className), children });
|
|
6235
6201
|
}
|
|
6236
6202
|
function ComposerBlockerNotice({
|
|
6237
6203
|
blocker,
|
|
@@ -6245,10 +6211,10 @@ function ComposerBlockerNotice({
|
|
|
6245
6211
|
"aria-live": "polite",
|
|
6246
6212
|
className: noticeSurfaceClass("info", "relative z-20 mx-auto mb-2 w-full max-w-3xl text-xs"),
|
|
6247
6213
|
children: [
|
|
6248
|
-
/* @__PURE__ */
|
|
6214
|
+
/* @__PURE__ */ jsx17("span", { children: label }),
|
|
6249
6215
|
blocker?.actions?.map((action) => {
|
|
6250
6216
|
const icon = composerBlockerActionIcon(action.id);
|
|
6251
|
-
return icon ? /* @__PURE__ */
|
|
6217
|
+
return icon ? /* @__PURE__ */ jsx17(
|
|
6252
6218
|
IconButton2,
|
|
6253
6219
|
{
|
|
6254
6220
|
type: "button",
|
|
@@ -6261,7 +6227,7 @@ function ComposerBlockerNotice({
|
|
|
6261
6227
|
children: icon
|
|
6262
6228
|
},
|
|
6263
6229
|
action.id
|
|
6264
|
-
) : /* @__PURE__ */
|
|
6230
|
+
) : /* @__PURE__ */ jsx17(
|
|
6265
6231
|
"button",
|
|
6266
6232
|
{
|
|
6267
6233
|
type: "button",
|
|
@@ -6277,8 +6243,8 @@ function ComposerBlockerNotice({
|
|
|
6277
6243
|
);
|
|
6278
6244
|
}
|
|
6279
6245
|
function composerBlockerActionIcon(actionId) {
|
|
6280
|
-
if (actionId === "open") return /* @__PURE__ */
|
|
6281
|
-
if (actionId === "cancel") return /* @__PURE__ */
|
|
6246
|
+
if (actionId === "open") return /* @__PURE__ */ jsx17(ExternalLinkIcon2, { className: "size-3.5", "aria-hidden": "true" });
|
|
6247
|
+
if (actionId === "cancel") return /* @__PURE__ */ jsx17(XIcon3, { className: "size-3.5", "aria-hidden": "true" });
|
|
6282
6248
|
return null;
|
|
6283
6249
|
}
|
|
6284
6250
|
function QueuedComposerNotice({ followUps, onEdit }) {
|
|
@@ -6297,9 +6263,9 @@ function QueuedComposerNotice({ followUps, onEdit }) {
|
|
|
6297
6263
|
" queued follow-up",
|
|
6298
6264
|
followUps.length === 1 ? "" : "s"
|
|
6299
6265
|
] }),
|
|
6300
|
-
/* @__PURE__ */
|
|
6266
|
+
/* @__PURE__ */ jsx17("div", { className: "truncate text-[color:var(--muted-foreground)]", "data-boring-agent-part": "composer-queue-preview-text", children: followUps.map((followUp) => followUp.displayText).join(" - ") })
|
|
6301
6267
|
] }),
|
|
6302
|
-
/* @__PURE__ */
|
|
6268
|
+
/* @__PURE__ */ jsx17(
|
|
6303
6269
|
IconButton2,
|
|
6304
6270
|
{
|
|
6305
6271
|
type: "button",
|
|
@@ -6309,7 +6275,7 @@ function QueuedComposerNotice({ followUps, onEdit }) {
|
|
|
6309
6275
|
className: "shrink-0 text-[color:var(--muted-foreground)] hover:bg-[color:var(--muted)] hover:text-[color:var(--foreground)]",
|
|
6310
6276
|
"aria-label": "Edit queued follow-ups",
|
|
6311
6277
|
title: "Edit queued follow-ups",
|
|
6312
|
-
children: /* @__PURE__ */
|
|
6278
|
+
children: /* @__PURE__ */ jsx17(ListRestartIcon, { className: "size-3.5", "aria-hidden": "true" })
|
|
6313
6279
|
}
|
|
6314
6280
|
)
|
|
6315
6281
|
]
|
|
@@ -6318,7 +6284,7 @@ function QueuedComposerNotice({ followUps, onEdit }) {
|
|
|
6318
6284
|
}
|
|
6319
6285
|
|
|
6320
6286
|
// src/front/chat/components/PiTimelineMessage.tsx
|
|
6321
|
-
import { useCallback as useCallback13, useEffect as useEffect13, useState as useState14 } from "react";
|
|
6287
|
+
import { useCallback as useCallback13, useEffect as useEffect13, useMemo as useMemo12, useRef as useRef10, useState as useState14 } from "react";
|
|
6322
6288
|
import { CheckIcon as CheckIcon2, CopyIcon as CopyIcon3 } from "lucide-react";
|
|
6323
6289
|
import { Button as Button11 } from "@hachej/boring-ui-kit";
|
|
6324
6290
|
|
|
@@ -6333,8 +6299,8 @@ import {
|
|
|
6333
6299
|
VideoIcon,
|
|
6334
6300
|
XIcon as XIcon4
|
|
6335
6301
|
} from "lucide-react";
|
|
6336
|
-
import { createContext as
|
|
6337
|
-
import { jsx as
|
|
6302
|
+
import { createContext as createContext4, useCallback as useCallback9, useContext as useContext4, useMemo as useMemo6 } from "react";
|
|
6303
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
6338
6304
|
var mediaCategoryIcons = {
|
|
6339
6305
|
audio: Music2Icon,
|
|
6340
6306
|
document: FileTextIcon2,
|
|
@@ -6369,7 +6335,7 @@ var getAttachmentLabel = (data) => {
|
|
|
6369
6335
|
const category = getMediaCategory(data);
|
|
6370
6336
|
return data.filename || (category === "image" ? "Image" : "Attachment");
|
|
6371
6337
|
};
|
|
6372
|
-
var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */
|
|
6338
|
+
var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */ jsx18(
|
|
6373
6339
|
"img",
|
|
6374
6340
|
{
|
|
6375
6341
|
alt: filename || "Image",
|
|
@@ -6378,7 +6344,7 @@ var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */
|
|
|
6378
6344
|
src: url,
|
|
6379
6345
|
width: 96
|
|
6380
6346
|
}
|
|
6381
|
-
) : /* @__PURE__ */
|
|
6347
|
+
) : /* @__PURE__ */ jsx18(
|
|
6382
6348
|
"img",
|
|
6383
6349
|
{
|
|
6384
6350
|
alt: filename || "Image",
|
|
@@ -6388,11 +6354,11 @@ var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */
|
|
|
6388
6354
|
width: 20
|
|
6389
6355
|
}
|
|
6390
6356
|
);
|
|
6391
|
-
var AttachmentsContext =
|
|
6392
|
-
var AttachmentContext =
|
|
6393
|
-
var useAttachmentsContext = () =>
|
|
6357
|
+
var AttachmentsContext = createContext4(null);
|
|
6358
|
+
var AttachmentContext = createContext4(null);
|
|
6359
|
+
var useAttachmentsContext = () => useContext4(AttachmentsContext) ?? { variant: "grid" };
|
|
6394
6360
|
var useAttachmentContext = () => {
|
|
6395
|
-
const ctx =
|
|
6361
|
+
const ctx = useContext4(AttachmentContext);
|
|
6396
6362
|
if (!ctx) {
|
|
6397
6363
|
throw new Error("Attachment components must be used within <Attachment>");
|
|
6398
6364
|
}
|
|
@@ -6404,8 +6370,8 @@ var Attachments = ({
|
|
|
6404
6370
|
children,
|
|
6405
6371
|
...props
|
|
6406
6372
|
}) => {
|
|
6407
|
-
const contextValue =
|
|
6408
|
-
return /* @__PURE__ */
|
|
6373
|
+
const contextValue = useMemo6(() => ({ variant }), [variant]);
|
|
6374
|
+
return /* @__PURE__ */ jsx18(AttachmentsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx18(
|
|
6409
6375
|
"div",
|
|
6410
6376
|
{
|
|
6411
6377
|
className: cn(
|
|
@@ -6428,11 +6394,11 @@ var Attachment = ({
|
|
|
6428
6394
|
}) => {
|
|
6429
6395
|
const { variant } = useAttachmentsContext();
|
|
6430
6396
|
const mediaCategory = getMediaCategory(data);
|
|
6431
|
-
const contextValue =
|
|
6397
|
+
const contextValue = useMemo6(
|
|
6432
6398
|
() => ({ data, mediaCategory, onRemove, variant }),
|
|
6433
6399
|
[data, mediaCategory, onRemove, variant]
|
|
6434
6400
|
);
|
|
6435
|
-
return /* @__PURE__ */
|
|
6401
|
+
return /* @__PURE__ */ jsx18(AttachmentContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx18(
|
|
6436
6402
|
"div",
|
|
6437
6403
|
{
|
|
6438
6404
|
className: cn(
|
|
@@ -6462,18 +6428,18 @@ var AttachmentPreview = ({
|
|
|
6462
6428
|
}) => {
|
|
6463
6429
|
const { data, mediaCategory, variant } = useAttachmentContext();
|
|
6464
6430
|
const iconSize = variant === "inline" ? "size-3" : "size-4";
|
|
6465
|
-
const renderIcon = (Icon) => /* @__PURE__ */
|
|
6431
|
+
const renderIcon = (Icon) => /* @__PURE__ */ jsx18(Icon, { className: cn(iconSize, "text-muted-foreground") });
|
|
6466
6432
|
const renderContent = () => {
|
|
6467
6433
|
if (mediaCategory === "image" && data.type === "file" && data.url) {
|
|
6468
6434
|
return renderAttachmentImage(data.url, data.filename, variant === "grid");
|
|
6469
6435
|
}
|
|
6470
6436
|
if (mediaCategory === "video" && data.type === "file" && data.url) {
|
|
6471
|
-
return /* @__PURE__ */
|
|
6437
|
+
return /* @__PURE__ */ jsx18("video", { className: "size-full object-cover", muted: true, src: data.url });
|
|
6472
6438
|
}
|
|
6473
6439
|
const Icon = mediaCategoryIcons[mediaCategory];
|
|
6474
6440
|
return fallbackIcon ?? renderIcon(Icon);
|
|
6475
6441
|
};
|
|
6476
|
-
return /* @__PURE__ */
|
|
6442
|
+
return /* @__PURE__ */ jsx18(
|
|
6477
6443
|
"div",
|
|
6478
6444
|
{
|
|
6479
6445
|
className: cn(
|
|
@@ -6499,8 +6465,8 @@ var AttachmentInfo = ({
|
|
|
6499
6465
|
return null;
|
|
6500
6466
|
}
|
|
6501
6467
|
return /* @__PURE__ */ jsxs16("div", { className: cn("min-w-0 flex-1", className), ...props, children: [
|
|
6502
|
-
/* @__PURE__ */
|
|
6503
|
-
showMediaType && data.mediaType && /* @__PURE__ */
|
|
6468
|
+
/* @__PURE__ */ jsx18("span", { className: "block truncate", children: label }),
|
|
6469
|
+
showMediaType && data.mediaType && /* @__PURE__ */ jsx18("span", { className: "block truncate text-muted-foreground text-xs", children: data.mediaType })
|
|
6504
6470
|
] });
|
|
6505
6471
|
};
|
|
6506
6472
|
var AttachmentRemove = ({
|
|
@@ -6545,8 +6511,8 @@ var AttachmentRemove = ({
|
|
|
6545
6511
|
variant: "ghost",
|
|
6546
6512
|
...props,
|
|
6547
6513
|
children: [
|
|
6548
|
-
children ?? /* @__PURE__ */
|
|
6549
|
-
/* @__PURE__ */
|
|
6514
|
+
children ?? /* @__PURE__ */ jsx18(XIcon4, {}),
|
|
6515
|
+
/* @__PURE__ */ jsx18("span", { className: "sr-only", children: label })
|
|
6550
6516
|
]
|
|
6551
6517
|
}
|
|
6552
6518
|
);
|
|
@@ -6560,28 +6526,33 @@ import {
|
|
|
6560
6526
|
TooltipProvider as TooltipProvider2,
|
|
6561
6527
|
TooltipTrigger as TooltipTrigger2
|
|
6562
6528
|
} from "@hachej/boring-ui-kit";
|
|
6529
|
+
|
|
6530
|
+
// src/front/primitives/markdownStyles.ts
|
|
6531
|
+
var INLINE_CODE_CLASS_NAME = "rounded-[0.3em] bg-muted/55 px-[0.32em] py-[0.08em] font-mono text-[0.9em] font-medium text-foreground/90";
|
|
6532
|
+
|
|
6533
|
+
// src/front/primitives/message.tsx
|
|
6563
6534
|
import { cjk } from "@streamdown/cjk";
|
|
6564
6535
|
import { code } from "@streamdown/code";
|
|
6565
6536
|
import { math } from "@streamdown/math";
|
|
6566
6537
|
import { mermaid } from "@streamdown/mermaid";
|
|
6567
6538
|
import { ChevronLeftIcon as ChevronLeftIcon2, ChevronRightIcon } from "lucide-react";
|
|
6568
6539
|
import {
|
|
6569
|
-
createContext as
|
|
6540
|
+
createContext as createContext5,
|
|
6570
6541
|
memo as memo3,
|
|
6571
6542
|
useCallback as useCallback10,
|
|
6572
|
-
useContext as
|
|
6543
|
+
useContext as useContext5,
|
|
6573
6544
|
useEffect as useEffect10,
|
|
6574
|
-
useMemo as
|
|
6545
|
+
useMemo as useMemo7,
|
|
6575
6546
|
useState as useState11
|
|
6576
6547
|
} from "react";
|
|
6577
6548
|
import { Streamdown } from "streamdown";
|
|
6578
|
-
import { jsx as
|
|
6579
|
-
var Message = ({ className, from, ...props }) => /* @__PURE__ */
|
|
6549
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
6550
|
+
var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsx19(
|
|
6580
6551
|
"div",
|
|
6581
6552
|
{
|
|
6582
6553
|
"data-boring-agent-message-role": from,
|
|
6583
6554
|
className: cn(
|
|
6584
|
-
"group flex w-full max-w-
|
|
6555
|
+
"group flex w-full max-w-full flex-col gap-1.5",
|
|
6585
6556
|
from === "user" ? "is-user ml-auto justify-end" : "is-assistant",
|
|
6586
6557
|
className
|
|
6587
6558
|
),
|
|
@@ -6592,13 +6563,13 @@ var MessageContent = ({
|
|
|
6592
6563
|
children,
|
|
6593
6564
|
className,
|
|
6594
6565
|
...props
|
|
6595
|
-
}) => /* @__PURE__ */
|
|
6566
|
+
}) => /* @__PURE__ */ jsx19(
|
|
6596
6567
|
"div",
|
|
6597
6568
|
{
|
|
6598
6569
|
className: cn(
|
|
6599
|
-
"is-user:dark flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-
|
|
6600
|
-
"group-[.is-user]:ml-auto group-[.is-user]:rounded-lg group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-
|
|
6601
|
-
"group-[.is-assistant]:text-foreground",
|
|
6570
|
+
"is-user:dark flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-visible text-[13px] leading-5",
|
|
6571
|
+
"group-[.is-user]:ml-auto group-[.is-user]:max-w-[80%] group-[.is-user]:rounded-[var(--radius-lg)] group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-2.5 group-[.is-user]:text-foreground",
|
|
6572
|
+
"group-[.is-assistant]:w-full group-[.is-assistant]:max-w-[40.5rem] group-[.is-assistant]:bg-transparent group-[.is-assistant]:p-0 group-[.is-assistant]:text-foreground",
|
|
6602
6573
|
className
|
|
6603
6574
|
),
|
|
6604
6575
|
...props,
|
|
@@ -6609,7 +6580,7 @@ var MessageActions = ({
|
|
|
6609
6580
|
className,
|
|
6610
6581
|
children,
|
|
6611
6582
|
...props
|
|
6612
|
-
}) => /* @__PURE__ */
|
|
6583
|
+
}) => /* @__PURE__ */ jsx19("div", { className: cn("flex items-center gap-1", className), ...props, children });
|
|
6613
6584
|
var MessageAction = ({
|
|
6614
6585
|
tooltip,
|
|
6615
6586
|
children,
|
|
@@ -6620,17 +6591,17 @@ var MessageAction = ({
|
|
|
6620
6591
|
}) => {
|
|
6621
6592
|
const button = /* @__PURE__ */ jsxs17(Button10, { size, type: "button", variant, ...props, children: [
|
|
6622
6593
|
children,
|
|
6623
|
-
/* @__PURE__ */
|
|
6594
|
+
/* @__PURE__ */ jsx19("span", { className: "sr-only", children: label || tooltip })
|
|
6624
6595
|
] });
|
|
6625
6596
|
if (tooltip) {
|
|
6626
|
-
return /* @__PURE__ */
|
|
6627
|
-
/* @__PURE__ */
|
|
6628
|
-
/* @__PURE__ */
|
|
6597
|
+
return /* @__PURE__ */ jsx19(TooltipProvider2, { children: /* @__PURE__ */ jsxs17(Tooltip2, { children: [
|
|
6598
|
+
/* @__PURE__ */ jsx19(TooltipTrigger2, { asChild: true, children: button }),
|
|
6599
|
+
/* @__PURE__ */ jsx19(TooltipContent2, { children: /* @__PURE__ */ jsx19("p", { children: tooltip }) })
|
|
6629
6600
|
] }) });
|
|
6630
6601
|
}
|
|
6631
6602
|
return button;
|
|
6632
6603
|
};
|
|
6633
|
-
var MessageBranchContext =
|
|
6604
|
+
var MessageBranchContext = createContext5(
|
|
6634
6605
|
null
|
|
6635
6606
|
);
|
|
6636
6607
|
var streamdownPlugins = { cjk, code, math, mermaid };
|
|
@@ -6666,9 +6637,9 @@ function extractCodeBlockText(children) {
|
|
|
6666
6637
|
var MarkdownPre = ({ children }) => {
|
|
6667
6638
|
const code3 = extractCodeBlockText(children).replace(/\n$/, "");
|
|
6668
6639
|
const language = extractCodeBlockLanguage(children);
|
|
6669
|
-
return /* @__PURE__ */
|
|
6670
|
-
/* @__PURE__ */
|
|
6671
|
-
/* @__PURE__ */
|
|
6640
|
+
return /* @__PURE__ */ jsx19(CodeBlock2, { code: code3, language: language ?? "text", className: "my-3", children: /* @__PURE__ */ jsxs17(CodeBlockHeader, { children: [
|
|
6641
|
+
/* @__PURE__ */ jsx19(CodeBlockTitle, { children: /* @__PURE__ */ jsx19(CodeBlockFilename, { children: language ?? "text" }) }),
|
|
6642
|
+
/* @__PURE__ */ jsx19(CodeBlockCopyButton, {})
|
|
6672
6643
|
] }) });
|
|
6673
6644
|
};
|
|
6674
6645
|
var MarkdownCode = ({
|
|
@@ -6678,14 +6649,13 @@ var MarkdownCode = ({
|
|
|
6678
6649
|
...props
|
|
6679
6650
|
}) => {
|
|
6680
6651
|
if (inline === false) {
|
|
6681
|
-
return /* @__PURE__ */
|
|
6652
|
+
return /* @__PURE__ */ jsx19("code", { className, ...props, children });
|
|
6682
6653
|
}
|
|
6683
|
-
return /* @__PURE__ */
|
|
6654
|
+
return /* @__PURE__ */ jsx19(
|
|
6684
6655
|
"code",
|
|
6685
6656
|
{
|
|
6686
6657
|
className: cn(
|
|
6687
|
-
|
|
6688
|
-
"font-mono text-[0.9em] font-medium text-foreground/90",
|
|
6658
|
+
INLINE_CODE_CLASS_NAME,
|
|
6689
6659
|
className
|
|
6690
6660
|
),
|
|
6691
6661
|
...props,
|
|
@@ -6698,7 +6668,7 @@ var markdownComponents = {
|
|
|
6698
6668
|
code: MarkdownCode
|
|
6699
6669
|
};
|
|
6700
6670
|
var MessageResponse = memo3(
|
|
6701
|
-
({ className, shikiTheme, components, ...props }) => /* @__PURE__ */
|
|
6671
|
+
({ className, shikiTheme, components, ...props }) => /* @__PURE__ */ jsx19(
|
|
6702
6672
|
Streamdown,
|
|
6703
6673
|
{
|
|
6704
6674
|
className: cn(
|
|
@@ -6711,7 +6681,7 @@ var MessageResponse = memo3(
|
|
|
6711
6681
|
...props
|
|
6712
6682
|
}
|
|
6713
6683
|
),
|
|
6714
|
-
(prevProps, nextProps) => prevProps.children === nextProps.children && nextProps.isAnimating === prevProps.isAnimating
|
|
6684
|
+
(prevProps, nextProps) => prevProps.children === nextProps.children && nextProps.isAnimating === prevProps.isAnimating && nextProps.components === prevProps.components
|
|
6715
6685
|
);
|
|
6716
6686
|
MessageResponse.displayName = "MessageResponse";
|
|
6717
6687
|
|
|
@@ -6728,12 +6698,12 @@ import { math as math2 } from "@streamdown/math";
|
|
|
6728
6698
|
import { mermaid as mermaid2 } from "@streamdown/mermaid";
|
|
6729
6699
|
import { BrainIcon, ChevronDownIcon as ChevronDownIcon3 } from "lucide-react";
|
|
6730
6700
|
import {
|
|
6731
|
-
createContext as
|
|
6701
|
+
createContext as createContext6,
|
|
6732
6702
|
memo as memo5,
|
|
6733
6703
|
useCallback as useCallback11,
|
|
6734
|
-
useContext as
|
|
6704
|
+
useContext as useContext6,
|
|
6735
6705
|
useEffect as useEffect11,
|
|
6736
|
-
useMemo as
|
|
6706
|
+
useMemo as useMemo9,
|
|
6737
6707
|
useRef as useRef9,
|
|
6738
6708
|
useState as useState12
|
|
6739
6709
|
} from "react";
|
|
@@ -6741,8 +6711,8 @@ import { Streamdown as Streamdown2 } from "streamdown";
|
|
|
6741
6711
|
|
|
6742
6712
|
// src/front/primitives/shimmer.tsx
|
|
6743
6713
|
import { motion } from "motion/react";
|
|
6744
|
-
import { memo as memo4, useMemo as
|
|
6745
|
-
import { jsx as
|
|
6714
|
+
import { memo as memo4, useMemo as useMemo8 } from "react";
|
|
6715
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
6746
6716
|
var motionComponentCache = /* @__PURE__ */ new Map();
|
|
6747
6717
|
var getMotionComponent = (element) => {
|
|
6748
6718
|
let component = motionComponentCache.get(element);
|
|
@@ -6762,11 +6732,11 @@ var ShimmerComponent = ({
|
|
|
6762
6732
|
const MotionComponent = getMotionComponent(
|
|
6763
6733
|
Component
|
|
6764
6734
|
);
|
|
6765
|
-
const dynamicSpread =
|
|
6735
|
+
const dynamicSpread = useMemo8(
|
|
6766
6736
|
() => (children?.length ?? 0) * spread,
|
|
6767
6737
|
[children, spread]
|
|
6768
6738
|
);
|
|
6769
|
-
return /* @__PURE__ */
|
|
6739
|
+
return /* @__PURE__ */ jsx20(
|
|
6770
6740
|
MotionComponent,
|
|
6771
6741
|
{
|
|
6772
6742
|
animate: { backgroundPosition: "0% center" },
|
|
@@ -6792,10 +6762,10 @@ var ShimmerComponent = ({
|
|
|
6792
6762
|
var Shimmer = memo4(ShimmerComponent);
|
|
6793
6763
|
|
|
6794
6764
|
// src/front/primitives/reasoning.tsx
|
|
6795
|
-
import { Fragment as
|
|
6796
|
-
var ReasoningContext =
|
|
6765
|
+
import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
6766
|
+
var ReasoningContext = createContext6(null);
|
|
6797
6767
|
var useReasoning = () => {
|
|
6798
|
-
const context =
|
|
6768
|
+
const context = useContext6(ReasoningContext);
|
|
6799
6769
|
if (!context) {
|
|
6800
6770
|
throw new Error("Reasoning components must be used within Reasoning");
|
|
6801
6771
|
}
|
|
@@ -6860,11 +6830,11 @@ var Reasoning = memo5(
|
|
|
6860
6830
|
},
|
|
6861
6831
|
[setIsOpen]
|
|
6862
6832
|
);
|
|
6863
|
-
const contextValue =
|
|
6833
|
+
const contextValue = useMemo9(
|
|
6864
6834
|
() => ({ duration, isOpen, isStreaming, setIsOpen }),
|
|
6865
6835
|
[duration, isOpen, isStreaming, setIsOpen]
|
|
6866
6836
|
);
|
|
6867
|
-
return /* @__PURE__ */
|
|
6837
|
+
return /* @__PURE__ */ jsx21(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx21(
|
|
6868
6838
|
Collapsible2,
|
|
6869
6839
|
{
|
|
6870
6840
|
className: cn("not-prose mb-2", className),
|
|
@@ -6878,10 +6848,10 @@ var Reasoning = memo5(
|
|
|
6878
6848
|
);
|
|
6879
6849
|
var defaultGetThinkingMessage = (isStreaming, duration) => {
|
|
6880
6850
|
if (isStreaming || duration === 0) {
|
|
6881
|
-
return /* @__PURE__ */
|
|
6851
|
+
return /* @__PURE__ */ jsx21(Shimmer, { duration: 1, children: "thinking" });
|
|
6882
6852
|
}
|
|
6883
6853
|
if (duration === void 0) {
|
|
6884
|
-
return /* @__PURE__ */
|
|
6854
|
+
return /* @__PURE__ */ jsx21("span", { children: "thoughts" });
|
|
6885
6855
|
}
|
|
6886
6856
|
return /* @__PURE__ */ jsxs18("span", { children: [
|
|
6887
6857
|
"thoughts \xB7 ",
|
|
@@ -6897,7 +6867,7 @@ var ReasoningTrigger = memo5(
|
|
|
6897
6867
|
...props
|
|
6898
6868
|
}) => {
|
|
6899
6869
|
const { isStreaming, isOpen, duration } = useReasoning();
|
|
6900
|
-
return /* @__PURE__ */
|
|
6870
|
+
return /* @__PURE__ */ jsx21(
|
|
6901
6871
|
CollapsibleTrigger3,
|
|
6902
6872
|
{
|
|
6903
6873
|
className: cn(
|
|
@@ -6905,10 +6875,10 @@ var ReasoningTrigger = memo5(
|
|
|
6905
6875
|
className
|
|
6906
6876
|
),
|
|
6907
6877
|
...props,
|
|
6908
|
-
children: children ?? /* @__PURE__ */ jsxs18(
|
|
6909
|
-
/* @__PURE__ */
|
|
6878
|
+
children: children ?? /* @__PURE__ */ jsxs18(Fragment7, { children: [
|
|
6879
|
+
/* @__PURE__ */ jsx21(BrainIcon, { className: "size-3" }),
|
|
6910
6880
|
getThinkingMessage(isStreaming, duration),
|
|
6911
|
-
/* @__PURE__ */
|
|
6881
|
+
/* @__PURE__ */ jsx21(
|
|
6912
6882
|
ChevronDownIcon3,
|
|
6913
6883
|
{
|
|
6914
6884
|
className: cn(
|
|
@@ -6924,7 +6894,7 @@ var ReasoningTrigger = memo5(
|
|
|
6924
6894
|
);
|
|
6925
6895
|
var streamdownPlugins2 = { cjk: cjk2, code: code2, math: math2, mermaid: mermaid2 };
|
|
6926
6896
|
var ReasoningContent = memo5(
|
|
6927
|
-
({ className, children, ...props }) => /* @__PURE__ */
|
|
6897
|
+
({ className, children, ...props }) => /* @__PURE__ */ jsx21(
|
|
6928
6898
|
CollapsibleContent2,
|
|
6929
6899
|
{
|
|
6930
6900
|
className: cn(
|
|
@@ -6933,7 +6903,7 @@ var ReasoningContent = memo5(
|
|
|
6933
6903
|
className
|
|
6934
6904
|
),
|
|
6935
6905
|
...props,
|
|
6936
|
-
children: /* @__PURE__ */
|
|
6906
|
+
children: /* @__PURE__ */ jsx21(Streamdown2, { plugins: streamdownPlugins2, children })
|
|
6937
6907
|
}
|
|
6938
6908
|
)
|
|
6939
6909
|
);
|
|
@@ -6943,7 +6913,7 @@ ReasoningContent.displayName = "ReasoningContent";
|
|
|
6943
6913
|
|
|
6944
6914
|
// src/front/primitives/tool-call-group.tsx
|
|
6945
6915
|
import { ChevronDownIcon as ChevronDownIcon4 } from "lucide-react";
|
|
6946
|
-
import { memo as memo6, useCallback as useCallback12, useEffect as useEffect12, useMemo as
|
|
6916
|
+
import { memo as memo6, useCallback as useCallback12, useEffect as useEffect12, useMemo as useMemo10, useState as useState13 } from "react";
|
|
6947
6917
|
import { Collapsible as Collapsible3, CollapsibleContent as CollapsibleContent3, CollapsibleTrigger as CollapsibleTrigger4 } from "@hachej/boring-ui-kit";
|
|
6948
6918
|
|
|
6949
6919
|
// src/front/primitives/tool-call-group-state.ts
|
|
@@ -6982,10 +6952,7 @@ var TOOL_GROUP_VISUAL_PRESENTATION = {
|
|
|
6982
6952
|
};
|
|
6983
6953
|
|
|
6984
6954
|
// src/front/primitives/tool-call-group.tsx
|
|
6985
|
-
import { jsx as
|
|
6986
|
-
function isSettledState(state) {
|
|
6987
|
-
return state === "output-available" || state === "output-error" || state === "output-denied" || state === "approval-responded" || state === "aborted";
|
|
6988
|
-
}
|
|
6955
|
+
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
6989
6956
|
function isInputRunningState(state) {
|
|
6990
6957
|
return state === "input-streaming" || state === "input-available";
|
|
6991
6958
|
}
|
|
@@ -7035,11 +7002,10 @@ function resolveVisualState({
|
|
|
7035
7002
|
return "settled";
|
|
7036
7003
|
}
|
|
7037
7004
|
var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
|
|
7038
|
-
const toolParts =
|
|
7005
|
+
const toolParts = useMemo10(() => tools.map(({ part, key }) => {
|
|
7039
7006
|
const toolPart = toToolPart(part);
|
|
7040
7007
|
return toolPart ? { part: toolPart, key } : null;
|
|
7041
7008
|
}).filter((entry) => Boolean(entry)), [tools]);
|
|
7042
|
-
const isSettled = toolParts.every(({ part }) => isSettledState(part.state));
|
|
7043
7009
|
const workspaceNotReady = toolParts.map(({ part }) => getWorkspaceNotReadyStatus(part.output)).find(Boolean);
|
|
7044
7010
|
const hasError = toolParts.some(({ part }) => part.state === "output-error") && !workspaceNotReady;
|
|
7045
7011
|
const hasAborted = toolParts.some(({ part }) => part.state === "aborted") && !workspaceNotReady;
|
|
@@ -7056,7 +7022,7 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
|
|
|
7056
7022
|
});
|
|
7057
7023
|
const isRunning = visualState === RUNNING_TOOL_GROUP_VISUAL_STATE;
|
|
7058
7024
|
const [elapsedSeconds, setElapsedSeconds] = useState13(0);
|
|
7059
|
-
const title =
|
|
7025
|
+
const title = useMemo10(() => buildTitle(toolParts.map(({ part }) => part), visualState), [toolParts, visualState]);
|
|
7060
7026
|
const elapsedLabel = isRunning ? `Running ${formatElapsed(elapsedSeconds)}` : null;
|
|
7061
7027
|
useEffect12(() => {
|
|
7062
7028
|
if (!isRunning) {
|
|
@@ -7084,50 +7050,48 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
|
|
|
7084
7050
|
{
|
|
7085
7051
|
"aria-label": `Tool calls: ${title}`,
|
|
7086
7052
|
className: cn(
|
|
7087
|
-
"group/trigger flex w-
|
|
7088
|
-
"border border-border/
|
|
7089
|
-
"
|
|
7053
|
+
"group/trigger flex min-h-10 w-full items-center gap-2 rounded-[var(--radius-md)] px-2 py-1 text-[13px] font-normal",
|
|
7054
|
+
"border border-border/60 bg-muted/45 text-muted-foreground",
|
|
7055
|
+
"transition-colors hover:bg-muted/70 hover:text-foreground motion-reduce:transition-none",
|
|
7056
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
7090
7057
|
TOOL_GROUP_VISUAL_PRESENTATION[visualState].triggerClassName
|
|
7091
7058
|
),
|
|
7092
7059
|
children: [
|
|
7093
|
-
/* @__PURE__ */
|
|
7060
|
+
/* @__PURE__ */ jsx22("span", { className: "flex size-4 shrink-0 items-center justify-center", "aria-hidden": "true", children: /* @__PURE__ */ jsx22(
|
|
7094
7061
|
"span",
|
|
7095
7062
|
{
|
|
7096
7063
|
"data-boring-agent-part": "tool-group-state-dot",
|
|
7097
7064
|
className: cn(
|
|
7098
|
-
"size-1.5
|
|
7065
|
+
"size-1.5 rounded-full",
|
|
7099
7066
|
TOOL_GROUP_VISUAL_PRESENTATION[visualState].dotClassName
|
|
7100
7067
|
)
|
|
7101
7068
|
}
|
|
7102
|
-
),
|
|
7103
|
-
/* @__PURE__ */
|
|
7069
|
+
) }),
|
|
7070
|
+
/* @__PURE__ */ jsx22("span", { "data-boring-agent-part": "tool-group-title", children: workspaceNotReady ? workspaceNotReady.message : title }),
|
|
7071
|
+
elapsedLabel ? /* @__PURE__ */ jsx22("span", { className: "ml-1 shrink-0 tabular-nums text-[12px] text-muted-foreground/70", children: elapsedLabel }) : null,
|
|
7072
|
+
/* @__PURE__ */ jsx22("span", { className: "ml-1 shrink-0 tabular-nums text-[12px] text-muted-foreground/70", children: toolParts.length }),
|
|
7073
|
+
/* @__PURE__ */ jsx22(
|
|
7104
7074
|
ChevronDownIcon4,
|
|
7105
7075
|
{
|
|
7106
7076
|
className: cn(
|
|
7107
|
-
"size-
|
|
7077
|
+
"ml-auto size-4 shrink-0 transition-transform duration-150 motion-reduce:transition-none",
|
|
7108
7078
|
isOpen && "rotate-180"
|
|
7109
7079
|
)
|
|
7110
7080
|
}
|
|
7111
|
-
)
|
|
7112
|
-
workspaceNotReady ? /* @__PURE__ */ jsx21("span", { "data-boring-agent-part": "tool-group-title", children: workspaceNotReady.message }) : !isSettled ? /* @__PURE__ */ jsx21("span", { "data-boring-agent-part": "tool-group-title", children: /* @__PURE__ */ jsx21(Shimmer, { as: "span", duration: 1.5, children: title }) }) : /* @__PURE__ */ jsx21("span", { "data-boring-agent-part": "tool-group-title", children: title }),
|
|
7113
|
-
elapsedLabel ? /* @__PURE__ */ jsx21("span", { className: "ml-1 shrink-0 tabular-nums text-[10px] text-muted-foreground/50", children: elapsedLabel }) : null,
|
|
7114
|
-
/* @__PURE__ */ jsx21("span", { className: cn(
|
|
7115
|
-
"ml-1 shrink-0 rounded-sm border border-border/40 px-1 tabular-nums",
|
|
7116
|
-
"text-[10px] text-muted-foreground/50"
|
|
7117
|
-
), children: toolParts.length })
|
|
7081
|
+
)
|
|
7118
7082
|
]
|
|
7119
7083
|
}
|
|
7120
7084
|
),
|
|
7121
|
-
/* @__PURE__ */
|
|
7085
|
+
/* @__PURE__ */ jsx22(CollapsibleContent3, { className: "overflow-hidden data-[state=closed]:animate-[boring-collapse-close_200ms_ease] data-[state=open]:animate-[boring-collapse-open_200ms_ease]", children: /* @__PURE__ */ jsxs19(
|
|
7122
7086
|
"div",
|
|
7123
7087
|
{
|
|
7124
7088
|
"data-boring-agent-part": "tool-group-details",
|
|
7125
7089
|
className: "relative mt-1.5 w-full max-w-2xl pl-[18px]",
|
|
7126
7090
|
children: [
|
|
7127
|
-
/* @__PURE__ */
|
|
7128
|
-
/* @__PURE__ */
|
|
7091
|
+
/* @__PURE__ */ jsx22("div", { className: "absolute left-[5px] top-0 bottom-2 w-px bg-border/35" }),
|
|
7092
|
+
/* @__PURE__ */ jsx22("div", { className: "flex min-w-0 flex-col gap-1.5 [&_[data-boring-agent-part=tool-card]]:!my-0", children: toolParts.map(({ part, key }) => {
|
|
7129
7093
|
const { renderer, part: resolvedPart, resolution } = resolveToolRendererForPart(part, mergedToolRenderers);
|
|
7130
|
-
return /* @__PURE__ */
|
|
7094
|
+
return /* @__PURE__ */ jsx22(
|
|
7131
7095
|
"div",
|
|
7132
7096
|
{
|
|
7133
7097
|
className: "min-w-0",
|
|
@@ -7148,8 +7112,237 @@ var ToolCallGroup = memo6(({ tools, mergedToolRenderers }) => {
|
|
|
7148
7112
|
});
|
|
7149
7113
|
ToolCallGroup.displayName = "ToolCallGroup";
|
|
7150
7114
|
|
|
7115
|
+
// src/front/chat/messageContributions.tsx
|
|
7116
|
+
import { createContext as createContext7, createElement, useContext as useContext7, useMemo as useMemo11 } from "react";
|
|
7117
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
7118
|
+
var ChatMessageContributionContext = createContext7([]);
|
|
7119
|
+
function ChatMessageContributionProvider({
|
|
7120
|
+
contribution,
|
|
7121
|
+
children
|
|
7122
|
+
}) {
|
|
7123
|
+
const parent = useContext7(ChatMessageContributionContext);
|
|
7124
|
+
const contributions = useMemo11(
|
|
7125
|
+
() => [contribution, ...parent.filter((entry) => entry.id !== contribution.id)],
|
|
7126
|
+
[contribution, parent]
|
|
7127
|
+
);
|
|
7128
|
+
return /* @__PURE__ */ jsx23(ChatMessageContributionContext.Provider, { value: contributions, children });
|
|
7129
|
+
}
|
|
7130
|
+
function useCustomChatMessage(message) {
|
|
7131
|
+
const contributions = useContext7(ChatMessageContributionContext);
|
|
7132
|
+
const contribution = contributions.find((entry) => entry.matches(message));
|
|
7133
|
+
return contribution ? createElement(contribution.Component, { message }) : void 0;
|
|
7134
|
+
}
|
|
7135
|
+
function ChatMessageContributionBoundary({
|
|
7136
|
+
message,
|
|
7137
|
+
children
|
|
7138
|
+
}) {
|
|
7139
|
+
const customMessage = useCustomChatMessage(message);
|
|
7140
|
+
return customMessage !== void 0 ? customMessage : children;
|
|
7141
|
+
}
|
|
7142
|
+
|
|
7143
|
+
// src/front/chat/components/MessageMentions.tsx
|
|
7144
|
+
import { Children, cloneElement, isValidElement as isValidElement2 } from "react";
|
|
7145
|
+
import { Fragment as Fragment8, jsx as jsx24 } from "react/jsx-runtime";
|
|
7146
|
+
var TERMINAL_BOUNDARY = String.raw`(?=$|\s|[.,;!?)}\]"'”’]+(?=$|\s))`;
|
|
7147
|
+
var PREFIX_BOUNDARY = String.raw`(^|[\s(\[{"'“‘])`;
|
|
7148
|
+
function escapeRegExp2(value) {
|
|
7149
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7150
|
+
}
|
|
7151
|
+
function registeredNamePattern(names) {
|
|
7152
|
+
const safeNames = [...new Set(names)].filter((name) => /^\w[\w-]*$/.test(name)).sort((a, b) => b.length - a.length);
|
|
7153
|
+
return safeNames.length > 0 ? safeNames.map(escapeRegExp2).join("|") : void 0;
|
|
7154
|
+
}
|
|
7155
|
+
function addRegisteredCandidates(text, prefix, names, createMention, candidates) {
|
|
7156
|
+
const namesPattern = registeredNamePattern(names);
|
|
7157
|
+
if (!namesPattern || !text.includes(prefix)) return;
|
|
7158
|
+
const pattern = new RegExp(`${PREFIX_BOUNDARY}\\${prefix}(${namesPattern})${TERMINAL_BOUNDARY}`, "g");
|
|
7159
|
+
for (const match of text.matchAll(pattern)) {
|
|
7160
|
+
if (match.index === void 0) continue;
|
|
7161
|
+
const boundary = match[1] ?? "";
|
|
7162
|
+
const name = match[2];
|
|
7163
|
+
const mention = createMention(name);
|
|
7164
|
+
if (!mention) continue;
|
|
7165
|
+
const start = match.index + boundary.length;
|
|
7166
|
+
candidates.push({ start, end: start + name.length + 1, mention });
|
|
7167
|
+
}
|
|
7168
|
+
}
|
|
7169
|
+
function isSafeWorkspaceMentionPath(path) {
|
|
7170
|
+
if (!path || path.startsWith("/") || path.includes("\\") || path.includes("://")) return false;
|
|
7171
|
+
const segments = path.split("/");
|
|
7172
|
+
if (!segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..")) return false;
|
|
7173
|
+
const basename = segments.at(-1) ?? "";
|
|
7174
|
+
return basename.startsWith(".") || /\.[A-Za-z0-9]{1,12}$/.test(basename);
|
|
7175
|
+
}
|
|
7176
|
+
function addFileCandidates(text, candidates) {
|
|
7177
|
+
if (!text.includes("@")) return;
|
|
7178
|
+
const pattern = new RegExp(`${PREFIX_BOUNDARY}@([A-Za-z0-9_.-]+(?:/[A-Za-z0-9_.-]+)*)${TERMINAL_BOUNDARY}`, "g");
|
|
7179
|
+
for (const match of text.matchAll(pattern)) {
|
|
7180
|
+
if (match.index === void 0) continue;
|
|
7181
|
+
const boundary = match[1] ?? "";
|
|
7182
|
+
const path = match[2].replace(/[.,;!?]+$/, "");
|
|
7183
|
+
if (!isSafeWorkspaceMentionPath(path)) continue;
|
|
7184
|
+
const start = match.index + boundary.length;
|
|
7185
|
+
const label = `@${path}`;
|
|
7186
|
+
candidates.push({ start, end: start + label.length, mention: { kind: "file", path, label } });
|
|
7187
|
+
}
|
|
7188
|
+
}
|
|
7189
|
+
function collectMessageMentionCandidates(text, catalog) {
|
|
7190
|
+
const candidates = [];
|
|
7191
|
+
const commandsByName = new Map(catalog.commands.map((command) => [command.name, command]));
|
|
7192
|
+
addRegisteredCandidates(text, "/", [...commandsByName.keys()], (name) => {
|
|
7193
|
+
const command = commandsByName.get(name);
|
|
7194
|
+
return command ? { kind: "command", name, label: `/${name}`, behavior: command.clickBehavior } : void 0;
|
|
7195
|
+
}, candidates);
|
|
7196
|
+
const skillsByName = new Map(catalog.skills.map((skill) => [skill.name, skill]));
|
|
7197
|
+
addRegisteredCandidates(text, "!", [...skillsByName.keys()], (name) => {
|
|
7198
|
+
const skill = skillsByName.get(name);
|
|
7199
|
+
return skill ? { kind: "skill", name, commandName: skill.commandName, label: `!${name}` } : void 0;
|
|
7200
|
+
}, candidates);
|
|
7201
|
+
if (catalog.files) addFileCandidates(text, candidates);
|
|
7202
|
+
return candidates;
|
|
7203
|
+
}
|
|
7204
|
+
function splitMessageMentions(text, catalog, context = {}) {
|
|
7205
|
+
const before = context.before ?? "";
|
|
7206
|
+
const after = context.after ?? "";
|
|
7207
|
+
const source = `${before}${text}${after}`;
|
|
7208
|
+
const contentStart = before.length;
|
|
7209
|
+
const contentEnd = contentStart + text.length;
|
|
7210
|
+
const candidates = collectMessageMentionCandidates(source, catalog).filter((candidate) => candidate.start >= contentStart && candidate.end <= contentEnd).map((candidate) => ({ ...candidate, start: candidate.start - contentStart, end: candidate.end - contentStart })).sort((a, b) => a.start - b.start || b.end - a.end);
|
|
7211
|
+
const segments = [];
|
|
7212
|
+
let cursor = 0;
|
|
7213
|
+
for (const candidate of candidates) {
|
|
7214
|
+
if (candidate.start < cursor) continue;
|
|
7215
|
+
if (candidate.start > cursor) segments.push({ text: text.slice(cursor, candidate.start) });
|
|
7216
|
+
segments.push({ text: candidate.mention.label, mention: candidate.mention });
|
|
7217
|
+
cursor = candidate.end;
|
|
7218
|
+
}
|
|
7219
|
+
if (cursor < text.length) segments.push({ text: text.slice(cursor) });
|
|
7220
|
+
return segments.length > 0 ? segments : [{ text }];
|
|
7221
|
+
}
|
|
7222
|
+
function mentionActionLabel(mention) {
|
|
7223
|
+
if (mention.kind === "command") return mention.behavior === "execute" ? `Run ${mention.label} command` : `Insert ${mention.label} command`;
|
|
7224
|
+
if (mention.kind === "skill") return `Insert ${mention.label} skill`;
|
|
7225
|
+
return `Open ${mention.path}`;
|
|
7226
|
+
}
|
|
7227
|
+
function visibleText(node) {
|
|
7228
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
7229
|
+
if (!isValidElement2(node)) return "";
|
|
7230
|
+
const element = node;
|
|
7231
|
+
return Children.toArray(element.props.children).map(visibleText).join("");
|
|
7232
|
+
}
|
|
7233
|
+
function MessageMentions({
|
|
7234
|
+
children,
|
|
7235
|
+
catalog,
|
|
7236
|
+
onActivate,
|
|
7237
|
+
before = "",
|
|
7238
|
+
after = ""
|
|
7239
|
+
}) {
|
|
7240
|
+
const nodes = Children.toArray(children);
|
|
7241
|
+
const boundaryText = (index, direction) => {
|
|
7242
|
+
const sibling = nodes[index + direction];
|
|
7243
|
+
if (sibling !== void 0) return visibleText(sibling);
|
|
7244
|
+
return direction === -1 ? before : after;
|
|
7245
|
+
};
|
|
7246
|
+
const decorate = (child, index) => {
|
|
7247
|
+
if (typeof child === "string") {
|
|
7248
|
+
return splitMessageMentions(child, catalog, {
|
|
7249
|
+
before: boundaryText(index, -1),
|
|
7250
|
+
after: boundaryText(index, 1)
|
|
7251
|
+
}).map((segment, segmentIndex) => {
|
|
7252
|
+
if (!segment.mention) return segment.text;
|
|
7253
|
+
const actionLabel = mentionActionLabel(segment.mention);
|
|
7254
|
+
return /* @__PURE__ */ jsx24(
|
|
7255
|
+
"button",
|
|
7256
|
+
{
|
|
7257
|
+
type: "button",
|
|
7258
|
+
"aria-label": actionLabel,
|
|
7259
|
+
title: actionLabel,
|
|
7260
|
+
"data-message-mention-kind": segment.mention.kind,
|
|
7261
|
+
className: cn(
|
|
7262
|
+
"mx-0.5 inline-flex items-center rounded-[var(--radius-sm)] border border-border/70 bg-muted/55 px-1.5 py-0.5",
|
|
7263
|
+
"font-mono text-[0.9em] font-medium leading-none text-foreground underline-offset-2",
|
|
7264
|
+
"hover:bg-muted hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
|
|
7265
|
+
),
|
|
7266
|
+
onClick: () => onActivate(segment.mention),
|
|
7267
|
+
children: segment.text
|
|
7268
|
+
},
|
|
7269
|
+
`${index}:${segmentIndex}`
|
|
7270
|
+
);
|
|
7271
|
+
});
|
|
7272
|
+
}
|
|
7273
|
+
if (isValidElement2(child)) {
|
|
7274
|
+
const element = child;
|
|
7275
|
+
const tagName = element.props.node?.tagName;
|
|
7276
|
+
if (tagName === "strong" || tagName === "em" || tagName === "del" || element.type === "em" || element.type === "del") {
|
|
7277
|
+
return cloneElement(
|
|
7278
|
+
element,
|
|
7279
|
+
void 0,
|
|
7280
|
+
/* @__PURE__ */ jsx24(
|
|
7281
|
+
MessageMentions,
|
|
7282
|
+
{
|
|
7283
|
+
catalog,
|
|
7284
|
+
onActivate,
|
|
7285
|
+
before: boundaryText(index, -1),
|
|
7286
|
+
after: boundaryText(index, 1),
|
|
7287
|
+
children: element.props.children
|
|
7288
|
+
}
|
|
7289
|
+
)
|
|
7290
|
+
);
|
|
7291
|
+
}
|
|
7292
|
+
}
|
|
7293
|
+
return child;
|
|
7294
|
+
};
|
|
7295
|
+
return nodes.map(decorate);
|
|
7296
|
+
}
|
|
7297
|
+
function createMessageMentionMarkdownComponents(catalog, onActivate) {
|
|
7298
|
+
const decorate = (children) => /* @__PURE__ */ jsx24(MessageMentions, { catalog, onActivate, children });
|
|
7299
|
+
const paragraph = ({ node: _node, children, ...props }) => {
|
|
7300
|
+
const content = Children.toArray(children).filter((child) => child !== null && child !== "");
|
|
7301
|
+
if (content.length === 1 && isValidElement2(content[0])) {
|
|
7302
|
+
const child = content[0];
|
|
7303
|
+
if (child.props.node?.tagName === "img") return /* @__PURE__ */ jsx24(Fragment8, { children });
|
|
7304
|
+
if (child.props.node?.tagName === "code" && "data-block" in child.props) return /* @__PURE__ */ jsx24(Fragment8, { children });
|
|
7305
|
+
}
|
|
7306
|
+
return /* @__PURE__ */ jsx24("p", { ...props, children: decorate(children) });
|
|
7307
|
+
};
|
|
7308
|
+
const tableHeader = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24("th", { ...props, "data-streamdown": "table-header-cell", className: cn("whitespace-nowrap px-4 py-2 text-left font-semibold text-sm", className), children: decorate(children) });
|
|
7309
|
+
const tableCell = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24("td", { ...props, "data-streamdown": "table-cell", className: cn("px-4 py-2 text-sm", className), children: decorate(children) });
|
|
7310
|
+
const listItem = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24("li", { ...props, "data-streamdown": "list-item", className: cn("py-1 [&>p]:inline", className), children: decorate(children) });
|
|
7311
|
+
const headingClasses = {
|
|
7312
|
+
h1: "text-3xl",
|
|
7313
|
+
h2: "text-2xl",
|
|
7314
|
+
h3: "text-xl",
|
|
7315
|
+
h4: "text-lg",
|
|
7316
|
+
h5: "text-base",
|
|
7317
|
+
h6: "text-sm"
|
|
7318
|
+
};
|
|
7319
|
+
const heading = (Tag) => ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24(Tag, { ...props, "data-streamdown": `heading-${Tag.slice(1)}`, className: cn("mt-6 mb-2 font-semibold", headingClasses[Tag], className), children: decorate(children) });
|
|
7320
|
+
const inlineCode = ({ node: _node, children, className, ...props }) => /* @__PURE__ */ jsx24(
|
|
7321
|
+
"code",
|
|
7322
|
+
{
|
|
7323
|
+
...props,
|
|
7324
|
+
className: cn(INLINE_CODE_CLASS_NAME, className),
|
|
7325
|
+
children
|
|
7326
|
+
}
|
|
7327
|
+
);
|
|
7328
|
+
return {
|
|
7329
|
+
p: paragraph,
|
|
7330
|
+
th: tableHeader,
|
|
7331
|
+
td: tableCell,
|
|
7332
|
+
li: listItem,
|
|
7333
|
+
h1: heading("h1"),
|
|
7334
|
+
h2: heading("h2"),
|
|
7335
|
+
h3: heading("h3"),
|
|
7336
|
+
h4: heading("h4"),
|
|
7337
|
+
h5: heading("h5"),
|
|
7338
|
+
h6: heading("h6"),
|
|
7339
|
+
inlineCode
|
|
7340
|
+
};
|
|
7341
|
+
}
|
|
7342
|
+
|
|
7151
7343
|
// src/front/chat/components/PiTimelineMessage.tsx
|
|
7152
|
-
import { jsx as
|
|
7344
|
+
import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
7345
|
+
var EMPTY_MENTION_CATALOG = { commands: [], skills: [], files: false };
|
|
7153
7346
|
var COLLAPSIBLE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
7154
7347
|
"read",
|
|
7155
7348
|
"ls",
|
|
@@ -7163,7 +7356,10 @@ var COLLAPSIBLE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
7163
7356
|
function isCollapsibleTool(part) {
|
|
7164
7357
|
return part.type === "tool-call" && COLLAPSIBLE_TOOL_NAMES.has(part.toolName);
|
|
7165
7358
|
}
|
|
7166
|
-
function PiTimelineMessage(
|
|
7359
|
+
function PiTimelineMessage(props) {
|
|
7360
|
+
return /* @__PURE__ */ jsx25(ChatMessageContributionBoundary, { message: props.message, children: /* @__PURE__ */ jsx25(DefaultPiTimelineMessage, { ...props }) });
|
|
7361
|
+
}
|
|
7362
|
+
function DefaultPiTimelineMessage({ message, isLast, isStreaming, showThoughts, toolRenderers, mentionCatalog = EMPTY_MENTION_CATALOG, onMentionActivate }) {
|
|
7167
7363
|
const role = message.role;
|
|
7168
7364
|
const isAssistant = role === "assistant";
|
|
7169
7365
|
const textParts = message.parts.filter((part) => part.type === "text");
|
|
@@ -7171,6 +7367,31 @@ function PiTimelineMessage({ message, isLast, isStreaming, showThoughts, toolRen
|
|
|
7171
7367
|
const finalParts = groupRenderableParts(message);
|
|
7172
7368
|
const attachmentSummaryPaths = role === "user" ? attachmentPathsFromTextParts(textParts) : [];
|
|
7173
7369
|
const openArtifact = useOpenArtifact();
|
|
7370
|
+
const effectiveMentionCatalog = useMemo12(() => ({
|
|
7371
|
+
commands: mentionCatalog.commands,
|
|
7372
|
+
skills: mentionCatalog.skills,
|
|
7373
|
+
files: mentionCatalog.files && Boolean(openArtifact)
|
|
7374
|
+
}), [mentionCatalog, openArtifact]);
|
|
7375
|
+
const mentionSignature = [
|
|
7376
|
+
...effectiveMentionCatalog.commands.map((command) => `command:${command.name}:${command.clickBehavior}`),
|
|
7377
|
+
...effectiveMentionCatalog.skills.map((skill) => `skill:${skill.name}:${skill.commandName}`),
|
|
7378
|
+
effectiveMentionCatalog.files ? "files:enabled" : "files:disabled"
|
|
7379
|
+
].join("|");
|
|
7380
|
+
const mentionActivateRef = useRef10(onMentionActivate);
|
|
7381
|
+
mentionActivateRef.current = onMentionActivate;
|
|
7382
|
+
const activateCurrentMention = useCallback13((mention) => {
|
|
7383
|
+
if (mention.kind === "file") {
|
|
7384
|
+
openArtifact?.(mention.path);
|
|
7385
|
+
return;
|
|
7386
|
+
}
|
|
7387
|
+
mentionActivateRef.current?.(mention);
|
|
7388
|
+
}, [openArtifact]);
|
|
7389
|
+
const hasMentions = effectiveMentionCatalog.files || effectiveMentionCatalog.commands.length > 0 || effectiveMentionCatalog.skills.length > 0;
|
|
7390
|
+
const mentionsEnabled = Boolean(isAssistant && !(isStreaming && isLast) && hasMentions);
|
|
7391
|
+
const mentionMarkdownComponents = useMemo12(
|
|
7392
|
+
() => mentionsEnabled ? createMessageMentionMarkdownComponents(effectiveMentionCatalog, activateCurrentMention) : void 0,
|
|
7393
|
+
[activateCurrentMention, effectiveMentionCatalog, mentionSignature, mentionsEnabled]
|
|
7394
|
+
);
|
|
7174
7395
|
const shouldReserveStreamingActions = isStreaming && isAssistant && isLast;
|
|
7175
7396
|
return /* @__PURE__ */ jsxs20(
|
|
7176
7397
|
Message,
|
|
@@ -7180,118 +7401,93 @@ function PiTimelineMessage({ message, isLast, isStreaming, showThoughts, toolRen
|
|
|
7180
7401
|
"data-boring-agent-message-id": message.id,
|
|
7181
7402
|
"data-boring-agent-message-role": role,
|
|
7182
7403
|
"data-boring-agent-message-status": message.status,
|
|
7183
|
-
className: "!max-w-full !gap-1.5",
|
|
7184
7404
|
children: [
|
|
7185
|
-
/* @__PURE__ */ jsxs20(
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
"
|
|
7190
|
-
|
|
7191
|
-
"
|
|
7192
|
-
"
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
),
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
...openPath ? { "data-workspace-path": openPath } : {},
|
|
7232
|
-
onClick: openAttachment,
|
|
7233
|
-
onKeyDown: openAttachmentFromKeyboard
|
|
7234
|
-
} : void 0,
|
|
7235
|
-
children: [
|
|
7236
|
-
/* @__PURE__ */ jsx22(AttachmentPreview, { className: role === "user" ? "!size-5 shrink-0 rounded-[var(--radius-sm)]" : "size-10 shrink-0 rounded-[var(--radius-md)]" }),
|
|
7237
|
-
/* @__PURE__ */ jsx22(AttachmentInfo, { className: role === "user" ? "min-w-0 max-w-[220px] flex-1 text-[12px]" : "min-w-0 flex-1" })
|
|
7238
|
-
]
|
|
7239
|
-
},
|
|
7240
|
-
`file-${message.id}-${index}`
|
|
7241
|
-
);
|
|
7242
|
-
})
|
|
7243
|
-
}
|
|
7244
|
-
) : null,
|
|
7245
|
-
finalParts.map((item) => {
|
|
7246
|
-
if (item.kind === "reasoning") {
|
|
7247
|
-
return /* @__PURE__ */ jsx22(
|
|
7248
|
-
TimelineReasoningPart,
|
|
7249
|
-
{
|
|
7250
|
-
item,
|
|
7251
|
-
showThoughts
|
|
7252
|
-
},
|
|
7253
|
-
item.key
|
|
7254
|
-
);
|
|
7255
|
-
}
|
|
7256
|
-
if (item.kind === "tool-group") {
|
|
7257
|
-
return /* @__PURE__ */ jsx22("div", { "data-boring-agent-part": "message-tools", children: /* @__PURE__ */ jsx22(ToolCallGroup, { tools: item.tools, mergedToolRenderers: toolRenderers }) }, item.key);
|
|
7258
|
-
}
|
|
7259
|
-
if (item.kind === "tool-plain") {
|
|
7260
|
-
return /* @__PURE__ */ jsx22("div", { "data-boring-agent-part": "message-tools", children: /* @__PURE__ */ jsx22(PlainToolCard, { part: item.part, renderers: toolRenderers }) }, item.key);
|
|
7261
|
-
}
|
|
7262
|
-
if (item.part.type === "text") {
|
|
7263
|
-
const text = textForMessageDisplay(item.part.text, role);
|
|
7264
|
-
if (!text) return null;
|
|
7265
|
-
return /* @__PURE__ */ jsx22("div", { "data-boring-agent-part": "message-text", children: /* @__PURE__ */ jsx22(
|
|
7266
|
-
MessageResponse,
|
|
7267
|
-
{
|
|
7268
|
-
className: cn(
|
|
7269
|
-
"max-w-none",
|
|
7270
|
-
"prose prose-invert prose-neutral",
|
|
7271
|
-
"prose-p:my-3 prose-p:leading-[1.7] prose-p:text-[13px]",
|
|
7272
|
-
"prose-headings:mt-5 prose-headings:mb-2 prose-headings:font-semibold prose-headings:tracking-[-0.01em]",
|
|
7273
|
-
"prose-ul:my-3 prose-ul:pl-6 prose-ol:my-3 prose-ol:pl-6",
|
|
7274
|
-
"prose-li:my-1.5 prose-li:leading-[1.7] prose-li:pl-1 prose-li:marker:text-muted-foreground/70",
|
|
7275
|
-
"prose-strong:font-semibold prose-strong:text-foreground",
|
|
7276
|
-
"prose-em:text-foreground/90",
|
|
7277
|
-
"prose-a:text-[color:var(--accent)] prose-a:underline-offset-4 hover:prose-a:underline",
|
|
7278
|
-
"prose-code:before:content-none prose-code:after:content-none",
|
|
7279
|
-
"prose-pre:my-0 prose-pre:rounded-none prose-pre:border-0",
|
|
7280
|
-
"prose-pre:bg-transparent prose-pre:p-0"
|
|
7281
|
-
),
|
|
7282
|
-
children: text
|
|
7283
|
-
}
|
|
7284
|
-
) }, item.key);
|
|
7285
|
-
}
|
|
7286
|
-
if (item.part.type === "notice") {
|
|
7287
|
-
return /* @__PURE__ */ jsx22(NoticeBubble, { level: item.part.level, text: item.part.text }, item.key);
|
|
7288
|
-
}
|
|
7289
|
-
return null;
|
|
7405
|
+
/* @__PURE__ */ jsxs20(MessageContent, { children: [
|
|
7406
|
+
fileParts.length > 0 ? /* @__PURE__ */ jsx25(
|
|
7407
|
+
Attachments,
|
|
7408
|
+
{
|
|
7409
|
+
variant: role === "user" ? "inline" : "list",
|
|
7410
|
+
className: cn(
|
|
7411
|
+
role === "user" ? "mb-2 w-full gap-2" : "gap-1.5",
|
|
7412
|
+
role === "user" ? "[&>div]:max-w-full [&>div]:border-input/60 [&>div]:bg-background/35 [&>div]:px-1.5 [&>div]:text-secondary-foreground [&>div:hover]:bg-background/45" : void 0
|
|
7413
|
+
),
|
|
7414
|
+
children: fileParts.map((file, index) => {
|
|
7415
|
+
const openPath = file.path ?? attachmentSummaryPaths[index];
|
|
7416
|
+
const openUrl = file.url && !openPath ? file.url : void 0;
|
|
7417
|
+
const canOpen = Boolean(openArtifact && openPath || openUrl);
|
|
7418
|
+
const openAttachment = () => {
|
|
7419
|
+
if (openPath) {
|
|
7420
|
+
if (file.filesystem) openArtifact?.(openPath, { filesystem: file.filesystem });
|
|
7421
|
+
else openArtifact?.(openPath);
|
|
7422
|
+
return;
|
|
7423
|
+
}
|
|
7424
|
+
if (openUrl) window.open(openUrl, "_blank", "noopener,noreferrer");
|
|
7425
|
+
};
|
|
7426
|
+
const openAttachmentFromKeyboard = (event) => {
|
|
7427
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
7428
|
+
event.preventDefault();
|
|
7429
|
+
openAttachment();
|
|
7430
|
+
};
|
|
7431
|
+
return /* @__PURE__ */ jsxs20(
|
|
7432
|
+
Attachment,
|
|
7433
|
+
{
|
|
7434
|
+
data: toAttachmentData(file, `file-${message.id}-${index}`),
|
|
7435
|
+
...canOpen ? {
|
|
7436
|
+
role: "button",
|
|
7437
|
+
tabIndex: 0,
|
|
7438
|
+
title: openPath ? `Open ${openPath} in workspace` : `Open ${file.filename ?? "attachment"}`,
|
|
7439
|
+
"aria-label": openPath ? `Open ${file.filename ?? openPath} in workspace` : `Open ${file.filename ?? "attachment"}`,
|
|
7440
|
+
...openPath ? { "data-workspace-path": openPath } : {},
|
|
7441
|
+
onClick: openAttachment,
|
|
7442
|
+
onKeyDown: openAttachmentFromKeyboard
|
|
7443
|
+
} : void 0,
|
|
7444
|
+
children: [
|
|
7445
|
+
/* @__PURE__ */ jsx25(AttachmentPreview, { className: role === "user" ? "!size-5 shrink-0 rounded-[var(--radius-sm)]" : "size-10 shrink-0 rounded-[var(--radius-md)]" }),
|
|
7446
|
+
/* @__PURE__ */ jsx25(AttachmentInfo, { className: role === "user" ? "min-w-0 max-w-[220px] flex-1 text-[12px]" : "min-w-0 flex-1" })
|
|
7447
|
+
]
|
|
7448
|
+
},
|
|
7449
|
+
`file-${message.id}-${index}`
|
|
7450
|
+
);
|
|
7290
7451
|
})
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7452
|
+
}
|
|
7453
|
+
) : null,
|
|
7454
|
+
finalParts.map((item) => {
|
|
7455
|
+
if (item.kind === "reasoning") {
|
|
7456
|
+
return /* @__PURE__ */ jsx25(
|
|
7457
|
+
TimelineReasoningPart,
|
|
7458
|
+
{
|
|
7459
|
+
item,
|
|
7460
|
+
showThoughts
|
|
7461
|
+
},
|
|
7462
|
+
item.key
|
|
7463
|
+
);
|
|
7464
|
+
}
|
|
7465
|
+
if (item.kind === "tool-group") {
|
|
7466
|
+
return /* @__PURE__ */ jsx25("div", { "data-boring-agent-part": "message-tools", children: /* @__PURE__ */ jsx25(ToolCallGroup, { tools: item.tools, mergedToolRenderers: toolRenderers }) }, item.key);
|
|
7467
|
+
}
|
|
7468
|
+
if (item.kind === "tool-plain") {
|
|
7469
|
+
return /* @__PURE__ */ jsx25("div", { "data-boring-agent-part": "message-tools", children: /* @__PURE__ */ jsx25(PlainToolCard, { part: item.part, renderers: toolRenderers }) }, item.key);
|
|
7470
|
+
}
|
|
7471
|
+
if (item.part.type === "text") {
|
|
7472
|
+
const text = textForMessageDisplay(item.part.text, role);
|
|
7473
|
+
if (!text) return null;
|
|
7474
|
+
return /* @__PURE__ */ jsx25("div", { "data-boring-agent-part": "message-text", children: /* @__PURE__ */ jsx25(
|
|
7475
|
+
MessageResponse,
|
|
7476
|
+
{
|
|
7477
|
+
components: mentionMarkdownComponents,
|
|
7478
|
+
className: "boring-agent-markdown max-w-none",
|
|
7479
|
+
children: text
|
|
7480
|
+
},
|
|
7481
|
+
`${mentionSignature || "no-message-mentions"}:${mentionsEnabled ? "enabled" : "static"}`
|
|
7482
|
+
) }, item.key);
|
|
7483
|
+
}
|
|
7484
|
+
if (item.part.type === "notice") {
|
|
7485
|
+
return /* @__PURE__ */ jsx25(NoticeBubble, { level: item.part.level, text: item.part.text }, item.key);
|
|
7486
|
+
}
|
|
7487
|
+
return null;
|
|
7488
|
+
})
|
|
7489
|
+
] }),
|
|
7490
|
+
isAssistant && (textParts.length > 0 || shouldReserveStreamingActions) ? /* @__PURE__ */ jsx25(
|
|
7295
7491
|
MessageActionsBar,
|
|
7296
7492
|
{
|
|
7297
7493
|
text: textParts.map((part) => part.text).join("\n\n"),
|
|
@@ -7326,15 +7522,15 @@ function TimelineReasoningPart({ item, showThoughts }) {
|
|
|
7326
7522
|
onOpenChange: handleOpenChange,
|
|
7327
7523
|
autoClose: false,
|
|
7328
7524
|
children: [
|
|
7329
|
-
/* @__PURE__ */
|
|
7525
|
+
/* @__PURE__ */ jsx25(
|
|
7330
7526
|
ReasoningTrigger,
|
|
7331
7527
|
{
|
|
7332
7528
|
className: "mb-1 w-fit rounded-[var(--radius-sm)] px-0 py-0 !text-xs !font-normal !text-muted-foreground/75 hover:bg-transparent hover:!text-muted-foreground/75 [&_svg]:!text-muted-foreground/75",
|
|
7333
|
-
getThinkingMessage: (streaming) => /* @__PURE__ */
|
|
7529
|
+
getThinkingMessage: (streaming) => /* @__PURE__ */ jsx25("span", { children: streaming ? "thinking" : "thoughts" }),
|
|
7334
7530
|
onClick: toggleManualOpen
|
|
7335
7531
|
}
|
|
7336
7532
|
),
|
|
7337
|
-
/* @__PURE__ */
|
|
7533
|
+
/* @__PURE__ */ jsx25(ReasoningContent, { children: item.text })
|
|
7338
7534
|
]
|
|
7339
7535
|
}
|
|
7340
7536
|
);
|
|
@@ -7343,7 +7539,7 @@ function PlainToolCard({ part, renderers }) {
|
|
|
7343
7539
|
const toolPart = toToolPart(part);
|
|
7344
7540
|
if (!toolPart) return null;
|
|
7345
7541
|
const { renderer, part: resolved, resolution } = resolveToolRendererForPart(toolPart, renderers);
|
|
7346
|
-
return /* @__PURE__ */
|
|
7542
|
+
return /* @__PURE__ */ jsx25(
|
|
7347
7543
|
"div",
|
|
7348
7544
|
{
|
|
7349
7545
|
"data-tool-call-id": resolved.toolCallId,
|
|
@@ -7392,13 +7588,13 @@ ${part.text}`;
|
|
|
7392
7588
|
return grouped;
|
|
7393
7589
|
}
|
|
7394
7590
|
function NoticeBubble({ level, text }) {
|
|
7395
|
-
return /* @__PURE__ */
|
|
7591
|
+
return /* @__PURE__ */ jsx25(
|
|
7396
7592
|
"div",
|
|
7397
7593
|
{
|
|
7398
7594
|
"data-boring-agent-part": "message-notice",
|
|
7399
7595
|
"data-notice-level": level,
|
|
7400
7596
|
className: noticeSurfaceClass(level, "text-xs"),
|
|
7401
|
-
children: /* @__PURE__ */
|
|
7597
|
+
children: /* @__PURE__ */ jsx25("div", { className: noticeTextClass(), children: text })
|
|
7402
7598
|
}
|
|
7403
7599
|
);
|
|
7404
7600
|
}
|
|
@@ -7477,7 +7673,7 @@ function MessageActionsBar({
|
|
|
7477
7673
|
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[color:var(--accent)]/40"
|
|
7478
7674
|
);
|
|
7479
7675
|
const hiddenActionProps = visible ? {} : { tabIndex: -1 };
|
|
7480
|
-
return /* @__PURE__ */
|
|
7676
|
+
return /* @__PURE__ */ jsx25(
|
|
7481
7677
|
"div",
|
|
7482
7678
|
{
|
|
7483
7679
|
"aria-hidden": !visible,
|
|
@@ -7485,7 +7681,7 @@ function MessageActionsBar({
|
|
|
7485
7681
|
"flex min-h-6 items-center gap-0.5 -mt-1 transition-opacity duration-200",
|
|
7486
7682
|
visible ? "opacity-100" : "pointer-events-none opacity-0"
|
|
7487
7683
|
),
|
|
7488
|
-
children: /* @__PURE__ */
|
|
7684
|
+
children: /* @__PURE__ */ jsx25(
|
|
7489
7685
|
Button11,
|
|
7490
7686
|
{
|
|
7491
7687
|
type: "button",
|
|
@@ -7496,7 +7692,7 @@ function MessageActionsBar({
|
|
|
7496
7692
|
"aria-label": copied ? "Copied" : "Copy message",
|
|
7497
7693
|
title: copied ? "Copied" : "Copy",
|
|
7498
7694
|
...hiddenActionProps,
|
|
7499
|
-
children: copied ? /* @__PURE__ */
|
|
7695
|
+
children: copied ? /* @__PURE__ */ jsx25(CheckIcon2, { className: "h-3.5 w-3.5 text-[color:var(--accent)]" }) : /* @__PURE__ */ jsx25(CopyIcon3, { className: "h-3.5 w-3.5" })
|
|
7500
7696
|
}
|
|
7501
7697
|
)
|
|
7502
7698
|
}
|
|
@@ -7517,7 +7713,7 @@ function partKey(messageId, part, index) {
|
|
|
7517
7713
|
}
|
|
7518
7714
|
|
|
7519
7715
|
// src/front/chat/components/PiConversationSurface.tsx
|
|
7520
|
-
import { jsx as
|
|
7716
|
+
import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
7521
7717
|
var TRANSCRIPT_WINDOW = 60;
|
|
7522
7718
|
var TRANSCRIPT_WINDOW_STEP = 40;
|
|
7523
7719
|
var LOAD_OLDER_THRESHOLD_PX = 320;
|
|
@@ -7531,6 +7727,8 @@ function PiConversationSurface({
|
|
|
7531
7727
|
isStreaming,
|
|
7532
7728
|
showThoughts,
|
|
7533
7729
|
toolRenderers,
|
|
7730
|
+
mentionCatalog,
|
|
7731
|
+
onMentionActivate,
|
|
7534
7732
|
runtimeNotices,
|
|
7535
7733
|
onDismissNotice,
|
|
7536
7734
|
renderNoticeAction,
|
|
@@ -7565,10 +7763,10 @@ function PiConversationSurface({
|
|
|
7565
7763
|
emptyHero && "py-4 text-center"
|
|
7566
7764
|
), children: [
|
|
7567
7765
|
messages.length === 0 && emptyStateHydrating ? /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2 rounded-xl border border-border bg-card/70 px-4 py-3 text-sm text-muted-foreground", children: [
|
|
7568
|
-
/* @__PURE__ */
|
|
7766
|
+
/* @__PURE__ */ jsx26(Loader22, { className: "h-4 w-4 animate-spin" }),
|
|
7569
7767
|
"Loading chat history\u2026"
|
|
7570
7768
|
] }) : null,
|
|
7571
|
-
messages.length === 0 && !emptyStateHydrating ? /* @__PURE__ */
|
|
7769
|
+
messages.length === 0 && !emptyStateHydrating ? /* @__PURE__ */ jsx26(
|
|
7572
7770
|
ChatEmptyState,
|
|
7573
7771
|
{
|
|
7574
7772
|
eyebrow: emptyState?.eyebrow,
|
|
@@ -7586,29 +7784,31 @@ function PiConversationSurface({
|
|
|
7586
7784
|
}
|
|
7587
7785
|
}
|
|
7588
7786
|
) : null,
|
|
7589
|
-
hasOlder ? /* @__PURE__ */
|
|
7590
|
-
visibleItems.map(({ message, key }, index) => /* @__PURE__ */
|
|
7787
|
+
hasOlder ? /* @__PURE__ */ jsx26(TranscriptHistoryLoader, { olderCount, onLoadOlder: loadOlder }) : null,
|
|
7788
|
+
visibleItems.map(({ message, key }, index) => /* @__PURE__ */ jsx26(
|
|
7591
7789
|
PiTimelineMessage,
|
|
7592
7790
|
{
|
|
7593
7791
|
message,
|
|
7594
7792
|
isLast: index === visibleItems.length - 1,
|
|
7595
7793
|
isStreaming,
|
|
7596
7794
|
showThoughts,
|
|
7597
|
-
toolRenderers
|
|
7795
|
+
toolRenderers,
|
|
7796
|
+
mentionCatalog,
|
|
7797
|
+
onMentionActivate
|
|
7598
7798
|
},
|
|
7599
7799
|
key
|
|
7600
7800
|
)),
|
|
7601
|
-
/* @__PURE__ */
|
|
7801
|
+
/* @__PURE__ */ jsx26(RuntimeNoticeMessages, { notices: runtimeNotices, onDismiss: onDismissNotice, renderAction: renderNoticeAction })
|
|
7602
7802
|
] }),
|
|
7603
|
-
/* @__PURE__ */
|
|
7803
|
+
/* @__PURE__ */ jsx26(ConversationScrollButton, {})
|
|
7604
7804
|
]
|
|
7605
7805
|
}
|
|
7606
7806
|
);
|
|
7607
7807
|
}
|
|
7608
7808
|
function TranscriptHistoryLoader({ olderCount, onLoadOlder }) {
|
|
7609
7809
|
const { scrollRef } = useStickToBottomContext2();
|
|
7610
|
-
const pendingAnchor =
|
|
7611
|
-
const armed =
|
|
7810
|
+
const pendingAnchor = useRef11(null);
|
|
7811
|
+
const armed = useRef11(true);
|
|
7612
7812
|
useEffect14(() => {
|
|
7613
7813
|
const el = scrollRef.current;
|
|
7614
7814
|
if (!el) return;
|
|
@@ -7632,7 +7832,7 @@ function TranscriptHistoryLoader({ olderCount, onLoadOlder }) {
|
|
|
7632
7832
|
}
|
|
7633
7833
|
if (el.scrollTop > LOAD_OLDER_THRESHOLD_PX) armed.current = true;
|
|
7634
7834
|
});
|
|
7635
|
-
return /* @__PURE__ */
|
|
7835
|
+
return /* @__PURE__ */ jsx26("div", { className: "flex justify-center", "data-boring-agent-part": "transcript-load-older", children: /* @__PURE__ */ jsxs21(
|
|
7636
7836
|
"button",
|
|
7637
7837
|
{
|
|
7638
7838
|
type: "button",
|
|
@@ -7673,10 +7873,10 @@ import { useCallback as useCallback16, useLayoutEffect as useLayoutEffect2 } fro
|
|
|
7673
7873
|
import { motion as motion2 } from "motion/react";
|
|
7674
7874
|
|
|
7675
7875
|
// src/front/composer/PluginUpdateStatus.tsx
|
|
7676
|
-
import { useEffect as useEffect15, useRef as
|
|
7876
|
+
import { useEffect as useEffect15, useRef as useRef12 } from "react";
|
|
7677
7877
|
|
|
7678
7878
|
// src/front/composer/ComposerStatusBanner.tsx
|
|
7679
|
-
import { jsx as
|
|
7879
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
7680
7880
|
function ComposerStatusBanner({
|
|
7681
7881
|
tone,
|
|
7682
7882
|
dataAttribute,
|
|
@@ -7705,8 +7905,8 @@ function ComposerStatusBanner({
|
|
|
7705
7905
|
maxWidthClassName
|
|
7706
7906
|
),
|
|
7707
7907
|
children: [
|
|
7708
|
-
/* @__PURE__ */
|
|
7709
|
-
/* @__PURE__ */
|
|
7908
|
+
/* @__PURE__ */ jsx27("span", { className: "inline-block h-2 w-2 animate-pulse rounded-full bg-accent", "aria-hidden": "true" }),
|
|
7909
|
+
/* @__PURE__ */ jsx27("span", { children: runningContent })
|
|
7710
7910
|
]
|
|
7711
7911
|
}
|
|
7712
7912
|
);
|
|
@@ -7725,12 +7925,12 @@ function ComposerStatusBanner({
|
|
|
7725
7925
|
),
|
|
7726
7926
|
children: [
|
|
7727
7927
|
/* @__PURE__ */ jsxs22("div", { className: "flex items-start gap-2", children: [
|
|
7728
|
-
/* @__PURE__ */
|
|
7928
|
+
/* @__PURE__ */ jsx27("span", { className: "mt-0.5 text-[oklch(0.45_0.13_148)]", "aria-hidden": "true", children: "\u2713" }),
|
|
7729
7929
|
/* @__PURE__ */ jsxs22("span", { className: "min-w-0 flex-1", children: [
|
|
7730
|
-
/* @__PURE__ */
|
|
7731
|
-
detail ? /* @__PURE__ */
|
|
7930
|
+
/* @__PURE__ */ jsx27("span", { className: "block font-medium leading-5", children: title }),
|
|
7931
|
+
detail ? /* @__PURE__ */ jsx27("span", { className: "block leading-4 text-muted-foreground", children: detail }) : null
|
|
7732
7932
|
] }),
|
|
7733
|
-
onDismiss ? /* @__PURE__ */
|
|
7933
|
+
onDismiss ? /* @__PURE__ */ jsx27(
|
|
7734
7934
|
"button",
|
|
7735
7935
|
{
|
|
7736
7936
|
type: "button",
|
|
@@ -7759,9 +7959,9 @@ function ComposerStatusBanner({
|
|
|
7759
7959
|
),
|
|
7760
7960
|
children: [
|
|
7761
7961
|
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
7762
|
-
/* @__PURE__ */
|
|
7763
|
-
/* @__PURE__ */
|
|
7764
|
-
onRetry ? /* @__PURE__ */
|
|
7962
|
+
/* @__PURE__ */ jsx27("span", { className: "text-destructive", "aria-hidden": "true", children: "\u26A0" }),
|
|
7963
|
+
/* @__PURE__ */ jsx27("span", { className: "flex-1 font-medium", children: title }),
|
|
7964
|
+
onRetry ? /* @__PURE__ */ jsx27(
|
|
7765
7965
|
"button",
|
|
7766
7966
|
{
|
|
7767
7967
|
type: "button",
|
|
@@ -7770,7 +7970,7 @@ function ComposerStatusBanner({
|
|
|
7770
7970
|
children: retryLabel
|
|
7771
7971
|
}
|
|
7772
7972
|
) : null,
|
|
7773
|
-
onDismiss ? /* @__PURE__ */
|
|
7973
|
+
onDismiss ? /* @__PURE__ */ jsx27(
|
|
7774
7974
|
"button",
|
|
7775
7975
|
{
|
|
7776
7976
|
type: "button",
|
|
@@ -7781,14 +7981,14 @@ function ComposerStatusBanner({
|
|
|
7781
7981
|
}
|
|
7782
7982
|
) : null
|
|
7783
7983
|
] }),
|
|
7784
|
-
message ? /* @__PURE__ */
|
|
7984
|
+
message ? /* @__PURE__ */ jsx27("pre", { className: "mt-2 whitespace-pre-wrap break-words text-[11px] text-destructive/90", children: message }) : null
|
|
7785
7985
|
]
|
|
7786
7986
|
}
|
|
7787
7987
|
);
|
|
7788
7988
|
}
|
|
7789
7989
|
|
|
7790
7990
|
// src/front/composer/PluginUpdateStatus.tsx
|
|
7791
|
-
import { jsx as
|
|
7991
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
7792
7992
|
function PluginUpdateStatus({
|
|
7793
7993
|
state,
|
|
7794
7994
|
onDismiss,
|
|
@@ -7796,7 +7996,7 @@ function PluginUpdateStatus({
|
|
|
7796
7996
|
successAutoDismissMs = 1400,
|
|
7797
7997
|
maxWidthClassName = "max-w-3xl"
|
|
7798
7998
|
}) {
|
|
7799
|
-
const onDismissRef =
|
|
7999
|
+
const onDismissRef = useRef12(onDismiss);
|
|
7800
8000
|
useEffect15(() => {
|
|
7801
8001
|
onDismissRef.current = onDismiss;
|
|
7802
8002
|
}, [onDismiss]);
|
|
@@ -7810,7 +8010,7 @@ function PluginUpdateStatus({
|
|
|
7810
8010
|
}, [state?.kind, successDismissKey, successAutoDismissMs]);
|
|
7811
8011
|
if (!state) return null;
|
|
7812
8012
|
if (state.kind === "running") {
|
|
7813
|
-
return /* @__PURE__ */
|
|
8013
|
+
return /* @__PURE__ */ jsx28(
|
|
7814
8014
|
ComposerStatusBanner,
|
|
7815
8015
|
{
|
|
7816
8016
|
tone: "running",
|
|
@@ -7848,7 +8048,7 @@ function PluginUpdateStatus({
|
|
|
7848
8048
|
),
|
|
7849
8049
|
children: [
|
|
7850
8050
|
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-1.5 font-medium text-[oklch(0.48_0.15_60)]", children: [
|
|
7851
|
-
/* @__PURE__ */
|
|
8051
|
+
/* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u26A0" }),
|
|
7852
8052
|
/* @__PURE__ */ jsxs23("span", { children: [
|
|
7853
8053
|
"Reload diagnostics for ",
|
|
7854
8054
|
diagnostics.length,
|
|
@@ -7856,8 +8056,8 @@ function PluginUpdateStatus({
|
|
|
7856
8056
|
diagnostics.length === 1 ? "" : "s"
|
|
7857
8057
|
] })
|
|
7858
8058
|
] }),
|
|
7859
|
-
/* @__PURE__ */
|
|
7860
|
-
/* @__PURE__ */
|
|
8059
|
+
/* @__PURE__ */ jsx28("ul", { className: "mt-1 ml-4 list-disc text-foreground/85", children: diagnostics.map((diagnostic, index) => /* @__PURE__ */ jsxs23("li", { children: [
|
|
8060
|
+
/* @__PURE__ */ jsx28("code", { className: "font-mono text-[10.5px]", children: diagnostic.pluginId ?? diagnostic.source ?? "plugin" }),
|
|
7861
8061
|
" \u2014 ",
|
|
7862
8062
|
diagnostic.message ?? "reload diagnostic"
|
|
7863
8063
|
] }, `${diagnostic.pluginId ?? diagnostic.source ?? "plugin"}-${index}`)) })
|
|
@@ -7874,7 +8074,7 @@ function PluginUpdateStatus({
|
|
|
7874
8074
|
),
|
|
7875
8075
|
children: [
|
|
7876
8076
|
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-1.5 font-medium text-[oklch(0.48_0.15_60)]", children: [
|
|
7877
|
-
/* @__PURE__ */
|
|
8077
|
+
/* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u26A0" }),
|
|
7878
8078
|
/* @__PURE__ */ jsxs23("span", { children: [
|
|
7879
8079
|
"Restart needed for ",
|
|
7880
8080
|
warnings.length,
|
|
@@ -7882,12 +8082,12 @@ function PluginUpdateStatus({
|
|
|
7882
8082
|
warnings.length === 1 ? "" : "s"
|
|
7883
8083
|
] })
|
|
7884
8084
|
] }),
|
|
7885
|
-
/* @__PURE__ */
|
|
7886
|
-
/* @__PURE__ */
|
|
8085
|
+
/* @__PURE__ */ jsx28("ul", { className: "mt-1 ml-4 list-disc text-foreground/85", children: warnings.map((w) => /* @__PURE__ */ jsxs23("li", { children: [
|
|
8086
|
+
/* @__PURE__ */ jsx28("code", { className: "font-mono text-[10.5px]", children: w.id }),
|
|
7887
8087
|
" \u2014 ",
|
|
7888
8088
|
w.surfaces.join(" + ")
|
|
7889
8089
|
] }, w.id)) }),
|
|
7890
|
-
/* @__PURE__ */
|
|
8090
|
+
/* @__PURE__ */ jsx28("p", { className: "mt-1 text-foreground/70", children: "The interface reloaded successfully, but routes and tools were wired at boot. Restart the workspace process to pick up the new code." })
|
|
7891
8091
|
]
|
|
7892
8092
|
}
|
|
7893
8093
|
) : null
|
|
@@ -7895,7 +8095,7 @@ function PluginUpdateStatus({
|
|
|
7895
8095
|
}
|
|
7896
8096
|
);
|
|
7897
8097
|
}
|
|
7898
|
-
return /* @__PURE__ */
|
|
8098
|
+
return /* @__PURE__ */ jsx28(
|
|
7899
8099
|
ComposerStatusBanner,
|
|
7900
8100
|
{
|
|
7901
8101
|
tone: "error",
|
|
@@ -7912,15 +8112,15 @@ function PluginUpdateStatus({
|
|
|
7912
8112
|
}
|
|
7913
8113
|
|
|
7914
8114
|
// src/front/composer/CommandRunStatus.tsx
|
|
7915
|
-
import { useEffect as useEffect16, useRef as
|
|
7916
|
-
import { Fragment as
|
|
8115
|
+
import { useEffect as useEffect16, useRef as useRef13 } from "react";
|
|
8116
|
+
import { Fragment as Fragment9, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
7917
8117
|
function CommandRunStatus({
|
|
7918
8118
|
state,
|
|
7919
8119
|
onDismiss,
|
|
7920
8120
|
successAutoDismissMs = 1400,
|
|
7921
8121
|
maxWidthClassName = "max-w-3xl"
|
|
7922
8122
|
}) {
|
|
7923
|
-
const onDismissRef =
|
|
8123
|
+
const onDismissRef = useRef13(onDismiss);
|
|
7924
8124
|
useEffect16(() => {
|
|
7925
8125
|
onDismissRef.current = onDismiss;
|
|
7926
8126
|
}, [onDismiss]);
|
|
@@ -7932,13 +8132,13 @@ function CommandRunStatus({
|
|
|
7932
8132
|
}, [state?.kind, successKey, successAutoDismissMs]);
|
|
7933
8133
|
if (!state) return null;
|
|
7934
8134
|
if (state.kind === "running") {
|
|
7935
|
-
return /* @__PURE__ */
|
|
8135
|
+
return /* @__PURE__ */ jsx29(
|
|
7936
8136
|
ComposerStatusBanner,
|
|
7937
8137
|
{
|
|
7938
8138
|
tone: "running",
|
|
7939
8139
|
dataAttribute: "data-boring-command-run",
|
|
7940
8140
|
maxWidthClassName,
|
|
7941
|
-
runningContent: state.command ? /* @__PURE__ */ jsxs24(
|
|
8141
|
+
runningContent: state.command ? /* @__PURE__ */ jsxs24(Fragment9, { children: [
|
|
7942
8142
|
" Running ",
|
|
7943
8143
|
/* @__PURE__ */ jsxs24("code", { className: "font-mono", children: [
|
|
7944
8144
|
"/",
|
|
@@ -7950,13 +8150,13 @@ function CommandRunStatus({
|
|
|
7950
8150
|
);
|
|
7951
8151
|
}
|
|
7952
8152
|
if (state.kind === "success") {
|
|
7953
|
-
return /* @__PURE__ */
|
|
8153
|
+
return /* @__PURE__ */ jsx29(
|
|
7954
8154
|
ComposerStatusBanner,
|
|
7955
8155
|
{
|
|
7956
8156
|
tone: "success",
|
|
7957
8157
|
dataAttribute: "data-boring-command-run",
|
|
7958
8158
|
maxWidthClassName,
|
|
7959
|
-
title: state.command ? /* @__PURE__ */ jsxs24(
|
|
8159
|
+
title: state.command ? /* @__PURE__ */ jsxs24(Fragment9, { children: [
|
|
7960
8160
|
" Ran ",
|
|
7961
8161
|
/* @__PURE__ */ jsxs24("code", { className: "font-mono", children: [
|
|
7962
8162
|
"/",
|
|
@@ -7970,13 +8170,13 @@ function CommandRunStatus({
|
|
|
7970
8170
|
}
|
|
7971
8171
|
);
|
|
7972
8172
|
}
|
|
7973
|
-
return /* @__PURE__ */
|
|
8173
|
+
return /* @__PURE__ */ jsx29(
|
|
7974
8174
|
ComposerStatusBanner,
|
|
7975
8175
|
{
|
|
7976
8176
|
tone: "error",
|
|
7977
8177
|
dataAttribute: "data-boring-command-run",
|
|
7978
8178
|
maxWidthClassName,
|
|
7979
|
-
title: state.command ? /* @__PURE__ */ jsxs24(
|
|
8179
|
+
title: state.command ? /* @__PURE__ */ jsxs24(Fragment9, { children: [
|
|
7980
8180
|
" ",
|
|
7981
8181
|
/* @__PURE__ */ jsxs24("code", { className: "font-mono", children: [
|
|
7982
8182
|
"/",
|
|
@@ -7992,7 +8192,7 @@ function CommandRunStatus({
|
|
|
7992
8192
|
}
|
|
7993
8193
|
|
|
7994
8194
|
// src/front/chatPanelComposerControls.tsx
|
|
7995
|
-
import { forwardRef, useEffect as useEffect17, useRef as
|
|
8195
|
+
import { forwardRef, useEffect as useEffect17, useRef as useRef14, useState as useState16 } from "react";
|
|
7996
8196
|
import { CheckIcon as CheckIcon3, ChevronDownIcon as ChevronDownIcon5 } from "lucide-react";
|
|
7997
8197
|
import {
|
|
7998
8198
|
Command,
|
|
@@ -8026,7 +8226,7 @@ function displayProviderLabel(provider) {
|
|
|
8026
8226
|
}
|
|
8027
8227
|
|
|
8028
8228
|
// src/front/chatPanelComposerControls.tsx
|
|
8029
|
-
import { Fragment as
|
|
8229
|
+
import { Fragment as Fragment10, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
8030
8230
|
var composerActionClass = cn(
|
|
8031
8231
|
"inline-flex h-8 items-center justify-center gap-1.5 rounded-[var(--radius-md)] border-0 bg-transparent",
|
|
8032
8232
|
"text-muted-foreground shadow-none transition",
|
|
@@ -8094,7 +8294,7 @@ function useDismissOnOutsidePointer(ref, onClose) {
|
|
|
8094
8294
|
}
|
|
8095
8295
|
function ThinkingLevelGlyph({ level }) {
|
|
8096
8296
|
const lit = level === "off" ? 0 : level === "low" ? 1 : level === "medium" ? 2 : 3;
|
|
8097
|
-
return /* @__PURE__ */
|
|
8297
|
+
return /* @__PURE__ */ jsx30(
|
|
8098
8298
|
"svg",
|
|
8099
8299
|
{
|
|
8100
8300
|
"aria-hidden": "true",
|
|
@@ -8103,7 +8303,7 @@ function ThinkingLevelGlyph({ level }) {
|
|
|
8103
8303
|
viewBox: "0 0 14 14",
|
|
8104
8304
|
fill: "none",
|
|
8105
8305
|
className: "shrink-0",
|
|
8106
|
-
children: [0, 1, 2].map((i) => /* @__PURE__ */
|
|
8306
|
+
children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx30(
|
|
8107
8307
|
"rect",
|
|
8108
8308
|
{
|
|
8109
8309
|
x: 2 + i * 4,
|
|
@@ -8149,7 +8349,7 @@ var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
|
|
|
8149
8349
|
}, ref) {
|
|
8150
8350
|
const triggerLabel = modelTriggerLabel(value, options, emptyLabel);
|
|
8151
8351
|
const triggerDisplay = value ? `${triggerLabel} (${displayProviderLabel(value.provider)})` : triggerLabel;
|
|
8152
|
-
return /* @__PURE__ */
|
|
8352
|
+
return /* @__PURE__ */ jsx30(
|
|
8153
8353
|
"button",
|
|
8154
8354
|
{
|
|
8155
8355
|
ref,
|
|
@@ -8167,12 +8367,12 @@ var ModelSelectTrigger = forwardRef(function ModelSelectTrigger2({
|
|
|
8167
8367
|
className
|
|
8168
8368
|
),
|
|
8169
8369
|
...props,
|
|
8170
|
-
children: trigger === "slash" ? /* @__PURE__ */ jsxs25(
|
|
8171
|
-
/* @__PURE__ */
|
|
8172
|
-
/* @__PURE__ */
|
|
8173
|
-
] }) : /* @__PURE__ */ jsxs25(
|
|
8174
|
-
/* @__PURE__ */
|
|
8175
|
-
/* @__PURE__ */
|
|
8370
|
+
children: trigger === "slash" ? /* @__PURE__ */ jsxs25(Fragment10, { children: [
|
|
8371
|
+
/* @__PURE__ */ jsx30("span", { className: "text-muted-foreground", children: "/model: " }),
|
|
8372
|
+
/* @__PURE__ */ jsx30("span", { className: "text-foreground", children: triggerDisplay })
|
|
8373
|
+
] }) : /* @__PURE__ */ jsxs25(Fragment10, { children: [
|
|
8374
|
+
/* @__PURE__ */ jsx30("span", { className: "min-w-0 truncate", children: triggerDisplay }),
|
|
8375
|
+
/* @__PURE__ */ jsx30(ChevronDownIcon5, { className: "h-3 w-3 shrink-0 text-muted-foreground/50", "aria-hidden": "true" })
|
|
8176
8376
|
] })
|
|
8177
8377
|
}
|
|
8178
8378
|
);
|
|
@@ -8193,8 +8393,8 @@ function ModelPickerMenu({
|
|
|
8193
8393
|
const keyboardOptions = hideDefaultOption ? groupedOptions : [null, ...groupedOptions];
|
|
8194
8394
|
const selectedIndex = currentKey ? Math.max(0, keyboardOptions.findIndex((option) => option && encodeModelKey(option) === currentKey)) : 0;
|
|
8195
8395
|
const [activeIndex, setActiveIndex] = useState16(selectedIndex);
|
|
8196
|
-
const activeIndexRef =
|
|
8197
|
-
const menuRef =
|
|
8396
|
+
const activeIndexRef = useRef14(selectedIndex);
|
|
8397
|
+
const menuRef = useRef14(null);
|
|
8198
8398
|
useDismissOnOutsidePointer(menuRef, onClose);
|
|
8199
8399
|
const setKeyboardActiveIndex = (next) => {
|
|
8200
8400
|
const resolved = typeof next === "function" ? next(activeIndexRef.current) : next;
|
|
@@ -8229,8 +8429,8 @@ function ModelPickerMenu({
|
|
|
8229
8429
|
}, [activeIndex, disabled, keyboardOptions, onChange, onClose]);
|
|
8230
8430
|
const optionIndexOffset = hideDefaultOption ? 0 : 1;
|
|
8231
8431
|
const optionIndexes = new Map(groupedOptions.map((option, index) => [encodeModelKey(option), index + optionIndexOffset]));
|
|
8232
|
-
return /* @__PURE__ */
|
|
8233
|
-
menuOptions.length > 8 && /* @__PURE__ */
|
|
8432
|
+
return /* @__PURE__ */ jsx30("div", { ref: menuRef, "data-boring-agent": "", "data-boring-agent-part": "model-picker-menu", className: cn(composerPickerMenuClass, className), children: /* @__PURE__ */ jsxs25(Command, { className: "bg-transparent text-[color:var(--popover-foreground)]", children: [
|
|
8433
|
+
menuOptions.length > 8 && /* @__PURE__ */ jsx30("div", { className: "border-b border-border/60 px-2", children: /* @__PURE__ */ jsx30(
|
|
8234
8434
|
CommandInput,
|
|
8235
8435
|
{
|
|
8236
8436
|
placeholder: "Search models\u2026",
|
|
@@ -8239,8 +8439,8 @@ function ModelPickerMenu({
|
|
|
8239
8439
|
}
|
|
8240
8440
|
) }),
|
|
8241
8441
|
/* @__PURE__ */ jsxs25(CommandList, { className: "max-h-[300px] p-0.5", children: [
|
|
8242
|
-
/* @__PURE__ */
|
|
8243
|
-
!hideDefaultOption ? /* @__PURE__ */
|
|
8442
|
+
/* @__PURE__ */ jsx30(CommandEmpty, { className: "py-4 text-center text-[13px] text-muted-foreground", children: "No models found" }),
|
|
8443
|
+
!hideDefaultOption ? /* @__PURE__ */ jsx30(CommandGroup, { children: /* @__PURE__ */ jsxs25(
|
|
8244
8444
|
CommandItem,
|
|
8245
8445
|
{
|
|
8246
8446
|
value: "Default model automatic auto",
|
|
@@ -8251,7 +8451,7 @@ function ModelPickerMenu({
|
|
|
8251
8451
|
},
|
|
8252
8452
|
className: selectorItemClass(!value || activeIndex === 0),
|
|
8253
8453
|
children: [
|
|
8254
|
-
/* @__PURE__ */
|
|
8454
|
+
/* @__PURE__ */ jsx30(
|
|
8255
8455
|
CheckIcon3,
|
|
8256
8456
|
{
|
|
8257
8457
|
className: cn(
|
|
@@ -8260,12 +8460,12 @@ function ModelPickerMenu({
|
|
|
8260
8460
|
)
|
|
8261
8461
|
}
|
|
8262
8462
|
),
|
|
8263
|
-
/* @__PURE__ */
|
|
8264
|
-
/* @__PURE__ */
|
|
8463
|
+
/* @__PURE__ */ jsx30("span", { className: "truncate", children: "Default model" }),
|
|
8464
|
+
/* @__PURE__ */ jsx30("span", { className: "ml-auto shrink-0 text-[10px] text-muted-foreground/60", children: "auto" })
|
|
8265
8465
|
]
|
|
8266
8466
|
}
|
|
8267
8467
|
) }) : null,
|
|
8268
|
-
[...groups.entries()].map(([provider, list]) => /* @__PURE__ */
|
|
8468
|
+
[...groups.entries()].map(([provider, list]) => /* @__PURE__ */ jsx30(
|
|
8269
8469
|
CommandGroup,
|
|
8270
8470
|
{
|
|
8271
8471
|
heading: displayProviderLabel(provider),
|
|
@@ -8285,7 +8485,7 @@ function ModelPickerMenu({
|
|
|
8285
8485
|
},
|
|
8286
8486
|
className: cn(selectorItemClass(key === currentKey || activeIndex === itemIndex)),
|
|
8287
8487
|
children: [
|
|
8288
|
-
/* @__PURE__ */
|
|
8488
|
+
/* @__PURE__ */ jsx30(
|
|
8289
8489
|
CheckIcon3,
|
|
8290
8490
|
{
|
|
8291
8491
|
className: cn(
|
|
@@ -8294,8 +8494,8 @@ function ModelPickerMenu({
|
|
|
8294
8494
|
)
|
|
8295
8495
|
}
|
|
8296
8496
|
),
|
|
8297
|
-
/* @__PURE__ */
|
|
8298
|
-
/* @__PURE__ */
|
|
8497
|
+
/* @__PURE__ */ jsx30("span", { className: "min-w-0 flex-1 truncate whitespace-nowrap", children: label }),
|
|
8498
|
+
/* @__PURE__ */ jsx30("span", { className: "ml-auto max-w-[45%] shrink-0 truncate whitespace-nowrap text-right text-[10px] text-muted-foreground/60", children: m.id })
|
|
8299
8499
|
]
|
|
8300
8500
|
},
|
|
8301
8501
|
key
|
|
@@ -8321,7 +8521,7 @@ function ModelSelect({
|
|
|
8321
8521
|
hideDefaultOption = false
|
|
8322
8522
|
}) {
|
|
8323
8523
|
const [open, setOpen] = useState16(false);
|
|
8324
|
-
const previousOpenSignalRef =
|
|
8524
|
+
const previousOpenSignalRef = useRef14(openSignal);
|
|
8325
8525
|
useEffect17(() => {
|
|
8326
8526
|
if (disabled) setOpen(false);
|
|
8327
8527
|
}, [disabled]);
|
|
@@ -8334,7 +8534,7 @@ function ModelSelect({
|
|
|
8334
8534
|
previousOpenSignalRef.current = openSignal;
|
|
8335
8535
|
}, [disabled, openSignal]);
|
|
8336
8536
|
return /* @__PURE__ */ jsxs25(Popover, { open, onOpenChange: disabled ? void 0 : setOpen, children: [
|
|
8337
|
-
/* @__PURE__ */
|
|
8537
|
+
/* @__PURE__ */ jsx30(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx30(
|
|
8338
8538
|
ModelSelectTrigger,
|
|
8339
8539
|
{
|
|
8340
8540
|
value,
|
|
@@ -8348,7 +8548,7 @@ function ModelSelect({
|
|
|
8348
8548
|
"aria-describedby": ariaDescribedBy
|
|
8349
8549
|
}
|
|
8350
8550
|
) }),
|
|
8351
|
-
/* @__PURE__ */
|
|
8551
|
+
/* @__PURE__ */ jsx30(
|
|
8352
8552
|
PopoverContent,
|
|
8353
8553
|
{
|
|
8354
8554
|
align: trigger === "slash" ? "center" : "start",
|
|
@@ -8357,7 +8557,7 @@ function ModelSelect({
|
|
|
8357
8557
|
collisionPadding: 12,
|
|
8358
8558
|
"data-boring-agent": "",
|
|
8359
8559
|
className: cn("w-[min(92vw,340px)]", selectorContentClass),
|
|
8360
|
-
children: /* @__PURE__ */
|
|
8560
|
+
children: /* @__PURE__ */ jsx30(
|
|
8361
8561
|
ModelPickerMenu,
|
|
8362
8562
|
{
|
|
8363
8563
|
value,
|
|
@@ -8382,7 +8582,7 @@ function ThinkingSelect({
|
|
|
8382
8582
|
className
|
|
8383
8583
|
}) {
|
|
8384
8584
|
const [open, setOpen] = useState16(false);
|
|
8385
|
-
const previousOpenSignalRef =
|
|
8585
|
+
const previousOpenSignalRef = useRef14(openSignal);
|
|
8386
8586
|
useEffect17(() => {
|
|
8387
8587
|
if (disabled) setOpen(false);
|
|
8388
8588
|
}, [disabled]);
|
|
@@ -8395,7 +8595,7 @@ function ThinkingSelect({
|
|
|
8395
8595
|
previousOpenSignalRef.current = openSignal;
|
|
8396
8596
|
}, [disabled, openSignal]);
|
|
8397
8597
|
return /* @__PURE__ */ jsxs25(Popover, { open, onOpenChange: disabled ? void 0 : setOpen, children: [
|
|
8398
|
-
/* @__PURE__ */
|
|
8598
|
+
/* @__PURE__ */ jsx30(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx30(
|
|
8399
8599
|
ThinkingSelectTrigger,
|
|
8400
8600
|
{
|
|
8401
8601
|
value,
|
|
@@ -8405,7 +8605,7 @@ function ThinkingSelect({
|
|
|
8405
8605
|
className
|
|
8406
8606
|
}
|
|
8407
8607
|
) }),
|
|
8408
|
-
/* @__PURE__ */
|
|
8608
|
+
/* @__PURE__ */ jsx30(
|
|
8409
8609
|
PopoverContent,
|
|
8410
8610
|
{
|
|
8411
8611
|
align: trigger === "slash" ? "center" : "end",
|
|
@@ -8414,7 +8614,7 @@ function ThinkingSelect({
|
|
|
8414
8614
|
collisionPadding: 12,
|
|
8415
8615
|
"data-boring-agent": "",
|
|
8416
8616
|
className: cn("w-[min(92vw,240px)]", selectorContentClass),
|
|
8417
|
-
children: /* @__PURE__ */
|
|
8617
|
+
children: /* @__PURE__ */ jsx30(
|
|
8418
8618
|
ThinkingPickerMenu,
|
|
8419
8619
|
{
|
|
8420
8620
|
value,
|
|
@@ -8458,13 +8658,13 @@ var ThinkingSelectTrigger = forwardRef(function ThinkingSelectTrigger2({
|
|
|
8458
8658
|
onClick,
|
|
8459
8659
|
...props,
|
|
8460
8660
|
children: [
|
|
8461
|
-
trigger === "button" ? /* @__PURE__ */
|
|
8462
|
-
trigger === "slash" ? /* @__PURE__ */ jsxs25(
|
|
8463
|
-
/* @__PURE__ */
|
|
8464
|
-
/* @__PURE__ */
|
|
8465
|
-
] }) : /* @__PURE__ */ jsxs25(
|
|
8466
|
-
/* @__PURE__ */
|
|
8467
|
-
/* @__PURE__ */
|
|
8661
|
+
trigger === "button" ? /* @__PURE__ */ jsx30(ThinkingLevelGlyph, { level: value }) : null,
|
|
8662
|
+
trigger === "slash" ? /* @__PURE__ */ jsxs25(Fragment10, { children: [
|
|
8663
|
+
/* @__PURE__ */ jsx30("span", { className: "text-muted-foreground", children: "/thinking: " }),
|
|
8664
|
+
/* @__PURE__ */ jsx30("span", { className: "text-foreground", children: THINKING_LEVEL_STATUS_LABELS[value] })
|
|
8665
|
+
] }) : /* @__PURE__ */ jsxs25(Fragment10, { children: [
|
|
8666
|
+
/* @__PURE__ */ jsx30("span", { children: THINKING_LEVEL_LABELS[value] }),
|
|
8667
|
+
/* @__PURE__ */ jsx30(ChevronDownIcon5, { className: "h-3 w-3 shrink-0 text-muted-foreground/50", "aria-hidden": "true" })
|
|
8468
8668
|
] })
|
|
8469
8669
|
]
|
|
8470
8670
|
}
|
|
@@ -8479,8 +8679,8 @@ function ThinkingPickerMenu({
|
|
|
8479
8679
|
}) {
|
|
8480
8680
|
const selectedIndex = Math.max(0, THINKING_LEVELS.indexOf(value));
|
|
8481
8681
|
const [activeIndex, setActiveIndex] = useState16(selectedIndex);
|
|
8482
|
-
const activeIndexRef =
|
|
8483
|
-
const menuRef =
|
|
8682
|
+
const activeIndexRef = useRef14(selectedIndex);
|
|
8683
|
+
const menuRef = useRef14(null);
|
|
8484
8684
|
useDismissOnOutsidePointer(menuRef, onClose);
|
|
8485
8685
|
const setKeyboardActiveIndex = (next) => {
|
|
8486
8686
|
const resolved = typeof next === "function" ? next(activeIndexRef.current) : next;
|
|
@@ -8513,7 +8713,7 @@ function ThinkingPickerMenu({
|
|
|
8513
8713
|
window.addEventListener("keydown", handler, { capture: true });
|
|
8514
8714
|
return () => window.removeEventListener("keydown", handler, { capture: true });
|
|
8515
8715
|
}, [activeIndex, disabled, onChange, onClose]);
|
|
8516
|
-
return /* @__PURE__ */
|
|
8716
|
+
return /* @__PURE__ */ jsx30("div", { ref: menuRef, "data-boring-agent": "", "data-boring-agent-part": "thinking-picker-menu", className: cn(composerPickerMenuClass, className), children: /* @__PURE__ */ jsx30(Command, { className: "bg-transparent text-[color:var(--popover-foreground)]", children: /* @__PURE__ */ jsx30(CommandList, { className: "max-h-[300px] p-0.5", children: THINKING_LEVELS.map((level, index) => /* @__PURE__ */ jsxs25(
|
|
8517
8717
|
CommandItem,
|
|
8518
8718
|
{
|
|
8519
8719
|
value: `Thinking ${THINKING_LEVEL_LABELS[level]} ${THINKING_LEVEL_DETAILS[level]}`,
|
|
@@ -8524,7 +8724,7 @@ function ThinkingPickerMenu({
|
|
|
8524
8724
|
},
|
|
8525
8725
|
className: selectorItemClass(level === value || index === activeIndex),
|
|
8526
8726
|
children: [
|
|
8527
|
-
/* @__PURE__ */
|
|
8727
|
+
/* @__PURE__ */ jsx30(
|
|
8528
8728
|
CheckIcon3,
|
|
8529
8729
|
{
|
|
8530
8730
|
className: cn(
|
|
@@ -8533,9 +8733,9 @@ function ThinkingPickerMenu({
|
|
|
8533
8733
|
)
|
|
8534
8734
|
}
|
|
8535
8735
|
),
|
|
8536
|
-
/* @__PURE__ */
|
|
8537
|
-
/* @__PURE__ */
|
|
8538
|
-
/* @__PURE__ */
|
|
8736
|
+
/* @__PURE__ */ jsx30(ThinkingLevelGlyph, { level }),
|
|
8737
|
+
/* @__PURE__ */ jsx30("span", { className: "font-medium", children: THINKING_LEVEL_LABELS[level] }),
|
|
8738
|
+
/* @__PURE__ */ jsx30("span", { className: "ml-auto text-[11px] text-muted-foreground/65", children: THINKING_LEVEL_DETAILS[level] })
|
|
8539
8739
|
]
|
|
8540
8740
|
},
|
|
8541
8741
|
level
|
|
@@ -8576,22 +8776,22 @@ import {
|
|
|
8576
8776
|
XIcon as XIcon5
|
|
8577
8777
|
} from "lucide-react";
|
|
8578
8778
|
import { nanoid } from "nanoid";
|
|
8579
|
-
import { useCallback as useCallback15, useEffect as useEffect18, useMemo as
|
|
8779
|
+
import { useCallback as useCallback15, useEffect as useEffect18, useMemo as useMemo13, useRef as useRef15, useState as useState17 } from "react";
|
|
8580
8780
|
|
|
8581
8781
|
// src/front/primitives/prompt-input-context.ts
|
|
8582
|
-
import { createContext as
|
|
8583
|
-
var PromptInputController =
|
|
8782
|
+
import { createContext as createContext8, useContext as useContext8 } from "react";
|
|
8783
|
+
var PromptInputController = createContext8(
|
|
8584
8784
|
null
|
|
8585
8785
|
);
|
|
8586
|
-
var ProviderAttachmentsContext =
|
|
8786
|
+
var ProviderAttachmentsContext = createContext8(
|
|
8587
8787
|
null
|
|
8588
8788
|
);
|
|
8589
|
-
var useOptionalPromptInputController = () =>
|
|
8590
|
-
var useOptionalProviderAttachments = () =>
|
|
8591
|
-
var LocalAttachmentsContext =
|
|
8789
|
+
var useOptionalPromptInputController = () => useContext8(PromptInputController);
|
|
8790
|
+
var useOptionalProviderAttachments = () => useContext8(ProviderAttachmentsContext);
|
|
8791
|
+
var LocalAttachmentsContext = createContext8(null);
|
|
8592
8792
|
var usePromptInputAttachments = () => {
|
|
8593
8793
|
const provider = useOptionalProviderAttachments();
|
|
8594
|
-
const local =
|
|
8794
|
+
const local = useContext8(LocalAttachmentsContext);
|
|
8595
8795
|
const context = local ?? provider;
|
|
8596
8796
|
if (!context) {
|
|
8597
8797
|
throw new Error(
|
|
@@ -8600,7 +8800,7 @@ var usePromptInputAttachments = () => {
|
|
|
8600
8800
|
}
|
|
8601
8801
|
return context;
|
|
8602
8802
|
};
|
|
8603
|
-
var LocalReferencedSourcesContext =
|
|
8803
|
+
var LocalReferencedSourcesContext = createContext8(null);
|
|
8604
8804
|
|
|
8605
8805
|
// src/front/primitives/prompt-input-wrappers.tsx
|
|
8606
8806
|
import {
|
|
@@ -8610,13 +8810,13 @@ import {
|
|
|
8610
8810
|
TooltipContent as TooltipContent3,
|
|
8611
8811
|
TooltipTrigger as TooltipTrigger3
|
|
8612
8812
|
} from "@hachej/boring-ui-kit";
|
|
8613
|
-
import { Children } from "react";
|
|
8614
|
-
import { jsx as
|
|
8813
|
+
import { Children as Children2 } from "react";
|
|
8814
|
+
import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
8615
8815
|
var PromptInputFooter = ({
|
|
8616
8816
|
align = "block-end",
|
|
8617
8817
|
className,
|
|
8618
8818
|
...props
|
|
8619
|
-
}) => /* @__PURE__ */
|
|
8819
|
+
}) => /* @__PURE__ */ jsx31(
|
|
8620
8820
|
InputGroupAddon,
|
|
8621
8821
|
{
|
|
8622
8822
|
align,
|
|
@@ -8626,7 +8826,7 @@ var PromptInputFooter = ({
|
|
|
8626
8826
|
);
|
|
8627
8827
|
|
|
8628
8828
|
// src/front/primitives/prompt-input.tsx
|
|
8629
|
-
import { Fragment as
|
|
8829
|
+
import { Fragment as Fragment11, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
8630
8830
|
var PromptInput = ({
|
|
8631
8831
|
className,
|
|
8632
8832
|
accept,
|
|
@@ -8643,12 +8843,12 @@ var PromptInput = ({
|
|
|
8643
8843
|
}) => {
|
|
8644
8844
|
const controller = useOptionalPromptInputController();
|
|
8645
8845
|
const usingProvider = !!controller;
|
|
8646
|
-
const providerTextValueRef =
|
|
8846
|
+
const providerTextValueRef = useRef15("");
|
|
8647
8847
|
if (usingProvider) {
|
|
8648
8848
|
providerTextValueRef.current = controller.textInput.value;
|
|
8649
8849
|
}
|
|
8650
|
-
const inputRef =
|
|
8651
|
-
const formRef =
|
|
8850
|
+
const inputRef = useRef15(null);
|
|
8851
|
+
const formRef = useRef15(null);
|
|
8652
8852
|
const [items, setItems] = useState17([]);
|
|
8653
8853
|
const setFileUrlLocal = useCallback15((id, url, status, path) => {
|
|
8654
8854
|
setItems((prev) => prev.map((f) => {
|
|
@@ -8659,7 +8859,7 @@ var PromptInput = ({
|
|
|
8659
8859
|
}, []);
|
|
8660
8860
|
const files = usingProvider ? controller.attachments.files : items;
|
|
8661
8861
|
const [referencedSources, setReferencedSources] = useState17([]);
|
|
8662
|
-
const filesRef =
|
|
8862
|
+
const filesRef = useRef15(files);
|
|
8663
8863
|
useEffect18(() => {
|
|
8664
8864
|
filesRef.current = files;
|
|
8665
8865
|
}, [files]);
|
|
@@ -8881,7 +9081,7 @@ var PromptInput = ({
|
|
|
8881
9081
|
[add]
|
|
8882
9082
|
);
|
|
8883
9083
|
const setFileUrl = usingProvider ? controller.attachments.setFileUrl : setFileUrlLocal;
|
|
8884
|
-
const attachmentsCtx =
|
|
9084
|
+
const attachmentsCtx = useMemo13(
|
|
8885
9085
|
() => ({
|
|
8886
9086
|
add,
|
|
8887
9087
|
clear: clearAttachments,
|
|
@@ -8893,7 +9093,7 @@ var PromptInput = ({
|
|
|
8893
9093
|
}),
|
|
8894
9094
|
[files, add, remove, clearAttachments, openFileDialog, setFileUrl]
|
|
8895
9095
|
);
|
|
8896
|
-
const refsCtx =
|
|
9096
|
+
const refsCtx = useMemo13(
|
|
8897
9097
|
() => ({
|
|
8898
9098
|
add: (incoming) => {
|
|
8899
9099
|
const array = Array.isArray(incoming) ? incoming : [incoming];
|
|
@@ -8969,8 +9169,8 @@ var PromptInput = ({
|
|
|
8969
9169
|
},
|
|
8970
9170
|
[usingProvider, controller, files, onSubmit, clear]
|
|
8971
9171
|
);
|
|
8972
|
-
const inner = /* @__PURE__ */ jsxs27(
|
|
8973
|
-
/* @__PURE__ */
|
|
9172
|
+
const inner = /* @__PURE__ */ jsxs27(Fragment11, { children: [
|
|
9173
|
+
/* @__PURE__ */ jsx32(
|
|
8974
9174
|
Input,
|
|
8975
9175
|
{
|
|
8976
9176
|
accept,
|
|
@@ -8983,7 +9183,7 @@ var PromptInput = ({
|
|
|
8983
9183
|
type: "file"
|
|
8984
9184
|
}
|
|
8985
9185
|
),
|
|
8986
|
-
/* @__PURE__ */
|
|
9186
|
+
/* @__PURE__ */ jsx32(
|
|
8987
9187
|
"form",
|
|
8988
9188
|
{
|
|
8989
9189
|
"data-boring-agent-part": "composer",
|
|
@@ -8991,12 +9191,12 @@ var PromptInput = ({
|
|
|
8991
9191
|
onSubmit: handleSubmit,
|
|
8992
9192
|
ref: formRef,
|
|
8993
9193
|
...props,
|
|
8994
|
-
children: /* @__PURE__ */
|
|
9194
|
+
children: /* @__PURE__ */ jsx32(InputGroup, { className: "overflow-hidden", children })
|
|
8995
9195
|
}
|
|
8996
9196
|
)
|
|
8997
9197
|
] });
|
|
8998
|
-
const withReferencedSources = /* @__PURE__ */
|
|
8999
|
-
return /* @__PURE__ */
|
|
9198
|
+
const withReferencedSources = /* @__PURE__ */ jsx32(LocalReferencedSourcesContext.Provider, { value: refsCtx, children: inner });
|
|
9199
|
+
return /* @__PURE__ */ jsx32(LocalAttachmentsContext.Provider, { value: attachmentsCtx, children: withReferencedSources });
|
|
9000
9200
|
};
|
|
9001
9201
|
var PromptInputTextarea = ({
|
|
9002
9202
|
onChange,
|
|
@@ -9074,7 +9274,7 @@ var PromptInputTextarea = ({
|
|
|
9074
9274
|
} : {
|
|
9075
9275
|
onChange
|
|
9076
9276
|
};
|
|
9077
|
-
return /* @__PURE__ */
|
|
9277
|
+
return /* @__PURE__ */ jsx32(
|
|
9078
9278
|
InputGroupTextarea,
|
|
9079
9279
|
{
|
|
9080
9280
|
"data-boring-agent-part": "composer-input",
|
|
@@ -9101,13 +9301,13 @@ var PromptInputSubmit = ({
|
|
|
9101
9301
|
...props
|
|
9102
9302
|
}) => {
|
|
9103
9303
|
const isGenerating = status === "submitted" || status === "streaming";
|
|
9104
|
-
let Icon = /* @__PURE__ */
|
|
9304
|
+
let Icon = /* @__PURE__ */ jsx32(CornerDownLeftIcon, { className: "size-4" });
|
|
9105
9305
|
if (status === "submitted") {
|
|
9106
|
-
Icon = /* @__PURE__ */
|
|
9306
|
+
Icon = /* @__PURE__ */ jsx32(Spinner, {});
|
|
9107
9307
|
} else if (status === "streaming") {
|
|
9108
|
-
Icon = /* @__PURE__ */
|
|
9308
|
+
Icon = /* @__PURE__ */ jsx32(SquareIcon, { className: "size-4" });
|
|
9109
9309
|
} else if (status === "error") {
|
|
9110
|
-
Icon = /* @__PURE__ */
|
|
9310
|
+
Icon = /* @__PURE__ */ jsx32(XIcon5, { className: "size-4" });
|
|
9111
9311
|
}
|
|
9112
9312
|
const handleClick = useCallback15(
|
|
9113
9313
|
(e) => {
|
|
@@ -9120,7 +9320,7 @@ var PromptInputSubmit = ({
|
|
|
9120
9320
|
},
|
|
9121
9321
|
[isGenerating, onStop, onClick]
|
|
9122
9322
|
);
|
|
9123
|
-
return /* @__PURE__ */
|
|
9323
|
+
return /* @__PURE__ */ jsx32(
|
|
9124
9324
|
InputGroupButton2,
|
|
9125
9325
|
{
|
|
9126
9326
|
"aria-label": isGenerating ? "Stop" : "Submit",
|
|
@@ -9137,8 +9337,8 @@ var PromptInputSubmit = ({
|
|
|
9137
9337
|
};
|
|
9138
9338
|
|
|
9139
9339
|
// src/front/primitives/slash-command-picker.tsx
|
|
9140
|
-
import { useEffect as useEffect19, useMemo as
|
|
9141
|
-
import { Fragment as
|
|
9340
|
+
import { useEffect as useEffect19, useMemo as useMemo14, useRef as useRef16, useState as useState18 } from "react";
|
|
9341
|
+
import { Fragment as Fragment12, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
9142
9342
|
var ALL_PLUGINS = "__all__";
|
|
9143
9343
|
function commandGroup(cmd) {
|
|
9144
9344
|
if (cmd.source === "skill") return "skills";
|
|
@@ -9149,17 +9349,17 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
|
|
|
9149
9349
|
const [plugin, setPlugin] = useState18(ALL_PLUGINS);
|
|
9150
9350
|
const [searchQuery, setSearchQuery] = useState18(query);
|
|
9151
9351
|
const [activeIdx, setActiveIdx] = useState18(0);
|
|
9152
|
-
const containerRef =
|
|
9153
|
-
const listRef =
|
|
9154
|
-
const inputRef =
|
|
9352
|
+
const containerRef = useRef16(null);
|
|
9353
|
+
const listRef = useRef16(null);
|
|
9354
|
+
const inputRef = useRef16(null);
|
|
9155
9355
|
useEffect19(() => {
|
|
9156
9356
|
setSearchQuery(query);
|
|
9157
9357
|
}, [query]);
|
|
9158
|
-
const groups =
|
|
9358
|
+
const groups = useMemo14(() => {
|
|
9159
9359
|
const set = new Set(commands.map(commandGroup));
|
|
9160
9360
|
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
9161
9361
|
}, [commands]);
|
|
9162
|
-
const filtered =
|
|
9362
|
+
const filtered = useMemo14(() => {
|
|
9163
9363
|
const q = searchQuery.trim().toLowerCase();
|
|
9164
9364
|
return commands.filter((c) => {
|
|
9165
9365
|
if (plugin !== ALL_PLUGINS && commandGroup(c) !== plugin) return false;
|
|
@@ -9190,7 +9390,7 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
|
|
|
9190
9390
|
onDismiss
|
|
9191
9391
|
});
|
|
9192
9392
|
return /* @__PURE__ */ jsxs28("div", { ref: containerRef, className: "mb-1 w-full overflow-hidden rounded-lg border border-border/60 bg-popover shadow-lg", children: [
|
|
9193
|
-
/* @__PURE__ */
|
|
9393
|
+
/* @__PURE__ */ jsx33(
|
|
9194
9394
|
"input",
|
|
9195
9395
|
{
|
|
9196
9396
|
ref: inputRef,
|
|
@@ -9205,9 +9405,9 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
|
|
|
9205
9405
|
autoComplete: "off"
|
|
9206
9406
|
}
|
|
9207
9407
|
),
|
|
9208
|
-
/* @__PURE__ */
|
|
9408
|
+
/* @__PURE__ */ jsx33("div", { className: "flex flex-wrap gap-1 border-b border-border/50 px-2 py-1.5", role: "tablist", "aria-label": "Filter by plugin", children: [ALL_PLUGINS, ...groups].map((g) => {
|
|
9209
9409
|
const selected = plugin === g;
|
|
9210
|
-
return /* @__PURE__ */
|
|
9410
|
+
return /* @__PURE__ */ jsx33(
|
|
9211
9411
|
"button",
|
|
9212
9412
|
{
|
|
9213
9413
|
type: "button",
|
|
@@ -9227,7 +9427,7 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
|
|
|
9227
9427
|
g
|
|
9228
9428
|
);
|
|
9229
9429
|
}) }),
|
|
9230
|
-
filtered.length === 0 ? /* @__PURE__ */
|
|
9430
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx33("div", { className: "px-3 py-2 text-[11px] text-muted-foreground", children: "No matching commands." }) : /* @__PURE__ */ jsx33("ul", { ref: listRef, className: "max-h-80 overflow-y-auto py-1", role: "listbox", "aria-label": "Commands", children: filtered.map((cmd, i) => /* @__PURE__ */ jsxs28(
|
|
9231
9431
|
"li",
|
|
9232
9432
|
{
|
|
9233
9433
|
role: "option",
|
|
@@ -9250,15 +9450,15 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
|
|
|
9250
9450
|
"/",
|
|
9251
9451
|
cmd.name
|
|
9252
9452
|
] }),
|
|
9253
|
-
cmd.source === "skill" ? /* @__PURE__ */ jsxs28(
|
|
9254
|
-
/* @__PURE__ */
|
|
9255
|
-
cmd.sourcePlugin ? /* @__PURE__ */
|
|
9453
|
+
cmd.source === "skill" ? /* @__PURE__ */ jsxs28(Fragment12, { children: [
|
|
9454
|
+
/* @__PURE__ */ jsx33("span", { className: "rounded-sm bg-accent/15 px-1 py-px text-[9px] font-medium uppercase tracking-wide text-accent-foreground", children: "skill" }),
|
|
9455
|
+
cmd.sourcePlugin ? /* @__PURE__ */ jsx33("span", { className: "rounded-sm bg-muted px-1 py-px text-[9px] font-medium text-muted-foreground", children: cmd.sourcePlugin }) : null
|
|
9256
9456
|
] }) : cmd.sourcePlugin ? (
|
|
9257
9457
|
// Originating plugin/package for non-skill commands.
|
|
9258
|
-
/* @__PURE__ */
|
|
9458
|
+
/* @__PURE__ */ jsx33("span", { className: "rounded-sm bg-muted px-1 py-px text-[9px] font-medium text-muted-foreground", children: cmd.sourcePlugin })
|
|
9259
9459
|
) : null
|
|
9260
9460
|
] }),
|
|
9261
|
-
/* @__PURE__ */
|
|
9461
|
+
/* @__PURE__ */ jsx33("span", { className: "truncate text-[11px] opacity-50", children: cmd.description })
|
|
9262
9462
|
]
|
|
9263
9463
|
},
|
|
9264
9464
|
cmd.name
|
|
@@ -9269,10 +9469,10 @@ function SlashCommandPicker({ query, commands, onSelect, onDismiss }) {
|
|
|
9269
9469
|
// src/front/chat/components/ComposerAttachments.tsx
|
|
9270
9470
|
import { AlertCircleIcon as AlertCircleIcon2, Loader2 as Loader23, PaperclipIcon as PaperclipIcon2 } from "lucide-react";
|
|
9271
9471
|
import { IconButton as IconButton3 } from "@hachej/boring-ui-kit";
|
|
9272
|
-
import { jsx as
|
|
9472
|
+
import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
9273
9473
|
function AttachmentButton({ disabled, className }) {
|
|
9274
9474
|
const attachments = usePromptInputAttachments();
|
|
9275
|
-
return /* @__PURE__ */
|
|
9475
|
+
return /* @__PURE__ */ jsx34(
|
|
9276
9476
|
IconButton3,
|
|
9277
9477
|
{
|
|
9278
9478
|
type: "button",
|
|
@@ -9285,14 +9485,14 @@ function AttachmentButton({ disabled, className }) {
|
|
|
9285
9485
|
className: cn(composerActionClass, "w-8", className),
|
|
9286
9486
|
"aria-label": "Attach files",
|
|
9287
9487
|
title: disabled ? "Attachments are available when the composer is ready." : "Attach files",
|
|
9288
|
-
children: /* @__PURE__ */
|
|
9488
|
+
children: /* @__PURE__ */ jsx34(PaperclipIcon2, { className: "h-3.5 w-3.5", strokeWidth: 1.75 })
|
|
9289
9489
|
}
|
|
9290
9490
|
);
|
|
9291
9491
|
}
|
|
9292
9492
|
function AttachmentsList() {
|
|
9293
9493
|
const attachments = usePromptInputAttachments();
|
|
9294
9494
|
if (attachments.files.length === 0) return null;
|
|
9295
|
-
return /* @__PURE__ */
|
|
9495
|
+
return /* @__PURE__ */ jsx34(
|
|
9296
9496
|
Attachments,
|
|
9297
9497
|
{
|
|
9298
9498
|
"data-boring-agent-part": "composer-attachment-row",
|
|
@@ -9311,12 +9511,12 @@ function AttachmentsList() {
|
|
|
9311
9511
|
),
|
|
9312
9512
|
children: [
|
|
9313
9513
|
/* @__PURE__ */ jsxs29("div", { className: "relative shrink-0", children: [
|
|
9314
|
-
/* @__PURE__ */
|
|
9315
|
-
file.status === "uploading" ? /* @__PURE__ */
|
|
9316
|
-
file.status === "error" ? /* @__PURE__ */
|
|
9514
|
+
/* @__PURE__ */ jsx34(AttachmentPreview, { className: "!size-7 overflow-hidden !rounded-full bg-background/60" }),
|
|
9515
|
+
file.status === "uploading" ? /* @__PURE__ */ jsx34("div", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-background/70", children: /* @__PURE__ */ jsx34(Loader23, { className: "size-3.5 animate-spin text-muted-foreground" }) }) : null,
|
|
9516
|
+
file.status === "error" ? /* @__PURE__ */ jsx34("div", { className: "absolute inset-0 flex items-center justify-center rounded-full bg-destructive/20", children: /* @__PURE__ */ jsx34(AlertCircleIcon2, { className: "size-3.5 text-destructive" }) }) : null
|
|
9317
9517
|
] }),
|
|
9318
|
-
/* @__PURE__ */
|
|
9319
|
-
/* @__PURE__ */
|
|
9518
|
+
/* @__PURE__ */ jsx34(AttachmentInfo, { className: "min-w-0 !max-w-[180px] truncate text-[13px] font-medium" }),
|
|
9519
|
+
/* @__PURE__ */ jsx34(AttachmentRemove, { className: "!size-5 !rounded-full !opacity-100 text-muted-foreground/80 hover:text-foreground" })
|
|
9320
9520
|
]
|
|
9321
9521
|
},
|
|
9322
9522
|
file.id
|
|
@@ -9326,7 +9526,7 @@ function AttachmentsList() {
|
|
|
9326
9526
|
}
|
|
9327
9527
|
|
|
9328
9528
|
// src/front/chat/components/PiChatComposerSurface.tsx
|
|
9329
|
-
import { jsx as
|
|
9529
|
+
import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
9330
9530
|
var MAX_PROMPT_ATTACHMENTS = 2;
|
|
9331
9531
|
var MAX_PROMPT_ATTACHMENT_BYTES = 4 * 1024 * 1024;
|
|
9332
9532
|
var COMPOSER_INPUT_GROUP_MIN_HEIGHT = 56;
|
|
@@ -9403,10 +9603,12 @@ function PiChatComposerSurface({
|
|
|
9403
9603
|
textareaRef,
|
|
9404
9604
|
onTextareaChange,
|
|
9405
9605
|
onTextareaKeyDown,
|
|
9606
|
+
updateDraft,
|
|
9406
9607
|
onSubmitMessage,
|
|
9407
9608
|
onStop
|
|
9408
9609
|
}) {
|
|
9409
9610
|
const workspaceRequestId = getHeaderValue(requestHeaders, "x-boring-workspace-id");
|
|
9611
|
+
const composerContributions = useComposerContributions();
|
|
9410
9612
|
const uploadAttachment = useCallback16((file) => uploadFile(file, {
|
|
9411
9613
|
apiBaseUrl,
|
|
9412
9614
|
workspaceRequestId,
|
|
@@ -9438,7 +9640,7 @@ function PiChatComposerSurface({
|
|
|
9438
9640
|
resizeTextarea(textareaRef.current);
|
|
9439
9641
|
}, [draft, resizeTextarea, textareaRef]);
|
|
9440
9642
|
return /* @__PURE__ */ jsxs30("div", { className: cn("relative z-20", chrome ? "px-4 pb-4 pt-2 sm:px-6 sm:pb-5" : "px-3 pb-2 pt-1"), children: [
|
|
9441
|
-
/* @__PURE__ */
|
|
9643
|
+
/* @__PURE__ */ jsx35(
|
|
9442
9644
|
"div",
|
|
9443
9645
|
{
|
|
9444
9646
|
"data-boring-agent-part": "chat-working-slot",
|
|
@@ -9456,7 +9658,7 @@ function PiChatComposerSurface({
|
|
|
9456
9658
|
"aria-live": isStreaming ? "polite" : void 0,
|
|
9457
9659
|
className: "inline-flex items-center gap-2 rounded-full border border-border/50 bg-background/85 px-2.5 py-1 text-[12px] text-muted-foreground/75 shadow-sm backdrop-blur",
|
|
9458
9660
|
children: [
|
|
9459
|
-
/* @__PURE__ */
|
|
9661
|
+
/* @__PURE__ */ jsx35(
|
|
9460
9662
|
motion2.span,
|
|
9461
9663
|
{
|
|
9462
9664
|
"aria-hidden": "true",
|
|
@@ -9465,14 +9667,14 @@ function PiChatComposerSurface({
|
|
|
9465
9667
|
transition: { duration: 1.2, repeat: Infinity, ease: "easeInOut" }
|
|
9466
9668
|
}
|
|
9467
9669
|
),
|
|
9468
|
-
/* @__PURE__ */
|
|
9670
|
+
/* @__PURE__ */ jsx35("span", { children: "Working\u2026" })
|
|
9469
9671
|
]
|
|
9470
9672
|
}
|
|
9471
9673
|
)
|
|
9472
9674
|
}
|
|
9473
9675
|
),
|
|
9474
|
-
composerStatusNotice ? /* @__PURE__ */
|
|
9475
|
-
composerBlocked && !workspaceWarmupBlocked ? /* @__PURE__ */
|
|
9676
|
+
composerStatusNotice ? /* @__PURE__ */ jsx35(ComposerRuntimeNotice, { notice: composerStatusNotice }) : null,
|
|
9677
|
+
composerBlocked && !workspaceWarmupBlocked ? /* @__PURE__ */ jsx35(
|
|
9476
9678
|
ComposerBlockerNotice,
|
|
9477
9679
|
{
|
|
9478
9680
|
blocker: primaryComposerBlocker,
|
|
@@ -9480,8 +9682,8 @@ function PiChatComposerSurface({
|
|
|
9480
9682
|
onAction: onComposerBlockerAction
|
|
9481
9683
|
}
|
|
9482
9684
|
) : null,
|
|
9483
|
-
queuePreview.length > 0 ? /* @__PURE__ */
|
|
9484
|
-
hotReloadEnabled ? /* @__PURE__ */
|
|
9685
|
+
queuePreview.length > 0 ? /* @__PURE__ */ jsx35(QueuedComposerNotice, { followUps: queuePreview, onEdit: onEditQueued }) : null,
|
|
9686
|
+
hotReloadEnabled ? /* @__PURE__ */ jsx35(
|
|
9485
9687
|
PluginUpdateStatus,
|
|
9486
9688
|
{
|
|
9487
9689
|
state: pluginUpdateState,
|
|
@@ -9489,14 +9691,14 @@ function PiChatComposerSurface({
|
|
|
9489
9691
|
onRetry: onRunPluginUpdate
|
|
9490
9692
|
}
|
|
9491
9693
|
) : null,
|
|
9492
|
-
/* @__PURE__ */
|
|
9694
|
+
/* @__PURE__ */ jsx35(
|
|
9493
9695
|
CommandRunStatus,
|
|
9494
9696
|
{
|
|
9495
9697
|
state: commandNotifyState,
|
|
9496
9698
|
onDismiss: onDismissCommandNotify
|
|
9497
9699
|
}
|
|
9498
9700
|
),
|
|
9499
|
-
attachmentNotice ? /* @__PURE__ */
|
|
9701
|
+
attachmentNotice ? /* @__PURE__ */ jsx35(
|
|
9500
9702
|
"div",
|
|
9501
9703
|
{
|
|
9502
9704
|
role: "status",
|
|
@@ -9506,7 +9708,7 @@ function PiChatComposerSurface({
|
|
|
9506
9708
|
}
|
|
9507
9709
|
) : null,
|
|
9508
9710
|
/* @__PURE__ */ jsxs30("div", { className: cn("mx-auto w-full", chrome ? "max-w-3xl" : "max-w-[680px]"), children: [
|
|
9509
|
-
mentionState ? /* @__PURE__ */
|
|
9711
|
+
mentionState ? /* @__PURE__ */ jsx35(
|
|
9510
9712
|
MentionPicker,
|
|
9511
9713
|
{
|
|
9512
9714
|
mention: mentionState,
|
|
@@ -9518,7 +9720,7 @@ function PiChatComposerSurface({
|
|
|
9518
9720
|
onDismiss: onDismissMention
|
|
9519
9721
|
}
|
|
9520
9722
|
) : null,
|
|
9521
|
-
slashQuery !== null ? /* @__PURE__ */
|
|
9723
|
+
slashQuery !== null ? /* @__PURE__ */ jsx35(
|
|
9522
9724
|
SlashCommandPicker,
|
|
9523
9725
|
{
|
|
9524
9726
|
query: slashQuery,
|
|
@@ -9527,7 +9729,7 @@ function PiChatComposerSurface({
|
|
|
9527
9729
|
onDismiss: onDismissSlash
|
|
9528
9730
|
}
|
|
9529
9731
|
) : null,
|
|
9530
|
-
mentionState === null && slashQuery === null && modelPickerOpen ? /* @__PURE__ */
|
|
9732
|
+
mentionState === null && slashQuery === null && modelPickerOpen ? /* @__PURE__ */ jsx35(
|
|
9531
9733
|
ModelPickerMenu,
|
|
9532
9734
|
{
|
|
9533
9735
|
value: selectedModel,
|
|
@@ -9538,7 +9740,7 @@ function PiChatComposerSurface({
|
|
|
9538
9740
|
onClose: () => onSetModelPickerOpen(false)
|
|
9539
9741
|
}
|
|
9540
9742
|
) : null,
|
|
9541
|
-
mentionState === null && slashQuery === null && thinkingPickerOpen ? /* @__PURE__ */
|
|
9743
|
+
mentionState === null && slashQuery === null && thinkingPickerOpen ? /* @__PURE__ */ jsx35(
|
|
9542
9744
|
ThinkingPickerMenu,
|
|
9543
9745
|
{
|
|
9544
9746
|
value: selectedThinking,
|
|
@@ -9548,7 +9750,17 @@ function PiChatComposerSurface({
|
|
|
9548
9750
|
}
|
|
9549
9751
|
) : null
|
|
9550
9752
|
] }),
|
|
9551
|
-
/* @__PURE__ */
|
|
9753
|
+
composerContributions.map(({ id, Top }) => Top ? /* @__PURE__ */ jsx35(
|
|
9754
|
+
"div",
|
|
9755
|
+
{
|
|
9756
|
+
"data-boring-agent-part": "composer-contribution-top",
|
|
9757
|
+
"data-boring-agent-contribution-id": id,
|
|
9758
|
+
className: cn("mx-auto mb-2 w-full empty:hidden", chrome ? "max-w-3xl" : "max-w-[680px]"),
|
|
9759
|
+
children: /* @__PURE__ */ jsx35(Top, {})
|
|
9760
|
+
},
|
|
9761
|
+
id
|
|
9762
|
+
) : null),
|
|
9763
|
+
/* @__PURE__ */ jsx35(
|
|
9552
9764
|
"div",
|
|
9553
9765
|
{
|
|
9554
9766
|
"data-boring-agent-part": "composer-rail",
|
|
@@ -9583,15 +9795,15 @@ function PiChatComposerSurface({
|
|
|
9583
9795
|
else onAttachmentNotice(err.message || "Attachment rejected.");
|
|
9584
9796
|
},
|
|
9585
9797
|
children: [
|
|
9586
|
-
/* @__PURE__ */
|
|
9798
|
+
/* @__PURE__ */ jsx35(AttachmentsList, {}),
|
|
9587
9799
|
/* @__PURE__ */ jsxs30(
|
|
9588
9800
|
"div",
|
|
9589
9801
|
{
|
|
9590
9802
|
"data-boring-agent-part": "composer-input-row",
|
|
9591
9803
|
className: "flex min-h-[var(--composer-input-group-height)] w-full items-center",
|
|
9592
9804
|
children: [
|
|
9593
|
-
/* @__PURE__ */
|
|
9594
|
-
/* @__PURE__ */
|
|
9805
|
+
/* @__PURE__ */ jsx35("div", { className: "flex h-14 shrink-0 items-center pl-2", children: /* @__PURE__ */ jsx35(AttachmentButton, { disabled: disabled || isStreaming }) }),
|
|
9806
|
+
/* @__PURE__ */ jsx35(
|
|
9595
9807
|
PromptInputTextarea,
|
|
9596
9808
|
{
|
|
9597
9809
|
value: draft,
|
|
@@ -9615,32 +9827,44 @@ function PiChatComposerSurface({
|
|
|
9615
9827
|
)
|
|
9616
9828
|
}
|
|
9617
9829
|
),
|
|
9618
|
-
/* @__PURE__ */
|
|
9830
|
+
/* @__PURE__ */ jsx35(
|
|
9619
9831
|
PromptInputFooter,
|
|
9620
9832
|
{
|
|
9621
9833
|
align: "inline-end",
|
|
9622
9834
|
"data-boring-agent-part": "composer-submit-addon",
|
|
9623
9835
|
className: "!order-none !w-auto shrink-0 self-center justify-between border-0 bg-transparent !px-2 !py-0",
|
|
9624
|
-
children: /* @__PURE__ */
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
"
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9836
|
+
children: /* @__PURE__ */ jsxs30("div", { className: "ml-auto flex items-center gap-1.5", children: [
|
|
9837
|
+
composerContributions.map(({ id, Action }) => Action ? /* @__PURE__ */ jsx35(
|
|
9838
|
+
"span",
|
|
9839
|
+
{
|
|
9840
|
+
"data-boring-agent-part": "composer-contribution-action",
|
|
9841
|
+
"data-boring-agent-contribution-id": id,
|
|
9842
|
+
className: "contents",
|
|
9843
|
+
children: /* @__PURE__ */ jsx35(Action, { updateDraft })
|
|
9844
|
+
},
|
|
9845
|
+
id
|
|
9846
|
+
) : null),
|
|
9847
|
+
/* @__PURE__ */ jsx35(
|
|
9848
|
+
PromptInputSubmit,
|
|
9849
|
+
{
|
|
9850
|
+
"data-boring-agent-part": "composer-submit",
|
|
9851
|
+
status: submitStatus,
|
|
9852
|
+
onStop,
|
|
9853
|
+
disabled: submitDisabled,
|
|
9854
|
+
className: cn(
|
|
9855
|
+
"h-8 w-8 shrink-0 rounded-full",
|
|
9856
|
+
"bg-foreground",
|
|
9857
|
+
"text-background",
|
|
9858
|
+
"transition-all duration-150 ease-[cubic-bezier(0.22,1,0.36,1)]",
|
|
9859
|
+
"hover:bg-foreground/90 hover:shadow-[0_0_0_3px_oklch(from_var(--foreground)_l_c_h/0.12)] hover:scale-[1.04]",
|
|
9860
|
+
"active:scale-[0.93] active:brightness-95",
|
|
9861
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/20",
|
|
9862
|
+
"disabled:pointer-events-none disabled:opacity-40",
|
|
9863
|
+
"[&>svg]:size-3.5"
|
|
9864
|
+
)
|
|
9865
|
+
}
|
|
9866
|
+
)
|
|
9867
|
+
] })
|
|
9644
9868
|
}
|
|
9645
9869
|
)
|
|
9646
9870
|
]
|
|
@@ -9660,7 +9884,7 @@ function PiChatComposerSurface({
|
|
|
9660
9884
|
chrome ? "max-w-3xl" : "max-w-[680px]"
|
|
9661
9885
|
),
|
|
9662
9886
|
children: [
|
|
9663
|
-
/* @__PURE__ */
|
|
9887
|
+
/* @__PURE__ */ jsx35(
|
|
9664
9888
|
ModelSelectTrigger,
|
|
9665
9889
|
{
|
|
9666
9890
|
value: selectedModel,
|
|
@@ -9677,7 +9901,7 @@ function PiChatComposerSurface({
|
|
|
9677
9901
|
}
|
|
9678
9902
|
}
|
|
9679
9903
|
),
|
|
9680
|
-
thinkingControl ? /* @__PURE__ */
|
|
9904
|
+
thinkingControl ? /* @__PURE__ */ jsx35(
|
|
9681
9905
|
ThinkingSelectTrigger,
|
|
9682
9906
|
{
|
|
9683
9907
|
value: selectedThinking,
|
|
@@ -9704,7 +9928,7 @@ function getHeaderValue(headers, name) {
|
|
|
9704
9928
|
}
|
|
9705
9929
|
|
|
9706
9930
|
// src/front/chat/piChatPanelHooks.ts
|
|
9707
|
-
import { useCallback as useCallback17, useEffect as useEffect20, useMemo as
|
|
9931
|
+
import { useCallback as useCallback17, useEffect as useEffect20, useMemo as useMemo15, useRef as useRef17, useState as useState19, useSyncExternalStore } from "react";
|
|
9708
9932
|
function useExternalRemotePiSession({
|
|
9709
9933
|
sessionId,
|
|
9710
9934
|
agentTypeId,
|
|
@@ -9717,9 +9941,9 @@ function useExternalRemotePiSession({
|
|
|
9717
9941
|
remoteSessionOptions
|
|
9718
9942
|
}) {
|
|
9719
9943
|
const [session, setSession] = useState19();
|
|
9720
|
-
const remoteSessionOptionsRef =
|
|
9944
|
+
const remoteSessionOptionsRef = useRef17(remoteSessionOptions);
|
|
9721
9945
|
remoteSessionOptionsRef.current = remoteSessionOptions;
|
|
9722
|
-
const remoteSessionOptionsKey =
|
|
9946
|
+
const remoteSessionOptionsKey = useMemo15(
|
|
9723
9947
|
() => remoteSessionOptionsIdentity2(remoteSessionOptions),
|
|
9724
9948
|
[remoteSessionOptions]
|
|
9725
9949
|
);
|
|
@@ -9892,7 +10116,7 @@ function errorMessage2(error, fallback) {
|
|
|
9892
10116
|
}
|
|
9893
10117
|
|
|
9894
10118
|
// src/front/chat/PiChatPanel.tsx
|
|
9895
|
-
import { jsx as
|
|
10119
|
+
import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
9896
10120
|
var DebugDrawer2 = lazy(() => import("../DebugDrawer-RYEBQ6CO.js").then((m) => ({ default: m.DebugDrawer })));
|
|
9897
10121
|
var EMPTY_COMMANDS = [];
|
|
9898
10122
|
var EMPTY_COMMAND_NAMES = [];
|
|
@@ -9964,14 +10188,14 @@ function PiChatPanel({
|
|
|
9964
10188
|
}) {
|
|
9965
10189
|
const externalSessionId = sessionId?.trim() || void 0;
|
|
9966
10190
|
const showSessionSidebar = showSessions ?? externalSessionId === void 0;
|
|
9967
|
-
const onDataRef =
|
|
10191
|
+
const onDataRef = useRef18(onData);
|
|
9968
10192
|
onDataRef.current = onData;
|
|
9969
|
-
const onTurnCompleteRef =
|
|
10193
|
+
const onTurnCompleteRef = useRef18(onTurnComplete);
|
|
9970
10194
|
onTurnCompleteRef.current = onTurnComplete;
|
|
9971
|
-
const sessionListRefreshRef =
|
|
9972
|
-
const requestHeadersKey =
|
|
9973
|
-
const normalizedRequestHeaders =
|
|
9974
|
-
const remoteSessionOptionsWithEvents =
|
|
10195
|
+
const sessionListRefreshRef = useRef18(void 0);
|
|
10196
|
+
const requestHeadersKey = useMemo16(() => headersContentKey(requestHeaders), [requestHeaders]);
|
|
10197
|
+
const normalizedRequestHeaders = useMemo16(() => normalizedHeadersFromContentKey(requestHeadersKey), [requestHeadersKey]);
|
|
10198
|
+
const remoteSessionOptionsWithEvents = useMemo16(() => ({
|
|
9975
10199
|
...remoteSessionOptions,
|
|
9976
10200
|
...hydrateMessages ? {} : { autoStart: false },
|
|
9977
10201
|
onEvent: (event) => {
|
|
@@ -10038,7 +10262,7 @@ function PiChatPanel({
|
|
|
10038
10262
|
enabled: modelDiscoveryEnabled
|
|
10039
10263
|
});
|
|
10040
10264
|
const selectedModel = model === void 0 ? modelDiscovery.model : model;
|
|
10041
|
-
const modelOptions =
|
|
10265
|
+
const modelOptions = useMemo16(
|
|
10042
10266
|
() => modelOptionsForSelection(availableModels ?? modelDiscovery.availableModels, selectedModel),
|
|
10043
10267
|
[availableModels, modelDiscovery.availableModels, selectedModel]
|
|
10044
10268
|
);
|
|
@@ -10076,13 +10300,13 @@ function PiChatPanel({
|
|
|
10076
10300
|
const [modelPickerOpen, setModelPickerOpen] = useState20(false);
|
|
10077
10301
|
const [thinkingPickerOpen, setThinkingPickerOpen] = useState20(false);
|
|
10078
10302
|
const [draft, setDraft] = useState20(() => initialDraft ?? "");
|
|
10079
|
-
const draftRef =
|
|
10303
|
+
const draftRef = useRef18(draft);
|
|
10080
10304
|
draftRef.current = draft;
|
|
10081
|
-
const initialDraftGuard =
|
|
10082
|
-
const pendingAutoSubmitSettleRef =
|
|
10083
|
-
const acceptedAutoSubmitSettleRef =
|
|
10084
|
-
const resetInProgressRef =
|
|
10085
|
-
const autoCreateInFlightRef =
|
|
10305
|
+
const initialDraftGuard = useRef18(new InitialDraftAutoSubmitGuard());
|
|
10306
|
+
const pendingAutoSubmitSettleRef = useRef18(void 0);
|
|
10307
|
+
const acceptedAutoSubmitSettleRef = useRef18(void 0);
|
|
10308
|
+
const resetInProgressRef = useRef18(false);
|
|
10309
|
+
const autoCreateInFlightRef = useRef18(false);
|
|
10086
10310
|
const settlePendingAutoSubmit = useCallback18((sessionId2) => {
|
|
10087
10311
|
const pendingSessionId = pendingAutoSubmitSettleRef.current;
|
|
10088
10312
|
if (!pendingSessionId || sessionId2 && pendingSessionId !== sessionId2) return false;
|
|
@@ -10091,20 +10315,25 @@ function PiChatPanel({
|
|
|
10091
10315
|
onAutoSubmitInitialDraftSettled?.();
|
|
10092
10316
|
return true;
|
|
10093
10317
|
}, [onAutoSubmitInitialDraftSettled]);
|
|
10094
|
-
const prevStatusRef =
|
|
10095
|
-
const statusRef =
|
|
10096
|
-
const scrollToBottomRef =
|
|
10318
|
+
const prevStatusRef = useRef18("idle");
|
|
10319
|
+
const statusRef = useRef18("idle");
|
|
10320
|
+
const scrollToBottomRef = useRef18(() => {
|
|
10097
10321
|
});
|
|
10098
|
-
const textareaRef =
|
|
10322
|
+
const textareaRef = useRef18(null);
|
|
10099
10323
|
const [localNotices, setLocalNotices] = useState20([]);
|
|
10100
10324
|
const [dismissedNoticeIds, setDismissedNoticeIds] = useState20(() => /* @__PURE__ */ new Set());
|
|
10101
10325
|
const [pluginUpdateState, setPluginUpdateState] = useState20(null);
|
|
10102
10326
|
const [commandNotifyState, setCommandNotifyState] = useState20(null);
|
|
10103
|
-
const commandRunIdRef =
|
|
10327
|
+
const commandRunIdRef = useRef18(0);
|
|
10104
10328
|
const [serverSkillsRefreshKey, setServerSkillsRefreshKey] = useState20(0);
|
|
10105
10329
|
const [localSubmittedSessionId, setLocalSubmittedSessionId] = useState20();
|
|
10106
|
-
const localSubmittedSessionRef =
|
|
10330
|
+
const localSubmittedSessionRef = useRef18(void 0);
|
|
10107
10331
|
const { attachmentNotice, setAttachmentNotice } = useAttachmentNotice();
|
|
10332
|
+
const composerContributions = useComposerContributions();
|
|
10333
|
+
const contributedCommands = useMemo16(
|
|
10334
|
+
() => composerContributions.flatMap((contribution) => contribution.commands ?? []),
|
|
10335
|
+
[composerContributions]
|
|
10336
|
+
);
|
|
10108
10337
|
const markLocalSubmitted = useCallback18((sessionId2) => {
|
|
10109
10338
|
localSubmittedSessionRef.current = sessionId2;
|
|
10110
10339
|
setLocalSubmittedSessionId(sessionId2);
|
|
@@ -10114,7 +10343,7 @@ function PiChatPanel({
|
|
|
10114
10343
|
localSubmittedSessionRef.current = void 0;
|
|
10115
10344
|
setLocalSubmittedSessionId(void 0);
|
|
10116
10345
|
}, []);
|
|
10117
|
-
const registry =
|
|
10346
|
+
const registry = useMemo16(() => {
|
|
10118
10347
|
const excludedBuiltins = new Set(excludeBuiltinCommands);
|
|
10119
10348
|
const effectiveBuiltins = builtinCommands.filter((command) => {
|
|
10120
10349
|
if (!hotReloadEnabled && command.name === "reload") return false;
|
|
@@ -10122,9 +10351,10 @@ function PiChatPanel({
|
|
|
10122
10351
|
});
|
|
10123
10352
|
const next = createCommandRegistry(effectiveBuiltins);
|
|
10124
10353
|
for (const command of extraCommands ?? []) next.register(command);
|
|
10354
|
+
for (const command of contributedCommands) next.register(command);
|
|
10125
10355
|
for (const command of commands) next.register(command);
|
|
10126
10356
|
return next;
|
|
10127
|
-
}, [apiBaseUrl, commands, excludeBuiltinCommands, extraCommands, hotReloadEnabled, normalizedRequestHeaders, serverResourcesEnabled, serverSkillsRefreshKey, storageScope]);
|
|
10357
|
+
}, [apiBaseUrl, commands, contributedCommands, excludeBuiltinCommands, extraCommands, hotReloadEnabled, normalizedRequestHeaders, serverResourcesEnabled, serverSkillsRefreshKey, storageScope]);
|
|
10128
10358
|
const commandsStamp = useServerCommands({
|
|
10129
10359
|
registry,
|
|
10130
10360
|
requestHeaders: normalizedRequestHeaders,
|
|
@@ -10135,12 +10365,16 @@ function PiChatPanel({
|
|
|
10135
10365
|
refreshKey: serverSkillsRefreshKey,
|
|
10136
10366
|
enabled: serverResourcesEnabled
|
|
10137
10367
|
});
|
|
10138
|
-
const allCommands =
|
|
10368
|
+
const allCommands = useMemo16(() => registry.list(), [registry, commandsStamp]);
|
|
10369
|
+
const actionableSlashCommands = useMemo16(
|
|
10370
|
+
() => allCommands.flatMap((command) => command.clickBehavior === "execute" || command.clickBehavior === "insert" ? [{ name: command.name, clickBehavior: command.clickBehavior }] : []),
|
|
10371
|
+
[allCommands]
|
|
10372
|
+
);
|
|
10139
10373
|
const activeChatSessionId = selectedChatState?.sessionId;
|
|
10140
10374
|
const warmupNotice = composerNoticeForWarmup(workspaceWarmupStatus);
|
|
10141
10375
|
const runtimeDependenciesNotice = composerNoticeForRuntimeDependencies(workspaceWarmupStatus);
|
|
10142
10376
|
const workspaceWarmupBlocked = Boolean(warmupNotice);
|
|
10143
|
-
const activeBlockers =
|
|
10377
|
+
const activeBlockers = useMemo16(
|
|
10144
10378
|
// A missing active session id means a single/sessionless chat host. In that
|
|
10145
10379
|
// mode, keep scoped blockers visible instead of hiding the only attention UI.
|
|
10146
10380
|
// Multi-session hosts should pass a session id so unrelated blockers filter out.
|
|
@@ -10150,7 +10384,7 @@ function PiChatPanel({
|
|
|
10150
10384
|
const canonicalMessages = selectedChatState ? selectMessagesForRender(selectedChatState) : [];
|
|
10151
10385
|
const queuePreview = selectedChatState ? selectQueuePreview(selectedChatState) : [];
|
|
10152
10386
|
const messages = canonicalMessages;
|
|
10153
|
-
const userHistory =
|
|
10387
|
+
const userHistory = useMemo16(() => selectComposerHistoryFromCanonicalUsers(canonicalMessages), [canonicalMessages]);
|
|
10154
10388
|
const emptyStateHydrating = statusForState(selectedChatState, sessionsLoading || chatStatePending || selectedSessionPending) === "hydrating";
|
|
10155
10389
|
const emptyHero = emptyPlacement === "hero" && messages.length === 0 && queuePreview.length === 0 && !emptyStateHydrating;
|
|
10156
10390
|
const debugState = selectedPiSession?.getDebugState();
|
|
@@ -10158,7 +10392,7 @@ function PiChatPanel({
|
|
|
10158
10392
|
const primaryComposerBlocker = activeBlockers[0];
|
|
10159
10393
|
const composerBlockerLabel = workspaceWarmupBlocked ? warmupNotice?.title ?? "Preparing workspace..." : primaryComposerBlocker?.label ?? primaryComposerBlocker?.reason ?? "Complete the pending workspace action to continue.";
|
|
10160
10394
|
const composerStatusNotice = warmupNotice ?? runtimeDependenciesNotice;
|
|
10161
|
-
const runtimeNotices =
|
|
10395
|
+
const runtimeNotices = useMemo16(() => {
|
|
10162
10396
|
const fromState = selectedChatState ? selectRuntimeNotices(selectedChatState) : [];
|
|
10163
10397
|
const sessionNotice = sessionsError ? [{ id: "session-navigation-error", level: "error", text: sessionsError.message, dismissible: true }] : [];
|
|
10164
10398
|
const largeStateNotice = debug && debugState?.largeStateWarning ? [{
|
|
@@ -10372,7 +10606,7 @@ function PiChatPanel({
|
|
|
10372
10606
|
}
|
|
10373
10607
|
insertSlashCommand(name);
|
|
10374
10608
|
}, [dismissSlash, insertSlashCommand, openModelPicker, openThinkingPicker, setComposerDraft]);
|
|
10375
|
-
const policy =
|
|
10609
|
+
const policy = useMemo16(() => {
|
|
10376
10610
|
if (!selectedPiSession || !activeChatSessionId || !serverModelSelectionReady) return void 0;
|
|
10377
10611
|
const policySession = {
|
|
10378
10612
|
getState: () => {
|
|
@@ -10450,16 +10684,16 @@ function PiChatPanel({
|
|
|
10450
10684
|
...errorCode ? { errorCode } : {}
|
|
10451
10685
|
});
|
|
10452
10686
|
}, [addLocalNotice, dropLocalNotice]);
|
|
10453
|
-
const sendComposerMessage = useCallback18(async ({ text, files, source = "composer" }) => {
|
|
10687
|
+
const sendComposerMessage = useCallback18(async ({ text, files, source = "composer", preserveExistingDraft = false }) => {
|
|
10454
10688
|
if (!policy) {
|
|
10455
10689
|
addLocalNotice({ id: "composer-no-session", level: "warning", text: "Create or select a chat session before sending.", dismissible: true });
|
|
10456
10690
|
return false;
|
|
10457
10691
|
}
|
|
10458
10692
|
const submittedDraft = text;
|
|
10459
10693
|
const restoreSubmittedDraft = () => {
|
|
10460
|
-
if (draftRef.current === "") setComposerDraft(submittedDraft);
|
|
10694
|
+
if (!preserveExistingDraft && draftRef.current === "") setComposerDraft(submittedDraft);
|
|
10461
10695
|
};
|
|
10462
|
-
setComposerDraft("", false);
|
|
10696
|
+
if (!preserveExistingDraft) setComposerDraft("", false);
|
|
10463
10697
|
scrollToBottomRef.current();
|
|
10464
10698
|
try {
|
|
10465
10699
|
const result = await policy.submit({ text, files, source });
|
|
@@ -10483,6 +10717,53 @@ function PiChatPanel({
|
|
|
10483
10717
|
return false;
|
|
10484
10718
|
}
|
|
10485
10719
|
}, [activeChatSessionId, clearLocalSubmitted, dropLocalNotice, markLocalSubmitted, onPromptSubmitStarted, policy, selectedPiSession, setComposerDraft, surfaceRunRejected]);
|
|
10720
|
+
const availableAssistantSlashCommands = useMemo16(
|
|
10721
|
+
() => policy ? actionableSlashCommands : actionableSlashCommands.filter((command) => command.clickBehavior === "insert"),
|
|
10722
|
+
[actionableSlashCommands, policy]
|
|
10723
|
+
);
|
|
10724
|
+
const assistantMentionCatalog = useMemo16(() => {
|
|
10725
|
+
const skills = /* @__PURE__ */ new Map();
|
|
10726
|
+
for (const command of allCommands) {
|
|
10727
|
+
if (command.source !== "skill" && command.kind !== "skill") continue;
|
|
10728
|
+
const name = command.name.replace(/^skill:/, "");
|
|
10729
|
+
if (!name) continue;
|
|
10730
|
+
const priority = command.kind === "skill" ? 2 : 1;
|
|
10731
|
+
const existing = skills.get(name);
|
|
10732
|
+
if (!existing || priority > existing.priority) skills.set(name, { name, commandName: command.name, priority });
|
|
10733
|
+
}
|
|
10734
|
+
return {
|
|
10735
|
+
commands: availableAssistantSlashCommands,
|
|
10736
|
+
skills: [...skills.values()].map(({ name, commandName }) => ({ name, commandName })),
|
|
10737
|
+
files: true
|
|
10738
|
+
};
|
|
10739
|
+
}, [allCommands, availableAssistantSlashCommands]);
|
|
10740
|
+
const insertMentionDraft = useCallback18((invocation) => {
|
|
10741
|
+
const currentDraft = draftRef.current;
|
|
10742
|
+
const separator = currentDraft && !/\s$/.test(invocation) ? "\n" : "";
|
|
10743
|
+
setComposerDraft(`${invocation}${separator}${currentDraft}`, true);
|
|
10744
|
+
}, [setComposerDraft]);
|
|
10745
|
+
const activateAssistantMention = useCallback18((mention) => {
|
|
10746
|
+
const command = registry.get(mention.kind === "skill" ? mention.commandName : mention.name);
|
|
10747
|
+
if (mention.kind === "skill") {
|
|
10748
|
+
if (command?.source !== "skill" && command?.kind !== "skill") return;
|
|
10749
|
+
const invocation = command.kind === "skill" && !mention.commandName.includes(":") ? `/${mention.commandName} ` : `skill: ${mention.name}
|
|
10750
|
+
|
|
10751
|
+
`;
|
|
10752
|
+
insertMentionDraft(invocation);
|
|
10753
|
+
return;
|
|
10754
|
+
}
|
|
10755
|
+
if (command?.clickBehavior === "insert") {
|
|
10756
|
+
insertMentionDraft(`/${mention.name} `);
|
|
10757
|
+
return;
|
|
10758
|
+
}
|
|
10759
|
+
if (command?.clickBehavior !== "execute" || !policy) return;
|
|
10760
|
+
void sendComposerMessage({
|
|
10761
|
+
text: `/${mention.name}`,
|
|
10762
|
+
files: [],
|
|
10763
|
+
source: "composer",
|
|
10764
|
+
preserveExistingDraft: true
|
|
10765
|
+
});
|
|
10766
|
+
}, [insertMentionDraft, policy, registry, sendComposerMessage]);
|
|
10486
10767
|
const editQueued = useCallback18(() => {
|
|
10487
10768
|
if (!policy) return;
|
|
10488
10769
|
void policy.editQueued().then((result) => {
|
|
@@ -10589,8 +10870,8 @@ function PiChatPanel({
|
|
|
10589
10870
|
const isStreaming = isPiBusyStatus(status);
|
|
10590
10871
|
const submitStatus = initialHydrationPromptAllowed ? "ready" : toPromptSubmitStatus(status);
|
|
10591
10872
|
const submitDisabled = !policy || sessionsLoading || modelSelectionBlocked || composerBlocked && !isStreaming;
|
|
10592
|
-
const mergedToolRenderers =
|
|
10593
|
-
const debugMessages =
|
|
10873
|
+
const mergedToolRenderers = useMemo16(() => mergeShadcnToolRenderers(toolRenderers), [toolRenderers]);
|
|
10874
|
+
const debugMessages = useMemo16(() => messages.map(toDebugUiMessage), [messages]);
|
|
10594
10875
|
const onTextareaChange = useCallback18((event) => {
|
|
10595
10876
|
setModelPickerOpen(false);
|
|
10596
10877
|
setThinkingPickerOpen(false);
|
|
@@ -10624,7 +10905,7 @@ function PiChatPanel({
|
|
|
10624
10905
|
}
|
|
10625
10906
|
handleComposerKeyDown(event);
|
|
10626
10907
|
}, [handleComposerKeyDown, interrupt, isStreaming, mentionState, slashQuery]);
|
|
10627
|
-
return /* @__PURE__ */
|
|
10908
|
+
return /* @__PURE__ */ jsx36(ArtifactOpenProvider, { onOpenArtifact, children: /* @__PURE__ */ jsxs31(
|
|
10628
10909
|
"div",
|
|
10629
10910
|
{
|
|
10630
10911
|
"data-boring-agent": "",
|
|
@@ -10641,7 +10922,7 @@ function PiChatPanel({
|
|
|
10641
10922
|
role: "region",
|
|
10642
10923
|
"aria-label": "Agent assistant",
|
|
10643
10924
|
children: [
|
|
10644
|
-
showSessionSidebar ? /* @__PURE__ */
|
|
10925
|
+
showSessionSidebar ? /* @__PURE__ */ jsx36("aside", { "data-boring-agent-part": "pi-chat-session-sidebar", className: "min-h-0 w-64 shrink-0 border-r border-border/60", children: /* @__PURE__ */ jsx36(
|
|
10645
10926
|
SessionList,
|
|
10646
10927
|
{
|
|
10647
10928
|
sessions: sessionList,
|
|
@@ -10655,7 +10936,7 @@ function PiChatPanel({
|
|
|
10655
10936
|
loadingMore: sessions.loadingMore
|
|
10656
10937
|
}
|
|
10657
10938
|
) }) : null,
|
|
10658
|
-
/* @__PURE__ */
|
|
10939
|
+
/* @__PURE__ */ jsx36("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: /* @__PURE__ */ jsxs31(
|
|
10659
10940
|
"div",
|
|
10660
10941
|
{
|
|
10661
10942
|
className: cn(
|
|
@@ -10664,7 +10945,7 @@ function PiChatPanel({
|
|
|
10664
10945
|
chrome && "mx-3 my-3 rounded-xl bg-[color:var(--surface-chat)] shadow-[0_1px_0_oklch(0_0_0/0.02),0_1px_2px_-1px_oklch(0_0_0/0.04),inset_0_0_0_1px_oklch(from_var(--border)_l_c_h/0.6)]"
|
|
10665
10946
|
),
|
|
10666
10947
|
children: [
|
|
10667
|
-
/* @__PURE__ */
|
|
10948
|
+
/* @__PURE__ */ jsx36(
|
|
10668
10949
|
PiConversationSurface,
|
|
10669
10950
|
{
|
|
10670
10951
|
chrome,
|
|
@@ -10676,6 +10957,8 @@ function PiChatPanel({
|
|
|
10676
10957
|
isStreaming,
|
|
10677
10958
|
showThoughts,
|
|
10678
10959
|
toolRenderers: mergedToolRenderers,
|
|
10960
|
+
mentionCatalog: assistantMentionCatalog,
|
|
10961
|
+
onMentionActivate: activateAssistantMention,
|
|
10679
10962
|
runtimeNotices,
|
|
10680
10963
|
onDismissNotice: clearLocalNotice,
|
|
10681
10964
|
renderNoticeAction,
|
|
@@ -10687,7 +10970,7 @@ function PiChatPanel({
|
|
|
10687
10970
|
windowResetKey: activeSessionId
|
|
10688
10971
|
}
|
|
10689
10972
|
),
|
|
10690
|
-
/* @__PURE__ */
|
|
10973
|
+
/* @__PURE__ */ jsx36(
|
|
10691
10974
|
PiChatComposerSurface,
|
|
10692
10975
|
{
|
|
10693
10976
|
chrome,
|
|
@@ -10744,6 +11027,9 @@ function PiChatPanel({
|
|
|
10744
11027
|
textareaRef,
|
|
10745
11028
|
onTextareaChange,
|
|
10746
11029
|
onTextareaKeyDown,
|
|
11030
|
+
updateDraft: (update, options) => {
|
|
11031
|
+
setComposerDraft(update(draftRef.current), options?.focus ?? true);
|
|
11032
|
+
},
|
|
10747
11033
|
onSubmitMessage: ({ text, files }) => sendComposerMessage({ text, files }),
|
|
10748
11034
|
onStop: stop
|
|
10749
11035
|
}
|
|
@@ -10751,7 +11037,7 @@ function PiChatPanel({
|
|
|
10751
11037
|
]
|
|
10752
11038
|
}
|
|
10753
11039
|
) }),
|
|
10754
|
-
debug ? /* @__PURE__ */
|
|
11040
|
+
debug ? /* @__PURE__ */ jsx36(Suspense, { fallback: null, children: /* @__PURE__ */ jsx36("div", { "aria-label": "Chat debug metadata", className: "contents", role: "region", children: /* @__PURE__ */ jsx36(
|
|
10755
11041
|
DebugDrawer2,
|
|
10756
11042
|
{
|
|
10757
11043
|
apiBaseUrl,
|
|
@@ -10807,8 +11093,10 @@ function getAgentCommands(options = {}) {
|
|
|
10807
11093
|
export {
|
|
10808
11094
|
ArtifactOpenProvider,
|
|
10809
11095
|
ChatEmptyState,
|
|
11096
|
+
ChatMessageContributionProvider,
|
|
10810
11097
|
PiChatPanel as ChatPanel,
|
|
10811
11098
|
CodeBlock2 as CodeBlock,
|
|
11099
|
+
ComposerContributionProvider,
|
|
10812
11100
|
Conversation,
|
|
10813
11101
|
ConversationContent,
|
|
10814
11102
|
ConversationScrollButton,
|
|
@@ -10832,7 +11120,10 @@ export {
|
|
|
10832
11120
|
ReasoningContent,
|
|
10833
11121
|
ReasoningTrigger,
|
|
10834
11122
|
ThinkingSelect,
|
|
11123
|
+
Tool2 as Tool,
|
|
10835
11124
|
ToolCallGroup,
|
|
11125
|
+
ToolContent,
|
|
11126
|
+
ToolHeader,
|
|
10836
11127
|
activeSessionStorageKey,
|
|
10837
11128
|
builtinCommands,
|
|
10838
11129
|
clearActiveSessionId,
|