@blade-hq/agent-react 2610.0.0-beta.1 → 2610.0.1-alpha.1
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/README.md +3 -5
- package/dist/components/AgentChat.d.ts +0 -3
- package/dist/components/AssistantTurnBlock.d.ts +1 -1
- package/dist/components/ChatSurface.d.ts +2 -11
- package/dist/components/ChatView.d.ts +0 -1
- package/dist/components/FileCard.d.ts +16 -0
- package/dist/components/MarkdownContent.d.ts +6 -3
- package/dist/components/MessageList.d.ts +3 -10
- package/dist/embed/entry.d.ts +0 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +312 -636
- package/dist/index.js.map +1 -1
- package/dist/lib/media-tags.d.ts +24 -0
- package/dist/style.full.css +1 -1
- package/package.json +2 -2
- package/public-api.md +1 -145
- package/dist/components/PostChatFollowupBlock.d.ts +0 -59
package/dist/index.js
CHANGED
|
@@ -545,7 +545,7 @@ function toToolCallInfo(call, results, failedToolIds) {
|
|
|
545
545
|
}
|
|
546
546
|
|
|
547
547
|
// src/components/AgentChat.tsx
|
|
548
|
-
import { BladeApiError
|
|
548
|
+
import { BladeApiError } from "@blade-hq/agent-client";
|
|
549
549
|
|
|
550
550
|
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/createLucideIcon.js
|
|
551
551
|
import { forwardRef as forwardRef2, createElement as createElement2 } from "react";
|
|
@@ -618,16 +618,11 @@ var createLucideIcon = (iconName, iconNode) => {
|
|
|
618
618
|
return Component2;
|
|
619
619
|
};
|
|
620
620
|
|
|
621
|
-
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/
|
|
622
|
-
var
|
|
623
|
-
["
|
|
624
|
-
["path", { d: "
|
|
625
|
-
]
|
|
626
|
-
|
|
627
|
-
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/arrow-up-right.js
|
|
628
|
-
var ArrowUpRight = createLucideIcon("ArrowUpRight", [
|
|
629
|
-
["path", { d: "M7 7h10v10", key: "1tivn9" }],
|
|
630
|
-
["path", { d: "M7 17 17 7", key: "1vkiza" }]
|
|
621
|
+
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/archive.js
|
|
622
|
+
var Archive = createLucideIcon("Archive", [
|
|
623
|
+
["rect", { width: "20", height: "5", x: "2", y: "3", rx: "1", key: "1wp1u1" }],
|
|
624
|
+
["path", { d: "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8", key: "1s80jp" }],
|
|
625
|
+
["path", { d: "M10 12h4", key: "a56b0p" }]
|
|
631
626
|
]);
|
|
632
627
|
|
|
633
628
|
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/arrow-up.js
|
|
@@ -704,6 +699,24 @@ var Download = createLucideIcon("Download", [
|
|
|
704
699
|
["line", { x1: "12", x2: "12", y1: "15", y2: "3", key: "1vk2je" }]
|
|
705
700
|
]);
|
|
706
701
|
|
|
702
|
+
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/file-code-2.js
|
|
703
|
+
var FileCode2 = createLucideIcon("FileCode2", [
|
|
704
|
+
["path", { d: "M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4", key: "1pf5j1" }],
|
|
705
|
+
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
|
|
706
|
+
["path", { d: "m5 12-3 3 3 3", key: "oke12k" }],
|
|
707
|
+
["path", { d: "m9 18 3-3-3-3", key: "112psh" }]
|
|
708
|
+
]);
|
|
709
|
+
|
|
710
|
+
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/file-spreadsheet.js
|
|
711
|
+
var FileSpreadsheet = createLucideIcon("FileSpreadsheet", [
|
|
712
|
+
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
713
|
+
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
|
|
714
|
+
["path", { d: "M8 13h2", key: "yr2amv" }],
|
|
715
|
+
["path", { d: "M14 13h2", key: "un5t4a" }],
|
|
716
|
+
["path", { d: "M8 17h2", key: "2yhykz" }],
|
|
717
|
+
["path", { d: "M14 17h2", key: "10kma7" }]
|
|
718
|
+
]);
|
|
719
|
+
|
|
707
720
|
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/file-text.js
|
|
708
721
|
var FileText = createLucideIcon("FileText", [
|
|
709
722
|
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
@@ -731,11 +744,11 @@ var Film = createLucideIcon("Film", [
|
|
|
731
744
|
["path", { d: "M17 16.5h4", key: "go4c1d" }]
|
|
732
745
|
]);
|
|
733
746
|
|
|
734
|
-
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/
|
|
735
|
-
var
|
|
736
|
-
["
|
|
737
|
-
["
|
|
738
|
-
["path", { d: "
|
|
747
|
+
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/image.js
|
|
748
|
+
var Image = createLucideIcon("Image", [
|
|
749
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
|
|
750
|
+
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
|
|
751
|
+
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
|
|
739
752
|
]);
|
|
740
753
|
|
|
741
754
|
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/layers.js
|
|
@@ -801,6 +814,13 @@ var MessageSquare = createLucideIcon("MessageSquare", [
|
|
|
801
814
|
["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z", key: "1lielz" }]
|
|
802
815
|
]);
|
|
803
816
|
|
|
817
|
+
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/music.js
|
|
818
|
+
var Music = createLucideIcon("Music", [
|
|
819
|
+
["path", { d: "M9 18V5l12-2v13", key: "1jmyc2" }],
|
|
820
|
+
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
|
|
821
|
+
["circle", { cx: "18", cy: "16", r: "3", key: "1hluhg" }]
|
|
822
|
+
]);
|
|
823
|
+
|
|
804
824
|
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/play.js
|
|
805
825
|
var Play = createLucideIcon("Play", [
|
|
806
826
|
["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]
|
|
@@ -814,21 +834,6 @@ var Settings2 = createLucideIcon("Settings2", [
|
|
|
814
834
|
["circle", { cx: "7", cy: "7", r: "3", key: "dfmy0x" }]
|
|
815
835
|
]);
|
|
816
836
|
|
|
817
|
-
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/sparkles.js
|
|
818
|
-
var Sparkles = createLucideIcon("Sparkles", [
|
|
819
|
-
[
|
|
820
|
-
"path",
|
|
821
|
-
{
|
|
822
|
-
d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",
|
|
823
|
-
key: "4pj2yx"
|
|
824
|
-
}
|
|
825
|
-
],
|
|
826
|
-
["path", { d: "M20 3v4", key: "1olli1" }],
|
|
827
|
-
["path", { d: "M22 5h-4", key: "1gvqau" }],
|
|
828
|
-
["path", { d: "M4 17v2", key: "vumght" }],
|
|
829
|
-
["path", { d: "M5 18H3", key: "zchphs" }]
|
|
830
|
-
]);
|
|
831
|
-
|
|
832
837
|
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/square.js
|
|
833
838
|
var Square = createLucideIcon("Square", [
|
|
834
839
|
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }]
|
|
@@ -854,7 +859,7 @@ var X = createLucideIcon("X", [
|
|
|
854
859
|
]);
|
|
855
860
|
|
|
856
861
|
// src/components/AgentChat.tsx
|
|
857
|
-
import {
|
|
862
|
+
import { useEffect as useEffect7, useState as useState12 } from "react";
|
|
858
863
|
|
|
859
864
|
// src/lib/utils.ts
|
|
860
865
|
function cn(...inputs) {
|
|
@@ -1078,7 +1083,7 @@ function ConnectionBanner({ connection, className }) {
|
|
|
1078
1083
|
|
|
1079
1084
|
// src/components/MessageList.tsx
|
|
1080
1085
|
import { isHiddenInternalMessage } from "@blade-hq/agent-client";
|
|
1081
|
-
import { useCallback as
|
|
1086
|
+
import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo7, useRef as useRef6, useState as useState11 } from "react";
|
|
1082
1087
|
|
|
1083
1088
|
// ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
|
|
1084
1089
|
import { useCallback as useCallback3, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
|
|
@@ -1506,7 +1511,7 @@ function useStickToBottomContext() {
|
|
|
1506
1511
|
|
|
1507
1512
|
// src/components/AssistantTurnBlock.tsx
|
|
1508
1513
|
import { getTextContent, normalizeMessageContent } from "@blade-hq/agent-client";
|
|
1509
|
-
import { useState as
|
|
1514
|
+
import { useState as useState10 } from "react";
|
|
1510
1515
|
|
|
1511
1516
|
// src/components/AgentLoopBlock.tsx
|
|
1512
1517
|
import { useState as useState5 } from "react";
|
|
@@ -1709,14 +1714,142 @@ import {
|
|
|
1709
1714
|
useEffect as useEffect4,
|
|
1710
1715
|
useMemo as useMemo5,
|
|
1711
1716
|
useRef as useRef5,
|
|
1712
|
-
useState as
|
|
1717
|
+
useState as useState7
|
|
1713
1718
|
} from "react";
|
|
1719
|
+
|
|
1720
|
+
// src/lib/media-tags.ts
|
|
1721
|
+
var FILE_CARD_TAG = "blade-file-card";
|
|
1722
|
+
var MEDIA_LINE_RE = /^[ \t]*(?:[-*+][ \t]+|\d+\.[ \t]+)?(?<wrap>[`"'*_]*)MEDIA:[ \t]*(?<path>.+?)\k<wrap>[ \t]*[。,、;;,]?[ \t]*\r?$/gm;
|
|
1723
|
+
var MEDIA_LINE_START_RE = /^[ \t]*(?:[-*+][ \t]+|\d+\.[ \t]+)?[`"'*_]*MEDIA:/;
|
|
1724
|
+
function basename(path) {
|
|
1725
|
+
return path.split(/[/\\]/).filter(Boolean).pop() || path;
|
|
1726
|
+
}
|
|
1727
|
+
function unwrapMediaPath(path) {
|
|
1728
|
+
if (!path.startsWith("<")) return path;
|
|
1729
|
+
const closingBracket = path.indexOf(">");
|
|
1730
|
+
if (closingBracket < 0) return null;
|
|
1731
|
+
return `${path.slice(1, closingBracket)}${path.slice(closingBracket + 1)}`;
|
|
1732
|
+
}
|
|
1733
|
+
function isSafeMediaPath(path) {
|
|
1734
|
+
if (!path) return false;
|
|
1735
|
+
return !path.split(/[/\\]/).includes("..");
|
|
1736
|
+
}
|
|
1737
|
+
function escapeAttribute(value) {
|
|
1738
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
1739
|
+
}
|
|
1740
|
+
function foldMediaLines(text) {
|
|
1741
|
+
return text.replace(MEDIA_LINE_RE, (match, _wrap, rawPath) => {
|
|
1742
|
+
const path = unwrapMediaPath(rawPath);
|
|
1743
|
+
if (path === null) return match;
|
|
1744
|
+
const name = basename(path);
|
|
1745
|
+
if (!isSafeMediaPath(path)) {
|
|
1746
|
+
return `\`${name}\``;
|
|
1747
|
+
}
|
|
1748
|
+
return `<${FILE_CARD_TAG} data-path="${escapeAttribute(path)}" data-name="${escapeAttribute(name)}">${escapeAttribute(name)}</${FILE_CARD_TAG}>`;
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
function collapseMediaTags(text, options) {
|
|
1752
|
+
if (!text.includes("MEDIA:")) return text;
|
|
1753
|
+
if (!options?.streaming) return foldMediaLines(text);
|
|
1754
|
+
const newlineIndex = text.lastIndexOf("\n");
|
|
1755
|
+
const head = newlineIndex < 0 ? "" : text.slice(0, newlineIndex + 1);
|
|
1756
|
+
const lastLine = newlineIndex < 0 ? text : text.slice(newlineIndex + 1);
|
|
1757
|
+
if (MEDIA_LINE_START_RE.test(lastLine)) {
|
|
1758
|
+
return foldMediaLines(head);
|
|
1759
|
+
}
|
|
1760
|
+
return foldMediaLines(head) + lastLine;
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
// src/components/FileCard.tsx
|
|
1764
|
+
import { useState as useState6 } from "react";
|
|
1714
1765
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1766
|
+
var IMAGE_EXTS = /* @__PURE__ */ new Set(["png", "jpg", "jpeg", "gif", "svg", "webp", "ico", "bmp"]);
|
|
1767
|
+
var SHEET_EXTS = /* @__PURE__ */ new Set(["xlsx", "xls", "xlsm", "xlsb", "csv"]);
|
|
1768
|
+
var TEXT_EXTS = /* @__PURE__ */ new Set(["txt", "md", "markdown", "pdf", "doc", "docx", "rtf"]);
|
|
1769
|
+
var CODE_EXTS = /* @__PURE__ */ new Set(["js", "jsx", "ts", "tsx", "py", "go", "json", "yaml", "yml", "html", "css"]);
|
|
1770
|
+
var VIDEO_EXTS = /* @__PURE__ */ new Set(["mp4", "webm", "mov", "mkv", "avi"]);
|
|
1771
|
+
var AUDIO_EXTS = /* @__PURE__ */ new Set(["mp3", "wav", "ogg", "m4a", "flac"]);
|
|
1772
|
+
var ARCHIVE_EXTS = /* @__PURE__ */ new Set(["zip", "tar", "gz", "tgz", "rar", "7z"]);
|
|
1773
|
+
function getFileIcon(name) {
|
|
1774
|
+
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
1775
|
+
if (IMAGE_EXTS.has(ext)) return Image;
|
|
1776
|
+
if (SHEET_EXTS.has(ext)) return FileSpreadsheet;
|
|
1777
|
+
if (TEXT_EXTS.has(ext)) return FileText;
|
|
1778
|
+
if (CODE_EXTS.has(ext)) return FileCode2;
|
|
1779
|
+
if (VIDEO_EXTS.has(ext)) return Film;
|
|
1780
|
+
if (AUDIO_EXTS.has(ext)) return Music;
|
|
1781
|
+
if (ARCHIVE_EXTS.has(ext)) return Archive;
|
|
1782
|
+
return File;
|
|
1783
|
+
}
|
|
1784
|
+
function stringValue(value) {
|
|
1785
|
+
return typeof value === "string" ? value : void 0;
|
|
1786
|
+
}
|
|
1787
|
+
function extractChildrenText(children) {
|
|
1788
|
+
if (typeof children === "string") return children;
|
|
1789
|
+
if (Array.isArray(children)) return children.map(extractChildrenText).join("");
|
|
1790
|
+
if (children && typeof children === "object" && "props" in children) {
|
|
1791
|
+
return extractChildrenText(children.props?.children);
|
|
1792
|
+
}
|
|
1793
|
+
return "";
|
|
1794
|
+
}
|
|
1795
|
+
function FileCard({
|
|
1796
|
+
node,
|
|
1797
|
+
"data-path": pathAttribute,
|
|
1798
|
+
"data-name": nameAttribute,
|
|
1799
|
+
dataPath,
|
|
1800
|
+
dataName,
|
|
1801
|
+
sessionId,
|
|
1802
|
+
children,
|
|
1803
|
+
className,
|
|
1804
|
+
...props
|
|
1805
|
+
}) {
|
|
1806
|
+
const client = useBladeClient();
|
|
1807
|
+
const [downloading, setDownloading] = useState6(false);
|
|
1808
|
+
const [failed, setFailed] = useState6(false);
|
|
1809
|
+
const nodeProperties = node && typeof node === "object" && "properties" in node ? node.properties : void 0;
|
|
1810
|
+
const path = pathAttribute ?? dataPath ?? stringValue(nodeProperties?.["data-path"]) ?? stringValue(nodeProperties?.dataPath) ?? "";
|
|
1811
|
+
const name = nameAttribute ?? dataName ?? stringValue(nodeProperties?.["data-name"]) ?? stringValue(nodeProperties?.dataName) ?? extractChildrenText(children) ?? "";
|
|
1812
|
+
const disabled = !sessionId || !isSafeMediaPath(path);
|
|
1813
|
+
const Icon2 = getFileIcon(name);
|
|
1814
|
+
const handleDownload = async () => {
|
|
1815
|
+
if (disabled || downloading || !sessionId) return;
|
|
1816
|
+
setDownloading(true);
|
|
1817
|
+
setFailed(false);
|
|
1818
|
+
try {
|
|
1819
|
+
await client.sessions.downloadFile(sessionId, path, name);
|
|
1820
|
+
} catch {
|
|
1821
|
+
setFailed(true);
|
|
1822
|
+
} finally {
|
|
1823
|
+
setDownloading(false);
|
|
1824
|
+
}
|
|
1825
|
+
};
|
|
1826
|
+
return /* @__PURE__ */ jsxs6("span", { ...props, className: cn("blade-chat-file-card", className), children: [
|
|
1827
|
+
/* @__PURE__ */ jsxs6(
|
|
1828
|
+
"button",
|
|
1829
|
+
{
|
|
1830
|
+
type: "button",
|
|
1831
|
+
onClick: handleDownload,
|
|
1832
|
+
disabled: disabled || downloading,
|
|
1833
|
+
"aria-label": `\u4E0B\u8F7D\u6587\u4EF6\uFF1A${name}`,
|
|
1834
|
+
title: failed ? "\u4E0B\u8F7D\u5931\u8D25\uFF0C\u70B9\u51FB\u91CD\u8BD5" : `\u4E0B\u8F7D ${name}`,
|
|
1835
|
+
children: [
|
|
1836
|
+
/* @__PURE__ */ jsx7("span", { className: "blade-chat-file-card-icon", children: downloading ? /* @__PURE__ */ jsx7(LoaderCircle, { size: 15, className: "animate-spin" }) : /* @__PURE__ */ jsx7(Icon2, { size: 15 }) }),
|
|
1837
|
+
/* @__PURE__ */ jsx7("span", { className: "blade-chat-file-card-name", children: name }),
|
|
1838
|
+
/* @__PURE__ */ jsx7(Download, { size: 13, className: "blade-chat-file-card-action" })
|
|
1839
|
+
]
|
|
1840
|
+
}
|
|
1841
|
+
),
|
|
1842
|
+
failed && /* @__PURE__ */ jsx7("span", { className: "blade-chat-file-card-error", children: "\u4E0B\u8F7D\u5931\u8D25" })
|
|
1843
|
+
] });
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
// src/components/MarkdownContent.tsx
|
|
1847
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1715
1848
|
var SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
1716
1849
|
function CodeBlockPre({ children, node: _node, ...props }) {
|
|
1717
1850
|
const preRef = useRef5(null);
|
|
1718
|
-
const [copied, setCopied] =
|
|
1719
|
-
const [language, setLanguage] =
|
|
1851
|
+
const [copied, setCopied] = useState7(false);
|
|
1852
|
+
const [language, setLanguage] = useState7("");
|
|
1720
1853
|
useEffect4(() => {
|
|
1721
1854
|
const codeEl = preRef.current?.querySelector("code");
|
|
1722
1855
|
setLanguage(codeEl?.className.match(/language-(\S+)/)?.[1] ?? "");
|
|
@@ -1728,10 +1861,10 @@ function CodeBlockPre({ children, node: _node, ...props }) {
|
|
|
1728
1861
|
setTimeout(() => setCopied(false), 2e3);
|
|
1729
1862
|
}
|
|
1730
1863
|
};
|
|
1731
|
-
return /* @__PURE__ */
|
|
1732
|
-
/* @__PURE__ */
|
|
1733
|
-
/* @__PURE__ */
|
|
1734
|
-
/* @__PURE__ */
|
|
1864
|
+
return /* @__PURE__ */ jsxs7("div", { className: "blade-chat-codeblock not-prose my-3 overflow-hidden rounded-xl border border-[hsl(var(--border))]", children: [
|
|
1865
|
+
/* @__PURE__ */ jsxs7("div", { className: "blade-chat-codeblock-header flex h-[34px] items-center justify-between border-b border-[hsl(var(--border))] bg-[hsl(var(--muted))/0.5] pl-3.5 pr-1.5", children: [
|
|
1866
|
+
/* @__PURE__ */ jsx8("span", { className: "font-mono text-[12px] text-[hsl(var(--muted-foreground))]", children: language || "code" }),
|
|
1867
|
+
/* @__PURE__ */ jsxs7(
|
|
1735
1868
|
"button",
|
|
1736
1869
|
{
|
|
1737
1870
|
type: "button",
|
|
@@ -1741,13 +1874,13 @@ function CodeBlockPre({ children, node: _node, ...props }) {
|
|
|
1741
1874
|
copied ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]"
|
|
1742
1875
|
),
|
|
1743
1876
|
children: [
|
|
1744
|
-
copied ? /* @__PURE__ */
|
|
1745
|
-
/* @__PURE__ */
|
|
1877
|
+
copied ? /* @__PURE__ */ jsx8(Check, { size: 12 }) : /* @__PURE__ */ jsx8(Copy, { size: 12 }),
|
|
1878
|
+
/* @__PURE__ */ jsx8("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
|
|
1746
1879
|
]
|
|
1747
1880
|
}
|
|
1748
1881
|
)
|
|
1749
1882
|
] }),
|
|
1750
|
-
/* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx8(
|
|
1751
1884
|
"pre",
|
|
1752
1885
|
{
|
|
1753
1886
|
ref: preRef,
|
|
@@ -1759,22 +1892,36 @@ function CodeBlockPre({ children, node: _node, ...props }) {
|
|
|
1759
1892
|
] });
|
|
1760
1893
|
}
|
|
1761
1894
|
function ExternalAnchor({ node: _node, children, ...props }) {
|
|
1762
|
-
return /* @__PURE__ */
|
|
1895
|
+
return /* @__PURE__ */ jsx8("a", { ...props, target: "_blank", rel: "noopener noreferrer", children });
|
|
1763
1896
|
}
|
|
1764
1897
|
var MARKDOWN_COMPONENTS = {
|
|
1765
1898
|
pre: CodeBlockPre,
|
|
1766
1899
|
a: ExternalAnchor
|
|
1767
1900
|
};
|
|
1901
|
+
var CUSTOM_ALLOWED_TAGS = {
|
|
1902
|
+
[FILE_CARD_TAG]: ["dataPath", "dataName", "data-path", "data-name"]
|
|
1903
|
+
};
|
|
1768
1904
|
function MarkdownContent({ children, className, mode, sessionId }) {
|
|
1905
|
+
const streaming = mode === "streaming";
|
|
1769
1906
|
const resolvedChildren = useMemo5(() => {
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1907
|
+
const withoutReminders = children.replace(SYSTEM_REMINDER_RE, "");
|
|
1908
|
+
if (!sessionId) return withoutReminders;
|
|
1909
|
+
return collapseMediaTags(withoutReminders, { streaming });
|
|
1910
|
+
}, [children, sessionId, streaming]);
|
|
1911
|
+
const components = useMemo5(
|
|
1912
|
+
() => ({
|
|
1913
|
+
...MARKDOWN_COMPONENTS,
|
|
1914
|
+
[FILE_CARD_TAG]: (fileCardProps) => /* @__PURE__ */ jsx8(FileCard, { ...fileCardProps, sessionId })
|
|
1915
|
+
}),
|
|
1916
|
+
[sessionId]
|
|
1917
|
+
);
|
|
1918
|
+
return /* @__PURE__ */ jsx8(
|
|
1773
1919
|
_r,
|
|
1774
1920
|
{
|
|
1775
1921
|
className: cn("blade-chat-markdown break-words", className),
|
|
1776
1922
|
mode: mode ?? "static",
|
|
1777
|
-
components
|
|
1923
|
+
components,
|
|
1924
|
+
allowedTags: CUSTOM_ALLOWED_TAGS,
|
|
1778
1925
|
children: resolvedChildren
|
|
1779
1926
|
},
|
|
1780
1927
|
sessionId ?? "no-session"
|
|
@@ -1782,17 +1929,17 @@ function MarkdownContent({ children, className, mode, sessionId }) {
|
|
|
1782
1929
|
}
|
|
1783
1930
|
|
|
1784
1931
|
// src/components/Shimmer.tsx
|
|
1785
|
-
import { jsx as
|
|
1932
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1786
1933
|
function Shimmer({ children = "\u6B63\u5728\u601D\u8003...", className }) {
|
|
1787
|
-
return /* @__PURE__ */
|
|
1934
|
+
return /* @__PURE__ */ jsx9("span", { className: cn("blade-shimmer-text text-sm font-medium", className), children });
|
|
1788
1935
|
}
|
|
1789
1936
|
|
|
1790
1937
|
// src/components/ToolCallBlock.tsx
|
|
1791
|
-
import { useState as
|
|
1938
|
+
import { useState as useState9 } from "react";
|
|
1792
1939
|
|
|
1793
1940
|
// src/components/AskUserQuestionBlock.tsx
|
|
1794
|
-
import { useEffect as useEffect5, useMemo as useMemo6, useState as
|
|
1795
|
-
import { jsx as
|
|
1941
|
+
import { useEffect as useEffect5, useMemo as useMemo6, useState as useState8 } from "react";
|
|
1942
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1796
1943
|
function AskUserQuestionBlock({
|
|
1797
1944
|
data,
|
|
1798
1945
|
answered,
|
|
@@ -1801,10 +1948,10 @@ function AskUserQuestionBlock({
|
|
|
1801
1948
|
answerData,
|
|
1802
1949
|
onAnswer
|
|
1803
1950
|
}) {
|
|
1804
|
-
const [selections, setSelections] =
|
|
1805
|
-
const [customTexts, setCustomTexts] =
|
|
1806
|
-
const [usingCustom, setUsingCustom] =
|
|
1807
|
-
const [submitted, setSubmitted] =
|
|
1951
|
+
const [selections, setSelections] = useState8(/* @__PURE__ */ new Map());
|
|
1952
|
+
const [customTexts, setCustomTexts] = useState8(/* @__PURE__ */ new Map());
|
|
1953
|
+
const [usingCustom, setUsingCustom] = useState8(/* @__PURE__ */ new Set());
|
|
1954
|
+
const [submitted, setSubmitted] = useState8(false);
|
|
1808
1955
|
useEffect5(() => {
|
|
1809
1956
|
if (sessionStatus === "failed" || sessionStatus === "interrupted") {
|
|
1810
1957
|
setSubmitted(false);
|
|
@@ -1895,7 +2042,7 @@ ${parts.join("\n")}`;
|
|
|
1895
2042
|
setSubmitted(true);
|
|
1896
2043
|
onAnswer(text, toolCallId, nextAnswerData);
|
|
1897
2044
|
};
|
|
1898
|
-
return /* @__PURE__ */
|
|
2045
|
+
return /* @__PURE__ */ jsxs8(
|
|
1899
2046
|
"div",
|
|
1900
2047
|
{
|
|
1901
2048
|
className: cn(
|
|
@@ -1903,12 +2050,12 @@ ${parts.join("\n")}`;
|
|
|
1903
2050
|
answered ? "max-w-2xl space-y-3 p-3 text-xs text-[hsl(var(--muted-foreground))] opacity-80" : "max-w-lg space-y-5 p-4 text-sm"
|
|
1904
2051
|
),
|
|
1905
2052
|
children: [
|
|
1906
|
-
data.source_loop?.description && /* @__PURE__ */
|
|
2053
|
+
data.source_loop?.description && /* @__PURE__ */ jsxs8("div", { className: "rounded-lg bg-[hsl(var(--muted)/0.35)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
1907
2054
|
"\u5B50\u667A\u80FD\u4F53\u300C",
|
|
1908
2055
|
data.source_loop.description,
|
|
1909
2056
|
"\u300D\u5728\u7B49\u5F85\u4F60\u7684\u56DE\u7B54"
|
|
1910
2057
|
] }),
|
|
1911
|
-
data.questions.map((q, qIdx) => /* @__PURE__ */
|
|
2058
|
+
data.questions.map((q, qIdx) => /* @__PURE__ */ jsx10(
|
|
1912
2059
|
QuestionCard,
|
|
1913
2060
|
{
|
|
1914
2061
|
question: q,
|
|
@@ -1923,7 +2070,7 @@ ${parts.join("\n")}`;
|
|
|
1923
2070
|
},
|
|
1924
2071
|
q.question
|
|
1925
2072
|
)),
|
|
1926
|
-
!answered && !submitted && onAnswer && /* @__PURE__ */
|
|
2073
|
+
!answered && !submitted && onAnswer && /* @__PURE__ */ jsx10(
|
|
1927
2074
|
"button",
|
|
1928
2075
|
{
|
|
1929
2076
|
type: "button",
|
|
@@ -1933,14 +2080,14 @@ ${parts.join("\n")}`;
|
|
|
1933
2080
|
children: allAnswered ? "\u786E\u8BA4" : "\u8BF7\u5148\u9009\u62E9\u4E00\u4E2A\u9009\u9879"
|
|
1934
2081
|
}
|
|
1935
2082
|
),
|
|
1936
|
-
submitted && !answered && /* @__PURE__ */
|
|
2083
|
+
submitted && !answered && /* @__PURE__ */ jsxs8(
|
|
1937
2084
|
"button",
|
|
1938
2085
|
{
|
|
1939
2086
|
type: "button",
|
|
1940
2087
|
disabled: true,
|
|
1941
2088
|
className: "flex w-full items-center justify-center gap-2 rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-xs font-semibold text-[hsl(var(--primary-foreground))] opacity-80",
|
|
1942
2089
|
children: [
|
|
1943
|
-
/* @__PURE__ */
|
|
2090
|
+
/* @__PURE__ */ jsx10(LoaderCircle, { size: 14, className: "animate-spin" }),
|
|
1944
2091
|
"\u786E\u8BA4\u4E2D"
|
|
1945
2092
|
]
|
|
1946
2093
|
}
|
|
@@ -1961,30 +2108,30 @@ function QuestionCard({
|
|
|
1961
2108
|
onCustomChange
|
|
1962
2109
|
}) {
|
|
1963
2110
|
const multi = question.multiSelect ?? false;
|
|
1964
|
-
return /* @__PURE__ */
|
|
1965
|
-
/* @__PURE__ */
|
|
1966
|
-
/* @__PURE__ */
|
|
2111
|
+
return /* @__PURE__ */ jsxs8("div", { children: [
|
|
2112
|
+
/* @__PURE__ */ jsxs8("div", { className: cn("flex items-start gap-2", answered ? "mb-2" : "mb-3"), children: [
|
|
2113
|
+
/* @__PURE__ */ jsx10(
|
|
1967
2114
|
MessageSquareMore,
|
|
1968
2115
|
{
|
|
1969
2116
|
size: answered ? 12 : 13,
|
|
1970
2117
|
className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]"
|
|
1971
2118
|
}
|
|
1972
2119
|
),
|
|
1973
|
-
/* @__PURE__ */
|
|
2120
|
+
/* @__PURE__ */ jsx10(
|
|
1974
2121
|
"div",
|
|
1975
2122
|
{
|
|
1976
2123
|
className: cn(
|
|
1977
2124
|
"min-w-0 flex-1 font-medium text-[hsl(var(--foreground))]",
|
|
1978
2125
|
answered ? "text-xs" : "text-sm"
|
|
1979
2126
|
),
|
|
1980
|
-
children: /* @__PURE__ */
|
|
2127
|
+
children: /* @__PURE__ */ jsx10(MarkdownContent, { className: "blade-chat-prose", children: question.question })
|
|
1981
2128
|
}
|
|
1982
2129
|
)
|
|
1983
2130
|
] }),
|
|
1984
|
-
/* @__PURE__ */
|
|
2131
|
+
/* @__PURE__ */ jsxs8("div", { className: cn("flex flex-col pl-5", answered ? "gap-1" : "gap-1.5"), children: [
|
|
1985
2132
|
question.options.map((opt, optIdx) => {
|
|
1986
2133
|
const isSel = selected.has(optIdx);
|
|
1987
|
-
return /* @__PURE__ */
|
|
2134
|
+
return /* @__PURE__ */ jsxs8(
|
|
1988
2135
|
"button",
|
|
1989
2136
|
{
|
|
1990
2137
|
type: "button",
|
|
@@ -1998,14 +2145,14 @@ function QuestionCard({
|
|
|
1998
2145
|
answered && "cursor-default opacity-70"
|
|
1999
2146
|
),
|
|
2000
2147
|
children: [
|
|
2001
|
-
multi && /* @__PURE__ */
|
|
2148
|
+
multi && /* @__PURE__ */ jsx10(
|
|
2002
2149
|
"div",
|
|
2003
2150
|
{
|
|
2004
2151
|
className: cn(
|
|
2005
2152
|
"mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors",
|
|
2006
2153
|
isSel && !answered ? "border-[hsl(var(--primary-foreground)/0.6)] bg-[hsl(var(--primary-foreground)/0.2)]" : isSel ? "border-[hsl(var(--primary)/0.45)] bg-[hsl(var(--primary)/0.12)]" : "border-[hsl(var(--border))]"
|
|
2007
2154
|
),
|
|
2008
|
-
children: isSel && /* @__PURE__ */
|
|
2155
|
+
children: isSel && /* @__PURE__ */ jsx10(
|
|
2009
2156
|
Check,
|
|
2010
2157
|
{
|
|
2011
2158
|
size: 9,
|
|
@@ -2014,9 +2161,9 @@ function QuestionCard({
|
|
|
2014
2161
|
)
|
|
2015
2162
|
}
|
|
2016
2163
|
),
|
|
2017
|
-
/* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
opt.description && /* @__PURE__ */
|
|
2164
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
2165
|
+
/* @__PURE__ */ jsx10("div", { className: cn("font-medium", answered ? "text-xs" : "text-[13px]"), children: opt.label }),
|
|
2166
|
+
opt.description && /* @__PURE__ */ jsx10(
|
|
2020
2167
|
"div",
|
|
2021
2168
|
{
|
|
2022
2169
|
className: cn(
|
|
@@ -2033,7 +2180,7 @@ function QuestionCard({
|
|
|
2033
2180
|
opt.label
|
|
2034
2181
|
);
|
|
2035
2182
|
}),
|
|
2036
|
-
answered && !isCustom ? null : /* @__PURE__ */
|
|
2183
|
+
answered && !isCustom ? null : /* @__PURE__ */ jsxs8(
|
|
2037
2184
|
"div",
|
|
2038
2185
|
{
|
|
2039
2186
|
className: cn(
|
|
@@ -2043,8 +2190,8 @@ function QuestionCard({
|
|
|
2043
2190
|
answered && "cursor-default opacity-70"
|
|
2044
2191
|
),
|
|
2045
2192
|
children: [
|
|
2046
|
-
/* @__PURE__ */
|
|
2047
|
-
/* @__PURE__ */
|
|
2193
|
+
/* @__PURE__ */ jsx10("span", { className: "shrink-0 text-xs text-[hsl(var(--muted-foreground))]", children: "\u5176\u4ED6\uFF1A" }),
|
|
2194
|
+
/* @__PURE__ */ jsx10(
|
|
2048
2195
|
"input",
|
|
2049
2196
|
{
|
|
2050
2197
|
type: "text",
|
|
@@ -2112,7 +2259,7 @@ function normalizeOptionItem(value) {
|
|
|
2112
2259
|
}
|
|
2113
2260
|
|
|
2114
2261
|
// src/components/ToolCallBlock.tsx
|
|
2115
|
-
import { Fragment, jsx as
|
|
2262
|
+
import { Fragment, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2116
2263
|
function resolveAskQuestionState({
|
|
2117
2264
|
toolStatus,
|
|
2118
2265
|
hasAnswerData,
|
|
@@ -2132,12 +2279,12 @@ function ToolCallBlock({
|
|
|
2132
2279
|
sessionStatus,
|
|
2133
2280
|
renderer
|
|
2134
2281
|
}) {
|
|
2135
|
-
const [expanded, setExpanded] =
|
|
2282
|
+
const [expanded, setExpanded] = useState9(false);
|
|
2136
2283
|
const normalizedName = formatToolName(toolCall.name);
|
|
2137
2284
|
if (renderer) {
|
|
2138
2285
|
const custom = renderer(toolCall);
|
|
2139
2286
|
if (custom !== null && custom !== void 0) {
|
|
2140
|
-
return /* @__PURE__ */
|
|
2287
|
+
return /* @__PURE__ */ jsx11(Fragment, { children: custom });
|
|
2141
2288
|
}
|
|
2142
2289
|
}
|
|
2143
2290
|
if (normalizedName === "AskUserQuestion") {
|
|
@@ -2149,7 +2296,7 @@ function ToolCallBlock({
|
|
|
2149
2296
|
});
|
|
2150
2297
|
const canAnswer = questionState.awaitingAnswer && Boolean(onAnswer);
|
|
2151
2298
|
if (askData) {
|
|
2152
|
-
return /* @__PURE__ */
|
|
2299
|
+
return /* @__PURE__ */ jsx11(
|
|
2153
2300
|
AskUserQuestionBlock,
|
|
2154
2301
|
{
|
|
2155
2302
|
data: askData,
|
|
@@ -2162,24 +2309,24 @@ function ToolCallBlock({
|
|
|
2162
2309
|
);
|
|
2163
2310
|
}
|
|
2164
2311
|
if (toolCall.status === "pending") {
|
|
2165
|
-
return /* @__PURE__ */
|
|
2166
|
-
/* @__PURE__ */
|
|
2167
|
-
/* @__PURE__ */
|
|
2312
|
+
return /* @__PURE__ */ jsxs9("div", { className: "ml-4 flex max-w-lg items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-4 text-sm text-[hsl(var(--muted-foreground))]", children: [
|
|
2313
|
+
/* @__PURE__ */ jsx11(LoaderCircle, { size: 14, className: "animate-spin" }),
|
|
2314
|
+
/* @__PURE__ */ jsx11("span", { children: "\u6B63\u5728\u51C6\u5907\u95EE\u9898\u2026" })
|
|
2168
2315
|
] });
|
|
2169
2316
|
}
|
|
2170
|
-
return /* @__PURE__ */
|
|
2171
|
-
/* @__PURE__ */
|
|
2172
|
-
/* @__PURE__ */
|
|
2317
|
+
return /* @__PURE__ */ jsxs9("div", { className: "ml-4 max-w-lg rounded-xl border border-amber-500/35 bg-amber-500/10 p-4 text-sm text-[hsl(var(--foreground))]", children: [
|
|
2318
|
+
/* @__PURE__ */ jsx11("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
|
|
2319
|
+
/* @__PURE__ */ jsx11("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" })
|
|
2173
2320
|
] });
|
|
2174
2321
|
}
|
|
2175
2322
|
const tone = getToolTone(toolCall.status);
|
|
2176
2323
|
const displayName = getToolDisplayLabel(toolCall);
|
|
2177
2324
|
const toneClass = tone === "red" ? "border-l-[hsl(var(--muted-foreground)/0.5)]" : tone === "amber" ? "border-l-amber-400" : tone === "blue" ? "border-l-blue-500" : "border-l-[hsl(var(--primary))]";
|
|
2178
|
-
const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */
|
|
2325
|
+
const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx11(LoaderCircle, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx11(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx11(X, { size: 11 }) : /* @__PURE__ */ jsx11(Check, { size: 11 });
|
|
2179
2326
|
const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
|
|
2180
|
-
return /* @__PURE__ */
|
|
2181
|
-
/* @__PURE__ */
|
|
2182
|
-
/* @__PURE__ */
|
|
2327
|
+
return /* @__PURE__ */ jsxs9("div", { className: "blade-chat-tool ml-4 text-xs", children: [
|
|
2328
|
+
/* @__PURE__ */ jsxs9("div", { className: cn("border-l-[3px] flex items-center gap-2 px-3 py-2", toneClass), children: [
|
|
2329
|
+
/* @__PURE__ */ jsxs9(
|
|
2183
2330
|
"button",
|
|
2184
2331
|
{
|
|
2185
2332
|
type: "button",
|
|
@@ -2187,7 +2334,7 @@ function ToolCallBlock({
|
|
|
2187
2334
|
className: "flex min-w-0 flex-1 items-center gap-2 text-left transition-colors hover:bg-white/3 focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
|
|
2188
2335
|
"aria-expanded": expanded,
|
|
2189
2336
|
children: [
|
|
2190
|
-
/* @__PURE__ */
|
|
2337
|
+
/* @__PURE__ */ jsx11(
|
|
2191
2338
|
ChevronRight,
|
|
2192
2339
|
{
|
|
2193
2340
|
size: 11,
|
|
@@ -2197,24 +2344,24 @@ function ToolCallBlock({
|
|
|
2197
2344
|
)
|
|
2198
2345
|
}
|
|
2199
2346
|
),
|
|
2200
|
-
/* @__PURE__ */
|
|
2347
|
+
/* @__PURE__ */ jsxs9("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
|
|
2201
2348
|
statusIcon,
|
|
2202
|
-
/* @__PURE__ */
|
|
2349
|
+
/* @__PURE__ */ jsx11("span", { children: getToolStatusLabel(toolCall.status) })
|
|
2203
2350
|
] }),
|
|
2204
|
-
/* @__PURE__ */
|
|
2351
|
+
/* @__PURE__ */ jsx11("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: displayName })
|
|
2205
2352
|
]
|
|
2206
2353
|
}
|
|
2207
2354
|
),
|
|
2208
|
-
typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */
|
|
2355
|
+
typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx11("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) })
|
|
2209
2356
|
] }),
|
|
2210
|
-
expanded && /* @__PURE__ */
|
|
2211
|
-
/* @__PURE__ */
|
|
2212
|
-
/* @__PURE__ */
|
|
2213
|
-
/* @__PURE__ */
|
|
2214
|
-
/* @__PURE__ */
|
|
2215
|
-
toolCall.result != null && /* @__PURE__ */
|
|
2216
|
-
/* @__PURE__ */
|
|
2217
|
-
/* @__PURE__ */
|
|
2357
|
+
expanded && /* @__PURE__ */ jsxs9("div", { className: "blade-chat-tool-detail ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3", children: [
|
|
2358
|
+
/* @__PURE__ */ jsx11("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u5DE5\u5177" }),
|
|
2359
|
+
/* @__PURE__ */ jsx11("div", { className: "mb-3 font-mono text-[11px] text-[hsl(var(--foreground))]", children: normalizedName }),
|
|
2360
|
+
/* @__PURE__ */ jsx11("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
|
|
2361
|
+
/* @__PURE__ */ jsx11("pre", { className: "overflow-x-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolArgs(toolCall.arguments) }),
|
|
2362
|
+
toolCall.result != null && /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
2363
|
+
/* @__PURE__ */ jsx11("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
|
|
2364
|
+
/* @__PURE__ */ jsx11("pre", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolResult(toolCall.result) })
|
|
2218
2365
|
] })
|
|
2219
2366
|
] })
|
|
2220
2367
|
] });
|
|
@@ -2232,11 +2379,11 @@ function buildAskUserPayload(argumentsJson) {
|
|
|
2232
2379
|
}
|
|
2233
2380
|
|
|
2234
2381
|
// src/components/AssistantTurnBlock.tsx
|
|
2235
|
-
import { jsx as
|
|
2382
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2236
2383
|
function ThinkingBlock({ reasoning, isStreaming }) {
|
|
2237
|
-
const [open, setOpen] =
|
|
2238
|
-
return /* @__PURE__ */
|
|
2239
|
-
/* @__PURE__ */
|
|
2384
|
+
const [open, setOpen] = useState10(false);
|
|
2385
|
+
return /* @__PURE__ */ jsxs10("div", { className: "blade-chat-thinking ml-4 text-sm", children: [
|
|
2386
|
+
/* @__PURE__ */ jsxs10(
|
|
2240
2387
|
"button",
|
|
2241
2388
|
{
|
|
2242
2389
|
type: "button",
|
|
@@ -2244,14 +2391,14 @@ function ThinkingBlock({ reasoning, isStreaming }) {
|
|
|
2244
2391
|
"aria-expanded": open,
|
|
2245
2392
|
className: "inline-flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
|
|
2246
2393
|
children: [
|
|
2247
|
-
/* @__PURE__ */
|
|
2248
|
-
isStreaming ? /* @__PURE__ */
|
|
2249
|
-
/* @__PURE__ */
|
|
2394
|
+
/* @__PURE__ */ jsx12(Brain, { size: 12, className: "shrink-0" }),
|
|
2395
|
+
isStreaming ? /* @__PURE__ */ jsx12(Shimmer, { className: "text-xs", children: "\u6B63\u5728\u601D\u8003" }) : /* @__PURE__ */ jsx12("span", { children: "\u601D\u8003\u8FC7\u7A0B" }),
|
|
2396
|
+
/* @__PURE__ */ jsxs10("span", { className: "text-[hsl(var(--muted-foreground))]/70", children: [
|
|
2250
2397
|
"\xB7 ",
|
|
2251
2398
|
new Intl.NumberFormat("zh-CN").format(reasoning.length),
|
|
2252
2399
|
" \u5B57"
|
|
2253
2400
|
] }),
|
|
2254
|
-
/* @__PURE__ */
|
|
2401
|
+
/* @__PURE__ */ jsx12(
|
|
2255
2402
|
ChevronDown,
|
|
2256
2403
|
{
|
|
2257
2404
|
size: 12,
|
|
@@ -2261,7 +2408,7 @@ function ThinkingBlock({ reasoning, isStreaming }) {
|
|
|
2261
2408
|
]
|
|
2262
2409
|
}
|
|
2263
2410
|
),
|
|
2264
|
-
open && /* @__PURE__ */
|
|
2411
|
+
open && /* @__PURE__ */ jsx12("div", { className: "mt-1.5 whitespace-pre-wrap border-l-2 border-[hsl(var(--border))] pl-3 text-[11px] leading-5 text-[hsl(var(--muted-foreground))]", children: reasoning })
|
|
2265
2412
|
] });
|
|
2266
2413
|
}
|
|
2267
2414
|
function getMessageText(message) {
|
|
@@ -2287,21 +2434,21 @@ function AssistantTurnBlock({
|
|
|
2287
2434
|
(message) => getMessageText(message) || message.reasoning || (message.tool_calls?.length ?? 0) > 0
|
|
2288
2435
|
);
|
|
2289
2436
|
const latestReasoningIndex = isStreaming ? findLatestReasoningMessageIndex(messages) : -1;
|
|
2290
|
-
return /* @__PURE__ */
|
|
2291
|
-
hasInterrupted && /* @__PURE__ */
|
|
2437
|
+
return /* @__PURE__ */ jsxs10("div", { className: "blade-chat-assistant-turn flex flex-col gap-3", children: [
|
|
2438
|
+
hasInterrupted && /* @__PURE__ */ jsx12("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
|
|
2292
2439
|
messages.map((message, index) => {
|
|
2293
2440
|
const isLast = index === messages.length - 1;
|
|
2294
2441
|
const streamingThis = isStreaming && isLast;
|
|
2295
2442
|
const text = getMessageText(message);
|
|
2296
2443
|
const toolCalls = message.tool_calls ?? [];
|
|
2297
2444
|
const showReasoning = !!message.reasoning && (!isStreaming || index === latestReasoningIndex);
|
|
2298
|
-
return /* @__PURE__ */
|
|
2445
|
+
return /* @__PURE__ */ jsxs10(
|
|
2299
2446
|
"div",
|
|
2300
2447
|
{
|
|
2301
2448
|
className: "flex flex-col gap-3",
|
|
2302
2449
|
children: [
|
|
2303
|
-
showReasoning && message.reasoning && /* @__PURE__ */
|
|
2304
|
-
text && /* @__PURE__ */
|
|
2450
|
+
showReasoning && message.reasoning && /* @__PURE__ */ jsx12(ThinkingBlock, { reasoning: message.reasoning, isStreaming: streamingThis && !text }),
|
|
2451
|
+
text && /* @__PURE__ */ jsx12("div", { className: "blade-chat-assistant-text text-[15px] leading-8 text-[hsl(var(--foreground))]", children: /* @__PURE__ */ jsx12(
|
|
2305
2452
|
MarkdownContent,
|
|
2306
2453
|
{
|
|
2307
2454
|
mode: streamingThis ? "streaming" : "static",
|
|
@@ -2310,8 +2457,8 @@ function AssistantTurnBlock({
|
|
|
2310
2457
|
children: text
|
|
2311
2458
|
}
|
|
2312
2459
|
) }),
|
|
2313
|
-
toolCalls.length > 0 && /* @__PURE__ */
|
|
2314
|
-
(toolCall) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */
|
|
2460
|
+
toolCalls.length > 0 && /* @__PURE__ */ jsx12("div", { className: "flex flex-col gap-2", children: toolCalls.map(
|
|
2461
|
+
(toolCall) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx12(AgentLoopBlock, { toolCall }, toolCall.id) : /* @__PURE__ */ jsx12(
|
|
2315
2462
|
ToolCallBlock,
|
|
2316
2463
|
{
|
|
2317
2464
|
toolCall,
|
|
@@ -2329,13 +2476,13 @@ function AssistantTurnBlock({
|
|
|
2329
2476
|
message.entry_id ?? `${message.timestamp ?? "assistant"}-${index}`
|
|
2330
2477
|
);
|
|
2331
2478
|
}),
|
|
2332
|
-
isStreaming && !hasAnyContent && /* @__PURE__ */
|
|
2479
|
+
isStreaming && !hasAnyContent && /* @__PURE__ */ jsx12(Shimmer, { className: "ml-4", children: "\u6B63\u5728\u751F\u6210..." })
|
|
2333
2480
|
] });
|
|
2334
2481
|
}
|
|
2335
2482
|
|
|
2336
2483
|
// src/components/RenderErrorBoundary.tsx
|
|
2337
2484
|
import { Component } from "react";
|
|
2338
|
-
import { jsx as
|
|
2485
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2339
2486
|
function getFirstComponentName(componentStack) {
|
|
2340
2487
|
const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
|
|
2341
2488
|
return match?.[1] ?? null;
|
|
@@ -2368,408 +2515,23 @@ var RenderErrorBoundary = class extends Component {
|
|
|
2368
2515
|
return children;
|
|
2369
2516
|
}
|
|
2370
2517
|
const componentName = getFirstComponentName(componentStack);
|
|
2371
|
-
return /* @__PURE__ */
|
|
2372
|
-
/* @__PURE__ */
|
|
2373
|
-
/* @__PURE__ */
|
|
2374
|
-
/* @__PURE__ */
|
|
2518
|
+
return /* @__PURE__ */ jsx13("div", { className: "blade-chat-render-error rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-start gap-2", children: [
|
|
2519
|
+
/* @__PURE__ */ jsx13(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
|
|
2520
|
+
/* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
|
|
2521
|
+
/* @__PURE__ */ jsxs11("div", { className: "font-medium", children: [
|
|
2375
2522
|
label,
|
|
2376
2523
|
"\u6E32\u67D3\u5931\u8D25"
|
|
2377
2524
|
] }),
|
|
2378
|
-
/* @__PURE__ */
|
|
2525
|
+
/* @__PURE__ */ jsxs11("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
|
|
2379
2526
|
componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
|
|
2380
2527
|
error.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
|
|
2381
2528
|
] }),
|
|
2382
|
-
details ? /* @__PURE__ */
|
|
2529
|
+
details ? /* @__PURE__ */ jsx13("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
|
|
2383
2530
|
] })
|
|
2384
2531
|
] }) });
|
|
2385
2532
|
}
|
|
2386
2533
|
};
|
|
2387
2534
|
|
|
2388
|
-
// src/components/PostChatFollowupBlock.tsx
|
|
2389
|
-
import { useCallback as useCallback5, useEffect as useEffect6, useRef as useRef6, useState as useState10 } from "react";
|
|
2390
|
-
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2391
|
-
function emitInteraction(callback, event) {
|
|
2392
|
-
try {
|
|
2393
|
-
callback?.(event);
|
|
2394
|
-
} catch {
|
|
2395
|
-
}
|
|
2396
|
-
}
|
|
2397
|
-
function basename(path) {
|
|
2398
|
-
return path.split(/[\\/]/).filter(Boolean).pop() || path;
|
|
2399
|
-
}
|
|
2400
|
-
function isVideo(path) {
|
|
2401
|
-
return /\.(?:mp4|mov|webm|mkv|avi|m4v)$/i.test(path);
|
|
2402
|
-
}
|
|
2403
|
-
function ArtifactCard({
|
|
2404
|
-
artifact,
|
|
2405
|
-
sessionId,
|
|
2406
|
-
assistantEntryId,
|
|
2407
|
-
artifactIndex,
|
|
2408
|
-
onInteraction,
|
|
2409
|
-
onArtifactOpened
|
|
2410
|
-
}) {
|
|
2411
|
-
const client = useBladeClient();
|
|
2412
|
-
const [downloading, setDownloading] = useState10(false);
|
|
2413
|
-
const name = artifact.label || basename(artifact.target);
|
|
2414
|
-
if (artifact.kind === "link") {
|
|
2415
|
-
return /* @__PURE__ */ jsxs11(
|
|
2416
|
-
"a",
|
|
2417
|
-
{
|
|
2418
|
-
href: artifact.target,
|
|
2419
|
-
target: "_blank",
|
|
2420
|
-
rel: "noopener noreferrer",
|
|
2421
|
-
onClick: () => onArtifactOpened(artifactIndex, "link"),
|
|
2422
|
-
title: `${name}
|
|
2423
|
-
${artifact.target}`,
|
|
2424
|
-
className: "group relative flex min-w-0 items-center gap-1.5 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2 py-1.5 text-xs text-[hsl(var(--card-foreground))] hover:bg-[hsl(var(--accent))]",
|
|
2425
|
-
children: [
|
|
2426
|
-
/* @__PURE__ */ jsx13(Globe, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
|
|
2427
|
-
/* @__PURE__ */ jsx13("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
|
|
2428
|
-
/* @__PURE__ */ jsx13(ArrowUpRight, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
|
|
2429
|
-
]
|
|
2430
|
-
}
|
|
2431
|
-
);
|
|
2432
|
-
}
|
|
2433
|
-
const Icon2 = isVideo(artifact.target) ? Film : File;
|
|
2434
|
-
return /* @__PURE__ */ jsxs11(
|
|
2435
|
-
"button",
|
|
2436
|
-
{
|
|
2437
|
-
type: "button",
|
|
2438
|
-
disabled: !sessionId || downloading,
|
|
2439
|
-
onClick: async () => {
|
|
2440
|
-
if (!sessionId || downloading) return;
|
|
2441
|
-
setDownloading(true);
|
|
2442
|
-
emitInteraction(onInteraction, {
|
|
2443
|
-
type: "artifact_download_started",
|
|
2444
|
-
sessionId,
|
|
2445
|
-
assistantEntryId,
|
|
2446
|
-
artifactIndex,
|
|
2447
|
-
artifactKind: "file"
|
|
2448
|
-
});
|
|
2449
|
-
try {
|
|
2450
|
-
await client.sessions.downloadFile(sessionId, artifact.target, basename(artifact.target));
|
|
2451
|
-
emitInteraction(onInteraction, {
|
|
2452
|
-
type: "artifact_download_succeeded",
|
|
2453
|
-
sessionId,
|
|
2454
|
-
assistantEntryId,
|
|
2455
|
-
artifactIndex,
|
|
2456
|
-
artifactKind: "file"
|
|
2457
|
-
});
|
|
2458
|
-
} catch {
|
|
2459
|
-
} finally {
|
|
2460
|
-
setDownloading(false);
|
|
2461
|
-
}
|
|
2462
|
-
},
|
|
2463
|
-
title: name,
|
|
2464
|
-
"aria-label": `\u4E0B\u8F7D ${name}`,
|
|
2465
|
-
className: "group relative flex min-w-0 items-center gap-1.5 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2 py-1.5 text-left text-xs text-[hsl(var(--card-foreground))] hover:bg-[hsl(var(--accent))] disabled:opacity-60",
|
|
2466
|
-
children: [
|
|
2467
|
-
/* @__PURE__ */ jsx13(Icon2, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
|
|
2468
|
-
/* @__PURE__ */ jsx13("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
|
|
2469
|
-
/* @__PURE__ */ jsx13(Download, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
|
|
2470
|
-
]
|
|
2471
|
-
}
|
|
2472
|
-
);
|
|
2473
|
-
}
|
|
2474
|
-
var FEEDBACK_REASONS = [
|
|
2475
|
-
{ value: "not_solved", label: "\u6CA1\u89E3\u51B3\u95EE\u9898" },
|
|
2476
|
-
{ value: "inaccurate", label: "\u5185\u5BB9\u4E0D\u51C6\u786E" },
|
|
2477
|
-
{ value: "incomplete", label: "\u5185\u5BB9\u4E0D\u5B8C\u6574" },
|
|
2478
|
-
{ value: "needs_major_changes", label: "\u9700\u8981\u5927\u91CF\u4FEE\u6539" },
|
|
2479
|
-
{ value: "too_slow", label: "\u592A\u6162" },
|
|
2480
|
-
{ value: "other", label: "\u5176\u4ED6" }
|
|
2481
|
-
];
|
|
2482
|
-
function feedbackReasonLabel(reason) {
|
|
2483
|
-
return FEEDBACK_REASONS.find((item) => item.value === reason)?.label ?? null;
|
|
2484
|
-
}
|
|
2485
|
-
function HistoricalResultFeedback({ feedback }) {
|
|
2486
|
-
const label = feedbackReasonLabel(feedback.reason);
|
|
2487
|
-
return /* @__PURE__ */ jsxs11(
|
|
2488
|
-
"section",
|
|
2489
|
-
{
|
|
2490
|
-
"aria-label": "\u5386\u53F2\u7ED3\u679C\u53CD\u9988",
|
|
2491
|
-
className: "mt-3 w-fit max-w-full rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.2)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]",
|
|
2492
|
-
children: [
|
|
2493
|
-
/* @__PURE__ */ jsxs11("span", { children: [
|
|
2494
|
-
"\u4F60\u5BF9\u6B64\u8F6E\u7ED3\u679C\u7684\u8BC4\u4EF7\uFF1A",
|
|
2495
|
-
feedback.helpful ? "\u6709\u5E2E\u52A9" : "\u6CA1\u5E2E\u52A9"
|
|
2496
|
-
] }),
|
|
2497
|
-
label ? /* @__PURE__ */ jsxs11("span", { children: [
|
|
2498
|
-
" \xB7 ",
|
|
2499
|
-
label
|
|
2500
|
-
] }) : null
|
|
2501
|
-
]
|
|
2502
|
-
}
|
|
2503
|
-
);
|
|
2504
|
-
}
|
|
2505
|
-
function ResultFeedback({
|
|
2506
|
-
followup,
|
|
2507
|
-
sessionId,
|
|
2508
|
-
isViewer,
|
|
2509
|
-
onInteraction,
|
|
2510
|
-
savedFeedback,
|
|
2511
|
-
onFeedbackSaved
|
|
2512
|
-
}) {
|
|
2513
|
-
const client = useBladeClient();
|
|
2514
|
-
const [saved, setSaved] = useState10(savedFeedback ?? null);
|
|
2515
|
-
const [helpful, setHelpful] = useState10(savedFeedback?.helpful ?? null);
|
|
2516
|
-
const [reason, setReason] = useState10(savedFeedback?.reason ?? null);
|
|
2517
|
-
const [saving, setSaving] = useState10(false);
|
|
2518
|
-
const [saveError, setSaveError] = useState10(false);
|
|
2519
|
-
const reportedShown = useRef6(false);
|
|
2520
|
-
const latestChoice = useRef6(null);
|
|
2521
|
-
const eligible = followup.feedback_eligible === true && Boolean(sessionId) && !isViewer;
|
|
2522
|
-
useEffect6(() => {
|
|
2523
|
-
if (!eligible || reportedShown.current) return;
|
|
2524
|
-
reportedShown.current = true;
|
|
2525
|
-
emitInteraction(onInteraction, {
|
|
2526
|
-
type: "result_feedback_shown",
|
|
2527
|
-
sessionId,
|
|
2528
|
-
assistantEntryId: followup.assistant_entry_id
|
|
2529
|
-
});
|
|
2530
|
-
}, [eligible, followup.assistant_entry_id, onInteraction, sessionId]);
|
|
2531
|
-
useEffect6(() => {
|
|
2532
|
-
if (!savedFeedback || latestChoice.current) return;
|
|
2533
|
-
setSaved(savedFeedback);
|
|
2534
|
-
setHelpful(savedFeedback.helpful);
|
|
2535
|
-
setReason(savedFeedback.reason);
|
|
2536
|
-
}, [savedFeedback]);
|
|
2537
|
-
const submit = useCallback5(
|
|
2538
|
-
async (nextHelpful, nextReason) => {
|
|
2539
|
-
if (!sessionId) return;
|
|
2540
|
-
const choice = { helpful: nextHelpful, reason: nextReason };
|
|
2541
|
-
latestChoice.current = choice;
|
|
2542
|
-
setHelpful(nextHelpful);
|
|
2543
|
-
setReason(nextReason);
|
|
2544
|
-
setSaving(true);
|
|
2545
|
-
setSaveError(false);
|
|
2546
|
-
try {
|
|
2547
|
-
const result = await client.sessions.putResultFeedback(
|
|
2548
|
-
sessionId,
|
|
2549
|
-
followup.assistant_entry_id,
|
|
2550
|
-
choice
|
|
2551
|
-
);
|
|
2552
|
-
if (latestChoice.current !== choice) return;
|
|
2553
|
-
setSaved(result);
|
|
2554
|
-
onFeedbackSaved?.(result);
|
|
2555
|
-
emitInteraction(onInteraction, {
|
|
2556
|
-
type: "result_feedback_submitted",
|
|
2557
|
-
sessionId,
|
|
2558
|
-
assistantEntryId: followup.assistant_entry_id,
|
|
2559
|
-
helpful: result.helpful,
|
|
2560
|
-
reason: result.reason,
|
|
2561
|
-
updatedAt: result.updated_at
|
|
2562
|
-
});
|
|
2563
|
-
} catch {
|
|
2564
|
-
if (latestChoice.current === choice) setSaveError(true);
|
|
2565
|
-
} finally {
|
|
2566
|
-
if (latestChoice.current === choice) setSaving(false);
|
|
2567
|
-
}
|
|
2568
|
-
},
|
|
2569
|
-
[client, followup.assistant_entry_id, onFeedbackSaved, onInteraction, sessionId]
|
|
2570
|
-
);
|
|
2571
|
-
if (!eligible) return null;
|
|
2572
|
-
return /* @__PURE__ */ jsxs11(
|
|
2573
|
-
"section",
|
|
2574
|
-
{
|
|
2575
|
-
"aria-label": "\u7ED3\u679C\u53CD\u9988",
|
|
2576
|
-
className: "flex flex-col gap-2 border-t border-[hsl(var(--border))] pt-3",
|
|
2577
|
-
children: [
|
|
2578
|
-
/* @__PURE__ */ jsx13("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
|
|
2579
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap gap-1.5", children: [
|
|
2580
|
-
/* @__PURE__ */ jsx13(
|
|
2581
|
-
"button",
|
|
2582
|
-
{
|
|
2583
|
-
type: "button",
|
|
2584
|
-
"aria-pressed": helpful === true,
|
|
2585
|
-
disabled: saving,
|
|
2586
|
-
onClick: () => void submit(true, null),
|
|
2587
|
-
className: "rounded-lg border border-[hsl(var(--border))] px-2.5 py-1.5 text-xs aria-pressed:bg-[hsl(var(--primary)/0.1)] disabled:opacity-60",
|
|
2588
|
-
children: "\u6709\u5E2E\u52A9"
|
|
2589
|
-
}
|
|
2590
|
-
),
|
|
2591
|
-
/* @__PURE__ */ jsx13(
|
|
2592
|
-
"button",
|
|
2593
|
-
{
|
|
2594
|
-
type: "button",
|
|
2595
|
-
"aria-pressed": helpful === false,
|
|
2596
|
-
disabled: saving,
|
|
2597
|
-
onClick: () => void submit(false, reason),
|
|
2598
|
-
className: "rounded-lg border border-[hsl(var(--border))] px-2.5 py-1.5 text-xs aria-pressed:bg-[hsl(var(--primary)/0.1)] disabled:opacity-60",
|
|
2599
|
-
children: "\u6CA1\u5E2E\u52A9"
|
|
2600
|
-
}
|
|
2601
|
-
)
|
|
2602
|
-
] }),
|
|
2603
|
-
helpful === false ? /* @__PURE__ */ jsx13("div", { className: "flex flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: FEEDBACK_REASONS.map((item) => /* @__PURE__ */ jsx13(
|
|
2604
|
-
"button",
|
|
2605
|
-
{
|
|
2606
|
-
type: "button",
|
|
2607
|
-
"aria-pressed": reason === item.value,
|
|
2608
|
-
disabled: saving,
|
|
2609
|
-
onClick: () => void submit(false, item.value),
|
|
2610
|
-
className: "rounded-full bg-[hsl(var(--muted)/0.62)] px-2.5 py-1 text-[11px] aria-pressed:bg-[hsl(var(--primary)/0.14)] disabled:opacity-60",
|
|
2611
|
-
children: item.label
|
|
2612
|
-
},
|
|
2613
|
-
item.value
|
|
2614
|
-
)) }) : null,
|
|
2615
|
-
saveError ? /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--destructive))]", children: [
|
|
2616
|
-
/* @__PURE__ */ jsx13("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
|
|
2617
|
-
/* @__PURE__ */ jsx13(
|
|
2618
|
-
"button",
|
|
2619
|
-
{
|
|
2620
|
-
type: "button",
|
|
2621
|
-
className: "underline",
|
|
2622
|
-
onClick: () => {
|
|
2623
|
-
const choice = latestChoice.current;
|
|
2624
|
-
if (choice) void submit(choice.helpful, choice.reason);
|
|
2625
|
-
},
|
|
2626
|
-
children: "\u91CD\u8BD5"
|
|
2627
|
-
}
|
|
2628
|
-
)
|
|
2629
|
-
] }) : saved ? /* @__PURE__ */ jsx13("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
|
|
2630
|
-
]
|
|
2631
|
-
}
|
|
2632
|
-
);
|
|
2633
|
-
}
|
|
2634
|
-
function PostChatFollowupBlock({
|
|
2635
|
-
followup,
|
|
2636
|
-
sessionId,
|
|
2637
|
-
onSuggestion,
|
|
2638
|
-
isViewer = false,
|
|
2639
|
-
onInteraction,
|
|
2640
|
-
savedFeedback,
|
|
2641
|
-
onFeedbackSaved
|
|
2642
|
-
}) {
|
|
2643
|
-
const [expanded, setExpanded] = useState10(false);
|
|
2644
|
-
const adopted = useRef6(/* @__PURE__ */ new Set());
|
|
2645
|
-
const reportedSuggestions = useRef6(false);
|
|
2646
|
-
const reportedArtifacts = useRef6(/* @__PURE__ */ new Set());
|
|
2647
|
-
const openedArtifacts = useRef6(/* @__PURE__ */ new Set());
|
|
2648
|
-
const artifacts = followup.final_artifacts ?? [];
|
|
2649
|
-
const visibleArtifacts = expanded ? artifacts : artifacts.slice(0, 3);
|
|
2650
|
-
useEffect6(() => {
|
|
2651
|
-
if (!reportedSuggestions.current && followup.suggestions.length > 0) {
|
|
2652
|
-
reportedSuggestions.current = true;
|
|
2653
|
-
emitInteraction(onInteraction, {
|
|
2654
|
-
type: "suggestions_shown",
|
|
2655
|
-
sessionId,
|
|
2656
|
-
assistantEntryId: followup.assistant_entry_id,
|
|
2657
|
-
count: followup.suggestions.length
|
|
2658
|
-
});
|
|
2659
|
-
}
|
|
2660
|
-
for (let artifactIndex = 0; artifactIndex < visibleArtifacts.length; artifactIndex += 1) {
|
|
2661
|
-
if (reportedArtifacts.current.has(artifactIndex)) continue;
|
|
2662
|
-
const artifact = visibleArtifacts[artifactIndex];
|
|
2663
|
-
if (!artifact) continue;
|
|
2664
|
-
reportedArtifacts.current.add(artifactIndex);
|
|
2665
|
-
emitInteraction(onInteraction, {
|
|
2666
|
-
type: "artifact_shown",
|
|
2667
|
-
sessionId,
|
|
2668
|
-
assistantEntryId: followup.assistant_entry_id,
|
|
2669
|
-
artifactIndex,
|
|
2670
|
-
artifactKind: artifact.kind
|
|
2671
|
-
});
|
|
2672
|
-
}
|
|
2673
|
-
}, [
|
|
2674
|
-
followup.assistant_entry_id,
|
|
2675
|
-
followup.suggestions.length,
|
|
2676
|
-
onInteraction,
|
|
2677
|
-
sessionId,
|
|
2678
|
-
visibleArtifacts
|
|
2679
|
-
]);
|
|
2680
|
-
const reportArtifactOpened = useCallback5(
|
|
2681
|
-
(artifactIndex, artifactKind) => {
|
|
2682
|
-
if (openedArtifacts.current.has(artifactIndex)) return;
|
|
2683
|
-
openedArtifacts.current.add(artifactIndex);
|
|
2684
|
-
emitInteraction(onInteraction, {
|
|
2685
|
-
type: "artifact_opened",
|
|
2686
|
-
sessionId,
|
|
2687
|
-
assistantEntryId: followup.assistant_entry_id,
|
|
2688
|
-
artifactIndex,
|
|
2689
|
-
artifactKind
|
|
2690
|
-
});
|
|
2691
|
-
},
|
|
2692
|
-
[followup.assistant_entry_id, onInteraction, sessionId]
|
|
2693
|
-
);
|
|
2694
|
-
if (!followup.recaption && artifacts.length === 0 && followup.suggestions.length === 0 && !followup.feedback_eligible)
|
|
2695
|
-
return null;
|
|
2696
|
-
return /* @__PURE__ */ jsxs11("div", { className: "mt-3 flex w-fit max-w-full flex-col gap-3 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.28)] p-3 sm:max-w-[680px]", children: [
|
|
2697
|
-
followup.recaption || artifacts.length > 0 ? /* @__PURE__ */ jsxs11("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", className: "flex flex-col gap-2", children: [
|
|
2698
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]", children: [
|
|
2699
|
-
/* @__PURE__ */ jsx13(Sparkles, { size: 14 }),
|
|
2700
|
-
"\u672C\u8F6E\u5C0F\u7ED3"
|
|
2701
|
-
] }),
|
|
2702
|
-
followup.recaption ? /* @__PURE__ */ jsx13("p", { className: "text-[13px] leading-5", children: followup.recaption }) : null,
|
|
2703
|
-
artifacts.length > 0 ? /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
2704
|
-
/* @__PURE__ */ jsx13("div", { className: "grid max-w-full grid-cols-3 gap-1.5", children: visibleArtifacts.map((artifact, artifactIndex) => /* @__PURE__ */ jsx13(
|
|
2705
|
-
ArtifactCard,
|
|
2706
|
-
{
|
|
2707
|
-
artifact,
|
|
2708
|
-
sessionId,
|
|
2709
|
-
assistantEntryId: followup.assistant_entry_id,
|
|
2710
|
-
artifactIndex,
|
|
2711
|
-
onInteraction,
|
|
2712
|
-
onArtifactOpened: reportArtifactOpened
|
|
2713
|
-
},
|
|
2714
|
-
`${artifact.kind}:${artifactIndex}`
|
|
2715
|
-
)) }),
|
|
2716
|
-
artifacts.length > 3 ? /* @__PURE__ */ jsxs11(
|
|
2717
|
-
"button",
|
|
2718
|
-
{
|
|
2719
|
-
type: "button",
|
|
2720
|
-
onClick: () => setExpanded((value) => !value),
|
|
2721
|
-
"aria-expanded": expanded,
|
|
2722
|
-
className: "flex w-fit items-center gap-0.5 text-[11px] text-[hsl(var(--muted-foreground))]",
|
|
2723
|
-
children: [
|
|
2724
|
-
expanded ? "\u6536\u8D77" : `\u5C55\u5F00 ${artifacts.length - 3} \u4E2A`,
|
|
2725
|
-
/* @__PURE__ */ jsx13(ChevronDown, { size: 13, className: expanded ? "rotate-180" : void 0 })
|
|
2726
|
-
]
|
|
2727
|
-
}
|
|
2728
|
-
) : null
|
|
2729
|
-
] }) : null
|
|
2730
|
-
] }) : null,
|
|
2731
|
-
followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs11("section", { "aria-label": "\u4E0B\u4E00\u6B65\u5EFA\u8BAE", className: "flex flex-col gap-1.5", children: [
|
|
2732
|
-
/* @__PURE__ */ jsx13("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
|
|
2733
|
-
followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */ jsxs11(
|
|
2734
|
-
"button",
|
|
2735
|
-
{
|
|
2736
|
-
type: "button",
|
|
2737
|
-
disabled: isViewer,
|
|
2738
|
-
onClick: () => {
|
|
2739
|
-
if (!adopted.current.has(suggestionIndex)) {
|
|
2740
|
-
adopted.current.add(suggestionIndex);
|
|
2741
|
-
emitInteraction(onInteraction, {
|
|
2742
|
-
type: "suggestion_adopted",
|
|
2743
|
-
sessionId,
|
|
2744
|
-
assistantEntryId: followup.assistant_entry_id,
|
|
2745
|
-
suggestionIndex
|
|
2746
|
-
});
|
|
2747
|
-
}
|
|
2748
|
-
onSuggestion?.(suggestion);
|
|
2749
|
-
},
|
|
2750
|
-
className: "group flex items-center gap-2 rounded-xl bg-[hsl(var(--muted)/0.62)] px-3 py-2 text-left text-[13px] disabled:cursor-default disabled:opacity-60",
|
|
2751
|
-
children: [
|
|
2752
|
-
/* @__PURE__ */ jsx13("span", { children: suggestion }),
|
|
2753
|
-
/* @__PURE__ */ jsx13(ArrowRight, { size: 14, className: "ml-auto shrink-0" })
|
|
2754
|
-
]
|
|
2755
|
-
},
|
|
2756
|
-
suggestion
|
|
2757
|
-
))
|
|
2758
|
-
] }) : null,
|
|
2759
|
-
/* @__PURE__ */ jsx13(
|
|
2760
|
-
ResultFeedback,
|
|
2761
|
-
{
|
|
2762
|
-
followup,
|
|
2763
|
-
sessionId,
|
|
2764
|
-
isViewer,
|
|
2765
|
-
onInteraction,
|
|
2766
|
-
savedFeedback,
|
|
2767
|
-
onFeedbackSaved
|
|
2768
|
-
}
|
|
2769
|
-
)
|
|
2770
|
-
] });
|
|
2771
|
-
}
|
|
2772
|
-
|
|
2773
2535
|
// src/components/UserMessageBubble.tsx
|
|
2774
2536
|
import { getFileParts, getImageParts, getTextContent as getTextContent2 } from "@blade-hq/agent-client";
|
|
2775
2537
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
@@ -2855,8 +2617,6 @@ function getMessageResetSignature(messages) {
|
|
|
2855
2617
|
}
|
|
2856
2618
|
function MessageList({
|
|
2857
2619
|
messages,
|
|
2858
|
-
postChatFollowup,
|
|
2859
|
-
onSuggestion,
|
|
2860
2620
|
isStreaming,
|
|
2861
2621
|
sessionStatus,
|
|
2862
2622
|
askAnswers,
|
|
@@ -2864,11 +2624,7 @@ function MessageList({
|
|
|
2864
2624
|
toolCallRenderer,
|
|
2865
2625
|
emptyState,
|
|
2866
2626
|
className,
|
|
2867
|
-
sessionId
|
|
2868
|
-
isViewer = false,
|
|
2869
|
-
onFollowupInteraction,
|
|
2870
|
-
resultFeedbackByEntry = /* @__PURE__ */ new Map(),
|
|
2871
|
-
onResultFeedbackSaved
|
|
2627
|
+
sessionId
|
|
2872
2628
|
}) {
|
|
2873
2629
|
const renderBlocks = useMemo7(() => {
|
|
2874
2630
|
const visible = messages.filter((message) => {
|
|
@@ -2954,47 +2710,24 @@ function MessageList({
|
|
|
2954
2710
|
return /* @__PURE__ */ jsx15("div", { "data-entry-id": block.message.entry_id, children: isUserMessage(block.message) ? /* @__PURE__ */ jsx15(UserMessageBubble, { message: block.message }) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx15(ErrorMessageBlock, { message: block.message }) : null }, block.key);
|
|
2955
2711
|
}
|
|
2956
2712
|
if (block.type === "assistant_turn") {
|
|
2957
|
-
|
|
2958
|
-
(message) => message.entry_id ? resultFeedbackByEntry.get(message.entry_id) : void 0
|
|
2959
|
-
).find((feedback) => feedback != null);
|
|
2960
|
-
const hasActiveFollowup = Boolean(
|
|
2961
|
-
postChatFollowup && block.messages.some(
|
|
2962
|
-
(message) => message.entry_id === postChatFollowup.assistant_entry_id
|
|
2963
|
-
)
|
|
2964
|
-
);
|
|
2965
|
-
return /* @__PURE__ */ jsx15("div", { "data-entry-id": block.messages[0]?.entry_id, children: /* @__PURE__ */ jsxs13(
|
|
2713
|
+
return /* @__PURE__ */ jsx15("div", { "data-entry-id": block.messages[0]?.entry_id, children: /* @__PURE__ */ jsx15(
|
|
2966
2714
|
RenderErrorBoundary,
|
|
2967
2715
|
{
|
|
2968
2716
|
label: "\u52A9\u624B\u6D88\u606F",
|
|
2969
2717
|
details: block.key,
|
|
2970
2718
|
resetKey: getMessageResetSignature(block.messages),
|
|
2971
|
-
children:
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
),
|
|
2984
|
-
blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx15(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
|
|
2985
|
-
hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx15(
|
|
2986
|
-
PostChatFollowupBlock,
|
|
2987
|
-
{
|
|
2988
|
-
followup: postChatFollowup,
|
|
2989
|
-
sessionId,
|
|
2990
|
-
onSuggestion,
|
|
2991
|
-
isViewer,
|
|
2992
|
-
onInteraction: onFollowupInteraction,
|
|
2993
|
-
savedFeedback: blockFeedback,
|
|
2994
|
-
onFeedbackSaved: onResultFeedbackSaved
|
|
2995
|
-
}
|
|
2996
|
-
) : null
|
|
2997
|
-
]
|
|
2719
|
+
children: /* @__PURE__ */ jsx15(
|
|
2720
|
+
AssistantTurnBlock,
|
|
2721
|
+
{
|
|
2722
|
+
messages: block.messages,
|
|
2723
|
+
isStreaming: block.isStreaming,
|
|
2724
|
+
askAnswers,
|
|
2725
|
+
onAnswer,
|
|
2726
|
+
sessionStatus,
|
|
2727
|
+
toolCallRenderer,
|
|
2728
|
+
sessionId
|
|
2729
|
+
}
|
|
2730
|
+
)
|
|
2998
2731
|
}
|
|
2999
2732
|
) }, block.key);
|
|
3000
2733
|
}
|
|
@@ -3021,8 +2754,8 @@ function MessageList({
|
|
|
3021
2754
|
}
|
|
3022
2755
|
function AutoScrollOnUserSend({ userMessageCount }) {
|
|
3023
2756
|
const { scrollToBottom } = useStickToBottomContext();
|
|
3024
|
-
const previousCountRef =
|
|
3025
|
-
|
|
2757
|
+
const previousCountRef = useRef6(userMessageCount);
|
|
2758
|
+
useEffect6(() => {
|
|
3026
2759
|
if (userMessageCount > previousCountRef.current) {
|
|
3027
2760
|
scrollToBottom("instant");
|
|
3028
2761
|
}
|
|
@@ -3033,8 +2766,8 @@ function AutoScrollOnUserSend({ userMessageCount }) {
|
|
|
3033
2766
|
function ScrollToBottomButton() {
|
|
3034
2767
|
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
|
3035
2768
|
const [visible, setVisible] = useState11(false);
|
|
3036
|
-
const hideTimerRef =
|
|
3037
|
-
|
|
2769
|
+
const hideTimerRef = useRef6(null);
|
|
2770
|
+
useEffect6(() => {
|
|
3038
2771
|
if (isAtBottom) {
|
|
3039
2772
|
if (!hideTimerRef.current) {
|
|
3040
2773
|
hideTimerRef.current = setTimeout(() => {
|
|
@@ -3056,7 +2789,7 @@ function ScrollToBottomButton() {
|
|
|
3056
2789
|
}
|
|
3057
2790
|
};
|
|
3058
2791
|
}, [isAtBottom]);
|
|
3059
|
-
const handleClick =
|
|
2792
|
+
const handleClick = useCallback5(() => {
|
|
3060
2793
|
if (hideTimerRef.current) {
|
|
3061
2794
|
clearTimeout(hideTimerRef.current);
|
|
3062
2795
|
hideTimerRef.current = null;
|
|
@@ -3104,22 +2837,16 @@ function ChatSurface({
|
|
|
3104
2837
|
connection,
|
|
3105
2838
|
errorMessage,
|
|
3106
2839
|
messages,
|
|
3107
|
-
postChatFollowup,
|
|
3108
2840
|
isStreaming,
|
|
3109
2841
|
isStopping,
|
|
3110
2842
|
inputText,
|
|
3111
2843
|
onInputChange,
|
|
3112
|
-
onSuggestion,
|
|
3113
2844
|
onSend,
|
|
3114
2845
|
onStop,
|
|
3115
2846
|
sessionStatus,
|
|
3116
2847
|
askAnswers,
|
|
3117
2848
|
onAnswer,
|
|
3118
2849
|
sessionId,
|
|
3119
|
-
isViewer,
|
|
3120
|
-
resultFeedbackByEntry,
|
|
3121
|
-
onResultFeedbackSaved,
|
|
3122
|
-
onFollowupInteraction,
|
|
3123
2850
|
beforeInput,
|
|
3124
2851
|
banner
|
|
3125
2852
|
}) {
|
|
@@ -3143,8 +2870,6 @@ function ChatSurface({
|
|
|
3143
2870
|
MessageList,
|
|
3144
2871
|
{
|
|
3145
2872
|
messages,
|
|
3146
|
-
postChatFollowup,
|
|
3147
|
-
onSuggestion,
|
|
3148
2873
|
isStreaming,
|
|
3149
2874
|
sessionStatus,
|
|
3150
2875
|
askAnswers,
|
|
@@ -3152,11 +2877,7 @@ function ChatSurface({
|
|
|
3152
2877
|
toolCallRenderer: renderers?.toolCall,
|
|
3153
2878
|
emptyState: slots?.emptyState,
|
|
3154
2879
|
className: classNames?.messageList,
|
|
3155
|
-
sessionId
|
|
3156
|
-
isViewer,
|
|
3157
|
-
resultFeedbackByEntry,
|
|
3158
|
-
onResultFeedbackSaved,
|
|
3159
|
-
onFollowupInteraction
|
|
2880
|
+
sessionId
|
|
3160
2881
|
}
|
|
3161
2882
|
),
|
|
3162
2883
|
beforeInput,
|
|
@@ -3180,7 +2901,7 @@ function ChatSurface({
|
|
|
3180
2901
|
}
|
|
3181
2902
|
|
|
3182
2903
|
// src/components/AgentChat.tsx
|
|
3183
|
-
import { Fragment as
|
|
2904
|
+
import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3184
2905
|
function isUnauthorizedError(error) {
|
|
3185
2906
|
return error instanceof BladeApiError && error.status === 401;
|
|
3186
2907
|
}
|
|
@@ -3252,10 +2973,8 @@ function ChatSessionView({
|
|
|
3252
2973
|
slots,
|
|
3253
2974
|
placeholder,
|
|
3254
2975
|
theme,
|
|
3255
|
-
onFollowupInteraction,
|
|
3256
2976
|
onUnauthorized
|
|
3257
2977
|
}) {
|
|
3258
|
-
const client = useBladeClient();
|
|
3259
2978
|
const { session, state, error } = useAgentSession(sessionId, {
|
|
3260
2979
|
createOptions,
|
|
3261
2980
|
onSessionCreated
|
|
@@ -3263,50 +2982,12 @@ function ChatSessionView({
|
|
|
3263
2982
|
const replay = useReplay(session);
|
|
3264
2983
|
const [stopRequested, setStopRequested] = useState12(false);
|
|
3265
2984
|
const [inputText, setInputText] = useState12("");
|
|
3266
|
-
|
|
3267
|
-
const resolvedSessionId = session?.sessionId;
|
|
3268
|
-
const isViewer = state?.viewerRole === "viewer";
|
|
3269
|
-
useEffect8(() => {
|
|
3270
|
-
setResultFeedback([]);
|
|
3271
|
-
if (!resolvedSessionId || isViewer) return;
|
|
3272
|
-
let cancelled = false;
|
|
3273
|
-
void client.sessions.listResultFeedback(resolvedSessionId).then(
|
|
3274
|
-
(items) => {
|
|
3275
|
-
if (cancelled) return;
|
|
3276
|
-
setResultFeedback((current) => {
|
|
3277
|
-
const merged = new Map(items.map((item) => [item.assistant_entry_id, item]));
|
|
3278
|
-
for (const item of current) {
|
|
3279
|
-
const fetched = merged.get(item.assistant_entry_id);
|
|
3280
|
-
if (!fetched || fetched.updated_at < item.updated_at) {
|
|
3281
|
-
merged.set(item.assistant_entry_id, item);
|
|
3282
|
-
}
|
|
3283
|
-
}
|
|
3284
|
-
return [...merged.values()];
|
|
3285
|
-
});
|
|
3286
|
-
},
|
|
3287
|
-
() => {
|
|
3288
|
-
}
|
|
3289
|
-
);
|
|
3290
|
-
return () => {
|
|
3291
|
-
cancelled = true;
|
|
3292
|
-
};
|
|
3293
|
-
}, [client, isViewer, resolvedSessionId]);
|
|
3294
|
-
const resultFeedbackByEntry = useMemo8(
|
|
3295
|
-
() => new Map(resultFeedback.map((item) => [item.assistant_entry_id, item])),
|
|
3296
|
-
[resultFeedback]
|
|
3297
|
-
);
|
|
3298
|
-
const handleResultFeedbackSaved = useCallback7((saved) => {
|
|
3299
|
-
setResultFeedback((current) => [
|
|
3300
|
-
...current.filter((item) => item.assistant_entry_id !== saved.assistant_entry_id),
|
|
3301
|
-
saved
|
|
3302
|
-
]);
|
|
3303
|
-
}, []);
|
|
3304
|
-
useEffect8(() => {
|
|
2985
|
+
useEffect7(() => {
|
|
3305
2986
|
if (session) {
|
|
3306
2987
|
onSessionReady?.(session);
|
|
3307
2988
|
}
|
|
3308
2989
|
}, [session, onSessionReady]);
|
|
3309
|
-
|
|
2990
|
+
useEffect7(() => {
|
|
3310
2991
|
if (!session) return;
|
|
3311
2992
|
const offAttach = session.on("attachRequested", ({ label, content }) => {
|
|
3312
2993
|
setInputText((prev) => `${prev ? `${prev}
|
|
@@ -3322,12 +3003,12 @@ ${content}`);
|
|
|
3322
3003
|
offInsert();
|
|
3323
3004
|
};
|
|
3324
3005
|
}, [session]);
|
|
3325
|
-
|
|
3006
|
+
useEffect7(() => {
|
|
3326
3007
|
if (isUnauthorizedError(error)) {
|
|
3327
3008
|
onUnauthorized();
|
|
3328
3009
|
}
|
|
3329
3010
|
}, [error, onUnauthorized]);
|
|
3330
|
-
|
|
3011
|
+
useEffect7(() => {
|
|
3331
3012
|
if (!session || !commands) return;
|
|
3332
3013
|
const unsubscribes = Object.entries(commands).map(
|
|
3333
3014
|
([action, handler]) => session.onCommand(action, (payload) => handler(payload))
|
|
@@ -3352,13 +3033,12 @@ ${content}`);
|
|
|
3352
3033
|
ChatSurface,
|
|
3353
3034
|
{
|
|
3354
3035
|
theme,
|
|
3355
|
-
onFollowupInteraction,
|
|
3356
3036
|
classNames,
|
|
3357
3037
|
renderers,
|
|
3358
3038
|
slots,
|
|
3359
3039
|
placeholder,
|
|
3360
3040
|
connection: state?.connection ?? "connecting",
|
|
3361
|
-
banner: /* @__PURE__ */ jsxs15(
|
|
3041
|
+
banner: /* @__PURE__ */ jsxs15(Fragment2, { children: [
|
|
3362
3042
|
/* @__PURE__ */ jsx17(
|
|
3363
3043
|
ReplayBar,
|
|
3364
3044
|
{
|
|
@@ -3373,14 +3053,10 @@ ${content}`);
|
|
|
3373
3053
|
] }),
|
|
3374
3054
|
errorMessage,
|
|
3375
3055
|
messages: state?.messages ?? [],
|
|
3376
|
-
postChatFollowup: latestPostChatFollowup(state?.turns ?? []),
|
|
3377
|
-
resultFeedbackByEntry,
|
|
3378
|
-
onResultFeedbackSaved: handleResultFeedbackSaved,
|
|
3379
3056
|
isStreaming,
|
|
3380
3057
|
isStopping,
|
|
3381
3058
|
inputText,
|
|
3382
3059
|
onInputChange: setInputText,
|
|
3383
|
-
onSuggestion: setInputText,
|
|
3384
3060
|
onSend: handleSend,
|
|
3385
3061
|
onStop: handleStop,
|
|
3386
3062
|
sessionStatus: state?.status ?? void 0,
|
|
@@ -3391,14 +3067,13 @@ ${content}`);
|
|
|
3391
3067
|
askUserAnswer: { tool_call_id: toolCallId, ...answerData }
|
|
3392
3068
|
});
|
|
3393
3069
|
},
|
|
3394
|
-
sessionId:
|
|
3395
|
-
isViewer
|
|
3070
|
+
sessionId: session?.sessionId
|
|
3396
3071
|
}
|
|
3397
3072
|
);
|
|
3398
3073
|
}
|
|
3399
3074
|
|
|
3400
3075
|
// src/components/LlmChat.tsx
|
|
3401
|
-
import { useEffect as
|
|
3076
|
+
import { useEffect as useEffect8, useMemo as useMemo8, useState as useState14 } from "react";
|
|
3402
3077
|
|
|
3403
3078
|
// src/components/LlmAdvancedSettings.tsx
|
|
3404
3079
|
import { useState as useState13 } from "react";
|
|
@@ -3537,7 +3212,7 @@ function LlmChat({
|
|
|
3537
3212
|
const { messages, isStreaming, error, send, stop, reset } = useLlmChat(effective);
|
|
3538
3213
|
const [inputText, setInputText] = useState14("");
|
|
3539
3214
|
const [stopRequested, setStopRequested] = useState14(false);
|
|
3540
|
-
const handle =
|
|
3215
|
+
const handle = useMemo8(
|
|
3541
3216
|
() => ({
|
|
3542
3217
|
insertText: (text) => setInputText((prev) => prev ? `${prev}
|
|
3543
3218
|
${text}` : text),
|
|
@@ -3546,7 +3221,7 @@ ${text}` : text),
|
|
|
3546
3221
|
}),
|
|
3547
3222
|
[send, reset]
|
|
3548
3223
|
);
|
|
3549
|
-
|
|
3224
|
+
useEffect8(() => {
|
|
3550
3225
|
onReady?.(handle);
|
|
3551
3226
|
}, [handle, onReady]);
|
|
3552
3227
|
return /* @__PURE__ */ jsx19(
|
|
@@ -3636,8 +3311,7 @@ lucide-react/dist/esm/shared/src/utils.js:
|
|
|
3636
3311
|
lucide-react/dist/esm/defaultAttributes.js:
|
|
3637
3312
|
lucide-react/dist/esm/Icon.js:
|
|
3638
3313
|
lucide-react/dist/esm/createLucideIcon.js:
|
|
3639
|
-
lucide-react/dist/esm/icons/
|
|
3640
|
-
lucide-react/dist/esm/icons/arrow-up-right.js:
|
|
3314
|
+
lucide-react/dist/esm/icons/archive.js:
|
|
3641
3315
|
lucide-react/dist/esm/icons/arrow-up.js:
|
|
3642
3316
|
lucide-react/dist/esm/icons/bot.js:
|
|
3643
3317
|
lucide-react/dist/esm/icons/brain.js:
|
|
@@ -3647,19 +3321,21 @@ lucide-react/dist/esm/icons/chevron-right.js:
|
|
|
3647
3321
|
lucide-react/dist/esm/icons/circle-alert.js:
|
|
3648
3322
|
lucide-react/dist/esm/icons/copy.js:
|
|
3649
3323
|
lucide-react/dist/esm/icons/download.js:
|
|
3324
|
+
lucide-react/dist/esm/icons/file-code-2.js:
|
|
3325
|
+
lucide-react/dist/esm/icons/file-spreadsheet.js:
|
|
3650
3326
|
lucide-react/dist/esm/icons/file-text.js:
|
|
3651
3327
|
lucide-react/dist/esm/icons/file.js:
|
|
3652
3328
|
lucide-react/dist/esm/icons/film.js:
|
|
3653
|
-
lucide-react/dist/esm/icons/
|
|
3329
|
+
lucide-react/dist/esm/icons/image.js:
|
|
3654
3330
|
lucide-react/dist/esm/icons/layers.js:
|
|
3655
3331
|
lucide-react/dist/esm/icons/lightbulb.js:
|
|
3656
3332
|
lucide-react/dist/esm/icons/loader-circle.js:
|
|
3657
3333
|
lucide-react/dist/esm/icons/lock-keyhole.js:
|
|
3658
3334
|
lucide-react/dist/esm/icons/message-square-more.js:
|
|
3659
3335
|
lucide-react/dist/esm/icons/message-square.js:
|
|
3336
|
+
lucide-react/dist/esm/icons/music.js:
|
|
3660
3337
|
lucide-react/dist/esm/icons/play.js:
|
|
3661
3338
|
lucide-react/dist/esm/icons/settings-2.js:
|
|
3662
|
-
lucide-react/dist/esm/icons/sparkles.js:
|
|
3663
3339
|
lucide-react/dist/esm/icons/square.js:
|
|
3664
3340
|
lucide-react/dist/esm/icons/triangle-alert.js:
|
|
3665
3341
|
lucide-react/dist/esm/icons/x.js:
|