@blade-hq/agent-react 2610.0.0-beta.30 → 2610.0.0-beta.31
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 +18 -2
- package/dist/components/ContextCard.d.ts +13 -0
- package/dist/components/MarkdownContent.d.ts +2 -0
- package/dist/components/UserMessageBubble.d.ts +1 -1
- package/dist/components/WhatIfUserBubble.d.ts +7 -0
- package/dist/embed/entry.d.ts +2 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +238 -94
- package/dist/index.js.map +1 -1
- package/dist/lib/whatif-prompt.d.ts +18 -0
- package/dist/style.css +12 -1
- package/dist/style.full.css +13 -2
- package/package.json +2 -2
- package/public-api.md +76 -2
package/dist/index.js
CHANGED
|
@@ -1023,6 +1023,14 @@ var Play = createLucideIcon("Play", [
|
|
|
1023
1023
|
["polygon", { points: "6 3 20 12 6 21 6 3", key: "1oa8hb" }]
|
|
1024
1024
|
]);
|
|
1025
1025
|
|
|
1026
|
+
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/refresh-ccw.js
|
|
1027
|
+
var RefreshCcw = createLucideIcon("RefreshCcw", [
|
|
1028
|
+
["path", { d: "M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "14sxne" }],
|
|
1029
|
+
["path", { d: "M3 3v5h5", key: "1xhq8a" }],
|
|
1030
|
+
["path", { d: "M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16", key: "1hlbsb" }],
|
|
1031
|
+
["path", { d: "M16 16h5v5", key: "ccwih5" }]
|
|
1032
|
+
]);
|
|
1033
|
+
|
|
1026
1034
|
// ../../node_modules/.pnpm/lucide-react@0.468.0_react@19.2.4/node_modules/lucide-react/dist/esm/icons/search.js
|
|
1027
1035
|
var Search = createLucideIcon("Search", [
|
|
1028
1036
|
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }],
|
|
@@ -2028,6 +2036,18 @@ import {
|
|
|
2028
2036
|
} from "react";
|
|
2029
2037
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2030
2038
|
var SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
2039
|
+
function normalizeAdjacentUrlFormatting(value) {
|
|
2040
|
+
const protectedSegments = [];
|
|
2041
|
+
const protectedValue = value.replace(/(`{1,3}[\s\S]*?`{1,3}|\[[^\]]*\]\([^)]*\))/g, (segment) => {
|
|
2042
|
+
const index = protectedSegments.push(segment) - 1;
|
|
2043
|
+
return `blade-url-protected-${index}-marker`;
|
|
2044
|
+
});
|
|
2045
|
+
const normalized = protectedValue.replace(
|
|
2046
|
+
/(\*\*|__|~~|\*|_)(https?:\/\/[^\s<>]+?)\1(?=[\s。,、!?;:,.!?;:]|$)/g,
|
|
2047
|
+
(_, marker, url) => `${marker}[${url}](<${url}>)${marker}`
|
|
2048
|
+
);
|
|
2049
|
+
return normalized.replace(/blade-url-protected-(\d+)-marker/g, (_, index) => protectedSegments[Number(index)]);
|
|
2050
|
+
}
|
|
2031
2051
|
function CodeBlockPre({ children, node: _node, ...props }) {
|
|
2032
2052
|
const preRef = useRef7(null);
|
|
2033
2053
|
const [copied, setCopied] = useState7(false);
|
|
@@ -2082,7 +2102,7 @@ var MARKDOWN_COMPONENTS = {
|
|
|
2082
2102
|
};
|
|
2083
2103
|
function MarkdownContent({ children, className, mode, sessionId }) {
|
|
2084
2104
|
const resolvedChildren = useMemo5(() => {
|
|
2085
|
-
return children.replace(SYSTEM_REMINDER_RE, "");
|
|
2105
|
+
return normalizeAdjacentUrlFormatting(children.replace(SYSTEM_REMINDER_RE, ""));
|
|
2086
2106
|
}, [children]);
|
|
2087
2107
|
return /* @__PURE__ */ jsx7(
|
|
2088
2108
|
_r,
|
|
@@ -3652,7 +3672,85 @@ import {
|
|
|
3652
3672
|
getImageParts as getImageParts2,
|
|
3653
3673
|
getTextContent as getTextContent2
|
|
3654
3674
|
} from "@blade-hq/agent-client";
|
|
3675
|
+
|
|
3676
|
+
// src/lib/whatif-prompt.ts
|
|
3677
|
+
var HEADER_RE = /^以下消息和 step 产物标记为 deprecated_by_rerun,请基于最新用户假设从 step(\d+) 开始完整重新推演,不要复用旧结论。$/;
|
|
3678
|
+
var QUOTE_HEADER_RE = /^\[步骤(\d+)\s*·\s*(.+?)\]$/;
|
|
3679
|
+
var USER_INPUT_TAG = "[\u7528\u6237\u8F93\u5165]";
|
|
3680
|
+
function parseWhatIfPrompt(text) {
|
|
3681
|
+
const lines = text.replace(/\r\n/g, "\n").trimEnd().split("\n");
|
|
3682
|
+
const headerMatch = lines[0]?.match(HEADER_RE);
|
|
3683
|
+
if (!headerMatch) return null;
|
|
3684
|
+
const userTagIdx = lines.indexOf(USER_INPUT_TAG);
|
|
3685
|
+
const hasUserTag = userTagIdx >= 0;
|
|
3686
|
+
const quoteBlockEndExclusive = hasUserTag ? userTagIdx : lines.length;
|
|
3687
|
+
const quoteHeaderIdxs = [];
|
|
3688
|
+
let quoteBlockFound = false;
|
|
3689
|
+
for (let i = 1; i < quoteBlockEndExclusive; i++) {
|
|
3690
|
+
if (!quoteBlockFound && lines[i].trim() === "[\u5F15\u7528]") {
|
|
3691
|
+
quoteBlockFound = true;
|
|
3692
|
+
} else if (quoteBlockFound && QUOTE_HEADER_RE.test(lines[i])) {
|
|
3693
|
+
quoteHeaderIdxs.push(i);
|
|
3694
|
+
}
|
|
3695
|
+
}
|
|
3696
|
+
let legacyUserTextStart = -1;
|
|
3697
|
+
if (!hasUserTag && quoteHeaderIdxs.length > 0) {
|
|
3698
|
+
const lastSnapshotStart = quoteHeaderIdxs.at(-1) + 1;
|
|
3699
|
+
let i = lines.length - 1;
|
|
3700
|
+
while (i >= lastSnapshotStart && lines[i].trim() === "") i -= 1;
|
|
3701
|
+
while (i >= lastSnapshotStart && lines[i].trim() !== "") i -= 1;
|
|
3702
|
+
if (i >= lastSnapshotStart) legacyUserTextStart = i + 1;
|
|
3703
|
+
}
|
|
3704
|
+
const quotes = quoteHeaderIdxs.map((headerIdx, index) => {
|
|
3705
|
+
const match = lines[headerIdx].match(QUOTE_HEADER_RE);
|
|
3706
|
+
const nextHeader = quoteHeaderIdxs[index + 1];
|
|
3707
|
+
const end = nextHeader ?? (legacyUserTextStart >= 0 ? legacyUserTextStart : quoteBlockEndExclusive);
|
|
3708
|
+
const snapshotLines = lines.slice(headerIdx + 1, end);
|
|
3709
|
+
while (snapshotLines.at(-1)?.trim() === "") snapshotLines.pop();
|
|
3710
|
+
return {
|
|
3711
|
+
stepNumber: Number.parseInt(match[1], 10),
|
|
3712
|
+
label: match[2].trim(),
|
|
3713
|
+
snapshot: snapshotLines.join("\n")
|
|
3714
|
+
};
|
|
3715
|
+
});
|
|
3716
|
+
const userTextStart = hasUserTag ? userTagIdx + 1 : legacyUserTextStart;
|
|
3717
|
+
const userLines = userTextStart >= 0 ? lines.slice(userTextStart) : [];
|
|
3718
|
+
while (userLines[0]?.trim() === "") userLines.shift();
|
|
3719
|
+
while (userLines.at(-1)?.trim() === "") userLines.pop();
|
|
3720
|
+
const fromStep = Number.parseInt(headerMatch[1], 10);
|
|
3721
|
+
return {
|
|
3722
|
+
fromStep: Number.isFinite(fromStep) ? fromStep : null,
|
|
3723
|
+
quotes,
|
|
3724
|
+
userText: userLines.join("\n")
|
|
3725
|
+
};
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
// src/components/WhatIfUserBubble.tsx
|
|
3655
3729
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3730
|
+
function WhatIfUserBubble({ parsed, onQuoteClick }) {
|
|
3731
|
+
const { fromStep, quotes, userText } = parsed;
|
|
3732
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-end gap-2", children: [
|
|
3733
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.5)] px-2.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
|
|
3734
|
+
/* @__PURE__ */ jsx14(RefreshCcw, { size: 10 }),
|
|
3735
|
+
/* @__PURE__ */ jsx14("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
|
|
3736
|
+
] }),
|
|
3737
|
+
quotes.length > 0 && /* @__PURE__ */ jsx14("div", { className: "flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2", children: quotes.map((quote, index) => {
|
|
3738
|
+
const clickable = quote.stepNumber != null && !!onQuoteClick;
|
|
3739
|
+
const label = quote.stepNumber != null ? `\u6B65\u9AA4${quote.stepNumber} \xB7 ${quote.label}` : quote.label;
|
|
3740
|
+
return /* @__PURE__ */ jsxs12("div", { className: "rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.8)] px-3 py-2 text-left", children: [
|
|
3741
|
+
/* @__PURE__ */ jsxs12("button", { type: "button", disabled: !clickable, onClick: () => clickable && onQuoteClick(quote.stepNumber), className: "inline-flex max-w-full items-center gap-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] disabled:cursor-default", title: clickable ? "\u8DF3\u8F6C\u5230\u5BF9\u5E94\u6B65\u9AA4\u5361\u7247" : void 0, children: [
|
|
3742
|
+
/* @__PURE__ */ jsx14("span", { children: "\u21B3" }),
|
|
3743
|
+
/* @__PURE__ */ jsx14("span", { className: "truncate", children: label })
|
|
3744
|
+
] }),
|
|
3745
|
+
quote.snapshot ? /* @__PURE__ */ jsx14("div", { className: "mt-1 border-l-2 border-[hsl(var(--accent-foreground)/0.35)] pl-2 text-xs leading-relaxed text-[hsl(var(--foreground)/0.8)]", children: /* @__PURE__ */ jsx14(MarkdownContent, { className: "blade-chat-prose", children: quote.snapshot }) }) : null
|
|
3746
|
+
] }, `${quote.stepNumber ?? "x"}-${index}`);
|
|
3747
|
+
}) }),
|
|
3748
|
+
userText && /* @__PURE__ */ jsx14("div", { className: "rounded-2xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-sm leading-relaxed text-[hsl(var(--user-msg-fg))]", children: /* @__PURE__ */ jsx14(MarkdownContent, { className: "blade-chat-prose", children: userText }) })
|
|
3749
|
+
] });
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3752
|
+
// src/components/UserMessageBubble.tsx
|
|
3753
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3656
3754
|
function isUserMessage(message) {
|
|
3657
3755
|
return message.role === "user";
|
|
3658
3756
|
}
|
|
@@ -3664,8 +3762,12 @@ function UserMessageBubble({ message, className }) {
|
|
|
3664
3762
|
const text = getTextContent2(message.content).trim();
|
|
3665
3763
|
const fileParts = getFileParts2(message.content);
|
|
3666
3764
|
const imageParts = getImageParts2(message.content);
|
|
3667
|
-
|
|
3668
|
-
|
|
3765
|
+
const whatifParsed = text && imageParts.length === 0 && fileParts.length === 0 ? parseWhatIfPrompt(text) : null;
|
|
3766
|
+
if (whatifParsed) {
|
|
3767
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("blade-chat-user-row flex justify-end", className), children: /* @__PURE__ */ jsx15("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: /* @__PURE__ */ jsx15(WhatIfUserBubble, { parsed: whatifParsed }) }) });
|
|
3768
|
+
}
|
|
3769
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("blade-chat-user-row flex justify-end", className), children: /* @__PURE__ */ jsxs13("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: [
|
|
3770
|
+
imageParts.length > 0 && /* @__PURE__ */ jsx15("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx15(
|
|
3669
3771
|
"img",
|
|
3670
3772
|
{
|
|
3671
3773
|
src: part.image_url.url,
|
|
@@ -3674,21 +3776,21 @@ function UserMessageBubble({ message, className }) {
|
|
|
3674
3776
|
},
|
|
3675
3777
|
part.image_url.url
|
|
3676
3778
|
)) }),
|
|
3677
|
-
fileParts.length > 0 && /* @__PURE__ */
|
|
3779
|
+
fileParts.length > 0 && /* @__PURE__ */ jsx15("div", { className: "flex flex-col items-end gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs13(
|
|
3678
3780
|
"div",
|
|
3679
3781
|
{
|
|
3680
3782
|
className: "flex items-center gap-1.5 rounded-lg border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--muted)/0.3)] px-2.5 py-1.5 text-xs text-[hsl(var(--muted-foreground))]",
|
|
3681
3783
|
children: [
|
|
3682
|
-
/* @__PURE__ */
|
|
3683
|
-
/* @__PURE__ */
|
|
3784
|
+
/* @__PURE__ */ jsx15(FileText, { size: 12, className: "shrink-0" }),
|
|
3785
|
+
/* @__PURE__ */ jsx15("span", { className: "max-w-56 truncate", title: part.name, children: part.name })
|
|
3684
3786
|
]
|
|
3685
3787
|
},
|
|
3686
3788
|
`${part.name}-${part.data.length}`
|
|
3687
3789
|
)) }),
|
|
3688
|
-
text && /* @__PURE__ */
|
|
3689
|
-
text && isSending(message) && /* @__PURE__ */
|
|
3690
|
-
/* @__PURE__ */
|
|
3691
|
-
/* @__PURE__ */
|
|
3790
|
+
text && /* @__PURE__ */ jsx15("div", { className: "blade-chat-user-bubble max-w-full rounded-[20px] rounded-br-[6px] border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-[18px] py-[13px] text-sm leading-[1.65] text-[hsl(var(--user-msg-fg))]", children: /* @__PURE__ */ jsx15(MarkdownContent, { className: "blade-chat-prose", children: text }) }),
|
|
3791
|
+
text && isSending(message) && /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
|
|
3792
|
+
/* @__PURE__ */ jsx15(LoaderCircle, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
|
|
3793
|
+
/* @__PURE__ */ jsx15("span", { children: "\u53D1\u9001\u4E2D" })
|
|
3692
3794
|
] })
|
|
3693
3795
|
] }) });
|
|
3694
3796
|
}
|
|
@@ -3697,11 +3799,11 @@ function ErrorMessageBlock({
|
|
|
3697
3799
|
className
|
|
3698
3800
|
}) {
|
|
3699
3801
|
const text = chatErrorForDisplay(getTextContent2(message.content));
|
|
3700
|
-
return /* @__PURE__ */
|
|
3802
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("blade-chat-error-row flex min-w-0 justify-start", className), children: /* @__PURE__ */ jsx15("div", { className: "blade-chat-error-block min-w-0 max-w-full whitespace-pre-wrap break-words border-l-[3px] border-[hsl(var(--border))] px-3 py-1 text-left text-sm leading-7 text-[hsl(var(--muted-foreground))] [overflow-wrap:anywhere]", children: text }) });
|
|
3701
3803
|
}
|
|
3702
3804
|
|
|
3703
3805
|
// src/components/MessageList.tsx
|
|
3704
|
-
import { jsx as
|
|
3806
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3705
3807
|
function parseModeChange(message) {
|
|
3706
3808
|
if (message.kind !== "mode_change" || typeof message.content !== "string") {
|
|
3707
3809
|
return null;
|
|
@@ -3827,23 +3929,23 @@ function MessageList({
|
|
|
3827
3929
|
}
|
|
3828
3930
|
return blocks;
|
|
3829
3931
|
}, [messages, isStreaming]);
|
|
3830
|
-
return /* @__PURE__ */
|
|
3831
|
-
isStreaming ? /* @__PURE__ */
|
|
3832
|
-
/* @__PURE__ */
|
|
3932
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn("blade-chat-messages relative min-h-0 flex-1", className), children: [
|
|
3933
|
+
isStreaming ? /* @__PURE__ */ jsx16("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
|
|
3934
|
+
/* @__PURE__ */ jsxs14(
|
|
3833
3935
|
StickToBottom,
|
|
3834
3936
|
{
|
|
3835
3937
|
className: "h-full overflow-y-hidden",
|
|
3836
3938
|
initial: "instant",
|
|
3837
3939
|
resize: "instant",
|
|
3838
3940
|
children: [
|
|
3839
|
-
/* @__PURE__ */
|
|
3840
|
-
renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */
|
|
3841
|
-
/* @__PURE__ */
|
|
3842
|
-
/* @__PURE__ */
|
|
3843
|
-
/* @__PURE__ */
|
|
3941
|
+
/* @__PURE__ */ jsx16(StickToBottom.Content, { className: "blade-chat-messages-scroll", children: /* @__PURE__ */ jsx16("div", { className: "blade-chat-messages-content mx-auto max-w-[748px]", children: /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-col", children: [
|
|
3942
|
+
renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */ jsxs14("div", { className: "blade-chat-empty", children: [
|
|
3943
|
+
/* @__PURE__ */ jsx16(MessageSquare, { size: 40, strokeWidth: 1.5 }),
|
|
3944
|
+
/* @__PURE__ */ jsx16("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
|
|
3945
|
+
/* @__PURE__ */ jsx16("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
|
|
3844
3946
|
] }) : renderBlocks.map((block) => {
|
|
3845
3947
|
if (block.type === "message") {
|
|
3846
|
-
return /* @__PURE__ */
|
|
3948
|
+
return /* @__PURE__ */ jsx16("div", { "data-entry-id": block.message.entry_id, children: isUserMessage(block.message) ? /* @__PURE__ */ jsx16(UserMessageBubble, { message: block.message }) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx16(ErrorMessageBlock, { message: block.message }) : null }, block.key);
|
|
3847
3949
|
}
|
|
3848
3950
|
if (block.type === "assistant_turn") {
|
|
3849
3951
|
const blockFeedback = block.messages.map(
|
|
@@ -3854,14 +3956,14 @@ function MessageList({
|
|
|
3854
3956
|
(message) => message.entry_id === postChatFollowup.assistant_entry_id
|
|
3855
3957
|
)
|
|
3856
3958
|
);
|
|
3857
|
-
return /* @__PURE__ */
|
|
3959
|
+
return /* @__PURE__ */ jsx16("div", { "data-entry-id": block.messages[0]?.entry_id, children: /* @__PURE__ */ jsxs14(
|
|
3858
3960
|
RenderErrorBoundary,
|
|
3859
3961
|
{
|
|
3860
3962
|
label: "\u52A9\u624B\u6D88\u606F",
|
|
3861
3963
|
details: block.key,
|
|
3862
3964
|
resetKey: getMessageResetSignature(block.messages),
|
|
3863
3965
|
children: [
|
|
3864
|
-
/* @__PURE__ */
|
|
3966
|
+
/* @__PURE__ */ jsx16(
|
|
3865
3967
|
AssistantTurnBlock,
|
|
3866
3968
|
{
|
|
3867
3969
|
messages: block.messages,
|
|
@@ -3873,8 +3975,8 @@ function MessageList({
|
|
|
3873
3975
|
sessionId
|
|
3874
3976
|
}
|
|
3875
3977
|
),
|
|
3876
|
-
blockFeedback && !hasActiveFollowup ? /* @__PURE__ */
|
|
3877
|
-
hasActiveFollowup && postChatFollowup ? /* @__PURE__ */
|
|
3978
|
+
blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx16(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
|
|
3979
|
+
hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx16(
|
|
3878
3980
|
PostChatFollowupBlock,
|
|
3879
3981
|
{
|
|
3880
3982
|
followup: postChatFollowup,
|
|
@@ -3891,23 +3993,23 @@ function MessageList({
|
|
|
3891
3993
|
) }, block.key);
|
|
3892
3994
|
}
|
|
3893
3995
|
if (block.type === "compaction") {
|
|
3894
|
-
return /* @__PURE__ */
|
|
3996
|
+
return /* @__PURE__ */ jsxs14(
|
|
3895
3997
|
"div",
|
|
3896
3998
|
{
|
|
3897
3999
|
className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]",
|
|
3898
4000
|
children: [
|
|
3899
|
-
/* @__PURE__ */
|
|
3900
|
-
/* @__PURE__ */
|
|
4001
|
+
/* @__PURE__ */ jsx16(Layers, { size: 12 }),
|
|
4002
|
+
/* @__PURE__ */ jsx16("span", { children: "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
|
|
3901
4003
|
]
|
|
3902
4004
|
},
|
|
3903
4005
|
block.key
|
|
3904
4006
|
);
|
|
3905
4007
|
}
|
|
3906
|
-
return /* @__PURE__ */
|
|
4008
|
+
return /* @__PURE__ */ jsx16(PlanningDivider, { kind: block.kind }, block.key);
|
|
3907
4009
|
}),
|
|
3908
|
-
sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */
|
|
4010
|
+
sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */ jsx16("div", { className: "flex", children: /* @__PURE__ */ jsx16("div", { className: "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" }) }) : null
|
|
3909
4011
|
] }) }) }),
|
|
3910
|
-
/* @__PURE__ */
|
|
4012
|
+
/* @__PURE__ */ jsx16(
|
|
3911
4013
|
PinLatestUserMessage,
|
|
3912
4014
|
{
|
|
3913
4015
|
userMessageCount: userMessages.length,
|
|
@@ -3916,7 +4018,7 @@ function MessageList({
|
|
|
3916
4018
|
},
|
|
3917
4019
|
sessionId ?? "no-session"
|
|
3918
4020
|
),
|
|
3919
|
-
/* @__PURE__ */
|
|
4021
|
+
/* @__PURE__ */ jsx16(ScrollToBottomButton, {})
|
|
3920
4022
|
]
|
|
3921
4023
|
},
|
|
3922
4024
|
sessionId ?? "no-session"
|
|
@@ -4002,7 +4104,7 @@ function ScrollToBottomButton() {
|
|
|
4002
4104
|
scrollToBottom();
|
|
4003
4105
|
}, [scrollToBottom]);
|
|
4004
4106
|
if (!visible) return null;
|
|
4005
|
-
return /* @__PURE__ */
|
|
4107
|
+
return /* @__PURE__ */ jsxs14(
|
|
4006
4108
|
"button",
|
|
4007
4109
|
{
|
|
4008
4110
|
type: "button",
|
|
@@ -4010,25 +4112,25 @@ function ScrollToBottomButton() {
|
|
|
4010
4112
|
"aria-label": "\u6EDA\u52A8\u5230\u5E95\u90E8",
|
|
4011
4113
|
className: "blade-chat-scroll-bottom absolute bottom-4 right-4 flex items-center gap-1 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-1.5 text-xs text-[hsl(var(--muted-foreground))] shadow-lg transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
|
|
4012
4114
|
children: [
|
|
4013
|
-
/* @__PURE__ */
|
|
4014
|
-
/* @__PURE__ */
|
|
4115
|
+
/* @__PURE__ */ jsx16(ChevronDown, { size: 14 }),
|
|
4116
|
+
/* @__PURE__ */ jsx16("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
|
|
4015
4117
|
]
|
|
4016
4118
|
}
|
|
4017
4119
|
);
|
|
4018
4120
|
}
|
|
4019
4121
|
function PlanningDivider({ kind }) {
|
|
4020
|
-
return /* @__PURE__ */
|
|
4021
|
-
/* @__PURE__ */
|
|
4022
|
-
/* @__PURE__ */
|
|
4023
|
-
/* @__PURE__ */
|
|
4024
|
-
/* @__PURE__ */
|
|
4122
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-3 py-1", children: [
|
|
4123
|
+
/* @__PURE__ */ jsx16("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
|
|
4124
|
+
/* @__PURE__ */ jsxs14("div", { className: "inline-flex items-center gap-1.5 rounded-full border border-amber-500/30 bg-amber-500/10 px-3 py-1 text-[11px] text-amber-300", children: [
|
|
4125
|
+
/* @__PURE__ */ jsx16(Lightbulb, { size: 12 }),
|
|
4126
|
+
/* @__PURE__ */ jsx16("span", { children: kind === "enter" ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
|
|
4025
4127
|
] }),
|
|
4026
|
-
/* @__PURE__ */
|
|
4128
|
+
/* @__PURE__ */ jsx16("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
|
|
4027
4129
|
] });
|
|
4028
4130
|
}
|
|
4029
4131
|
|
|
4030
4132
|
// src/components/ChatSurface.tsx
|
|
4031
|
-
import { jsx as
|
|
4133
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4032
4134
|
function themeAttr(theme) {
|
|
4033
4135
|
return theme === "dark" ? "dark" : void 0;
|
|
4034
4136
|
}
|
|
@@ -4060,7 +4162,7 @@ function ChatSurface({
|
|
|
4060
4162
|
beforeInput,
|
|
4061
4163
|
banner
|
|
4062
4164
|
}) {
|
|
4063
|
-
return /* @__PURE__ */
|
|
4165
|
+
return /* @__PURE__ */ jsxs15(
|
|
4064
4166
|
"div",
|
|
4065
4167
|
{
|
|
4066
4168
|
"data-theme": themeAttr(theme),
|
|
@@ -4069,14 +4171,14 @@ function ChatSurface({
|
|
|
4069
4171
|
classNames?.root
|
|
4070
4172
|
),
|
|
4071
4173
|
children: [
|
|
4072
|
-
/* @__PURE__ */
|
|
4174
|
+
/* @__PURE__ */ jsx17(ConnectionBanner, { connection, className: classNames?.banner }),
|
|
4073
4175
|
banner,
|
|
4074
|
-
errorMessage && /* @__PURE__ */
|
|
4075
|
-
/* @__PURE__ */
|
|
4076
|
-
/* @__PURE__ */
|
|
4176
|
+
errorMessage && /* @__PURE__ */ jsxs15("div", { className: "blade-chat-error-bar flex items-start gap-2 border-b px-4 py-3 text-sm", children: [
|
|
4177
|
+
/* @__PURE__ */ jsx17(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
|
|
4178
|
+
/* @__PURE__ */ jsx17("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay2(errorMessage) })
|
|
4077
4179
|
] }),
|
|
4078
4180
|
slots?.header,
|
|
4079
|
-
/* @__PURE__ */
|
|
4181
|
+
/* @__PURE__ */ jsx17(
|
|
4080
4182
|
MessageList,
|
|
4081
4183
|
{
|
|
4082
4184
|
messages,
|
|
@@ -4097,7 +4199,7 @@ function ChatSurface({
|
|
|
4097
4199
|
}
|
|
4098
4200
|
),
|
|
4099
4201
|
beforeInput,
|
|
4100
|
-
/* @__PURE__ */
|
|
4202
|
+
/* @__PURE__ */ jsx17(
|
|
4101
4203
|
ChatInput,
|
|
4102
4204
|
{
|
|
4103
4205
|
value: inputText,
|
|
@@ -4117,7 +4219,7 @@ function ChatSurface({
|
|
|
4117
4219
|
}
|
|
4118
4220
|
|
|
4119
4221
|
// src/components/AgentChat.tsx
|
|
4120
|
-
import { Fragment as Fragment3, jsx as
|
|
4222
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4121
4223
|
function isUnauthorizedError(error) {
|
|
4122
4224
|
return error instanceof BladeApiError && error.status === 401;
|
|
4123
4225
|
}
|
|
@@ -4136,11 +4238,11 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
4136
4238
|
setLoggingIn(false);
|
|
4137
4239
|
}
|
|
4138
4240
|
};
|
|
4139
|
-
return /* @__PURE__ */
|
|
4140
|
-
/* @__PURE__ */
|
|
4141
|
-
/* @__PURE__ */
|
|
4142
|
-
/* @__PURE__ */
|
|
4143
|
-
/* @__PURE__ */
|
|
4241
|
+
return /* @__PURE__ */ jsx18("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs16("div", { className: "flex w-full max-w-sm flex-col items-center gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-6 py-8 text-center", children: [
|
|
4242
|
+
/* @__PURE__ */ jsx18(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
|
|
4243
|
+
/* @__PURE__ */ jsx18("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
|
|
4244
|
+
/* @__PURE__ */ jsx18("div", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u767B\u5F55\u540E\u5373\u53EF\u4E0E\u667A\u80FD\u4F53\u5BF9\u8BDD\uFF0C\u4F60\u7684\u4F1A\u8BDD\u5185\u5BB9\u4EC5\u81EA\u5DF1\u53EF\u89C1\u3002" }),
|
|
4245
|
+
/* @__PURE__ */ jsx18(
|
|
4144
4246
|
"button",
|
|
4145
4247
|
{
|
|
4146
4248
|
type: "button",
|
|
@@ -4150,7 +4252,7 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
4150
4252
|
children: loggingIn ? "\u767B\u5F55\u4E2D\u2026" : "\u767B\u5F55"
|
|
4151
4253
|
}
|
|
4152
4254
|
),
|
|
4153
|
-
loginError && /* @__PURE__ */
|
|
4255
|
+
loginError && /* @__PURE__ */ jsx18("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
|
|
4154
4256
|
] }) });
|
|
4155
4257
|
}
|
|
4156
4258
|
function AgentChat(props) {
|
|
@@ -4158,12 +4260,12 @@ function AgentChat(props) {
|
|
|
4158
4260
|
const [attempt, setAttempt] = useState13(0);
|
|
4159
4261
|
const [needLogin, setNeedLogin] = useState13(() => !client.hasToken());
|
|
4160
4262
|
if (needLogin) {
|
|
4161
|
-
return /* @__PURE__ */
|
|
4263
|
+
return /* @__PURE__ */ jsx18(
|
|
4162
4264
|
"div",
|
|
4163
4265
|
{
|
|
4164
4266
|
"data-theme": themeAttr(props.theme),
|
|
4165
4267
|
className: cn("blade-chat flex min-h-0 flex-1 flex-col", props.classNames?.root),
|
|
4166
|
-
children: /* @__PURE__ */
|
|
4268
|
+
children: /* @__PURE__ */ jsx18(
|
|
4167
4269
|
LoginCard,
|
|
4168
4270
|
{
|
|
4169
4271
|
client,
|
|
@@ -4176,7 +4278,7 @@ function AgentChat(props) {
|
|
|
4176
4278
|
}
|
|
4177
4279
|
);
|
|
4178
4280
|
}
|
|
4179
|
-
return /* @__PURE__ */
|
|
4281
|
+
return /* @__PURE__ */ jsx18(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
|
|
4180
4282
|
}
|
|
4181
4283
|
function ChatSessionView({
|
|
4182
4284
|
sessionId,
|
|
@@ -4285,7 +4387,7 @@ ${content}`);
|
|
|
4285
4387
|
setStopRequested(true);
|
|
4286
4388
|
void session?.stop();
|
|
4287
4389
|
};
|
|
4288
|
-
return /* @__PURE__ */
|
|
4390
|
+
return /* @__PURE__ */ jsx18(
|
|
4289
4391
|
ChatSurface,
|
|
4290
4392
|
{
|
|
4291
4393
|
theme,
|
|
@@ -4295,8 +4397,8 @@ ${content}`);
|
|
|
4295
4397
|
slots,
|
|
4296
4398
|
placeholder,
|
|
4297
4399
|
connection: state?.connection ?? "connecting",
|
|
4298
|
-
banner: /* @__PURE__ */
|
|
4299
|
-
/* @__PURE__ */
|
|
4400
|
+
banner: /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
4401
|
+
/* @__PURE__ */ jsx18(
|
|
4300
4402
|
ReplayBar,
|
|
4301
4403
|
{
|
|
4302
4404
|
isReplay: replay.isReplay,
|
|
@@ -4306,7 +4408,7 @@ ${content}`);
|
|
|
4306
4408
|
onExit: () => void replay.exitToAutonomous()
|
|
4307
4409
|
}
|
|
4308
4410
|
),
|
|
4309
|
-
/* @__PURE__ */
|
|
4411
|
+
/* @__PURE__ */ jsx18(ReplayMismatchPrompt, { mismatch: replay.mismatch })
|
|
4310
4412
|
] }),
|
|
4311
4413
|
errorMessage,
|
|
4312
4414
|
messages: state?.messages ?? [],
|
|
@@ -4339,7 +4441,7 @@ import { useEffect as useEffect12, useMemo as useMemo9, useState as useState15 }
|
|
|
4339
4441
|
|
|
4340
4442
|
// src/components/LlmAdvancedSettings.tsx
|
|
4341
4443
|
import { useState as useState14 } from "react";
|
|
4342
|
-
import { jsx as
|
|
4444
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4343
4445
|
var FIELDS = [
|
|
4344
4446
|
{ id: "baseURL", label: "\u6A21\u578B\u670D\u52A1\u5730\u5740", placeholder: "http://\u5185\u7F51\u5730\u5740/v1" },
|
|
4345
4447
|
{ id: "model", label: "\u6A21\u578B", placeholder: "\u6A21\u578B\u540D\u79F0" },
|
|
@@ -4390,8 +4492,8 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4390
4492
|
if (!normalized) return null;
|
|
4391
4493
|
const fields = FIELDS.filter((field) => normalized[field.id]);
|
|
4392
4494
|
const dirty = Object.keys(override).length > 0;
|
|
4393
|
-
return /* @__PURE__ */
|
|
4394
|
-
/* @__PURE__ */
|
|
4495
|
+
return /* @__PURE__ */ jsxs17("div", { className: "blade-chat-advanced border-t border-[hsl(var(--border))] px-4 py-2 text-xs", children: [
|
|
4496
|
+
/* @__PURE__ */ jsxs17(
|
|
4395
4497
|
"button",
|
|
4396
4498
|
{
|
|
4397
4499
|
type: "button",
|
|
@@ -4401,16 +4503,16 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4401
4503
|
},
|
|
4402
4504
|
className: "flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
|
|
4403
4505
|
children: [
|
|
4404
|
-
/* @__PURE__ */
|
|
4506
|
+
/* @__PURE__ */ jsx19(Settings2, { size: 13 }),
|
|
4405
4507
|
"\u9AD8\u7EA7\u8BBE\u7F6E",
|
|
4406
|
-
dirty && /* @__PURE__ */
|
|
4508
|
+
dirty && /* @__PURE__ */ jsx19("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
|
|
4407
4509
|
]
|
|
4408
4510
|
}
|
|
4409
4511
|
),
|
|
4410
|
-
open && /* @__PURE__ */
|
|
4411
|
-
fields.map((field) => /* @__PURE__ */
|
|
4412
|
-
/* @__PURE__ */
|
|
4413
|
-
/* @__PURE__ */
|
|
4512
|
+
open && /* @__PURE__ */ jsxs17("div", { className: "mt-2 flex flex-col gap-2", children: [
|
|
4513
|
+
fields.map((field) => /* @__PURE__ */ jsxs17("label", { className: "flex flex-col gap-1", children: [
|
|
4514
|
+
/* @__PURE__ */ jsx19("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
|
|
4515
|
+
/* @__PURE__ */ jsx19(
|
|
4414
4516
|
"input",
|
|
4415
4517
|
{
|
|
4416
4518
|
type: field.secret ? "password" : "text",
|
|
@@ -4421,9 +4523,9 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4421
4523
|
}
|
|
4422
4524
|
)
|
|
4423
4525
|
] }, field.id)),
|
|
4424
|
-
normalized.apiKey && /* @__PURE__ */
|
|
4425
|
-
/* @__PURE__ */
|
|
4426
|
-
/* @__PURE__ */
|
|
4526
|
+
normalized.apiKey && /* @__PURE__ */ jsx19("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u5BC6\u94A5\u4F1A\u5B58\u5728\u8FD9\u53F0\u6D4F\u89C8\u5668\u91CC\u3002\u53EA\u5728\u4F60\u4FE1\u5F97\u8FC7\u8FD9\u53F0\u673A\u5668\u65F6\u586B\u3002" }),
|
|
4527
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex gap-2", children: [
|
|
4528
|
+
/* @__PURE__ */ jsx19(
|
|
4427
4529
|
"button",
|
|
4428
4530
|
{
|
|
4429
4531
|
type: "button",
|
|
@@ -4438,7 +4540,7 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4438
4540
|
children: "\u4FDD\u5B58"
|
|
4439
4541
|
}
|
|
4440
4542
|
),
|
|
4441
|
-
/* @__PURE__ */
|
|
4543
|
+
/* @__PURE__ */ jsx19(
|
|
4442
4544
|
"button",
|
|
4443
4545
|
{
|
|
4444
4546
|
type: "button",
|
|
@@ -4457,7 +4559,7 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
|
|
|
4457
4559
|
}
|
|
4458
4560
|
|
|
4459
4561
|
// src/components/LlmChat.tsx
|
|
4460
|
-
import { jsx as
|
|
4562
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
4461
4563
|
function LlmChat({
|
|
4462
4564
|
classNames,
|
|
4463
4565
|
renderers,
|
|
@@ -4486,7 +4588,7 @@ ${text}` : text),
|
|
|
4486
4588
|
useEffect12(() => {
|
|
4487
4589
|
onReady?.(handle);
|
|
4488
4590
|
}, [handle, onReady]);
|
|
4489
|
-
return /* @__PURE__ */
|
|
4591
|
+
return /* @__PURE__ */ jsx20(
|
|
4490
4592
|
ChatSurface,
|
|
4491
4593
|
{
|
|
4492
4594
|
theme,
|
|
@@ -4511,7 +4613,7 @@ ${text}` : text),
|
|
|
4511
4613
|
setStopRequested(true);
|
|
4512
4614
|
stop();
|
|
4513
4615
|
},
|
|
4514
|
-
beforeInput: advanced ? /* @__PURE__ */
|
|
4616
|
+
beforeInput: advanced ? /* @__PURE__ */ jsx20(
|
|
4515
4617
|
LlmAdvancedSettingsBar,
|
|
4516
4618
|
{
|
|
4517
4619
|
settings: advanced,
|
|
@@ -4529,14 +4631,14 @@ ${text}` : text),
|
|
|
4529
4631
|
}
|
|
4530
4632
|
|
|
4531
4633
|
// src/components/ChatView.tsx
|
|
4532
|
-
import { jsx as
|
|
4634
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
4533
4635
|
function ChatView(props) {
|
|
4534
4636
|
const { mode, llm, onLlmReady, ...rest } = props;
|
|
4535
4637
|
if (mode === "llm") {
|
|
4536
4638
|
if (!llm) {
|
|
4537
4639
|
throw new Error('ChatView: mode="llm" \u9700\u8981\u540C\u65F6\u4F20 llm={{ baseURL, model }}');
|
|
4538
4640
|
}
|
|
4539
|
-
return /* @__PURE__ */
|
|
4641
|
+
return /* @__PURE__ */ jsx21(
|
|
4540
4642
|
LlmChat,
|
|
4541
4643
|
{
|
|
4542
4644
|
...llm,
|
|
@@ -4549,23 +4651,24 @@ function ChatView(props) {
|
|
|
4549
4651
|
}
|
|
4550
4652
|
);
|
|
4551
4653
|
}
|
|
4552
|
-
return /* @__PURE__ */
|
|
4654
|
+
return /* @__PURE__ */ jsx21(AgentChat, { ...rest });
|
|
4553
4655
|
}
|
|
4554
4656
|
|
|
4555
4657
|
// src/components/ContextCard.tsx
|
|
4556
4658
|
import {
|
|
4557
|
-
getContextDisplayState
|
|
4659
|
+
getContextDisplayState,
|
|
4660
|
+
getContextGroupDisplayState
|
|
4558
4661
|
} from "@blade-hq/agent-client";
|
|
4559
|
-
import { jsx as
|
|
4662
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4560
4663
|
function ContextCard({ context, className }) {
|
|
4561
4664
|
const display = getContextDisplayState(context);
|
|
4562
|
-
return /* @__PURE__ */
|
|
4665
|
+
return /* @__PURE__ */ jsxs18(
|
|
4563
4666
|
"details",
|
|
4564
4667
|
{
|
|
4565
|
-
className: `blade-chat-context-card group rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
|
|
4668
|
+
className: `blade-chat-context-card group/context-card rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
|
|
4566
4669
|
children: [
|
|
4567
|
-
/* @__PURE__ */
|
|
4568
|
-
/* @__PURE__ */
|
|
4670
|
+
/* @__PURE__ */ jsxs18("summary", { className: "blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden", children: [
|
|
4671
|
+
/* @__PURE__ */ jsx22(
|
|
4569
4672
|
Layers,
|
|
4570
4673
|
{
|
|
4571
4674
|
size: 15,
|
|
@@ -4573,24 +4676,60 @@ function ContextCard({ context, className }) {
|
|
|
4573
4676
|
"aria-hidden": "true"
|
|
4574
4677
|
}
|
|
4575
4678
|
),
|
|
4576
|
-
/* @__PURE__ */
|
|
4577
|
-
/* @__PURE__ */
|
|
4578
|
-
/* @__PURE__ */
|
|
4679
|
+
/* @__PURE__ */ jsxs18("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
|
|
4680
|
+
/* @__PURE__ */ jsx22("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
|
|
4681
|
+
/* @__PURE__ */ jsx22("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
|
|
4579
4682
|
] }),
|
|
4580
|
-
/* @__PURE__ */
|
|
4683
|
+
/* @__PURE__ */ jsx22(
|
|
4581
4684
|
ChevronDown,
|
|
4582
4685
|
{
|
|
4583
4686
|
size: 14,
|
|
4584
|
-
className: "blade-chat-context-chevron shrink-0 text-[hsl(var(--muted-foreground))] transition-transform group-open:rotate-180",
|
|
4687
|
+
className: "blade-chat-context-chevron shrink-0 text-[hsl(var(--muted-foreground))] transition-transform group-open/context-card:rotate-180",
|
|
4585
4688
|
"aria-hidden": "true"
|
|
4586
4689
|
}
|
|
4587
4690
|
)
|
|
4588
4691
|
] }),
|
|
4589
|
-
/* @__PURE__ */
|
|
4692
|
+
/* @__PURE__ */ jsx22("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: display.detail })
|
|
4590
4693
|
]
|
|
4591
4694
|
}
|
|
4592
4695
|
);
|
|
4593
4696
|
}
|
|
4697
|
+
function ContextGroupCard({ contexts, className }) {
|
|
4698
|
+
if (contexts.length === 0) return null;
|
|
4699
|
+
const single = contexts.length === 1 ? getContextDisplayState(contexts[0]) : null;
|
|
4700
|
+
const group = single ? null : getContextGroupDisplayState(contexts);
|
|
4701
|
+
return /* @__PURE__ */ jsxs18("details", { className: `blade-chat-context-card group/context-group rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`, children: [
|
|
4702
|
+
/* @__PURE__ */ jsxs18("summary", { className: "blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden", children: [
|
|
4703
|
+
/* @__PURE__ */ jsx22(
|
|
4704
|
+
Layers,
|
|
4705
|
+
{
|
|
4706
|
+
size: 15,
|
|
4707
|
+
className: "blade-chat-context-icon shrink-0 text-[hsl(var(--muted-foreground))]",
|
|
4708
|
+
"aria-hidden": "true"
|
|
4709
|
+
}
|
|
4710
|
+
),
|
|
4711
|
+
/* @__PURE__ */ jsxs18("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
|
|
4712
|
+
/* @__PURE__ */ jsx22("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: single ? single.title : `${group?.title} \xB7 ${group?.count} \u9879` }),
|
|
4713
|
+
/* @__PURE__ */ jsx22("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: single ? single.summary : group?.summary })
|
|
4714
|
+
] }),
|
|
4715
|
+
/* @__PURE__ */ jsx22(
|
|
4716
|
+
ChevronDown,
|
|
4717
|
+
{
|
|
4718
|
+
size: 14,
|
|
4719
|
+
className: "blade-chat-context-chevron shrink-0 text-[hsl(var(--muted-foreground))] transition-transform group-open/context-group:rotate-180",
|
|
4720
|
+
"aria-hidden": "true"
|
|
4721
|
+
}
|
|
4722
|
+
)
|
|
4723
|
+
] }),
|
|
4724
|
+
single ? /* @__PURE__ */ jsx22("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: single.detail }) : /* @__PURE__ */ jsx22("div", { className: "blade-chat-context-group-items flex flex-col gap-1.5 border-t border-[hsl(var(--border))] p-2", children: contexts.map((context) => /* @__PURE__ */ jsx22(
|
|
4725
|
+
ContextCard,
|
|
4726
|
+
{
|
|
4727
|
+
context
|
|
4728
|
+
},
|
|
4729
|
+
`${context.context_kind}:${context.context_key}`
|
|
4730
|
+
)) })
|
|
4731
|
+
] });
|
|
4732
|
+
}
|
|
4594
4733
|
|
|
4595
4734
|
// src/lib/agent-computer-command.ts
|
|
4596
4735
|
var COMPUTER_LAUNCH_COMMAND_PATTERN = /(?:^|[\n;&|(]\s*)computer\s+launch(?:\s|$)/;
|
|
@@ -4641,15 +4780,19 @@ export {
|
|
|
4641
4780
|
BladeProvider,
|
|
4642
4781
|
ChatView,
|
|
4643
4782
|
ContextCard,
|
|
4783
|
+
ContextGroupCard,
|
|
4644
4784
|
LlmChat,
|
|
4645
4785
|
MarkdownContent,
|
|
4646
4786
|
MemoryRefsHint,
|
|
4647
4787
|
ReplayBar,
|
|
4648
4788
|
ReplayMismatchPrompt,
|
|
4789
|
+
WhatIfUserBubble,
|
|
4649
4790
|
classifyAgentComputerLaunchOutcome,
|
|
4650
4791
|
collectMemoryRefs,
|
|
4651
4792
|
isAgentComputerCommand,
|
|
4652
4793
|
isAgentComputerToolCall,
|
|
4794
|
+
normalizeAdjacentUrlFormatting,
|
|
4795
|
+
parseWhatIfPrompt,
|
|
4653
4796
|
useAgentSession,
|
|
4654
4797
|
useBladeClient,
|
|
4655
4798
|
useLlmChat,
|
|
@@ -4683,6 +4826,7 @@ lucide-react/dist/esm/icons/lock-keyhole.js:
|
|
|
4683
4826
|
lucide-react/dist/esm/icons/message-square-more.js:
|
|
4684
4827
|
lucide-react/dist/esm/icons/message-square.js:
|
|
4685
4828
|
lucide-react/dist/esm/icons/play.js:
|
|
4829
|
+
lucide-react/dist/esm/icons/refresh-ccw.js:
|
|
4686
4830
|
lucide-react/dist/esm/icons/search.js:
|
|
4687
4831
|
lucide-react/dist/esm/icons/settings-2.js:
|
|
4688
4832
|
lucide-react/dist/esm/icons/sparkles.js:
|