@blade-hq/agent-react 2612.0.0-beta.19 → 2612.0.0-beta.20

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.
@@ -113,7 +113,7 @@ import {
113
113
  useSessionSource,
114
114
  useSessionState,
115
115
  useSingleSessionSource
116
- } from "./chunk-GXJCVUXP.js";
116
+ } from "./chunk-C4FUFBG4.js";
117
117
  import {
118
118
  __export
119
119
  } from "./chunk-PR4QN5HX.js";
@@ -469,10 +469,10 @@ function ReplayMismatchPrompt({ mismatch, className }) {
469
469
 
470
470
  // src/components/AgentChat.tsx
471
471
  import { BladeApiError as BladeApiError2 } from "@blade-hq/agent-client/internal";
472
- import { useEffect as useEffect30, useMemo as useMemo18, useRef as useRef28, useState as useState36 } from "react";
472
+ import { useEffect as useEffect31, useMemo as useMemo18, useRef as useRef29, useState as useState37 } from "react";
473
473
 
474
474
  // src/chat/ChatPanel.tsx
475
- import { useCallback as useCallback17, useEffect as useEffect28, useMemo as useMemo17, useState as useState34 } from "react";
475
+ import { useCallback as useCallback17, useEffect as useEffect29, useMemo as useMemo17, useState as useState35 } from "react";
476
476
  import {
477
477
  chatErrorForDisplay as chatErrorForDisplay3,
478
478
  latestPostChatFollowup
@@ -26460,7 +26460,7 @@ function ChatLoadingIndicator({ preparing = false }) {
26460
26460
  }
26461
26461
 
26462
26462
  // src/chat/LiteMessageList.tsx
26463
- import { useCallback as useCallback8, useEffect as useEffect19, useMemo as useMemo12, useRef as useRef18, useState as useState24 } from "react";
26463
+ import { useCallback as useCallback8, useEffect as useEffect20, useMemo as useMemo12, useRef as useRef19, useState as useState25 } from "react";
26464
26464
  import {
26465
26465
  extractTextAttachments as extractTextAttachments2,
26466
26466
  getTextContent as getTextContent3,
@@ -26609,7 +26609,7 @@ var MessageImage = forwardRef(function MessageImage2({ client: suppliedClient, s
26609
26609
  });
26610
26610
 
26611
26611
  // src/chat/AssistantTurnBlock.tsx
26612
- import { memo as memo5, useCallback as useCallback5, useEffect as useEffect16, useMemo as useMemo11, useRef as useRef15, useState as useState22 } from "react";
26612
+ import { memo as memo5, useCallback as useCallback5, useEffect as useEffect17, useMemo as useMemo11, useRef as useRef16, useState as useState23 } from "react";
26613
26613
  import { getFileParts as getFileParts2, getImageParts as getImageParts2, getTextContent as getTextContent2, normalizeMessageContent } from "@blade-hq/agent-client/internal";
26614
26614
 
26615
26615
  // src/chat/lib/ui-meta.ts
@@ -38561,106 +38561,14 @@ function buildAskUserPayload(argumentsJson) {
38561
38561
  }
38562
38562
 
38563
38563
  // src/chat/WorkflowRunBlock.tsx
38564
- import { useMemo as useMemo10, useState as useState21 } from "react";
38564
+ import { useMemo as useMemo10, useState as useState22 } from "react";
38565
38565
 
38566
38566
  // src/chat/AgentLoopBlock.tsx
38567
- import { useEffect as useEffect15, useMemo as useMemo9, useState as useState20 } from "react";
38567
+ import { useEffect as useEffect16, useMemo as useMemo9, useState as useState21 } from "react";
38568
38568
  import { collectInlineToolUiCards } from "@blade-hq/agent-client/internal";
38569
38569
 
38570
- // src/chat/UserMessageBubble.tsx
38571
- import { chatErrorForDisplay } from "@blade-hq/agent-client";
38572
- import { useEffect as useEffect14, useState as useState19 } from "react";
38573
- import { extractTextAttachments, getFileParts, getImageParts, getTextContent } from "@blade-hq/agent-client/internal";
38574
-
38575
- // src/chat/lib/preview-dispatch.ts
38576
- var IMAGE_EXTS = [
38577
- // 静态
38578
- ".png",
38579
- ".jpg",
38580
- ".jpeg",
38581
- ".bmp",
38582
- ".svg",
38583
- ".heic",
38584
- // 动图(<img> 原生播放)
38585
- ".gif",
38586
- ".webp",
38587
- ".apng",
38588
- ".avif"
38589
- ];
38590
- var TEXT_EXTS = [".md", ".json", ".txt", ".yaml", ".yml"];
38591
- function lower(filename) {
38592
- return filename.toLowerCase();
38593
- }
38594
- function endsWithAny(name, exts) {
38595
- const n2 = lower(name);
38596
- for (const ext of exts) {
38597
- if (n2.endsWith(ext)) return true;
38598
- }
38599
- return false;
38600
- }
38601
- function isImageFilename(filename) {
38602
- return endsWithAny(filename, IMAGE_EXTS);
38603
- }
38604
- function isTextFilename(filename) {
38605
- return endsWithAny(filename, TEXT_EXTS);
38606
- }
38607
- function dispatchPreview(filename, url2) {
38608
- if (isImageFilename(filename)) return { kind: "image", filename, url: url2 };
38609
- if (isTextFilename(filename)) return { kind: "text", filename, url: url2 };
38610
- return { kind: "default", filename, url: url2 };
38611
- }
38612
-
38613
- // src/lib/whatif-prompt.ts
38614
- var HEADER_RE = /^以下消息和 step 产物标记为 deprecated_by_rerun,请基于最新用户假设从 step(\d+) 开始完整重新推演,不要复用旧结论。$/;
38615
- var QUOTE_HEADER_RE = /^\[步骤(\d+)\s*·\s*(.+?)\]$/;
38616
- var USER_INPUT_TAG = "[\u7528\u6237\u8F93\u5165]";
38617
- function parseWhatIfPrompt(text4) {
38618
- const lines = text4.replace(/\r\n/g, "\n").trimEnd().split("\n");
38619
- const headerMatch = lines[0]?.match(HEADER_RE);
38620
- if (!headerMatch) return null;
38621
- const userTagIdx = lines.indexOf(USER_INPUT_TAG);
38622
- const hasUserTag = userTagIdx >= 0;
38623
- const quoteBlockEndExclusive = hasUserTag ? userTagIdx : lines.length;
38624
- const quoteHeaderIdxs = [];
38625
- let quoteBlockFound = false;
38626
- for (let i2 = 1; i2 < quoteBlockEndExclusive; i2++) {
38627
- if (!quoteBlockFound && lines[i2].trim() === "[\u5F15\u7528]") {
38628
- quoteBlockFound = true;
38629
- } else if (quoteBlockFound && QUOTE_HEADER_RE.test(lines[i2])) {
38630
- quoteHeaderIdxs.push(i2);
38631
- }
38632
- }
38633
- let legacyUserTextStart = -1;
38634
- if (!hasUserTag && quoteHeaderIdxs.length > 0) {
38635
- const lastSnapshotStart = quoteHeaderIdxs.at(-1) + 1;
38636
- let i2 = lines.length - 1;
38637
- while (i2 >= lastSnapshotStart && lines[i2].trim() === "") i2 -= 1;
38638
- while (i2 >= lastSnapshotStart && lines[i2].trim() !== "") i2 -= 1;
38639
- if (i2 >= lastSnapshotStart) legacyUserTextStart = i2 + 1;
38640
- }
38641
- const quotes = quoteHeaderIdxs.map((headerIdx, index2) => {
38642
- const match = lines[headerIdx].match(QUOTE_HEADER_RE);
38643
- const nextHeader = quoteHeaderIdxs[index2 + 1];
38644
- const end = nextHeader ?? (legacyUserTextStart >= 0 ? legacyUserTextStart : quoteBlockEndExclusive);
38645
- const snapshotLines = lines.slice(headerIdx + 1, end);
38646
- while (snapshotLines.at(-1)?.trim() === "") snapshotLines.pop();
38647
- return {
38648
- stepNumber: Number.parseInt(match[1], 10),
38649
- label: match[2].trim(),
38650
- snapshot: snapshotLines.join("\n")
38651
- };
38652
- });
38653
- const userTextStart = hasUserTag ? userTagIdx + 1 : legacyUserTextStart;
38654
- const userLines = userTextStart >= 0 ? lines.slice(userTextStart) : [];
38655
- while (userLines[0]?.trim() === "") userLines.shift();
38656
- while (userLines.at(-1)?.trim() === "") userLines.pop();
38657
- const fromStep = Number.parseInt(headerMatch[1], 10);
38658
- return {
38659
- fromStep: Number.isFinite(fromStep) ? fromStep : null,
38660
- quotes,
38661
- userText: userLines.join("\n")
38662
- };
38663
- }
38570
+ // src/chat/ContextAttachmentPills.tsx
38571
+ import { useEffect as useEffect14, useRef as useRef15, useState as useState19 } from "react";
38664
38572
 
38665
38573
  // src/chat/lib/use-async-value.ts
38666
38574
  import { useEffect as useEffect13, useState as useState18 } from "react";
@@ -38769,18 +38677,173 @@ function renderContent({
38769
38677
  return /* @__PURE__ */ jsx31("pre", { className: "whitespace-pre-wrap font-mono text-xs leading-relaxed", children: content3 });
38770
38678
  }
38771
38679
 
38680
+ // src/chat/lib/preview-dispatch.ts
38681
+ var IMAGE_EXTS = [
38682
+ // 静态
38683
+ ".png",
38684
+ ".jpg",
38685
+ ".jpeg",
38686
+ ".bmp",
38687
+ ".svg",
38688
+ ".heic",
38689
+ // 动图(<img> 原生播放)
38690
+ ".gif",
38691
+ ".webp",
38692
+ ".apng",
38693
+ ".avif"
38694
+ ];
38695
+ var TEXT_EXTS = [".md", ".json", ".txt", ".yaml", ".yml"];
38696
+ function lower(filename) {
38697
+ return filename.toLowerCase();
38698
+ }
38699
+ function endsWithAny(name, exts) {
38700
+ const n2 = lower(name);
38701
+ for (const ext of exts) {
38702
+ if (n2.endsWith(ext)) return true;
38703
+ }
38704
+ return false;
38705
+ }
38706
+ function isImageFilename(filename) {
38707
+ return endsWithAny(filename, IMAGE_EXTS);
38708
+ }
38709
+ function isTextFilename(filename) {
38710
+ return endsWithAny(filename, TEXT_EXTS);
38711
+ }
38712
+ function dispatchPreview(filename, url2) {
38713
+ if (isImageFilename(filename)) return { kind: "image", filename, url: url2 };
38714
+ if (isTextFilename(filename)) return { kind: "text", filename, url: url2 };
38715
+ return { kind: "default", filename, url: url2 };
38716
+ }
38717
+
38718
+ // src/chat/ContextAttachmentPills.tsx
38719
+ import { Fragment as Fragment12, jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
38720
+ function ContextAttachmentPills({ attachments }) {
38721
+ const client = useOptionalBladeClient();
38722
+ const download = useRef15(null);
38723
+ useEffect14(() => () => download.current?.abort(), []);
38724
+ const [selected, setSelected] = useState19(null);
38725
+ const [preview, setPreview] = useState19(null);
38726
+ const [loading, setLoading] = useState19(null);
38727
+ const [unavailable, setUnavailable] = useState19(null);
38728
+ useEffect14(() => () => {
38729
+ if (preview) URL.revokeObjectURL(preview.url);
38730
+ }, [preview]);
38731
+ if (!attachments?.length) return null;
38732
+ const openFile = async (file2) => {
38733
+ if (!client || !file2.session_id || !file2.path) {
38734
+ setUnavailable(file2.name);
38735
+ return;
38736
+ }
38737
+ const controller = new AbortController();
38738
+ download.current?.abort();
38739
+ download.current = controller;
38740
+ setLoading(file2.name);
38741
+ setUnavailable(null);
38742
+ try {
38743
+ const response = await client.fetch("GET", `/api/sessions/${encodeURIComponent(file2.session_id)}/files/${encodeURIComponent(file2.path)}`, { signal: controller.signal });
38744
+ const blob = await response.blob();
38745
+ if (controller.signal.aborted) return;
38746
+ const url2 = URL.createObjectURL(blob);
38747
+ const kind = dispatchPreview(file2.name, url2).kind;
38748
+ setPreview({ name: file2.name, url: url2, mode: kind === "text" ? file2.name.endsWith(".md") ? "markdown" : "text" : "default" });
38749
+ } catch {
38750
+ if (!controller.signal.aborted) setUnavailable(file2.name);
38751
+ } finally {
38752
+ if (!controller.signal.aborted) setLoading(null);
38753
+ }
38754
+ };
38755
+ return /* @__PURE__ */ jsxs26(Fragment12, { children: [
38756
+ /* @__PURE__ */ jsx32("div", { className: "flex max-w-full flex-wrap justify-end gap-1.5", "aria-label": "\u9644\u52A0\u8D44\u6599", children: attachments.map((item) => /* @__PURE__ */ jsx32("button", { type: "button", onClick: () => {
38757
+ setSelected(selected?.id === item.id ? null : item);
38758
+ setUnavailable(null);
38759
+ }, "aria-expanded": selected?.id === item.id, className: "max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs text-foreground", children: item.label }, item.id)) }),
38760
+ selected && /* @__PURE__ */ jsxs26("div", { className: "max-w-full rounded-xl border border-border bg-muted p-3 text-sm text-foreground", children: [
38761
+ /* @__PURE__ */ jsx32("div", { className: "mb-2 font-medium", children: selected.label }),
38762
+ /* @__PURE__ */ jsx32("div", { className: "whitespace-pre-wrap break-words", children: selected.content }),
38763
+ selected.files?.map((file2, index2) => /* @__PURE__ */ jsxs26("button", { type: "button", disabled: loading != null || !file2.path || !file2.session_id, onClick: () => void openFile(file2), className: "mt-2 block max-w-full truncate text-left underline", children: [
38764
+ file2.name,
38765
+ !file2.path || !file2.session_id ? " \xB7 \u6587\u4EF6\u4E0D\u53EF\u7528" : loading === file2.name ? " \xB7 \u8BFB\u53D6\u4E2D" : ""
38766
+ ] }, index2)),
38767
+ unavailable && /* @__PURE__ */ jsxs26("output", { className: "mt-2 block text-xs text-muted-foreground", children: [
38768
+ unavailable,
38769
+ " \xB7 \u6587\u4EF6\u4E0D\u53EF\u7528"
38770
+ ] })
38771
+ ] }),
38772
+ preview && /* @__PURE__ */ jsx32(AttachmentPreviewDialog, { open: true, onOpenChange: (open2) => {
38773
+ if (!open2) setPreview(null);
38774
+ }, filename: preview.name, url: preview.url, mode: preview.mode })
38775
+ ] });
38776
+ }
38777
+
38778
+ // src/chat/UserMessageBubble.tsx
38779
+ import { chatErrorForDisplay } from "@blade-hq/agent-client";
38780
+ import { useEffect as useEffect15, useState as useState20 } from "react";
38781
+ import { extractTextAttachments, getFileParts, getImageParts, getTextContent } from "@blade-hq/agent-client/internal";
38782
+
38783
+ // src/lib/whatif-prompt.ts
38784
+ var HEADER_RE = /^以下消息和 step 产物标记为 deprecated_by_rerun,请基于最新用户假设从 step(\d+) 开始完整重新推演,不要复用旧结论。$/;
38785
+ var QUOTE_HEADER_RE = /^\[步骤(\d+)\s*·\s*(.+?)\]$/;
38786
+ var USER_INPUT_TAG = "[\u7528\u6237\u8F93\u5165]";
38787
+ function parseWhatIfPrompt(text4) {
38788
+ const lines = text4.replace(/\r\n/g, "\n").trimEnd().split("\n");
38789
+ const headerMatch = lines[0]?.match(HEADER_RE);
38790
+ if (!headerMatch) return null;
38791
+ const userTagIdx = lines.indexOf(USER_INPUT_TAG);
38792
+ const hasUserTag = userTagIdx >= 0;
38793
+ const quoteBlockEndExclusive = hasUserTag ? userTagIdx : lines.length;
38794
+ const quoteHeaderIdxs = [];
38795
+ let quoteBlockFound = false;
38796
+ for (let i2 = 1; i2 < quoteBlockEndExclusive; i2++) {
38797
+ if (!quoteBlockFound && lines[i2].trim() === "[\u5F15\u7528]") {
38798
+ quoteBlockFound = true;
38799
+ } else if (quoteBlockFound && QUOTE_HEADER_RE.test(lines[i2])) {
38800
+ quoteHeaderIdxs.push(i2);
38801
+ }
38802
+ }
38803
+ let legacyUserTextStart = -1;
38804
+ if (!hasUserTag && quoteHeaderIdxs.length > 0) {
38805
+ const lastSnapshotStart = quoteHeaderIdxs.at(-1) + 1;
38806
+ let i2 = lines.length - 1;
38807
+ while (i2 >= lastSnapshotStart && lines[i2].trim() === "") i2 -= 1;
38808
+ while (i2 >= lastSnapshotStart && lines[i2].trim() !== "") i2 -= 1;
38809
+ if (i2 >= lastSnapshotStart) legacyUserTextStart = i2 + 1;
38810
+ }
38811
+ const quotes = quoteHeaderIdxs.map((headerIdx, index2) => {
38812
+ const match = lines[headerIdx].match(QUOTE_HEADER_RE);
38813
+ const nextHeader = quoteHeaderIdxs[index2 + 1];
38814
+ const end = nextHeader ?? (legacyUserTextStart >= 0 ? legacyUserTextStart : quoteBlockEndExclusive);
38815
+ const snapshotLines = lines.slice(headerIdx + 1, end);
38816
+ while (snapshotLines.at(-1)?.trim() === "") snapshotLines.pop();
38817
+ return {
38818
+ stepNumber: Number.parseInt(match[1], 10),
38819
+ label: match[2].trim(),
38820
+ snapshot: snapshotLines.join("\n")
38821
+ };
38822
+ });
38823
+ const userTextStart = hasUserTag ? userTagIdx + 1 : legacyUserTextStart;
38824
+ const userLines = userTextStart >= 0 ? lines.slice(userTextStart) : [];
38825
+ while (userLines[0]?.trim() === "") userLines.shift();
38826
+ while (userLines.at(-1)?.trim() === "") userLines.pop();
38827
+ const fromStep = Number.parseInt(headerMatch[1], 10);
38828
+ return {
38829
+ fromStep: Number.isFinite(fromStep) ? fromStep : null,
38830
+ quotes,
38831
+ userText: userLines.join("\n")
38832
+ };
38833
+ }
38834
+
38772
38835
  // src/chat/MessageContextPills.tsx
38773
- import { jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
38836
+ import { jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
38774
38837
  function MessageContextPills({ contexts }) {
38775
38838
  if (contexts.length === 0) return null;
38776
- return /* @__PURE__ */ jsx32("div", { className: "flex flex-wrap gap-1.5", children: contexts.map((ctx, index2) => /* @__PURE__ */ jsxs26(
38839
+ return /* @__PURE__ */ jsx33("div", { className: "flex flex-wrap gap-1.5", children: contexts.map((ctx, index2) => /* @__PURE__ */ jsxs27(
38777
38840
  "div",
38778
38841
  {
38779
38842
  className: "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--primary)/0.25)] bg-[hsl(var(--primary)/0.1)] px-2.5 py-1 text-[11px] text-[hsl(var(--primary)/0.85)]",
38780
38843
  title: ctx.content,
38781
38844
  children: [
38782
- /* @__PURE__ */ jsx32(Bookmark, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.65)]" }),
38783
- /* @__PURE__ */ jsx32("span", { className: "max-w-56 truncate", children: ctx.label })
38845
+ /* @__PURE__ */ jsx33(Bookmark, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.65)]" }),
38846
+ /* @__PURE__ */ jsx33("span", { className: "max-w-56 truncate", children: ctx.label })
38784
38847
  ]
38785
38848
  },
38786
38849
  `${ctx.label}:${index2}`
@@ -38788,7 +38851,7 @@ function MessageContextPills({ contexts }) {
38788
38851
  }
38789
38852
 
38790
38853
  // src/chat/TextAttachmentPills.tsx
38791
- import { Fragment as Fragment12, jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
38854
+ import { Fragment as Fragment13, jsx as jsx34, jsxs as jsxs28 } from "react/jsx-runtime";
38792
38855
  function getFileIcon2(fileName) {
38793
38856
  const lower2 = fileName.toLowerCase();
38794
38857
  if (/\.(zip|rar|7z|tar|gz)$/.test(lower2)) return Archive;
@@ -38803,15 +38866,15 @@ function getFileIcon2(fileName) {
38803
38866
  function TextAttachmentPills({ attachments, onPreview }) {
38804
38867
  if (attachments.length === 0) return null;
38805
38868
  const pillClass = "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--primary)/0.2)] bg-[hsl(var(--primary)/0.08)] px-2.5 py-1 text-[11px] text-[hsl(var(--primary)/0.8)]";
38806
- return /* @__PURE__ */ jsx33("div", { className: "flex flex-wrap gap-1.5", children: attachments.map((att, index2) => {
38869
+ return /* @__PURE__ */ jsx34("div", { className: "flex flex-wrap gap-1.5", children: attachments.map((att, index2) => {
38807
38870
  const Icon = getFileIcon2(att.name);
38808
38871
  const key = `${att.uploadedPath ?? att.name}:${att.name}:${index2}`;
38809
- const content3 = /* @__PURE__ */ jsxs27(Fragment12, { children: [
38810
- /* @__PURE__ */ jsx33(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.6)]" }),
38811
- /* @__PURE__ */ jsx33("span", { className: "max-w-40 truncate", children: att.name })
38872
+ const content3 = /* @__PURE__ */ jsxs28(Fragment13, { children: [
38873
+ /* @__PURE__ */ jsx34(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.6)]" }),
38874
+ /* @__PURE__ */ jsx34("span", { className: "max-w-40 truncate", children: att.name })
38812
38875
  ] });
38813
38876
  if (onPreview) {
38814
- return /* @__PURE__ */ jsx33(
38877
+ return /* @__PURE__ */ jsx34(
38815
38878
  "button",
38816
38879
  {
38817
38880
  type: "button",
@@ -38823,36 +38886,36 @@ function TextAttachmentPills({ attachments, onPreview }) {
38823
38886
  key
38824
38887
  );
38825
38888
  }
38826
- return /* @__PURE__ */ jsx33("div", { className: pillClass, title: att.name, children: content3 }, key);
38889
+ return /* @__PURE__ */ jsx34("div", { className: pillClass, title: att.name, children: content3 }, key);
38827
38890
  }) });
38828
38891
  }
38829
38892
 
38830
38893
  // src/components/WhatIfUserBubble.tsx
38831
- import { jsx as jsx34, jsxs as jsxs28 } from "react/jsx-runtime";
38894
+ import { jsx as jsx35, jsxs as jsxs29 } from "react/jsx-runtime";
38832
38895
  function WhatIfUserBubble({ parsed, onQuoteClick }) {
38833
38896
  const { fromStep, quotes, userText } = parsed;
38834
- return /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-end gap-2", children: [
38835
- /* @__PURE__ */ jsxs28("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: [
38836
- /* @__PURE__ */ jsx34(RefreshCcw, { size: 10 }),
38837
- /* @__PURE__ */ jsx34("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
38897
+ return /* @__PURE__ */ jsxs29("div", { className: "flex flex-col items-end gap-2", children: [
38898
+ /* @__PURE__ */ jsxs29("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: [
38899
+ /* @__PURE__ */ jsx35(RefreshCcw, { size: 10 }),
38900
+ /* @__PURE__ */ jsx35("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
38838
38901
  ] }),
38839
- quotes.length > 0 && /* @__PURE__ */ jsx34("div", { className: "flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2", children: quotes.map((quote, index2) => {
38902
+ quotes.length > 0 && /* @__PURE__ */ jsx35("div", { className: "flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2", children: quotes.map((quote, index2) => {
38840
38903
  const clickable = quote.stepNumber != null && !!onQuoteClick;
38841
38904
  const label = quote.stepNumber != null ? `\u6B65\u9AA4${quote.stepNumber} \xB7 ${quote.label}` : quote.label;
38842
- return /* @__PURE__ */ jsxs28("div", { className: "rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.8)] px-3 py-2 text-left", children: [
38843
- /* @__PURE__ */ jsxs28("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: [
38844
- /* @__PURE__ */ jsx34("span", { children: "\u21B3" }),
38845
- /* @__PURE__ */ jsx34("span", { className: "truncate", children: label })
38905
+ return /* @__PURE__ */ jsxs29("div", { className: "rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.8)] px-3 py-2 text-left", children: [
38906
+ /* @__PURE__ */ jsxs29("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: [
38907
+ /* @__PURE__ */ jsx35("span", { children: "\u21B3" }),
38908
+ /* @__PURE__ */ jsx35("span", { className: "truncate", children: label })
38846
38909
  ] }),
38847
- quote.snapshot ? /* @__PURE__ */ jsx34("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__ */ jsx34(MarkdownContent, { className: "blade-chat-prose", children: quote.snapshot }) }) : null
38910
+ quote.snapshot ? /* @__PURE__ */ jsx35("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__ */ jsx35(MarkdownContent, { className: "blade-chat-prose", children: quote.snapshot }) }) : null
38848
38911
  ] }, `${quote.stepNumber ?? "x"}-${index2}`);
38849
38912
  }) }),
38850
- userText && /* @__PURE__ */ jsx34("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__ */ jsx34(MarkdownContent, { className: "blade-chat-prose", children: userText }) })
38913
+ userText && /* @__PURE__ */ jsx35("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__ */ jsx35(MarkdownContent, { className: "blade-chat-prose", children: userText }) })
38851
38914
  ] });
38852
38915
  }
38853
38916
 
38854
38917
  // src/chat/UserMessageBubble.tsx
38855
- import { jsx as jsx35, jsxs as jsxs29 } from "react/jsx-runtime";
38918
+ import { jsx as jsx36, jsxs as jsxs30 } from "react/jsx-runtime";
38856
38919
  function isUserMessage(message) {
38857
38920
  return message.role === "user";
38858
38921
  }
@@ -38880,7 +38943,7 @@ ${filePaths.join("\n")}` : null;
38880
38943
  );
38881
38944
  return results.map((result) => result.status === "fulfilled" ? result.value : null);
38882
38945
  });
38883
- useEffect14(
38946
+ useEffect15(
38884
38947
  () => () => {
38885
38948
  for (const url2 of data ?? []) if (url2) URL.revokeObjectURL(url2);
38886
38949
  },
@@ -38902,18 +38965,19 @@ function UserMessageBubble({ message, className }) {
38902
38965
  contexts: textContexts
38903
38966
  } = extractTextAttachments(message.content);
38904
38967
  const trimmedClean = cleanText.trim();
38905
- const pluginPills = message.refs?.length ? /* @__PURE__ */ jsx35("div", { className: "flex flex-wrap justify-end gap-1.5", "aria-label": "\u6D88\u606F\u5F15\u7528", children: message.refs.map((ref) => /* @__PURE__ */ jsx35("span", { className: "max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs", children: ref.provider === "skill" ? `\u6280\u80FD \xB7 ${ref.label}` : ref.label }, ref.provider === "skill" ? `skill:${ref.id}` : `${ref.plugin}:${ref.server}:${ref.id}`)) }) : null;
38906
- const topicAssetPills = message.topic_asset_refs?.length ? /* @__PURE__ */ jsx35("div", { className: "flex max-w-full flex-wrap justify-end gap-1.5", "aria-label": "\u5F15\u7528\u7684\u4E3B\u9898\u8D44\u4EA7", children: message.topic_asset_refs.map((ref) => /* @__PURE__ */ jsxs29("span", { title: ref.path, className: "max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs text-foreground", children: [
38968
+ const pluginPills = message.refs?.length ? /* @__PURE__ */ jsx36("div", { className: "flex flex-wrap justify-end gap-1.5", "aria-label": "\u6D88\u606F\u5F15\u7528", children: message.refs.map((ref) => /* @__PURE__ */ jsx36("span", { className: "max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs", children: ref.provider === "skill" ? `\u6280\u80FD \xB7 ${ref.label}` : ref.label }, ref.provider === "skill" ? `skill:${ref.id}` : `${ref.plugin}:${ref.server}:${ref.id}`)) }) : null;
38969
+ const topicAssetPills = message.topic_asset_refs?.length ? /* @__PURE__ */ jsx36("div", { className: "flex max-w-full flex-wrap justify-end gap-1.5", "aria-label": "\u5F15\u7528\u7684\u4E3B\u9898\u8D44\u4EA7", children: message.topic_asset_refs.map((ref) => /* @__PURE__ */ jsxs30("span", { title: ref.path, className: "max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs text-foreground", children: [
38907
38970
  "\u4E3B\u9898\u8D44\u4EA7 \xB7 ",
38908
38971
  ref.path
38909
38972
  ] }, `${ref.topic_id}:${ref.path}`)) }) : null;
38910
38973
  const whatifParsed = trimmedClean && imageParts.length === 0 && fileParts.length === 0 && textAttachments.length === 0 ? parseWhatIfPrompt(cleanText) : null;
38911
38974
  if (whatifParsed && customBubble == null) {
38912
- return /* @__PURE__ */ jsx35("div", { part: "user-row", className: "blade-chat-user-row flex justify-end", children: /* @__PURE__ */ jsxs29("div", { className: "blade-chat-user-col group flex max-w-[72%] flex-col items-end gap-2", children: [
38975
+ return /* @__PURE__ */ jsx36("div", { part: "user-row", className: "blade-chat-user-row flex justify-end", children: /* @__PURE__ */ jsxs30("div", { className: "blade-chat-user-col group flex max-w-[72%] flex-col items-end gap-2", children: [
38913
38976
  pluginPills,
38914
38977
  topicAssetPills,
38915
- /* @__PURE__ */ jsx35(WhatIfUserBubble, { parsed: whatifParsed }),
38916
- whatifParsed.userText && /* @__PURE__ */ jsx35(
38978
+ /* @__PURE__ */ jsx36(ContextAttachmentPills, { attachments: message.context_attachments }),
38979
+ /* @__PURE__ */ jsx36(WhatIfUserBubble, { parsed: whatifParsed }),
38980
+ whatifParsed.userText && /* @__PURE__ */ jsx36(
38917
38981
  MessageActions,
38918
38982
  {
38919
38983
  content: whatifParsed.userText,
@@ -38944,8 +39008,8 @@ function UserMessageBubble({ message, className }) {
38944
39008
  alt: imageTextAttachmentMeta[i2]?.name || "\u7528\u6237\u4E0A\u4F20\u7684\u56FE\u7247"
38945
39009
  }))
38946
39010
  ];
38947
- const [lightboxIndex, setLightboxIndex] = useState19(null);
38948
- const [preview, setPreview] = useState19(null);
39011
+ const [lightboxIndex, setLightboxIndex] = useState20(null);
39012
+ const [preview, setPreview] = useState20(null);
38949
39013
  const handleTextAttachmentPreview = (attachment) => {
38950
39014
  if (!activeSessionId || !client) return;
38951
39015
  const pathForUrl = attachment.uploadedPath ?? attachment.name;
@@ -38964,16 +39028,16 @@ function UserMessageBubble({ message, className }) {
38964
39028
  const mode = kind === "text" ? lower2.endsWith(".md") ? "markdown" : "text" : "default";
38965
39029
  setPreview({ filename: attachment.name, url: url2, mode });
38966
39030
  };
38967
- return /* @__PURE__ */ jsx35("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", className), children: /* @__PURE__ */ jsxs29("div", { className: "blade-chat-user-col group flex max-w-[72%] flex-col items-end gap-3", children: [
38968
- (imageParts.length > 0 || imageTextAttachmentMeta.length > 0) && /* @__PURE__ */ jsxs29("div", { className: "grid gap-2", children: [
38969
- imageParts.map((part, idx) => /* @__PURE__ */ jsx35(
39031
+ return /* @__PURE__ */ jsx36("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", className), children: /* @__PURE__ */ jsxs30("div", { className: "blade-chat-user-col group flex max-w-[72%] flex-col items-end gap-3", children: [
39032
+ (imageParts.length > 0 || imageTextAttachmentMeta.length > 0) && /* @__PURE__ */ jsxs30("div", { className: "grid gap-2", children: [
39033
+ imageParts.map((part, idx) => /* @__PURE__ */ jsx36(
38970
39034
  "button",
38971
39035
  {
38972
39036
  type: "button",
38973
39037
  onClick: () => setLightboxIndex(idx),
38974
39038
  className: "cursor-zoom-in",
38975
39039
  title: "\u67E5\u770B\u5927\u56FE",
38976
- children: /* @__PURE__ */ jsx35(
39040
+ children: /* @__PURE__ */ jsx36(
38977
39041
  MessageImage,
38978
39042
  {
38979
39043
  src: part.image_url.url,
@@ -38988,14 +39052,14 @@ function UserMessageBubble({ message, className }) {
38988
39052
  )),
38989
39053
  imageTextAttachmentMeta.map((att, idx) => {
38990
39054
  const blobUrl = imageAttachmentUrls[idx];
38991
- return blobUrl ? /* @__PURE__ */ jsx35(
39055
+ return blobUrl ? /* @__PURE__ */ jsx36(
38992
39056
  "button",
38993
39057
  {
38994
39058
  type: "button",
38995
39059
  onClick: () => setLightboxIndex(imageParts.length + idx),
38996
39060
  className: "cursor-zoom-in",
38997
39061
  title: "\u67E5\u770B\u5927\u56FE",
38998
- children: /* @__PURE__ */ jsx35(
39062
+ children: /* @__PURE__ */ jsx36(
38999
39063
  "img",
39000
39064
  {
39001
39065
  src: blobUrl,
@@ -39005,7 +39069,7 @@ function UserMessageBubble({ message, className }) {
39005
39069
  )
39006
39070
  },
39007
39071
  `${att.uploadedPath}:${att.name}`
39008
- ) : blobUrl === null ? null : /* @__PURE__ */ jsx35(
39072
+ ) : blobUrl === null ? null : /* @__PURE__ */ jsx36(
39009
39073
  "div",
39010
39074
  {
39011
39075
  className: "flex h-20 items-center justify-center rounded-xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--muted)/0.3)] text-xs text-[hsl(var(--muted-foreground))]",
@@ -39015,7 +39079,7 @@ function UserMessageBubble({ message, className }) {
39015
39079
  );
39016
39080
  })
39017
39081
  ] }),
39018
- lightboxImages.length > 0 && /* @__PURE__ */ jsx35(
39082
+ lightboxImages.length > 0 && /* @__PURE__ */ jsx36(
39019
39083
  ImageLightbox,
39020
39084
  {
39021
39085
  open: lightboxIndex != null,
@@ -39026,15 +39090,15 @@ function UserMessageBubble({ message, className }) {
39026
39090
  initialIndex: lightboxIndex ?? 0
39027
39091
  }
39028
39092
  ),
39029
- /* @__PURE__ */ jsx35(MessageFileAttachmentList, { files: fileParts }),
39030
- /* @__PURE__ */ jsx35(
39093
+ /* @__PURE__ */ jsx36(MessageFileAttachmentList, { files: fileParts }),
39094
+ /* @__PURE__ */ jsx36(
39031
39095
  TextAttachmentPills,
39032
39096
  {
39033
39097
  attachments: nonImageTextAttachments,
39034
39098
  onPreview: handleTextAttachmentPreview
39035
39099
  }
39036
39100
  ),
39037
- preview && /* @__PURE__ */ jsx35(
39101
+ preview && /* @__PURE__ */ jsx36(
39038
39102
  AttachmentPreviewDialog,
39039
39103
  {
39040
39104
  open: preview != null,
@@ -39046,16 +39110,17 @@ function UserMessageBubble({ message, className }) {
39046
39110
  mode: preview.mode
39047
39111
  }
39048
39112
  ),
39049
- /* @__PURE__ */ jsx35(MessageContextPills, { contexts: textContexts }),
39113
+ /* @__PURE__ */ jsx36(MessageContextPills, { contexts: textContexts }),
39050
39114
  pluginPills,
39051
39115
  topicAssetPills,
39116
+ /* @__PURE__ */ jsx36(ContextAttachmentPills, { attachments: message.context_attachments }),
39052
39117
  trimmedClean && // 原型:不对称圆角(指向发送侧的一角收窄),无边框、无内阴影。
39053
- (customBubble != null ? customBubble : /* @__PURE__ */ jsx35(
39118
+ (customBubble != null ? customBubble : /* @__PURE__ */ jsx36(
39054
39119
  "div",
39055
39120
  {
39056
39121
  part: "user-bubble",
39057
39122
  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))]",
39058
- children: /* @__PURE__ */ jsx35(
39123
+ children: /* @__PURE__ */ jsx36(
39059
39124
  MarkdownContent,
39060
39125
  {
39061
39126
  className: USER_MESSAGE_MARKDOWN_CLASS,
@@ -39065,10 +39130,10 @@ function UserMessageBubble({ message, className }) {
39065
39130
  )
39066
39131
  }
39067
39132
  )),
39068
- trimmedClean && (isSending(message) ? /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
39069
- /* @__PURE__ */ jsx35(LoaderCircle, { size: 12, className: "animate-spin", "aria-hidden": "true" }),
39070
- /* @__PURE__ */ jsx35("span", { children: "\u53D1\u9001\u4E2D" })
39071
- ] }) : /* @__PURE__ */ jsx35(
39133
+ trimmedClean && (isSending(message) ? /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
39134
+ /* @__PURE__ */ jsx36(LoaderCircle, { size: 12, className: "animate-spin", "aria-hidden": "true" }),
39135
+ /* @__PURE__ */ jsx36("span", { children: "\u53D1\u9001\u4E2D" })
39136
+ ] }) : /* @__PURE__ */ jsx36(
39072
39137
  MessageActions,
39073
39138
  {
39074
39139
  content: cleanText,
@@ -39083,9 +39148,9 @@ function ErrorMessageBlock({
39083
39148
  }) {
39084
39149
  const text4 = chatErrorForDisplay(getTextContent(message.content));
39085
39150
  const looksLikeModelUnavailable = /no source matches this model|404/i.test(text4);
39086
- return /* @__PURE__ */ jsx35("div", { part: "error-row", className: cn("blade-chat-error-row flex min-w-0 justify-start", className), children: /* @__PURE__ */ jsxs29("div", { className: "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: [
39151
+ return /* @__PURE__ */ jsx36("div", { part: "error-row", className: cn("blade-chat-error-row flex min-w-0 justify-start", className), children: /* @__PURE__ */ jsxs30("div", { className: "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: [
39087
39152
  text4,
39088
- looksLikeModelUnavailable ? /* @__PURE__ */ jsx35("div", { className: "mt-1 opacity-80", children: "\u6A21\u578B\u53EF\u80FD\u672A\u542F\u52A8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" }) : null
39153
+ looksLikeModelUnavailable ? /* @__PURE__ */ jsx36("div", { className: "mt-1 opacity-80", children: "\u6A21\u578B\u53EF\u80FD\u672A\u542F\u52A8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" }) : null
39089
39154
  ] }) });
39090
39155
  }
39091
39156
 
@@ -39098,7 +39163,7 @@ function findLatestReasoningMessageIndex(messages) {
39098
39163
  }
39099
39164
 
39100
39165
  // src/chat/AgentLoopBlock.tsx
39101
- import { Fragment as Fragment13, jsx as jsx36, jsxs as jsxs30 } from "react/jsx-runtime";
39166
+ import { Fragment as Fragment14, jsx as jsx37, jsxs as jsxs31 } from "react/jsx-runtime";
39102
39167
  var COLLAPSED_SUMMARY_HIDDEN_TOOLS = /* @__PURE__ */ new Set(["ReadSkill", "Read"]);
39103
39168
  function safeParseDescription(argsStr) {
39104
39169
  try {
@@ -39158,7 +39223,7 @@ function AgentLoopBlock({
39158
39223
  () => visibleLoopToolCalls.some((childToolCall) => childToolCall.status === "awaiting_answer" && !askAnswers?.[childToolCall.id]),
39159
39224
  [visibleLoopToolCalls, askAnswers]
39160
39225
  );
39161
- const [expanded, setExpanded] = useState20(defaultExpanded || hasAwaitingAnswer);
39226
+ const [expanded, setExpanded] = useState21(defaultExpanded || hasAwaitingAnswer);
39162
39227
  const completedToolLabels = useMemo9(
39163
39228
  () => visibleLoopToolCalls.flatMap((childToolCall) => {
39164
39229
  const isCompleted = childToolCall.status === "done" || childToolCall.status !== "pending" && childToolCall.status !== "awaiting_answer" && childToolCall.status !== "error" && childToolCall.status !== "cancelled";
@@ -39191,7 +39256,7 @@ function AgentLoopBlock({
39191
39256
  () => collectInlineToolUiCards(childMessages),
39192
39257
  [childMessages]
39193
39258
  );
39194
- useEffect15(() => {
39259
+ useEffect16(() => {
39195
39260
  if (hasAwaitingAnswer) {
39196
39261
  setExpanded(true);
39197
39262
  }
@@ -39201,7 +39266,7 @@ function AgentLoopBlock({
39201
39266
  const status = hasAwaitingAnswer || toolCall.status === "awaiting_answer" && visibleLoopToolCalls.length === 0 ? "awaiting_answer" : toolCall.status === "pending" || loopEntry?.info.status === "running" ? "running" : toolCall.status === "error" || loopEntry?.info.status === "error" ? "error" : toolCall.status === "cancelled" || loopEntry?.info.status === "cancelled" ? "cancelled" : "done";
39202
39267
  const latestReasoningIndex = status === "running" ? findLatestReasoningMessageIndex(childMessages) : -1;
39203
39268
  const cardStyles = getLoopCardStyles(status);
39204
- return /* @__PURE__ */ jsxs30(
39269
+ return /* @__PURE__ */ jsxs31(
39205
39270
  "div",
39206
39271
  {
39207
39272
  part: "agent-loop",
@@ -39210,8 +39275,8 @@ function AgentLoopBlock({
39210
39275
  cardStyles.borderClass
39211
39276
  ),
39212
39277
  children: [
39213
- status === "running" || status === "awaiting_answer" ? /* @__PURE__ */ jsxs30(Fragment13, { children: [
39214
- /* @__PURE__ */ jsxs30(
39278
+ status === "running" || status === "awaiting_answer" ? /* @__PURE__ */ jsxs31(Fragment14, { children: [
39279
+ /* @__PURE__ */ jsxs31(
39215
39280
  "div",
39216
39281
  {
39217
39282
  className: cn(
@@ -39219,24 +39284,24 @@ function AgentLoopBlock({
39219
39284
  cardStyles.headerClass
39220
39285
  ),
39221
39286
  children: [
39222
- /* @__PURE__ */ jsx36(
39287
+ /* @__PURE__ */ jsx37(
39223
39288
  "button",
39224
39289
  {
39225
39290
  type: "button",
39226
39291
  onClick: toggleExpanded,
39227
39292
  "aria-expanded": expanded,
39228
39293
  className: "flex min-w-0 flex-1 items-center gap-2 text-left focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
39229
- children: /* @__PURE__ */ jsxs30("span", { className: "min-w-0 flex items-center gap-2", children: [
39230
- status === "awaiting_answer" ? /* @__PURE__ */ jsx36(MessageSquareMore, { size: 14, className: "shrink-0 text-[hsl(var(--swf-warning))] motion-safe:animate-pulse" }) : /* @__PURE__ */ jsx36(Bot, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
39231
- /* @__PURE__ */ jsxs30("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: [
39294
+ children: /* @__PURE__ */ jsxs31("span", { className: "min-w-0 flex items-center gap-2", children: [
39295
+ status === "awaiting_answer" ? /* @__PURE__ */ jsx37(MessageSquareMore, { size: 14, className: "shrink-0 text-[hsl(var(--swf-warning))] motion-safe:animate-pulse" }) : /* @__PURE__ */ jsx37(Bot, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
39296
+ /* @__PURE__ */ jsxs31("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: [
39232
39297
  renderDescription ? renderDescription(description) : description,
39233
39298
  status === "awaiting_answer" ? " \u2014 \u7B49\u5F85\u56DE\u7B54" : ""
39234
39299
  ] })
39235
39300
  ] })
39236
39301
  }
39237
39302
  ),
39238
- reasoning ? /* @__PURE__ */ jsx36(ThinkingBadge, { reasoning, variant: "block" }) : null,
39239
- /* @__PURE__ */ jsx36(
39303
+ reasoning ? /* @__PURE__ */ jsx37(ThinkingBadge, { reasoning, variant: "block" }) : null,
39304
+ /* @__PURE__ */ jsx37(
39240
39305
  Bot,
39241
39306
  {
39242
39307
  size: 14,
@@ -39244,14 +39309,14 @@ function AgentLoopBlock({
39244
39309
  "aria-label": "\u5B50\u667A\u80FD\u4F53"
39245
39310
  }
39246
39311
  ),
39247
- /* @__PURE__ */ jsx36(
39312
+ /* @__PURE__ */ jsx37(
39248
39313
  "button",
39249
39314
  {
39250
39315
  type: "button",
39251
39316
  onClick: toggleExpanded,
39252
39317
  "aria-expanded": expanded,
39253
39318
  className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
39254
- children: /* @__PURE__ */ jsx36(
39319
+ children: /* @__PURE__ */ jsx37(
39255
39320
  ChevronRight,
39256
39321
  {
39257
39322
  size: 14,
@@ -39266,7 +39331,7 @@ function AgentLoopBlock({
39266
39331
  ]
39267
39332
  }
39268
39333
  ),
39269
- !expanded ? /* @__PURE__ */ jsx36("div", { className: "flex flex-col gap-1 py-2", children: visibleLoopToolCalls.length > 0 ? visibleLoopToolCalls.slice(-1).map((childToolCall) => /* @__PURE__ */ jsx36(
39334
+ !expanded ? /* @__PURE__ */ jsx37("div", { className: "flex flex-col gap-1 py-2", children: visibleLoopToolCalls.length > 0 ? visibleLoopToolCalls.slice(-1).map((childToolCall) => /* @__PURE__ */ jsx37(
39270
39335
  ToolCallBlock,
39271
39336
  {
39272
39337
  toolCall: childToolCall,
@@ -39274,12 +39339,12 @@ function AgentLoopBlock({
39274
39339
  level: 2
39275
39340
  },
39276
39341
  childToolCall.id
39277
- )) : /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
39278
- /* @__PURE__ */ jsx36(LoaderCircle, { size: 12, className: "shrink-0 animate-spin text-[hsl(var(--muted-foreground))]" }),
39279
- /* @__PURE__ */ jsx36("span", { children: "\u6B63\u5728\u542F\u52A8..." })
39280
- ] }) }) : status === "awaiting_answer" ? /* @__PURE__ */ jsx36("div", { className: "flex flex-col gap-1 py-2", children: /* @__PURE__ */ jsx36("div", { className: "px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u8BF7\u5728\u4E0B\u65B9\u5B50\u667A\u80FD\u4F53\u5BF9\u8BDD\u4E2D\u5B8C\u6210\u786E\u8BA4" }) }) : null
39281
- ] }) : /* @__PURE__ */ jsxs30(Fragment13, { children: [
39282
- /* @__PURE__ */ jsxs30(
39342
+ )) : /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
39343
+ /* @__PURE__ */ jsx37(LoaderCircle, { size: 12, className: "shrink-0 animate-spin text-[hsl(var(--muted-foreground))]" }),
39344
+ /* @__PURE__ */ jsx37("span", { children: "\u6B63\u5728\u542F\u52A8..." })
39345
+ ] }) }) : status === "awaiting_answer" ? /* @__PURE__ */ jsx37("div", { className: "flex flex-col gap-1 py-2", children: /* @__PURE__ */ jsx37("div", { className: "px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u8BF7\u5728\u4E0B\u65B9\u5B50\u667A\u80FD\u4F53\u5BF9\u8BDD\u4E2D\u5B8C\u6210\u786E\u8BA4" }) }) : null
39346
+ ] }) : /* @__PURE__ */ jsxs31(Fragment14, { children: [
39347
+ /* @__PURE__ */ jsxs31(
39283
39348
  "div",
39284
39349
  {
39285
39350
  className: cn(
@@ -39287,21 +39352,21 @@ function AgentLoopBlock({
39287
39352
  cardStyles.headerClass
39288
39353
  ),
39289
39354
  children: [
39290
- /* @__PURE__ */ jsx36(
39355
+ /* @__PURE__ */ jsx37(
39291
39356
  "button",
39292
39357
  {
39293
39358
  type: "button",
39294
39359
  onClick: toggleExpanded,
39295
39360
  "aria-expanded": expanded,
39296
39361
  className: "flex min-w-0 flex-1 items-center gap-2 text-left focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
39297
- children: /* @__PURE__ */ jsxs30("span", { className: "min-w-0 flex items-center gap-2", children: [
39298
- status === "error" ? /* @__PURE__ */ jsx36(X, { size: 14, className: cn("shrink-0", cardStyles.iconClass) }) : status === "cancelled" ? /* @__PURE__ */ jsx36(Ban, { size: 14, className: cn("shrink-0", cardStyles.iconClass) }) : /* @__PURE__ */ jsx36(Check, { size: 14, className: "shrink-0 text-[hsl(var(--swf-success))]" }),
39299
- /* @__PURE__ */ jsx36("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: renderDescription ? renderDescription(description) : description })
39362
+ children: /* @__PURE__ */ jsxs31("span", { className: "min-w-0 flex items-center gap-2", children: [
39363
+ status === "error" ? /* @__PURE__ */ jsx37(X, { size: 14, className: cn("shrink-0", cardStyles.iconClass) }) : status === "cancelled" ? /* @__PURE__ */ jsx37(Ban, { size: 14, className: cn("shrink-0", cardStyles.iconClass) }) : /* @__PURE__ */ jsx37(Check, { size: 14, className: "shrink-0 text-[hsl(var(--swf-success))]" }),
39364
+ /* @__PURE__ */ jsx37("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: renderDescription ? renderDescription(description) : description })
39300
39365
  ] })
39301
39366
  }
39302
39367
  ),
39303
- reasoning ? /* @__PURE__ */ jsx36(ThinkingBadge, { reasoning, variant: "block" }) : null,
39304
- /* @__PURE__ */ jsx36(
39368
+ reasoning ? /* @__PURE__ */ jsx37(ThinkingBadge, { reasoning, variant: "block" }) : null,
39369
+ /* @__PURE__ */ jsx37(
39305
39370
  Bot,
39306
39371
  {
39307
39372
  size: 14,
@@ -39309,14 +39374,14 @@ function AgentLoopBlock({
39309
39374
  "aria-label": "\u5B50\u667A\u80FD\u4F53"
39310
39375
  }
39311
39376
  ),
39312
- /* @__PURE__ */ jsx36(
39377
+ /* @__PURE__ */ jsx37(
39313
39378
  "button",
39314
39379
  {
39315
39380
  type: "button",
39316
39381
  onClick: toggleExpanded,
39317
39382
  "aria-expanded": expanded,
39318
39383
  className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
39319
- children: /* @__PURE__ */ jsx36(
39384
+ children: /* @__PURE__ */ jsx37(
39320
39385
  ChevronRight,
39321
39386
  {
39322
39387
  size: 14,
@@ -39331,20 +39396,20 @@ function AgentLoopBlock({
39331
39396
  ]
39332
39397
  }
39333
39398
  ),
39334
- !expanded ? /* @__PURE__ */ jsxs30(Fragment13, { children: [
39335
- /* @__PURE__ */ jsx36("div", { className: "flex flex-wrap gap-1.5 px-4 py-2", children: completedToolLabels.length > 0 ? completedToolLabels.map(
39336
- (item) => item.kind === "file" ? /* @__PURE__ */ jsxs30(
39399
+ !expanded ? /* @__PURE__ */ jsxs31(Fragment14, { children: [
39400
+ /* @__PURE__ */ jsx37("div", { className: "flex flex-wrap gap-1.5 px-4 py-2", children: completedToolLabels.length > 0 ? completedToolLabels.map(
39401
+ (item) => item.kind === "file" ? /* @__PURE__ */ jsxs31(
39337
39402
  "span",
39338
39403
  {
39339
39404
  className: "inline-flex min-w-0 items-center gap-1 rounded-[6px] bg-[hsl(var(--muted))] px-2 py-0.5 text-xs font-medium text-[hsl(var(--secondary-foreground))]",
39340
39405
  title: item.label,
39341
39406
  children: [
39342
- /* @__PURE__ */ jsx36(FileText, { size: 12, className: "shrink-0", "aria-hidden": "true" }),
39343
- /* @__PURE__ */ jsx36("span", { className: "truncate", children: item.label })
39407
+ /* @__PURE__ */ jsx37(FileText, { size: 12, className: "shrink-0", "aria-hidden": "true" }),
39408
+ /* @__PURE__ */ jsx37("span", { className: "truncate", children: item.label })
39344
39409
  ]
39345
39410
  },
39346
39411
  item.key
39347
- ) : /* @__PURE__ */ jsx36(
39412
+ ) : /* @__PURE__ */ jsx37(
39348
39413
  "span",
39349
39414
  {
39350
39415
  className: "inline-flex items-center rounded-[6px] bg-[hsl(var(--muted))] px-2 py-0.5 text-xs font-medium text-[hsl(var(--secondary-foreground))]",
@@ -39352,20 +39417,20 @@ function AgentLoopBlock({
39352
39417
  },
39353
39418
  item.key
39354
39419
  )
39355
- ) : /* @__PURE__ */ jsx36("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5DE5\u5177\u8C03\u7528" }) }),
39356
- inlineToolUiBlocks.length > 0 ? /* @__PURE__ */ jsx36("div", { className: "flex flex-col gap-2 px-4 pb-3", children: inlineToolUiBlocks.map((block) => /* @__PURE__ */ jsx36(ToolUiCard, { card: block.card, sessionId }, block.key)) }) : null
39420
+ ) : /* @__PURE__ */ jsx37("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5DE5\u5177\u8C03\u7528" }) }),
39421
+ inlineToolUiBlocks.length > 0 ? /* @__PURE__ */ jsx37("div", { className: "flex flex-col gap-2 px-4 pb-3", children: inlineToolUiBlocks.map((block) => /* @__PURE__ */ jsx37(ToolUiCard, { card: block.card, sessionId }, block.key)) }) : null
39357
39422
  ] }) : null
39358
39423
  ] }),
39359
- expanded && /* @__PURE__ */ jsxs30("div", { className: "border-t border-[hsl(var(--border))] py-2", children: [
39424
+ expanded && /* @__PURE__ */ jsxs31("div", { className: "border-t border-[hsl(var(--border))] py-2", children: [
39360
39425
  (() => {
39361
39426
  const taskPrompt = safeParsePrompt(toolCall.arguments);
39362
- return taskPrompt ? /* @__PURE__ */ jsxs30("details", { className: "mx-3 mb-2 rounded-md bg-[hsl(var(--muted))]/40", children: [
39363
- /* @__PURE__ */ jsx36("summary", { className: "cursor-pointer px-3 py-1.5 text-[11px] font-medium text-[hsl(var(--muted-foreground))]", children: "\u4EFB\u52A1" }),
39364
- /* @__PURE__ */ jsx36("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsx36("pre", { className: "whitespace-pre-wrap text-[11px] leading-relaxed text-[hsl(var(--foreground))]", children: taskPrompt }) })
39427
+ return taskPrompt ? /* @__PURE__ */ jsxs31("details", { className: "mx-3 mb-2 rounded-md bg-[hsl(var(--muted))]/40", children: [
39428
+ /* @__PURE__ */ jsx37("summary", { className: "cursor-pointer px-3 py-1.5 text-[11px] font-medium text-[hsl(var(--muted-foreground))]", children: "\u4EFB\u52A1" }),
39429
+ /* @__PURE__ */ jsx37("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsx37("pre", { className: "whitespace-pre-wrap text-[11px] leading-relaxed text-[hsl(var(--foreground))]", children: taskPrompt }) })
39365
39430
  ] }) : null;
39366
39431
  })(),
39367
- childMessages.length > 0 ? /* @__PURE__ */ jsx36("div", { className: "flex flex-col gap-3 px-3", children: childMessages.map(
39368
- (message, index2) => message.role === "assistant" ? /* @__PURE__ */ jsx36(
39432
+ childMessages.length > 0 ? /* @__PURE__ */ jsx37("div", { className: "flex flex-col gap-3 px-3", children: childMessages.map(
39433
+ (message, index2) => message.role === "assistant" ? /* @__PURE__ */ jsx37(
39369
39434
  ExpandedChildAssistantMessage,
39370
39435
  {
39371
39436
  message,
@@ -39375,13 +39440,13 @@ function AgentLoopBlock({
39375
39440
  hideAskUserQuestions
39376
39441
  },
39377
39442
  message.entry_id ?? `${message.timestamp ?? "child"}-${index2}`
39378
- ) : message.role === "user" ? /* @__PURE__ */ jsx36(
39443
+ ) : message.role === "user" ? /* @__PURE__ */ jsx37(
39379
39444
  ExpandedChildUserMessage,
39380
39445
  {
39381
39446
  message
39382
39447
  },
39383
39448
  message.entry_id ?? `${message.timestamp ?? "user"}-${index2}`
39384
- ) : message.role === "error" ? /* @__PURE__ */ jsx36(
39449
+ ) : message.role === "error" ? /* @__PURE__ */ jsx37(
39385
39450
  "div",
39386
39451
  {
39387
39452
  className: "border-l-[2px] border-l-[hsl(var(--border))] px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]",
@@ -39389,17 +39454,17 @@ function AgentLoopBlock({
39389
39454
  },
39390
39455
  message.entry_id ?? `${message.timestamp ?? "error"}-${index2}`
39391
39456
  ) : null
39392
- ) }) : status === "running" ? /* @__PURE__ */ jsxs30("div", { className: "px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
39393
- /* @__PURE__ */ jsx36(LoaderCircle, { size: 12, className: "mr-1.5 inline animate-spin" }),
39457
+ ) }) : status === "running" ? /* @__PURE__ */ jsxs31("div", { className: "px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
39458
+ /* @__PURE__ */ jsx37(LoaderCircle, { size: 12, className: "mr-1.5 inline animate-spin" }),
39394
39459
  "\u6B63\u5728\u542F\u52A8..."
39395
- ] }) : toolCall.result ? /* @__PURE__ */ jsx36("pre", { className: "max-h-[400px] overflow-auto px-3 py-2 whitespace-pre-wrap text-[11px] text-[hsl(var(--muted-foreground))]", children: typeof toolCall.result === "string" ? toolCall.result : JSON.stringify(toolCall.result, null, 2) }) : null
39460
+ ] }) : toolCall.result ? /* @__PURE__ */ jsx37("pre", { className: "max-h-[400px] overflow-auto px-3 py-2 whitespace-pre-wrap text-[11px] text-[hsl(var(--muted-foreground))]", children: typeof toolCall.result === "string" ? toolCall.result : JSON.stringify(toolCall.result, null, 2) }) : null
39396
39461
  ] })
39397
39462
  ]
39398
39463
  }
39399
39464
  );
39400
39465
  }
39401
39466
  function ExpandedChildUserMessage({ message }) {
39402
- return /* @__PURE__ */ jsx36("div", { className: "pl-8", children: /* @__PURE__ */ jsx36(UserMessageBubble, { message }) });
39467
+ return /* @__PURE__ */ jsx37("div", { className: "pl-8", children: /* @__PURE__ */ jsx37(UserMessageBubble, { message }) });
39403
39468
  }
39404
39469
  function ExpandedChildAssistantMessage({
39405
39470
  message,
@@ -39413,12 +39478,12 @@ function ExpandedChildAssistantMessage({
39413
39478
  (toolCall) => formatToolName(toolCall.name) !== "AskUserQuestion"
39414
39479
  ) : message.tool_calls ?? [];
39415
39480
  const hasToolCalls = toolCalls.length > 0;
39416
- return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-2", children: [
39417
- showReasoning && message.reasoning && /* @__PURE__ */ jsxs30(Reasoning, { isStreaming, children: [
39418
- /* @__PURE__ */ jsx36(ReasoningTrigger, { wordCount: message.reasoning.length }),
39419
- /* @__PURE__ */ jsx36(ReasoningContent, { children: message.reasoning })
39481
+ return /* @__PURE__ */ jsxs31("div", { className: "flex flex-col gap-2", children: [
39482
+ showReasoning && message.reasoning && /* @__PURE__ */ jsxs31(Reasoning, { isStreaming, children: [
39483
+ /* @__PURE__ */ jsx37(ReasoningTrigger, { wordCount: message.reasoning.length }),
39484
+ /* @__PURE__ */ jsx37(ReasoningContent, { children: message.reasoning })
39420
39485
  ] }),
39421
- text4 ? /* @__PURE__ */ jsx36(
39486
+ text4 ? /* @__PURE__ */ jsx37(
39422
39487
  ChildText,
39423
39488
  {
39424
39489
  text: text4,
@@ -39427,8 +39492,8 @@ function ExpandedChildAssistantMessage({
39427
39492
  reasoning: void 0
39428
39493
  }
39429
39494
  ) : null,
39430
- hasToolCalls && /* @__PURE__ */ jsx36("div", { className: "flex flex-col gap-2", children: toolCalls.map(
39431
- (toolCall) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx36(
39495
+ hasToolCalls && /* @__PURE__ */ jsx37("div", { className: "flex flex-col gap-2", children: toolCalls.map(
39496
+ (toolCall) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx37(
39432
39497
  AgentLoopBlock,
39433
39498
  {
39434
39499
  toolCall,
@@ -39437,7 +39502,7 @@ function ExpandedChildAssistantMessage({
39437
39502
  hideAskUserQuestions
39438
39503
  },
39439
39504
  toolCall.id
39440
- ) : /* @__PURE__ */ jsx36(
39505
+ ) : /* @__PURE__ */ jsx37(
39441
39506
  ToolCallBlock,
39442
39507
  {
39443
39508
  toolCall,
@@ -39449,8 +39514,8 @@ function ExpandedChildAssistantMessage({
39449
39514
  toolCall.id
39450
39515
  )
39451
39516
  ) }),
39452
- message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx36("div", { className: "flex flex-col gap-2", children: message.blocks.map(
39453
- (block, index2) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx36("div", { className: "ml-4", children: /* @__PURE__ */ jsx36(ToolUiCard, { card: block.content, sessionId }) }, `${block.tool_call_id}-${index2}`) : null
39517
+ message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx37("div", { className: "flex flex-col gap-2", children: message.blocks.map(
39518
+ (block, index2) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx37("div", { className: "ml-4", children: /* @__PURE__ */ jsx37(ToolUiCard, { card: block.content, sessionId }) }, `${block.tool_call_id}-${index2}`) : null
39454
39519
  ) }) : null
39455
39520
  ] });
39456
39521
  }
@@ -39460,8 +39525,8 @@ function ChildText({
39460
39525
  sessionId,
39461
39526
  reasoning
39462
39527
  }) {
39463
- return /* @__PURE__ */ jsxs30("div", { className: "pl-8 text-[12px] leading-6 text-[hsl(var(--foreground))]", children: [
39464
- /* @__PURE__ */ jsx36(
39528
+ return /* @__PURE__ */ jsxs31("div", { className: "pl-8 text-[12px] leading-6 text-[hsl(var(--foreground))]", children: [
39529
+ /* @__PURE__ */ jsx37(
39465
39530
  MarkdownContent,
39466
39531
  {
39467
39532
  mode: isStreaming ? "streaming" : "static",
@@ -39471,8 +39536,8 @@ function ChildText({
39471
39536
  children: text4
39472
39537
  }
39473
39538
  ),
39474
- isStreaming && /* @__PURE__ */ jsx36("span", { className: "ml-0.5 inline-block h-[1em] w-[3px] animate-pulse rounded-sm bg-current opacity-60" }),
39475
- reasoning ? /* @__PURE__ */ jsx36(ThinkingBadge, { reasoning }) : null
39539
+ isStreaming && /* @__PURE__ */ jsx37("span", { className: "ml-0.5 inline-block h-[1em] w-[3px] animate-pulse rounded-sm bg-current opacity-60" }),
39540
+ reasoning ? /* @__PURE__ */ jsx37(ThinkingBadge, { reasoning }) : null
39476
39541
  ] });
39477
39542
  }
39478
39543
  function getLoopCardStyles(status) {
@@ -39500,7 +39565,7 @@ function getLoopCardStyles(status) {
39500
39565
  }
39501
39566
 
39502
39567
  // src/chat/WorkflowRunBlock.tsx
39503
- import { Fragment as Fragment14, jsx as jsx37, jsxs as jsxs31 } from "react/jsx-runtime";
39568
+ import { Fragment as Fragment15, jsx as jsx38, jsxs as jsxs32 } from "react/jsx-runtime";
39504
39569
  var EMPTY_ENTRIES = [];
39505
39570
  function synthToolCall(loopName, info, desc) {
39506
39571
  return {
@@ -39545,10 +39610,10 @@ function stepStatus(group, runStatus) {
39545
39610
  return runStatus === "done" ? "done" : void 0;
39546
39611
  }
39547
39612
  function StatusIcon({ status }) {
39548
- if (status === "done") return /* @__PURE__ */ jsx37(Check, { size: 13, className: "shrink-0 text-emerald-600", "aria-label": "\u5B8C\u6210" });
39549
- if (status === "running") return /* @__PURE__ */ jsx37(LoaderCircle, { size: 13, className: "shrink-0 animate-spin text-[hsl(var(--muted-foreground))]", "aria-label": "\u8FDB\u884C\u4E2D" });
39550
- if (status === "error") return /* @__PURE__ */ jsx37(X, { size: 13, className: "shrink-0 text-red-600", "aria-label": "\u5931\u8D25" });
39551
- if (status === "cancelled") return /* @__PURE__ */ jsx37(CircleSlash, { size: 13, className: "shrink-0 text-[hsl(var(--muted-foreground))]", "aria-label": "\u5DF2\u53D6\u6D88" });
39613
+ if (status === "done") return /* @__PURE__ */ jsx38(Check, { size: 13, className: "shrink-0 text-emerald-600", "aria-label": "\u5B8C\u6210" });
39614
+ if (status === "running") return /* @__PURE__ */ jsx38(LoaderCircle, { size: 13, className: "shrink-0 animate-spin text-[hsl(var(--muted-foreground))]", "aria-label": "\u8FDB\u884C\u4E2D" });
39615
+ if (status === "error") return /* @__PURE__ */ jsx38(X, { size: 13, className: "shrink-0 text-red-600", "aria-label": "\u5931\u8D25" });
39616
+ if (status === "cancelled") return /* @__PURE__ */ jsx38(CircleSlash, { size: 13, className: "shrink-0 text-[hsl(var(--muted-foreground))]", "aria-label": "\u5DF2\u53D6\u6D88" });
39552
39617
  return null;
39553
39618
  }
39554
39619
  var CONTAINER_LABEL = { parallel: "\u5E76\u884C", choice: "\u6761\u4EF6", end: "\u7ED3\u675F" };
@@ -39561,7 +39626,7 @@ function meaningfulLogs(logs) {
39561
39626
  }
39562
39627
  function LogLines({ logs }) {
39563
39628
  if (logs.length === 0) return null;
39564
- return /* @__PURE__ */ jsx37("div", { className: "flex flex-col gap-0.5", children: logs.map((log, index2) => /* @__PURE__ */ jsx37(
39629
+ return /* @__PURE__ */ jsx38("div", { className: "flex flex-col gap-0.5", children: logs.map((log, index2) => /* @__PURE__ */ jsx38(
39565
39630
  "div",
39566
39631
  {
39567
39632
  className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]",
@@ -39592,7 +39657,7 @@ function RefTokenText({ text: text4, refs }) {
39592
39657
  const id = match[1];
39593
39658
  const info = refs.get(id);
39594
39659
  parts.push(
39595
- /* @__PURE__ */ jsxs31(
39660
+ /* @__PURE__ */ jsxs32(
39596
39661
  "span",
39597
39662
  {
39598
39663
  title: info?.value ? info.value.slice(0, 300) : "\u5C1A\u65E0\u8F93\u51FA",
@@ -39608,13 +39673,13 @@ function RefTokenText({ text: text4, refs }) {
39608
39673
  cursor = match.index + match[0].length;
39609
39674
  }
39610
39675
  if (cursor < text4.length) parts.push(text4.slice(cursor));
39611
- return /* @__PURE__ */ jsx37(Fragment14, { children: parts });
39676
+ return /* @__PURE__ */ jsx38(Fragment15, { children: parts });
39612
39677
  }
39613
39678
  function WorkflowRunBlock({ toolCall, sessionId }) {
39614
39679
  const run = useSessionState(sessionId, (state) => state.workflowRuns[toolCall.id]);
39615
39680
  const agentLoops = useSessionState(sessionId, (state) => state.agentLoops);
39616
39681
  const sessionMessages = useSessionState(sessionId, (state) => state.messages);
39617
- const [collapsed, setCollapsed] = useState21(false);
39682
+ const [collapsed, setCollapsed] = useState22(false);
39618
39683
  const stepLoops = useMemo10(
39619
39684
  () => Object.entries(agentLoops).filter(([, info]) => info.workflowRunId === toolCall.id).map(([loopName, info]) => ({ loopName, info })),
39620
39685
  [agentLoops, toolCall.id]
@@ -39656,7 +39721,7 @@ function WorkflowRunBlock({ toolCall, sessionId }) {
39656
39721
  });
39657
39722
  return map3;
39658
39723
  }, [toolCall.arguments, groups, groupLoops, sessionMessages]);
39659
- const renderRefText = (text4) => /* @__PURE__ */ jsx37(RefTokenText, { text: text4, refs: refInfos });
39724
+ const renderRefText = (text4) => /* @__PURE__ */ jsx38(RefTokenText, { text: text4, refs: refInfos });
39660
39725
  const finalOutput = useMemo10(
39661
39726
  () => output2.split("\n").filter((line) => !line.startsWith(LOG_PREFIX)).join("\n").trim(),
39662
39727
  [output2]
@@ -39667,8 +39732,8 @@ function WorkflowRunBlock({ toolCall, sessionId }) {
39667
39732
  const title = run?.name || "\u6280\u80FD";
39668
39733
  const statusSummary = running ? `\u8FDB\u884C\u4E2D \xB7 ${stepCount} \u6B65` : status === "error" ? `\u5931\u8D25 \xB7 ${stepCount} \u6B65` : status === "cancelled" ? `\u5DF2\u53D6\u6D88 \xB7 ${stepCount} \u6B65` : `\u5DF2\u5B8C\u6210 \xB7 ${stepCount} \u6B65`;
39669
39734
  const hasStepContent = groups.length > 0 || stepLoops.length > 0;
39670
- return /* @__PURE__ */ jsxs31("div", { className: "msg-animate overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))]/50", children: [
39671
- /* @__PURE__ */ jsxs31(
39735
+ return /* @__PURE__ */ jsxs32("div", { className: "msg-animate overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))]/50", children: [
39736
+ /* @__PURE__ */ jsxs32(
39672
39737
  "button",
39673
39738
  {
39674
39739
  type: "button",
@@ -39676,16 +39741,16 @@ function WorkflowRunBlock({ toolCall, sessionId }) {
39676
39741
  "aria-expanded": !collapsed,
39677
39742
  className: "flex w-full items-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--primary)/0.06)] px-4 py-2.5 text-left transition-colors hover:bg-[hsl(var(--primary)/0.1)] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
39678
39743
  children: [
39679
- /* @__PURE__ */ jsx37(Zap, { size: 15, className: "shrink-0 text-violet-600" }),
39680
- /* @__PURE__ */ jsxs31("span", { className: "min-w-0 truncate text-sm font-semibold text-[hsl(var(--foreground))]", children: [
39744
+ /* @__PURE__ */ jsx38(Zap, { size: 15, className: "shrink-0 text-violet-600" }),
39745
+ /* @__PURE__ */ jsxs32("span", { className: "min-w-0 truncate text-sm font-semibold text-[hsl(var(--foreground))]", children: [
39681
39746
  "\u56FA\u5B9A\u6D41\u7A0B \xB7 ",
39682
39747
  title
39683
39748
  ] }),
39684
- /* @__PURE__ */ jsxs31("span", { className: "ml-auto flex shrink-0 items-center gap-1.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
39685
- running ? /* @__PURE__ */ jsx37(LoaderCircle, { size: 12, className: "animate-spin" }) : null,
39749
+ /* @__PURE__ */ jsxs32("span", { className: "ml-auto flex shrink-0 items-center gap-1.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
39750
+ running ? /* @__PURE__ */ jsx38(LoaderCircle, { size: 12, className: "animate-spin" }) : null,
39686
39751
  statusSummary
39687
39752
  ] }),
39688
- /* @__PURE__ */ jsx37(
39753
+ /* @__PURE__ */ jsx38(
39689
39754
  ChevronRight,
39690
39755
  {
39691
39756
  size: 15,
@@ -39698,14 +39763,14 @@ function WorkflowRunBlock({ toolCall, sessionId }) {
39698
39763
  ]
39699
39764
  }
39700
39765
  ),
39701
- !collapsed && /* @__PURE__ */ jsxs31("div", { className: "flex flex-col gap-2 p-3", children: [
39702
- /* @__PURE__ */ jsx37(LogLines, { logs: meaningfulLogs(prelude) }),
39766
+ !collapsed && /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-2 p-3", children: [
39767
+ /* @__PURE__ */ jsx38(LogLines, { logs: meaningfulLogs(prelude) }),
39703
39768
  groups.map((group, index2) => {
39704
39769
  const loop = groupLoops[index2];
39705
39770
  const logs = meaningfulLogs(group.logs);
39706
39771
  if (loop) {
39707
- return /* @__PURE__ */ jsxs31("div", { className: "flex flex-col gap-1", children: [
39708
- /* @__PURE__ */ jsx37(
39772
+ return /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-1", children: [
39773
+ /* @__PURE__ */ jsx38(
39709
39774
  AgentLoopBlock,
39710
39775
  {
39711
39776
  toolCall: synthToolCall(loop.loopName, loop.info, group.desc),
@@ -39714,11 +39779,11 @@ function WorkflowRunBlock({ toolCall, sessionId }) {
39714
39779
  renderDescription: renderRefText
39715
39780
  }
39716
39781
  ),
39717
- /* @__PURE__ */ jsx37(LogLines, { logs })
39782
+ /* @__PURE__ */ jsx38(LogLines, { logs })
39718
39783
  ] }, group.key);
39719
39784
  }
39720
39785
  const container = CONTAINER_LABEL[group.stepKind];
39721
- return /* @__PURE__ */ jsxs31(
39786
+ return /* @__PURE__ */ jsxs32(
39722
39787
  "div",
39723
39788
  {
39724
39789
  className: cn(
@@ -39726,18 +39791,18 @@ function WorkflowRunBlock({ toolCall, sessionId }) {
39726
39791
  container ? "border border-dashed border-violet-400/50 bg-violet-500/5" : "border border-[hsl(var(--border))] bg-[hsl(var(--card))]"
39727
39792
  ),
39728
39793
  children: [
39729
- /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-1.5 text-sm text-[hsl(var(--foreground))]", children: [
39730
- /* @__PURE__ */ jsx37(StatusIcon, { status: stepStatus(group, status) }),
39731
- container ? /* @__PURE__ */ jsx37("span", { className: "text-[11px] font-semibold text-violet-600", children: container }) : null,
39732
- /* @__PURE__ */ jsx37("span", { className: "min-w-0 truncate", children: renderRefText(group.desc || group.stepId) })
39794
+ /* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-1.5 text-sm text-[hsl(var(--foreground))]", children: [
39795
+ /* @__PURE__ */ jsx38(StatusIcon, { status: stepStatus(group, status) }),
39796
+ container ? /* @__PURE__ */ jsx38("span", { className: "text-[11px] font-semibold text-violet-600", children: container }) : null,
39797
+ /* @__PURE__ */ jsx38("span", { className: "min-w-0 truncate", children: renderRefText(group.desc || group.stepId) })
39733
39798
  ] }),
39734
- /* @__PURE__ */ jsx37(LogLines, { logs })
39799
+ /* @__PURE__ */ jsx38(LogLines, { logs })
39735
39800
  ]
39736
39801
  },
39737
39802
  group.key
39738
39803
  );
39739
39804
  }),
39740
- leftoverLoops.map((step) => /* @__PURE__ */ jsx37(
39805
+ leftoverLoops.map((step) => /* @__PURE__ */ jsx38(
39741
39806
  AgentLoopBlock,
39742
39807
  {
39743
39808
  toolCall: synthToolCall(step.loopName, step.info),
@@ -39747,13 +39812,13 @@ function WorkflowRunBlock({ toolCall, sessionId }) {
39747
39812
  },
39748
39813
  step.loopName
39749
39814
  )),
39750
- (!hasStepContent && output2 || status === "error" && output2) && /* @__PURE__ */ jsx37("pre", { className: "max-h-48 overflow-y-auto whitespace-pre-wrap break-words rounded-lg border border-[hsl(var(--border))] px-3 py-2 font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]", children: output2 }),
39751
- status === "done" && hasStepContent && finalOutput && /* @__PURE__ */ jsxs31("details", { className: "rounded-lg border border-[hsl(var(--border))] px-3 py-2", children: [
39752
- /* @__PURE__ */ jsx37("summary", { className: "cursor-pointer select-none text-xs text-[hsl(var(--muted-foreground))]", children: "\u6700\u7EC8\u8F93\u51FA" }),
39753
- /* @__PURE__ */ jsx37("pre", { className: "mt-1.5 max-h-48 overflow-y-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]", children: finalOutput })
39815
+ (!hasStepContent && output2 || status === "error" && output2) && /* @__PURE__ */ jsx38("pre", { className: "max-h-48 overflow-y-auto whitespace-pre-wrap break-words rounded-lg border border-[hsl(var(--border))] px-3 py-2 font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]", children: output2 }),
39816
+ status === "done" && hasStepContent && finalOutput && /* @__PURE__ */ jsxs32("details", { className: "rounded-lg border border-[hsl(var(--border))] px-3 py-2", children: [
39817
+ /* @__PURE__ */ jsx38("summary", { className: "cursor-pointer select-none text-xs text-[hsl(var(--muted-foreground))]", children: "\u6700\u7EC8\u8F93\u51FA" }),
39818
+ /* @__PURE__ */ jsx38("pre", { className: "mt-1.5 max-h-48 overflow-y-auto whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.5] text-[hsl(var(--muted-foreground))]", children: finalOutput })
39754
39819
  ] }),
39755
39820
  status === "done" && hasStepContent && // 统一的终止行:正常跑完(不管是 end 节点还是自然走完)都有,观感一致
39756
- /* @__PURE__ */ jsx37("div", { className: "py-0.5 text-center text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u23F9 \u6D41\u7A0B\u5230\u6B64\u7ED3\u675F" })
39821
+ /* @__PURE__ */ jsx38("div", { className: "py-0.5 text-center text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u23F9 \u6D41\u7A0B\u5230\u6B64\u7ED3\u675F" })
39757
39822
  ] })
39758
39823
  ] });
39759
39824
  }
@@ -39811,7 +39876,7 @@ function toolCallAnswered(toolCall, sessionStatus, answerData) {
39811
39876
  }
39812
39877
 
39813
39878
  // src/chat/AssistantTurnBlock.tsx
39814
- import { jsx as jsx38, jsxs as jsxs32 } from "react/jsx-runtime";
39879
+ import { jsx as jsx39, jsxs as jsxs33 } from "react/jsx-runtime";
39815
39880
  var EMPTY_MESSAGES = [];
39816
39881
  var EMPTY_AGENT_LOOPS = {};
39817
39882
  var turnDisplayModeMemory = /* @__PURE__ */ new Map();
@@ -40030,11 +40095,11 @@ function AssistantTurnBlockBase({
40030
40095
  ),
40031
40096
  [assistantTurnMessages]
40032
40097
  );
40033
- const [displayMode, setDisplayMode] = useState22(
40098
+ const [displayMode, setDisplayMode] = useState23(
40034
40099
  () => forceExpanded ? "detail" : (displayModeMemoryKey ? turnDisplayModeMemory.get(displayModeMemoryKey) : void 0) ?? defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall, isStreaming })
40035
40100
  );
40036
- const wasStreamingRef = useRef15(isStreaming);
40037
- useEffect16(() => {
40101
+ const wasStreamingRef = useRef16(isStreaming);
40102
+ useEffect17(() => {
40038
40103
  if (wasStreamingRef.current && !isStreaming && !forceExpanded && !(displayModeMemoryKey && turnDisplayModeMemory.has(displayModeMemoryKey))) {
40039
40104
  setDisplayMode(
40040
40105
  defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall, isStreaming })
@@ -40112,20 +40177,20 @@ function AssistantTurnBlockBase({
40112
40177
  messages,
40113
40178
  isStreaming
40114
40179
  });
40115
- const [clock, setClock] = useState22(() => Date.now());
40116
- useEffect16(() => {
40180
+ const [clock, setClock] = useState23(() => Date.now());
40181
+ useEffect17(() => {
40117
40182
  if (!isStreaming) return;
40118
40183
  const timer = window.setInterval(() => setClock(Date.now()), 1e3);
40119
40184
  return () => window.clearInterval(timer);
40120
40185
  }, [isStreaming]);
40121
40186
  const liveExecutionDurationMs = isStreaming ? getExecutionDurationMs({ messages, isStreaming, now: clock }) : executionDurationMs;
40122
40187
  const observedMemoryRefs = useMemo11(() => collectMemoryRefs(messages), [messages]);
40123
- const [cachedMemoryRefs, setCachedMemoryRefs] = useState22([]);
40124
- useEffect16(() => {
40188
+ const [cachedMemoryRefs, setCachedMemoryRefs] = useState23([]);
40189
+ useEffect17(() => {
40125
40190
  if (observedMemoryRefs.length > 0) setCachedMemoryRefs(observedMemoryRefs);
40126
40191
  }, [observedMemoryRefs]);
40127
40192
  const memoryRefs = observedMemoryRefs.length > 0 ? observedMemoryRefs : cachedMemoryRefs;
40128
- return /* @__PURE__ */ jsxs32(
40193
+ return /* @__PURE__ */ jsxs33(
40129
40194
  "div",
40130
40195
  {
40131
40196
  "aria-busy": isStreaming || void 0,
@@ -40136,20 +40201,20 @@ function AssistantTurnBlockBase({
40136
40201
  customization?.classNames?.assistantTurn
40137
40202
  ),
40138
40203
  children: [
40139
- memoryRefs.length > 0 && /* @__PURE__ */ jsx38(MemoryRefsHint, { refs: memoryRefs }),
40140
- hasInterruptedState && /* @__PURE__ */ jsx38("div", { className: "ml-4 w-fit rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--swf-warning))]", children: "\u5DF2\u4E2D\u65AD" }),
40141
- hasFailedWithoutContent && /* @__PURE__ */ jsx38("div", { className: "ml-4 w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]", children: "\u751F\u6210\u5931\u8D25" }),
40142
- hasExecutionProcess && /* @__PURE__ */ jsxs32("div", { className: "flex w-full items-start gap-2.5", children: [
40143
- /* @__PURE__ */ jsx38(
40204
+ memoryRefs.length > 0 && /* @__PURE__ */ jsx39(MemoryRefsHint, { refs: memoryRefs }),
40205
+ hasInterruptedState && /* @__PURE__ */ jsx39("div", { className: "ml-4 w-fit rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--swf-warning))]", children: "\u5DF2\u4E2D\u65AD" }),
40206
+ hasFailedWithoutContent && /* @__PURE__ */ jsx39("div", { className: "ml-4 w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]", children: "\u751F\u6210\u5931\u8D25" }),
40207
+ hasExecutionProcess && /* @__PURE__ */ jsxs33("div", { className: "flex w-full items-start gap-2.5", children: [
40208
+ /* @__PURE__ */ jsx39(
40144
40209
  "span",
40145
40210
  {
40146
40211
  className: "grid size-[30px] shrink-0 place-items-center rounded-full bg-[hsl(var(--muted)/0.55)] text-[hsl(var(--foreground))]",
40147
40212
  "aria-hidden": "true",
40148
- children: /* @__PURE__ */ jsx38(Bot, { size: 16 })
40213
+ children: /* @__PURE__ */ jsx39(Bot, { size: 16 })
40149
40214
  }
40150
40215
  ),
40151
- /* @__PURE__ */ jsxs32("div", { className: "min-w-0 flex-1 pt-0.5", children: [
40152
- /* @__PURE__ */ jsxs32(
40216
+ /* @__PURE__ */ jsxs33("div", { className: "min-w-0 flex-1 pt-0.5", children: [
40217
+ /* @__PURE__ */ jsxs33(
40153
40218
  "button",
40154
40219
  {
40155
40220
  type: "button",
@@ -40163,14 +40228,14 @@ function AssistantTurnBlockBase({
40163
40228
  "data-testid": "assistant-execution-summary",
40164
40229
  className: "inline-flex min-w-0 max-w-full select-none items-center gap-1 bg-transparent p-0 text-left text-xs leading-[22px] text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
40165
40230
  children: [
40166
- /* @__PURE__ */ jsx38("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
40231
+ /* @__PURE__ */ jsx39("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
40167
40232
  messages: assistantTurnMessages,
40168
40233
  isStreaming,
40169
40234
  durationMs: liveExecutionDurationMs,
40170
40235
  sessionStatus,
40171
40236
  askAnswers
40172
40237
  }) }),
40173
- /* @__PURE__ */ jsx38(
40238
+ /* @__PURE__ */ jsx39(
40174
40239
  ChevronRight,
40175
40240
  {
40176
40241
  size: 14,
@@ -40188,11 +40253,11 @@ function AssistantTurnBlockBase({
40188
40253
  ]
40189
40254
  }
40190
40255
  ),
40191
- /* @__PURE__ */ jsx38("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
40256
+ /* @__PURE__ */ jsx39("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
40192
40257
  ] })
40193
40258
  ] }),
40194
- hasExecutionProcess && effectiveMode === "detail" ? /* @__PURE__ */ jsxs32("div", { className: "ml-10 flex flex-col gap-1", children: [
40195
- /* @__PURE__ */ jsx38(
40259
+ hasExecutionProcess && effectiveMode === "detail" ? /* @__PURE__ */ jsxs33("div", { className: "ml-10 flex flex-col gap-1", children: [
40260
+ /* @__PURE__ */ jsx39(
40196
40261
  AssistantMessages,
40197
40262
  {
40198
40263
  messages: assistantTurnMessages,
@@ -40210,7 +40275,7 @@ function AssistantTurnBlockBase({
40210
40275
  customization
40211
40276
  }
40212
40277
  ),
40213
- workflowRunToolCalls.map((workflowToolCall) => /* @__PURE__ */ jsx38(
40278
+ workflowRunToolCalls.map((workflowToolCall) => /* @__PURE__ */ jsx39(
40214
40279
  WorkflowRunBlock,
40215
40280
  {
40216
40281
  toolCall: workflowToolCall,
@@ -40219,8 +40284,8 @@ function AssistantTurnBlockBase({
40219
40284
  workflowToolCall.id
40220
40285
  ))
40221
40286
  ] }) : null,
40222
- resourceBlocks.some((block) => !compactOrderedToolIds.has(block.toolCallId)) ? /* @__PURE__ */ jsx38("div", { className: "ml-10 flex flex-col gap-3", children: resourceBlocks.filter((block) => !compactOrderedToolIds.has(block.toolCallId)).map((block) => /* @__PURE__ */ jsx38(ToolUiCard, { card: block.card, sessionId }, block.key)) }) : null,
40223
- previewToolCalls.some(({ toolCall }) => !compactOrderedToolIds.has(toolCall.id)) ? /* @__PURE__ */ jsx38("div", { className: "ml-10 flex flex-wrap gap-x-3 gap-y-1", children: previewToolCalls.filter(({ toolCall }) => !compactOrderedToolIds.has(toolCall.id)).map(({ key, toolCall, blocks }) => /* @__PURE__ */ jsx38(
40287
+ resourceBlocks.some((block) => !compactOrderedToolIds.has(block.toolCallId)) ? /* @__PURE__ */ jsx39("div", { className: "ml-10 flex flex-col gap-3", children: resourceBlocks.filter((block) => !compactOrderedToolIds.has(block.toolCallId)).map((block) => /* @__PURE__ */ jsx39(ToolUiCard, { card: block.card, sessionId }, block.key)) }) : null,
40288
+ previewToolCalls.some(({ toolCall }) => !compactOrderedToolIds.has(toolCall.id)) ? /* @__PURE__ */ jsx39("div", { className: "ml-10 flex flex-wrap gap-x-3 gap-y-1", children: previewToolCalls.filter(({ toolCall }) => !compactOrderedToolIds.has(toolCall.id)).map(({ key, toolCall, blocks }) => /* @__PURE__ */ jsx39(
40224
40289
  ToolPreviewAction,
40225
40290
  {
40226
40291
  toolCall,
@@ -40230,7 +40295,7 @@ function AssistantTurnBlockBase({
40230
40295
  },
40231
40296
  key
40232
40297
  )) }) : null,
40233
- isDeveloperMode && fileToolCalls.some((toolCall) => !compactOrderedToolIds.has(toolCall.id)) ? /* @__PURE__ */ jsx38("div", { className: "ml-10 flex flex-wrap gap-x-3 gap-y-1", children: fileToolCalls.filter((toolCall) => !compactOrderedToolIds.has(toolCall.id)).map((toolCall) => /* @__PURE__ */ jsx38(
40298
+ isDeveloperMode && fileToolCalls.some((toolCall) => !compactOrderedToolIds.has(toolCall.id)) ? /* @__PURE__ */ jsx39("div", { className: "ml-10 flex flex-wrap gap-x-3 gap-y-1", children: fileToolCalls.filter((toolCall) => !compactOrderedToolIds.has(toolCall.id)).map((toolCall) => /* @__PURE__ */ jsx39(
40234
40299
  ToolFilePreviewAction,
40235
40300
  {
40236
40301
  toolCall,
@@ -40239,7 +40304,7 @@ function AssistantTurnBlockBase({
40239
40304
  },
40240
40305
  toolCall.id
40241
40306
  )) }) : null,
40242
- effectiveMode === "compact" && finalMessage && finalOrderedParts.length > 0 ? /* @__PURE__ */ jsx38("div", { className: "ml-10 flex flex-col gap-3", children: finalOrderedParts.map((part) => part.type === "text" ? /* @__PURE__ */ jsx38(
40307
+ effectiveMode === "compact" && finalMessage && finalOrderedParts.length > 0 ? /* @__PURE__ */ jsx39("div", { className: "ml-10 flex flex-col gap-3", children: finalOrderedParts.map((part) => part.type === "text" ? /* @__PURE__ */ jsx39(
40243
40308
  AssistantMessageContent,
40244
40309
  {
40245
40310
  message: { ...finalMessage, content: part.content },
@@ -40250,12 +40315,12 @@ function AssistantTurnBlockBase({
40250
40315
  toolCalls: turnToolCalls
40251
40316
  },
40252
40317
  part.key
40253
- ) : /* @__PURE__ */ jsx38("div", { className: "flex flex-col gap-3", children: part.toolCalls.flatMap((toolCall) => [
40254
- ...resourceBlocks.filter((block) => block.toolCallId === toolCall.id).map((block) => /* @__PURE__ */ jsx38(ToolUiCard, { card: block.card, sessionId }, block.key)),
40255
- ...previewToolCalls.filter((item) => item.toolCall.id === toolCall.id).map(({ key, toolCall: previewToolCall, blocks }) => /* @__PURE__ */ jsx38(ToolPreviewAction, { toolCall: previewToolCall, sessionId, turnBlocks: blocks, className: "text-xs leading-[22px]" }, key)),
40256
- ...fileToolCalls.filter((fileToolCall) => fileToolCall.id === toolCall.id).map((fileToolCall) => /* @__PURE__ */ jsx38(ToolFilePreviewAction, { toolCall: fileToolCall, sessionId, className: "max-w-full text-xs leading-[22px] text-[hsl(var(--swf-link-text))]" }, fileToolCall.id))
40318
+ ) : /* @__PURE__ */ jsx39("div", { className: "flex flex-col gap-3", children: part.toolCalls.flatMap((toolCall) => [
40319
+ ...resourceBlocks.filter((block) => block.toolCallId === toolCall.id).map((block) => /* @__PURE__ */ jsx39(ToolUiCard, { card: block.card, sessionId }, block.key)),
40320
+ ...previewToolCalls.filter((item) => item.toolCall.id === toolCall.id).map(({ key, toolCall: previewToolCall, blocks }) => /* @__PURE__ */ jsx39(ToolPreviewAction, { toolCall: previewToolCall, sessionId, turnBlocks: blocks, className: "text-xs leading-[22px]" }, key)),
40321
+ ...fileToolCalls.filter((fileToolCall) => fileToolCall.id === toolCall.id).map((fileToolCall) => /* @__PURE__ */ jsx39(ToolFilePreviewAction, { toolCall: fileToolCall, sessionId, className: "max-w-full text-xs leading-[22px] text-[hsl(var(--swf-link-text))]" }, fileToolCall.id))
40257
40322
  ]) }, part.key)) }) : null,
40258
- finalMessage && finalOrderedParts.length === 0 ? /* @__PURE__ */ jsx38("div", { className: "ml-10", children: /* @__PURE__ */ jsx38(
40323
+ finalMessage && finalOrderedParts.length === 0 ? /* @__PURE__ */ jsx39("div", { className: "ml-10", children: /* @__PURE__ */ jsx39(
40259
40324
  AssistantMessageContent,
40260
40325
  {
40261
40326
  message: finalMessage,
@@ -40266,7 +40331,7 @@ function AssistantTurnBlockBase({
40266
40331
  toolCalls: turnToolCalls
40267
40332
  }
40268
40333
  ) }) : null,
40269
- /* @__PURE__ */ jsx38(
40334
+ /* @__PURE__ */ jsx39(
40270
40335
  PersistentAskUserQuestions,
40271
40336
  {
40272
40337
  questions: persistentAskUserQuestions,
@@ -40279,10 +40344,10 @@ function AssistantTurnBlockBase({
40279
40344
  }
40280
40345
  ),
40281
40346
  SHOW_FILE_DELIVERY_CARDS && level === 1 && // 用合并后的轮次消息:子智能体(fork Agent)写入的文件也要出交付卡片。
40282
- /* @__PURE__ */ jsx38(FileDeliveryCards, { toolCalls: turnToolCalls, sessionId }),
40347
+ /* @__PURE__ */ jsx39(FileDeliveryCards, { toolCalls: turnToolCalls, sessionId }),
40283
40348
  level === 1 && !isStreaming && finalMessageText ? (
40284
40349
  // 反馈行(原型):轮次底部的复制入口。
40285
- /* @__PURE__ */ jsx38(MessageActions, { content: finalMessageText, className: "-mt-1.5" })
40350
+ /* @__PURE__ */ jsx39(MessageActions, { content: finalMessageText, className: "-mt-1.5" })
40286
40351
  ) : null
40287
40352
  ]
40288
40353
  }
@@ -40303,7 +40368,7 @@ function PersistentAskUserQuestions({
40303
40368
  }) {
40304
40369
  const activeQuestionId = questions.filter(({ toolCall }) => toolCall.status === "pending").at(-1)?.toolCall.id;
40305
40370
  return questions.map(
40306
- ({ toolCall, turnBlocks }) => customization?.components?.ToolCall ? /* @__PURE__ */ jsx38(
40371
+ ({ toolCall, turnBlocks }) => customization?.components?.ToolCall ? /* @__PURE__ */ jsx39(
40307
40372
  customization.components.ToolCall,
40308
40373
  {
40309
40374
  toolCall,
@@ -40317,7 +40382,7 @@ function PersistentAskUserQuestions({
40317
40382
  customization
40318
40383
  },
40319
40384
  toolCall.id
40320
- ) : /* @__PURE__ */ jsx38(
40385
+ ) : /* @__PURE__ */ jsx39(
40321
40386
  ToolCallBlock,
40322
40387
  {
40323
40388
  toolCall,
@@ -40345,9 +40410,9 @@ function DetailedToolCallList({
40345
40410
  level,
40346
40411
  customization
40347
40412
  }) {
40348
- return /* @__PURE__ */ jsx38("div", { className: "flex flex-col gap-1", children: groupDetailedToolCalls(toolCalls).map((item) => {
40413
+ return /* @__PURE__ */ jsx39("div", { className: "flex flex-col gap-1", children: groupDetailedToolCalls(toolCalls).map((item) => {
40349
40414
  if (item.kind === "read_group") {
40350
- return /* @__PURE__ */ jsx38(
40415
+ return /* @__PURE__ */ jsx39(
40351
40416
  CompactToolGroupBlock,
40352
40417
  {
40353
40418
  toolCalls: item.toolCalls,
@@ -40365,7 +40430,7 @@ function DetailedToolCallList({
40365
40430
  }
40366
40431
  const { toolCall } = item;
40367
40432
  if (isWorkflowRunToolName2(toolCall.name)) return null;
40368
- return customization?.components?.ToolCall ? /* @__PURE__ */ jsx38(
40433
+ return customization?.components?.ToolCall ? /* @__PURE__ */ jsx39(
40369
40434
  customization.components.ToolCall,
40370
40435
  {
40371
40436
  toolCall,
@@ -40380,7 +40445,7 @@ function DetailedToolCallList({
40380
40445
  customization
40381
40446
  },
40382
40447
  toolCall.id
40383
- ) : /* @__PURE__ */ jsx38(
40448
+ ) : /* @__PURE__ */ jsx39(
40384
40449
  ToolCallBlock,
40385
40450
  {
40386
40451
  toolCall,
@@ -40425,32 +40490,32 @@ function AssistantMessages({
40425
40490
  );
40426
40491
  const hasToolCalls = toolCalls.length > 0;
40427
40492
  const orderedParts = getOrderedMessageParts(message, toolCalls);
40428
- return /* @__PURE__ */ jsxs32(
40493
+ return /* @__PURE__ */ jsxs33(
40429
40494
  "div",
40430
40495
  {
40431
40496
  className: "flex flex-col gap-1",
40432
40497
  children: [
40433
- showReasoning && /* @__PURE__ */ jsxs32(
40498
+ showReasoning && /* @__PURE__ */ jsxs33(
40434
40499
  Reasoning,
40435
40500
  {
40436
40501
  isStreaming: isReasoningStreamingLastMessage,
40437
40502
  part: "thinking",
40438
40503
  className: "blade-chat-thinking",
40439
40504
  children: [
40440
- /* @__PURE__ */ jsx38(
40505
+ /* @__PURE__ */ jsx39(
40441
40506
  ReasoningTrigger,
40442
40507
  {
40443
40508
  wordCount: reasoning.length,
40444
40509
  className: "gap-1 rounded-none p-0 text-xs leading-[22px]",
40445
- children: /* @__PURE__ */ jsx38("span", { children: isReasoningStreamingLastMessage ? "\u6B63\u5728\u601D\u8003" : "\u5DF2\u601D\u8003" })
40510
+ children: /* @__PURE__ */ jsx39("span", { children: isReasoningStreamingLastMessage ? "\u6B63\u5728\u601D\u8003" : "\u5DF2\u601D\u8003" })
40446
40511
  }
40447
40512
  ),
40448
- /* @__PURE__ */ jsx38(ReasoningContent, { className: "mt-1.5 rounded-none border-0 bg-transparent px-0 py-0 text-xs leading-[22px]", children: reasoning })
40513
+ /* @__PURE__ */ jsx39(ReasoningContent, { className: "mt-1.5 rounded-none border-0 bg-transparent px-0 py-0 text-xs leading-[22px]", children: reasoning })
40449
40514
  ]
40450
40515
  }
40451
40516
  ),
40452
40517
  orderedParts.length > 0 ? orderedParts.map(
40453
- (part) => part.type === "text" ? /* @__PURE__ */ jsx38(
40518
+ (part) => part.type === "text" ? /* @__PURE__ */ jsx39(
40454
40519
  AssistantMessageContent,
40455
40520
  {
40456
40521
  message: { ...message, content: part.content },
@@ -40465,7 +40530,7 @@ function AssistantMessages({
40465
40530
  )
40466
40531
  },
40467
40532
  part.key
40468
- ) : showToolDetails ? /* @__PURE__ */ jsx38(
40533
+ ) : showToolDetails ? /* @__PURE__ */ jsx39(
40469
40534
  DetailedToolCallList,
40470
40535
  {
40471
40536
  toolCalls: part.toolCalls,
@@ -40479,7 +40544,7 @@ function AssistantMessages({
40479
40544
  },
40480
40545
  part.key
40481
40546
  ) : null
40482
- ) : message !== hideMessageContentFor ? /* @__PURE__ */ jsx38(
40547
+ ) : message !== hideMessageContentFor ? /* @__PURE__ */ jsx39(
40483
40548
  AssistantMessageContent,
40484
40549
  {
40485
40550
  message,
@@ -40494,7 +40559,7 @@ function AssistantMessages({
40494
40559
  compact: true
40495
40560
  }
40496
40561
  ) : null,
40497
- orderedParts.length === 0 && hasToolCalls && showToolDetails ? /* @__PURE__ */ jsx38(
40562
+ orderedParts.length === 0 && hasToolCalls && showToolDetails ? /* @__PURE__ */ jsx39(
40498
40563
  DetailedToolCallList,
40499
40564
  {
40500
40565
  toolCalls,
@@ -40539,11 +40604,11 @@ function CompactToolGroupBlock({
40539
40604
  level,
40540
40605
  customization
40541
40606
  }) {
40542
- return /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-1", children: [
40607
+ return /* @__PURE__ */ jsxs33("div", { className: "flex flex-col gap-1", children: [
40543
40608
  toolCalls.map((toolCall) => {
40544
40609
  if (isWorkflowRunToolName2(toolCall.name)) return null;
40545
40610
  const CustomToolCall = customization?.components?.ToolCall;
40546
- return CustomToolCall ? /* @__PURE__ */ jsx38(
40611
+ return CustomToolCall ? /* @__PURE__ */ jsx39(
40547
40612
  CustomToolCall,
40548
40613
  {
40549
40614
  toolCall,
@@ -40557,7 +40622,7 @@ function CompactToolGroupBlock({
40557
40622
  customization
40558
40623
  },
40559
40624
  toolCall.id
40560
- ) : /* @__PURE__ */ jsx38(
40625
+ ) : /* @__PURE__ */ jsx39(
40561
40626
  ToolCallBlock,
40562
40627
  {
40563
40628
  toolCall,
@@ -40574,7 +40639,7 @@ function CompactToolGroupBlock({
40574
40639
  toolCall.id
40575
40640
  );
40576
40641
  }),
40577
- reasoning ? /* @__PURE__ */ jsx38(ThinkingBadge, { reasoning, variant: "block" }) : null
40642
+ reasoning ? /* @__PURE__ */ jsx39(ThinkingBadge, { reasoning, variant: "block" }) : null
40578
40643
  ] });
40579
40644
  }
40580
40645
  function AssistantMessageContent({
@@ -40600,9 +40665,9 @@ function AssistantMessageContent({
40600
40665
  if (!text4 && imageParts.length === 0 && fileParts.length === 0 && !reasoning && !failed) {
40601
40666
  return null;
40602
40667
  }
40603
- return /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-3", children: [
40604
- failed ? /* @__PURE__ */ jsx38("div", { className: "w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]", children: "\u751F\u6210\u5931\u8D25" }) : null,
40605
- imageParts.length > 0 && /* @__PURE__ */ jsx38("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx38(
40668
+ return /* @__PURE__ */ jsxs33("div", { className: "flex flex-col gap-3", children: [
40669
+ failed ? /* @__PURE__ */ jsx39("div", { className: "w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]", children: "\u751F\u6210\u5931\u8D25" }) : null,
40670
+ imageParts.length > 0 && /* @__PURE__ */ jsx39("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx39(
40606
40671
  MessageImage,
40607
40672
  {
40608
40673
  src: part.image_url.url,
@@ -40613,8 +40678,8 @@ function AssistantMessageContent({
40613
40678
  },
40614
40679
  part.image_url.url
40615
40680
  )) }),
40616
- /* @__PURE__ */ jsx38(MessageFileAttachmentList, { files: fileParts }),
40617
- text4 && customText != null ? customText : text4 ? /* @__PURE__ */ jsx38(
40681
+ /* @__PURE__ */ jsx39(MessageFileAttachmentList, { files: fileParts }),
40682
+ text4 && customText != null ? customText : text4 ? /* @__PURE__ */ jsx39(
40618
40683
  AssistantText,
40619
40684
  {
40620
40685
  text: text4,
@@ -40626,7 +40691,7 @@ function AssistantMessageContent({
40626
40691
  citations
40627
40692
  }
40628
40693
  ) : null,
40629
- !text4 && reasoning ? /* @__PURE__ */ jsx38(ThinkingBadge, { reasoning, variant: "block" }) : null
40694
+ !text4 && reasoning ? /* @__PURE__ */ jsx39(ThinkingBadge, { reasoning, variant: "block" }) : null
40630
40695
  ] });
40631
40696
  }
40632
40697
  function AssistantText({
@@ -40649,13 +40714,13 @@ function AssistantText({
40649
40714
  () => ({ sessionId, messageId, sendMessage }),
40650
40715
  [sessionId, messageId, sendMessage]
40651
40716
  );
40652
- return /* @__PURE__ */ jsxs32(
40717
+ return /* @__PURE__ */ jsxs33(
40653
40718
  "div",
40654
40719
  {
40655
40720
  part: "assistant-text",
40656
40721
  className: cn("blade-chat-assistant-text text-[15px] leading-8 text-[hsl(var(--foreground))]", className),
40657
40722
  children: [
40658
- /* @__PURE__ */ jsx38(CardContext.Provider, { value: cardCtx, children: /* @__PURE__ */ jsx38(
40723
+ /* @__PURE__ */ jsx39(CardContext.Provider, { value: cardCtx, children: /* @__PURE__ */ jsx39(
40659
40724
  MarkdownContent,
40660
40725
  {
40661
40726
  mode: isStreaming ? "streaming" : "static",
@@ -40666,7 +40731,7 @@ function AssistantText({
40666
40731
  children: text4
40667
40732
  }
40668
40733
  ) }),
40669
- reasoning ? /* @__PURE__ */ jsx38(ThinkingBadge, { reasoning }) : null
40734
+ reasoning ? /* @__PURE__ */ jsx39(ThinkingBadge, { reasoning }) : null
40670
40735
  ]
40671
40736
  }
40672
40737
  );
@@ -40680,31 +40745,31 @@ function collectMemoryRefs(messages) {
40680
40745
  }
40681
40746
  function MemoryRefsHint({ refs: rawRefs, className }) {
40682
40747
  const refs = Array.isArray(rawRefs) ? rawRefs : [];
40683
- const [expanded, setExpanded] = useState22(false);
40748
+ const [expanded, setExpanded] = useState23(false);
40684
40749
  const memoriesHref = useChatEnvironment().memoriesHref;
40685
40750
  const hasSkill = refs.some((r) => r.skill_name);
40686
40751
  const label = hasSkill ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
40687
- return /* @__PURE__ */ jsxs32(
40752
+ return /* @__PURE__ */ jsxs33(
40688
40753
  "div",
40689
40754
  {
40690
40755
  part: "memory-refs",
40691
40756
  className: cn("blade-chat-memory-refs relative z-[1] ml-1 w-[calc(100%-0.25rem)] max-w-[680px] self-start", className),
40692
40757
  children: [
40693
- /* @__PURE__ */ jsxs32(
40758
+ /* @__PURE__ */ jsxs33(
40694
40759
  "button",
40695
40760
  {
40696
40761
  type: "button",
40697
40762
  onClick: () => setExpanded(!expanded),
40698
40763
  className: "inline-flex h-8 items-center gap-1.5 rounded-lg border border-[hsl(var(--primary)/0.22)] bg-[hsl(var(--primary)/0.07)] px-3 text-xs font-medium text-[hsl(var(--primary))] transition-colors hover:bg-[hsl(var(--primary)/0.12)]",
40699
40764
  children: [
40700
- /* @__PURE__ */ jsx38(BookOpen, { size: 12 }),
40701
- /* @__PURE__ */ jsxs32("span", { children: [
40765
+ /* @__PURE__ */ jsx39(BookOpen, { size: 12 }),
40766
+ /* @__PURE__ */ jsxs33("span", { children: [
40702
40767
  label,
40703
40768
  "\uFF08",
40704
40769
  refs.length,
40705
40770
  "\uFF09"
40706
40771
  ] }),
40707
- /* @__PURE__ */ jsx38(
40772
+ /* @__PURE__ */ jsx39(
40708
40773
  ChevronRight,
40709
40774
  {
40710
40775
  size: 10,
@@ -40714,19 +40779,19 @@ function MemoryRefsHint({ refs: rawRefs, className }) {
40714
40779
  ]
40715
40780
  }
40716
40781
  ),
40717
- expanded && /* @__PURE__ */ jsxs32("div", { className: "mt-2 flex flex-col gap-2 rounded-xl border border-[hsl(var(--border)/0.8)] bg-[hsl(var(--muted)/0.28)] p-2.5", children: [
40718
- refs.map((ref) => /* @__PURE__ */ jsxs32(
40782
+ expanded && /* @__PURE__ */ jsxs33("div", { className: "mt-2 flex flex-col gap-2 rounded-xl border border-[hsl(var(--border)/0.8)] bg-[hsl(var(--muted)/0.28)] p-2.5", children: [
40783
+ refs.map((ref) => /* @__PURE__ */ jsxs33(
40719
40784
  "div",
40720
40785
  {
40721
40786
  className: "rounded-lg border border-[hsl(var(--border)/0.55)] bg-[hsl(var(--background)/0.72)] px-3 py-2.5",
40722
40787
  children: [
40723
- /* @__PURE__ */ jsx38("p", { className: "line-clamp-2 break-words text-xs leading-5 text-[hsl(var(--foreground)/0.86)]", children: ref.content_preview }),
40724
- ref.skill_name && /* @__PURE__ */ jsx38("span", { className: "mt-1.5 inline-flex rounded-md bg-[hsl(var(--primary)/0.09)] px-2 py-0.5 text-[10px] font-medium text-[hsl(var(--primary))]", children: ref.skill_name })
40788
+ /* @__PURE__ */ jsx39("p", { className: "line-clamp-2 break-words text-xs leading-5 text-[hsl(var(--foreground)/0.86)]", children: ref.content_preview }),
40789
+ ref.skill_name && /* @__PURE__ */ jsx39("span", { className: "mt-1.5 inline-flex rounded-md bg-[hsl(var(--primary)/0.09)] px-2 py-0.5 text-[10px] font-medium text-[hsl(var(--primary))]", children: ref.skill_name })
40725
40790
  ]
40726
40791
  },
40727
40792
  ref.id
40728
40793
  )),
40729
- memoriesHref ? /* @__PURE__ */ jsxs32(
40794
+ memoriesHref ? /* @__PURE__ */ jsxs33(
40730
40795
  "a",
40731
40796
  {
40732
40797
  href: memoriesHref,
@@ -40735,7 +40800,7 @@ function MemoryRefsHint({ refs: rawRefs, className }) {
40735
40800
  className: "inline-flex h-7 self-start items-center gap-1 rounded-lg px-2 text-[11px] font-medium text-[hsl(var(--primary))] transition-colors hover:bg-[hsl(var(--primary)/0.08)]",
40736
40801
  children: [
40737
40802
  "\u67E5\u770B\u5168\u90E8\u7ECF\u9A8C",
40738
- /* @__PURE__ */ jsx38(ArrowUpRight, { size: 12, "aria-hidden": "true" })
40803
+ /* @__PURE__ */ jsx39(ArrowUpRight, { size: 12, "aria-hidden": "true" })
40739
40804
  ]
40740
40805
  }
40741
40806
  ) : null
@@ -40746,7 +40811,7 @@ function MemoryRefsHint({ refs: rawRefs, className }) {
40746
40811
  }
40747
40812
 
40748
40813
  // src/hooks/use-message-pin.ts
40749
- import { useCallback as useCallback6, useEffect as useEffect17, useRef as useRef16 } from "react";
40814
+ import { useCallback as useCallback6, useEffect as useEffect18, useRef as useRef17 } from "react";
40750
40815
  var DEFAULT_MARGIN_PX = 24;
40751
40816
  var MANUAL_SCROLL_TOLERANCE_PX = 2;
40752
40817
  function useMessagePin({
@@ -40768,16 +40833,16 @@ function useMessagePin({
40768
40833
  scrollToBottom,
40769
40834
  margin = DEFAULT_MARGIN_PX
40770
40835
  }) {
40771
- const pinActiveRef = useRef16(false);
40772
- const frameRef = useRef16(null);
40773
- const retryTimeoutRef = useRef16(null);
40774
- const manualScrollCheckTimeoutRef = useRef16(null);
40775
- const repositionPendingRef = useRef16(false);
40776
- const pinnedTargetScrollTopRef = useRef16(null);
40777
- const appliedTargetKeyRef = useRef16(null);
40778
- const initialObservedTargetKeyRef = useRef16(pinTarget ? null : targetKey);
40779
- const observedTargetKeyRef = useRef16(initialObservedTargetKeyRef.current);
40780
- const setSpacerHeightRef = useRef16(setSpacerHeight);
40836
+ const pinActiveRef = useRef17(false);
40837
+ const frameRef = useRef17(null);
40838
+ const retryTimeoutRef = useRef17(null);
40839
+ const manualScrollCheckTimeoutRef = useRef17(null);
40840
+ const repositionPendingRef = useRef17(false);
40841
+ const pinnedTargetScrollTopRef = useRef17(null);
40842
+ const appliedTargetKeyRef = useRef17(null);
40843
+ const initialObservedTargetKeyRef = useRef17(pinTarget ? null : targetKey);
40844
+ const observedTargetKeyRef = useRef17(initialObservedTargetKeyRef.current);
40845
+ const setSpacerHeightRef = useRef17(setSpacerHeight);
40781
40846
  setSpacerHeightRef.current = setSpacerHeight;
40782
40847
  const release = useCallback6(() => {
40783
40848
  if (!pinActiveRef.current) return;
@@ -40839,7 +40904,7 @@ function useMessagePin({
40839
40904
  },
40840
40905
  [reposition]
40841
40906
  );
40842
- useEffect17(() => {
40907
+ useEffect18(() => {
40843
40908
  if (!targetKey) {
40844
40909
  release();
40845
40910
  appliedTargetKeyRef.current = null;
@@ -40869,10 +40934,10 @@ function useMessagePin({
40869
40934
  scheduleReposition();
40870
40935
  }, 80);
40871
40936
  }, [isStreaming, pinTarget, release, scheduleReposition, stopAutoScroll, targetKey]);
40872
- useEffect17(() => {
40937
+ useEffect18(() => {
40873
40938
  if (layoutKey !== void 0) scheduleReposition();
40874
40939
  }, [layoutKey, scheduleReposition]);
40875
- useEffect17(() => {
40940
+ useEffect18(() => {
40876
40941
  const scroll = getScrollElement();
40877
40942
  if (!scroll) return;
40878
40943
  const content3 = getContentElement?.();
@@ -40903,7 +40968,7 @@ function useMessagePin({
40903
40968
  scroll.removeEventListener("scroll", handleScroll);
40904
40969
  };
40905
40970
  }, [getContentElement, getScrollElement, release, scheduleReposition]);
40906
- useEffect17(
40971
+ useEffect18(
40907
40972
  () => () => {
40908
40973
  if (frameRef.current != null) cancelAnimationFrame(frameRef.current);
40909
40974
  frameRef.current = null;
@@ -41210,16 +41275,16 @@ import {
41210
41275
  getContextDisplayState,
41211
41276
  getContextGroupDisplayState
41212
41277
  } from "@blade-hq/agent-client/internal";
41213
- import { jsx as jsx39, jsxs as jsxs33 } from "react/jsx-runtime";
41278
+ import { jsx as jsx40, jsxs as jsxs34 } from "react/jsx-runtime";
41214
41279
  function ContextCard({ context, className }) {
41215
41280
  const display = getContextDisplayState(context);
41216
- return /* @__PURE__ */ jsxs33(
41281
+ return /* @__PURE__ */ jsxs34(
41217
41282
  "details",
41218
41283
  {
41219
41284
  className: `blade-chat-context-card group/context-card overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
41220
41285
  children: [
41221
- /* @__PURE__ */ jsxs33("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: [
41222
- /* @__PURE__ */ jsx39(
41286
+ /* @__PURE__ */ jsxs34("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: [
41287
+ /* @__PURE__ */ jsx40(
41223
41288
  Layers,
41224
41289
  {
41225
41290
  size: 15,
@@ -41227,11 +41292,11 @@ function ContextCard({ context, className }) {
41227
41292
  "aria-hidden": "true"
41228
41293
  }
41229
41294
  ),
41230
- /* @__PURE__ */ jsxs33("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
41231
- /* @__PURE__ */ jsx39("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
41232
- /* @__PURE__ */ jsx39("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
41295
+ /* @__PURE__ */ jsxs34("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
41296
+ /* @__PURE__ */ jsx40("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
41297
+ /* @__PURE__ */ jsx40("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
41233
41298
  ] }),
41234
- /* @__PURE__ */ jsx39(
41299
+ /* @__PURE__ */ jsx40(
41235
41300
  ChevronDown,
41236
41301
  {
41237
41302
  size: 14,
@@ -41240,7 +41305,7 @@ function ContextCard({ context, className }) {
41240
41305
  }
41241
41306
  )
41242
41307
  ] }),
41243
- /* @__PURE__ */ jsx39("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 })
41308
+ /* @__PURE__ */ jsx40("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 })
41244
41309
  ]
41245
41310
  }
41246
41311
  );
@@ -41249,9 +41314,9 @@ function ContextGroupCard({ contexts, className }) {
41249
41314
  if (contexts.length === 0) return null;
41250
41315
  const single = contexts.length === 1 ? getContextDisplayState(contexts[0]) : null;
41251
41316
  const group = single ? null : getContextGroupDisplayState(contexts);
41252
- return /* @__PURE__ */ jsxs33("details", { className: `blade-chat-context-card group/context-group overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`, children: [
41253
- /* @__PURE__ */ jsxs33("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: [
41254
- /* @__PURE__ */ jsx39(
41317
+ return /* @__PURE__ */ jsxs34("details", { className: `blade-chat-context-card group/context-group overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`, children: [
41318
+ /* @__PURE__ */ jsxs34("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: [
41319
+ /* @__PURE__ */ jsx40(
41255
41320
  Layers,
41256
41321
  {
41257
41322
  size: 15,
@@ -41259,11 +41324,11 @@ function ContextGroupCard({ contexts, className }) {
41259
41324
  "aria-hidden": "true"
41260
41325
  }
41261
41326
  ),
41262
- /* @__PURE__ */ jsxs33("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
41263
- /* @__PURE__ */ jsx39("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: single ? single.title : `${group?.title} \xB7 ${group?.count} \u9879` }),
41264
- /* @__PURE__ */ jsx39("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: single ? single.summary : group?.summary })
41327
+ /* @__PURE__ */ jsxs34("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
41328
+ /* @__PURE__ */ jsx40("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: single ? single.title : `${group?.title} \xB7 ${group?.count} \u9879` }),
41329
+ /* @__PURE__ */ jsx40("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: single ? single.summary : group?.summary })
41265
41330
  ] }),
41266
- /* @__PURE__ */ jsx39(
41331
+ /* @__PURE__ */ jsx40(
41267
41332
  ChevronDown,
41268
41333
  {
41269
41334
  size: 14,
@@ -41272,7 +41337,7 @@ function ContextGroupCard({ contexts, className }) {
41272
41337
  }
41273
41338
  )
41274
41339
  ] }),
41275
- single ? /* @__PURE__ */ jsx39("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__ */ jsx39("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__ */ jsx39(
41340
+ single ? /* @__PURE__ */ jsx40("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__ */ jsx40("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__ */ jsx40(
41276
41341
  ContextCard,
41277
41342
  {
41278
41343
  context
@@ -41283,8 +41348,8 @@ function ContextGroupCard({ contexts, className }) {
41283
41348
  }
41284
41349
 
41285
41350
  // src/chat/ResultFeedback.tsx
41286
- import { useCallback as useCallback7, useEffect as useEffect18, useRef as useRef17, useState as useState23 } from "react";
41287
- import { jsx as jsx40, jsxs as jsxs34 } from "react/jsx-runtime";
41351
+ import { useCallback as useCallback7, useEffect as useEffect19, useRef as useRef18, useState as useState24 } from "react";
41352
+ import { jsx as jsx41, jsxs as jsxs35 } from "react/jsx-runtime";
41288
41353
  var REASONS = [
41289
41354
  { value: "not_solved", label: "\u6CA1\u89E3\u51B3\u95EE\u9898" },
41290
41355
  { value: "inaccurate", label: "\u5185\u5BB9\u4E0D\u51C6\u786E" },
@@ -41298,17 +41363,17 @@ function reasonLabel(reason) {
41298
41363
  }
41299
41364
  function HistoricalResultFeedback({ feedback }) {
41300
41365
  const label = reasonLabel(feedback.reason);
41301
- return /* @__PURE__ */ jsxs34(
41366
+ return /* @__PURE__ */ jsxs35(
41302
41367
  "section",
41303
41368
  {
41304
41369
  "aria-label": "\u5386\u53F2\u7ED3\u679C\u53CD\u9988",
41305
41370
  className: "w-fit max-w-full rounded-lg border border-[hsl(var(--border)/0.7)] bg-[hsl(var(--muted)/0.2)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]",
41306
41371
  children: [
41307
- /* @__PURE__ */ jsxs34("span", { children: [
41372
+ /* @__PURE__ */ jsxs35("span", { children: [
41308
41373
  "\u4F60\u5BF9\u6B64\u8F6E\u7ED3\u679C\u7684\u8BC4\u4EF7\uFF1A",
41309
41374
  feedback.helpful ? "\u6709\u5E2E\u52A9" : "\u6CA1\u5E2E\u52A9"
41310
41375
  ] }),
41311
- label ? /* @__PURE__ */ jsxs34("span", { children: [
41376
+ label ? /* @__PURE__ */ jsxs35("span", { children: [
41312
41377
  " \xB7 ",
41313
41378
  label
41314
41379
  ] }) : null
@@ -41324,26 +41389,26 @@ function ResultFeedback({
41324
41389
  onSaved
41325
41390
  }) {
41326
41391
  const client = useBladeClient();
41327
- const [saved, setSaved] = useState23(savedFeedback ?? null);
41328
- const [selectedHelpful, setSelectedHelpful] = useState23(
41392
+ const [saved, setSaved] = useState24(savedFeedback ?? null);
41393
+ const [selectedHelpful, setSelectedHelpful] = useState24(
41329
41394
  savedFeedback?.helpful ?? null
41330
41395
  );
41331
- const [selectedReason, setSelectedReason] = useState23(
41396
+ const [selectedReason, setSelectedReason] = useState24(
41332
41397
  savedFeedback?.reason ?? null
41333
41398
  );
41334
- const [saving, setSaving] = useState23(false);
41335
- const [saveError, setSaveError] = useState23(false);
41336
- const latestChoice = useRef17(null);
41399
+ const [saving, setSaving] = useState24(false);
41400
+ const [saveError, setSaveError] = useState24(false);
41401
+ const latestChoice = useRef18(null);
41337
41402
  const eligible = followup.feedback_eligible === true;
41338
41403
  const emit = useFollowupInteraction();
41339
- const reportedShown = useRef17(false);
41404
+ const reportedShown = useRef18(false);
41340
41405
  const visible = eligible && !isViewer;
41341
- useEffect18(() => {
41406
+ useEffect19(() => {
41342
41407
  if (!visible || reportedShown.current) return;
41343
41408
  reportedShown.current = true;
41344
41409
  emit({ type: "result_feedback_shown", sessionId, assistantEntryId: followup.assistant_entry_id });
41345
41410
  }, [emit, followup.assistant_entry_id, sessionId, visible]);
41346
- useEffect18(() => {
41411
+ useEffect19(() => {
41347
41412
  if (!savedFeedback || latestChoice.current) return;
41348
41413
  setSaved(savedFeedback);
41349
41414
  setSelectedHelpful(savedFeedback.helpful);
@@ -41383,15 +41448,15 @@ function ResultFeedback({
41383
41448
  [client, emit, followup.assistant_entry_id, onSaved, sessionId]
41384
41449
  );
41385
41450
  if (!visible) return null;
41386
- return /* @__PURE__ */ jsxs34(
41451
+ return /* @__PURE__ */ jsxs35(
41387
41452
  "section",
41388
41453
  {
41389
41454
  "aria-label": "\u7ED3\u679C\u53CD\u9988",
41390
41455
  className: "flex flex-col gap-2 border-t border-[hsl(var(--border)/0.7)] pt-3",
41391
41456
  children: [
41392
- /* @__PURE__ */ jsx40("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
41393
- /* @__PURE__ */ jsxs34("div", { className: "flex flex-wrap gap-1.5", children: [
41394
- /* @__PURE__ */ jsx40(
41457
+ /* @__PURE__ */ jsx41("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
41458
+ /* @__PURE__ */ jsxs35("div", { className: "flex flex-wrap gap-1.5", children: [
41459
+ /* @__PURE__ */ jsx41(
41395
41460
  "button",
41396
41461
  {
41397
41462
  type: "button",
@@ -41402,7 +41467,7 @@ function ResultFeedback({
41402
41467
  children: "\u6709\u5E2E\u52A9"
41403
41468
  }
41404
41469
  ),
41405
- /* @__PURE__ */ jsx40(
41470
+ /* @__PURE__ */ jsx41(
41406
41471
  "button",
41407
41472
  {
41408
41473
  type: "button",
@@ -41414,7 +41479,7 @@ function ResultFeedback({
41414
41479
  }
41415
41480
  )
41416
41481
  ] }),
41417
- selectedHelpful === false ? /* @__PURE__ */ jsx40("div", { className: "flex max-w-[520px] flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: REASONS.map((reason) => /* @__PURE__ */ jsx40(
41482
+ selectedHelpful === false ? /* @__PURE__ */ jsx41("div", { className: "flex max-w-[520px] flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: REASONS.map((reason) => /* @__PURE__ */ jsx41(
41418
41483
  "button",
41419
41484
  {
41420
41485
  type: "button",
@@ -41426,9 +41491,9 @@ function ResultFeedback({
41426
41491
  },
41427
41492
  reason.value
41428
41493
  )) }) : null,
41429
- saveError ? /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--destructive))]", children: [
41430
- /* @__PURE__ */ jsx40("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
41431
- /* @__PURE__ */ jsx40(
41494
+ saveError ? /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--destructive))]", children: [
41495
+ /* @__PURE__ */ jsx41("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
41496
+ /* @__PURE__ */ jsx41(
41432
41497
  "button",
41433
41498
  {
41434
41499
  type: "button",
@@ -41440,14 +41505,14 @@ function ResultFeedback({
41440
41505
  children: "\u91CD\u8BD5"
41441
41506
  }
41442
41507
  )
41443
- ] }) : saved ? /* @__PURE__ */ jsx40("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
41508
+ ] }) : saved ? /* @__PURE__ */ jsx41("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
41444
41509
  ]
41445
41510
  }
41446
41511
  );
41447
41512
  }
41448
41513
 
41449
41514
  // src/chat/LiteMessageList.tsx
41450
- import { jsx as jsx41, jsxs as jsxs35 } from "react/jsx-runtime";
41515
+ import { jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
41451
41516
  var LITE_LOADING_INDICATOR_HEIGHT = 38;
41452
41517
  function messageText(message) {
41453
41518
  return getTextContent3(normalizeMessageContent2(message.content)).trim();
@@ -41589,12 +41654,12 @@ function LiteMessageList({
41589
41654
  onLoadOlder,
41590
41655
  historyLoadRevision = 0
41591
41656
  }) {
41592
- const scrollRef = useRef18(null);
41593
- const trailingSpacerRef = useRef18(null);
41594
- const stickToBottomRef = useRef18(true);
41595
- const scrollFrameRef = useRef18(null);
41596
- const loadingOlderRef = useRef18(false);
41597
- useEffect19(() => {
41657
+ const scrollRef = useRef19(null);
41658
+ const trailingSpacerRef = useRef19(null);
41659
+ const stickToBottomRef = useRef19(true);
41660
+ const scrollFrameRef = useRef19(null);
41661
+ const loadingOlderRef = useRef19(false);
41662
+ useEffect20(() => {
41598
41663
  void historyLoadRevision;
41599
41664
  const element2 = scrollRef.current;
41600
41665
  if (!element2 || !onLoadOlder) return;
@@ -41721,20 +41786,20 @@ function LiteMessageList({
41721
41786
  stopAutoScroll,
41722
41787
  scrollToBottom: followToBottom
41723
41788
  });
41724
- useEffect19(() => {
41789
+ useEffect20(() => {
41725
41790
  if (!isLoadingHistory && latestSignature && stickToBottomRef.current) scrollToLatest();
41726
41791
  }, [isLoadingHistory, latestSignature, scrollToLatest]);
41727
- useEffect19(() => {
41792
+ useEffect20(() => {
41728
41793
  if (!isStreaming || !stickToBottomRef.current) return;
41729
41794
  scrollToLatest();
41730
41795
  }, [isStreaming, scrollToLatest]);
41731
- useEffect19(
41796
+ useEffect20(
41732
41797
  () => () => {
41733
41798
  if (scrollFrameRef.current != null) cancelAnimationFrame(scrollFrameRef.current);
41734
41799
  },
41735
41800
  []
41736
41801
  );
41737
- return /* @__PURE__ */ jsxs35(
41802
+ return /* @__PURE__ */ jsxs36(
41738
41803
  "div",
41739
41804
  {
41740
41805
  ref: scrollRef,
@@ -41748,7 +41813,7 @@ function LiteMessageList({
41748
41813
  },
41749
41814
  className: "min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-6 sm:px-8",
41750
41815
  children: [
41751
- rows.length === 0 ? /* @__PURE__ */ jsx41("div", { className: "grid min-h-full place-items-center text-sm text-[hsl(var(--muted-foreground))]", children: isLoadingHistory ? "\u6B63\u5728\u52A0\u8F7D\u6D88\u606F\u2026" : "\u5F00\u59CB\u65B0\u7684\u5BF9\u8BDD\u5427" }) : /* @__PURE__ */ jsxs35(
41816
+ rows.length === 0 ? /* @__PURE__ */ jsx42("div", { className: "grid min-h-full place-items-center text-sm text-[hsl(var(--muted-foreground))]", children: isLoadingHistory ? "\u6B63\u5728\u52A0\u8F7D\u6D88\u606F\u2026" : "\u5F00\u59CB\u65B0\u7684\u5BF9\u8BDD\u5427" }) : /* @__PURE__ */ jsxs36(
41752
41817
  "div",
41753
41818
  {
41754
41819
  className: "relative mx-auto w-full max-w-3xl",
@@ -41759,7 +41824,7 @@ function LiteMessageList({
41759
41824
  virtualizer.getVirtualItems().map((virtualRow) => {
41760
41825
  const row = rows[virtualRow.index];
41761
41826
  if (!row) return null;
41762
- return /* @__PURE__ */ jsx41(
41827
+ return /* @__PURE__ */ jsx42(
41763
41828
  "div",
41764
41829
  {
41765
41830
  ref: virtualizer.measureElement,
@@ -41767,7 +41832,7 @@ function LiteMessageList({
41767
41832
  "data-lite-row-key": row.key,
41768
41833
  className: "absolute left-0 top-0 w-full pb-5",
41769
41834
  style: { transform: `translateY(${virtualRow.start}px)` },
41770
- children: row.type === "text" ? /* @__PURE__ */ jsx41(PlainTextMessage, { row, sessionId }) : row.type === "background-wakeup" ? /* @__PURE__ */ jsx41(BackgroundWakeNotice, {}) : row.type === "memory-refs" ? /* @__PURE__ */ jsx41(MemoryRefsHint, { refs: row.refs }) : row.type === "question" ? /* @__PURE__ */ jsx41(
41835
+ children: row.type === "text" ? /* @__PURE__ */ jsx42(PlainTextMessage, { row, sessionId }) : row.type === "background-wakeup" ? /* @__PURE__ */ jsx42(BackgroundWakeNotice, {}) : row.type === "memory-refs" ? /* @__PURE__ */ jsx42(MemoryRefsHint, { refs: row.refs }) : row.type === "question" ? /* @__PURE__ */ jsx42(
41771
41836
  ToolCallBlock,
41772
41837
  {
41773
41838
  toolCall: row.toolCall,
@@ -41783,7 +41848,7 @@ function LiteMessageList({
41783
41848
  isActiveQuestion: row.toolCall.id === activeQuestionId,
41784
41849
  turnBlocks: row.turnBlocks
41785
41850
  }
41786
- ) : row.type === "tool-description" ? /* @__PURE__ */ jsx41(ToolDescription, { row }) : row.type === "context-group" ? /* @__PURE__ */ jsx41(ContextGroupCard, { contexts: row.contexts }) : row.type === "context-divider" ? /* @__PURE__ */ jsx41("div", { "aria-hidden": "true", className: "h-px w-full bg-[hsl(var(--border)/0.55)]" }) : row.type === "historical-feedback" ? /* @__PURE__ */ jsx41(HistoricalResultFeedback, { feedback: row.feedback }) : /* @__PURE__ */ jsx41(
41851
+ ) : row.type === "tool-description" ? /* @__PURE__ */ jsx42(ToolDescription, { row }) : row.type === "context-group" ? /* @__PURE__ */ jsx42(ContextGroupCard, { contexts: row.contexts }) : row.type === "context-divider" ? /* @__PURE__ */ jsx42("div", { "aria-hidden": "true", className: "h-px w-full bg-[hsl(var(--border)/0.55)]" }) : row.type === "historical-feedback" ? /* @__PURE__ */ jsx42(HistoricalResultFeedback, { feedback: row.feedback }) : /* @__PURE__ */ jsx42(
41787
41852
  LiteFollowup,
41788
41853
  {
41789
41854
  sessionId,
@@ -41797,19 +41862,19 @@ function LiteMessageList({
41797
41862
  row.key
41798
41863
  );
41799
41864
  }),
41800
- isStreaming ? /* @__PURE__ */ jsx41(
41865
+ isStreaming ? /* @__PURE__ */ jsx42(
41801
41866
  "div",
41802
41867
  {
41803
41868
  className: "absolute left-0 top-0 w-full",
41804
41869
  style: { transform: `translateY(${totalSize}px)` },
41805
- children: /* @__PURE__ */ jsx41(ChatLoadingIndicator, { preparing: isPreparingReply(messages) })
41870
+ children: /* @__PURE__ */ jsx42(ChatLoadingIndicator, { preparing: isPreparingReply(messages) })
41806
41871
  }
41807
41872
  ) : null
41808
41873
  ]
41809
41874
  }
41810
41875
  ),
41811
- rows.length === 0 && isStreaming ? /* @__PURE__ */ jsx41(ChatLoadingIndicator, { preparing: isPreparingReply(messages) }) : null,
41812
- /* @__PURE__ */ jsx41("div", { ref: trailingSpacerRef, "aria-hidden": "true", className: "pointer-events-none w-full" })
41876
+ rows.length === 0 && isStreaming ? /* @__PURE__ */ jsx42(ChatLoadingIndicator, { preparing: isPreparingReply(messages) }) : null,
41877
+ /* @__PURE__ */ jsx42("div", { ref: trailingSpacerRef, "aria-hidden": "true", className: "pointer-events-none w-full" })
41813
41878
  ]
41814
41879
  }
41815
41880
  );
@@ -41817,13 +41882,13 @@ function LiteMessageList({
41817
41882
  function ToolDescription({ row }) {
41818
41883
  const description = row.description;
41819
41884
  const Icon = description.includes("\u641C\u7D22") ? Search : description.includes("\u6267\u884C") ? Terminal : description.includes("\u8BFB\u53D6") ? BookOpen : description.includes("\u6587\u4EF6") ? FilePenLine : Wrench;
41820
- return /* @__PURE__ */ jsx41("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", title: description, children: /* @__PURE__ */ jsx41(Icon, { size: 14, className: row.running ? "animate-pulse" : "opacity-55", "aria-hidden": "true" }) });
41885
+ return /* @__PURE__ */ jsx42("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", title: description, children: /* @__PURE__ */ jsx42(Icon, { size: 14, className: row.running ? "animate-pulse" : "opacity-55", "aria-hidden": "true" }) });
41821
41886
  }
41822
41887
  function PlainTextMessage({
41823
41888
  row,
41824
41889
  sessionId
41825
41890
  }) {
41826
- const markdown = /* @__PURE__ */ jsx41(
41891
+ const markdown = /* @__PURE__ */ jsx42(
41827
41892
  MarkdownContent,
41828
41893
  {
41829
41894
  sessionId,
@@ -41834,14 +41899,14 @@ function PlainTextMessage({
41834
41899
  }
41835
41900
  );
41836
41901
  if (row.role === "user") {
41837
- return /* @__PURE__ */ jsx41("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx41("div", { className: "max-w-[82%] rounded-[18px] rounded-br-[6px] border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-4 py-3 text-sm leading-6 text-[hsl(var(--user-msg-fg))]", children: markdown }) });
41902
+ return /* @__PURE__ */ jsx42("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx42("div", { className: "max-w-[82%] rounded-[18px] rounded-br-[6px] border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-4 py-3 text-sm leading-6 text-[hsl(var(--user-msg-fg))]", children: markdown }) });
41838
41903
  }
41839
- return /* @__PURE__ */ jsxs35(
41904
+ return /* @__PURE__ */ jsxs36(
41840
41905
  "div",
41841
41906
  {
41842
41907
  className: `break-words text-sm leading-6 ${row.role === "error" ? "text-[hsl(var(--destructive))]" : "text-[hsl(var(--foreground))]"}`,
41843
41908
  children: [
41844
- row.failed ? /* @__PURE__ */ jsx41("div", { className: "mb-1 w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]", children: "\u751F\u6210\u5931\u8D25" }) : null,
41909
+ row.failed ? /* @__PURE__ */ jsx42("div", { className: "mb-1 w-fit rounded-full border border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--destructive))]", children: "\u751F\u6210\u5931\u8D25" }) : null,
41845
41910
  markdown
41846
41911
  ]
41847
41912
  }
@@ -41856,7 +41921,7 @@ function LiteFollowup({
41856
41921
  }) {
41857
41922
  const client = useBladeClient();
41858
41923
  const composer = useComposerBridge(sessionId);
41859
- const [downloadingPath, setDownloadingPath] = useState24(null);
41924
+ const [downloadingPath, setDownloadingPath] = useState25(null);
41860
41925
  const artifacts = followup.final_artifacts ?? [];
41861
41926
  const downloadArtifact = async (target, label) => {
41862
41927
  if (downloadingPath) return;
@@ -41868,11 +41933,11 @@ function LiteFollowup({
41868
41933
  setDownloadingPath(null);
41869
41934
  }
41870
41935
  };
41871
- return /* @__PURE__ */ jsxs35("div", { className: "flex flex-col items-start gap-3", children: [
41872
- artifacts.length > 0 ? /* @__PURE__ */ jsxs35("div", { className: "flex w-full flex-col items-start gap-1.5", children: [
41873
- /* @__PURE__ */ jsx41("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u672C\u8F6E\u6210\u679C" }),
41936
+ return /* @__PURE__ */ jsxs36("div", { className: "flex flex-col items-start gap-3", children: [
41937
+ artifacts.length > 0 ? /* @__PURE__ */ jsxs36("div", { className: "flex w-full flex-col items-start gap-1.5", children: [
41938
+ /* @__PURE__ */ jsx42("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u672C\u8F6E\u6210\u679C" }),
41874
41939
  artifacts.map(
41875
- (artifact, artifactIndex) => artifact.kind === "link" ? /* @__PURE__ */ jsxs35(
41940
+ (artifact, artifactIndex) => artifact.kind === "link" ? /* @__PURE__ */ jsxs36(
41876
41941
  "a",
41877
41942
  {
41878
41943
  href: artifact.target,
@@ -41880,12 +41945,12 @@ function LiteFollowup({
41880
41945
  rel: "noopener noreferrer",
41881
41946
  className: "flex w-[320px] max-w-full items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2.5 text-sm hover:bg-[hsl(var(--muted)/0.5)]",
41882
41947
  children: [
41883
- /* @__PURE__ */ jsx41(ExternalLink, { size: 16, className: "shrink-0" }),
41884
- /* @__PURE__ */ jsx41("span", { className: "min-w-0 flex-1 truncate", children: artifact.label || artifact.target })
41948
+ /* @__PURE__ */ jsx42(ExternalLink, { size: 16, className: "shrink-0" }),
41949
+ /* @__PURE__ */ jsx42("span", { className: "min-w-0 flex-1 truncate", children: artifact.label || artifact.target })
41885
41950
  ]
41886
41951
  },
41887
41952
  `${artifact.kind}:${artifactIndex}`
41888
- ) : /* @__PURE__ */ jsxs35(
41953
+ ) : /* @__PURE__ */ jsxs36(
41889
41954
  "button",
41890
41955
  {
41891
41956
  type: "button",
@@ -41896,18 +41961,18 @@ function LiteFollowup({
41896
41961
  ),
41897
41962
  className: "flex w-[320px] max-w-full items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2.5 text-sm hover:bg-[hsl(var(--muted)/0.5)]",
41898
41963
  children: [
41899
- /* @__PURE__ */ jsx41(FileText, { size: 16, className: "shrink-0" }),
41900
- /* @__PURE__ */ jsx41("span", { className: "min-w-0 flex-1 truncate", children: artifact.label || artifact.target }),
41901
- /* @__PURE__ */ jsx41(Download, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" })
41964
+ /* @__PURE__ */ jsx42(FileText, { size: 16, className: "shrink-0" }),
41965
+ /* @__PURE__ */ jsx42("span", { className: "min-w-0 flex-1 truncate", children: artifact.label || artifact.target }),
41966
+ /* @__PURE__ */ jsx42(Download, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" })
41902
41967
  ]
41903
41968
  },
41904
41969
  `${artifact.kind}:${artifactIndex}`
41905
41970
  )
41906
41971
  )
41907
41972
  ] }) : null,
41908
- followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs35("div", { className: "flex max-w-full flex-col items-start gap-1.5", children: [
41909
- /* @__PURE__ */ jsx41("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
41910
- followup.suggestions.map((suggestion) => /* @__PURE__ */ jsxs35(
41973
+ followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs36("div", { className: "flex max-w-full flex-col items-start gap-1.5", children: [
41974
+ /* @__PURE__ */ jsx42("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
41975
+ followup.suggestions.map((suggestion) => /* @__PURE__ */ jsxs36(
41911
41976
  "button",
41912
41977
  {
41913
41978
  type: "button",
@@ -41917,14 +41982,14 @@ function LiteFollowup({
41917
41982
  },
41918
41983
  className: "flex max-w-full items-center gap-2 rounded-xl bg-[hsl(var(--muted)/0.62)] px-3 py-2 text-left text-sm disabled:opacity-60",
41919
41984
  children: [
41920
- /* @__PURE__ */ jsx41("span", { children: suggestion }),
41921
- /* @__PURE__ */ jsx41(ArrowRight, { size: 14, className: "shrink-0" })
41985
+ /* @__PURE__ */ jsx42("span", { children: suggestion }),
41986
+ /* @__PURE__ */ jsx42(ArrowRight, { size: 14, className: "shrink-0" })
41922
41987
  ]
41923
41988
  },
41924
41989
  suggestion
41925
41990
  ))
41926
41991
  ] }) : null,
41927
- /* @__PURE__ */ jsx41(
41992
+ /* @__PURE__ */ jsx42(
41928
41993
  ResultFeedback,
41929
41994
  {
41930
41995
  sessionId,
@@ -41941,15 +42006,15 @@ function LiteFollowup({
41941
42006
  import { isBackgroundWakeMessage as isBackgroundWakeMessage3 } from "@blade-hq/agent-client/internal";
41942
42007
  import {
41943
42008
  useCallback as useCallback14,
41944
- useEffect as useEffect26,
42009
+ useEffect as useEffect27,
41945
42010
  useLayoutEffect as useLayoutEffect7,
41946
42011
  useMemo as useMemo16,
41947
- useRef as useRef26,
41948
- useState as useState32
42012
+ useRef as useRef27,
42013
+ useState as useState33
41949
42014
  } from "react";
41950
42015
 
41951
42016
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
41952
- import { useCallback as useCallback9, useMemo as useMemo13, useRef as useRef19, useState as useState25 } from "react";
42017
+ import { useCallback as useCallback9, useMemo as useMemo13, useRef as useRef20, useState as useState26 } from "react";
41953
42018
  var DEFAULT_SPRING_ANIMATION = {
41954
42019
  /**
41955
42020
  * A value from 0 to 1, on how much to damp the animation.
@@ -41986,10 +42051,10 @@ globalThis.document?.addEventListener("click", () => {
41986
42051
  mouseDown = false;
41987
42052
  });
41988
42053
  var useStickToBottom = (options = {}) => {
41989
- const [escapedFromLock, updateEscapedFromLock] = useState25(false);
41990
- const [isAtBottom, updateIsAtBottom] = useState25(options.initial !== false);
41991
- const [isNearBottom, setIsNearBottom] = useState25(false);
41992
- const optionsRef = useRef19(null);
42054
+ const [escapedFromLock, updateEscapedFromLock] = useState26(false);
42055
+ const [isAtBottom, updateIsAtBottom] = useState26(options.initial !== false);
42056
+ const [isNearBottom, setIsNearBottom] = useState26(false);
42057
+ const optionsRef = useRef20(null);
41993
42058
  optionsRef.current = options;
41994
42059
  const isSelecting = useCallback9(() => {
41995
42060
  if (!mouseDown) {
@@ -42293,11 +42358,11 @@ function mergeAnimations(...animations) {
42293
42358
 
42294
42359
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/StickToBottom.js
42295
42360
  import * as React from "react";
42296
- import { createContext as createContext7, useContext as useContext7, useEffect as useEffect20, useImperativeHandle as useImperativeHandle2, useLayoutEffect as useLayoutEffect4, useMemo as useMemo14, useRef as useRef20 } from "react";
42361
+ import { createContext as createContext7, useContext as useContext7, useEffect as useEffect21, useImperativeHandle as useImperativeHandle2, useLayoutEffect as useLayoutEffect4, useMemo as useMemo14, useRef as useRef21 } from "react";
42297
42362
  var StickToBottomContext = createContext7(null);
42298
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect4 : useEffect20;
42363
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect4 : useEffect21;
42299
42364
  function StickToBottom({ instance, children, resize, initial, mass, damping, stiffness, targetScrollTop: currentTargetScrollTop, contextRef, ...props }) {
42300
- const customTargetScrollTop = useRef20(null);
42365
+ const customTargetScrollTop = useRef21(null);
42301
42366
  const targetScrollTop = React.useCallback((target, elements) => {
42302
42367
  const get = context?.targetScrollTop ?? currentTargetScrollTop;
42303
42368
  return get?.(target, elements) ?? target;
@@ -42378,7 +42443,7 @@ import {
42378
42443
  isHiddenInternalMessage as isHiddenInternalMessage2,
42379
42444
  normalizeMessageContent as normalizeMessageContent3
42380
42445
  } from "@blade-hq/agent-client/internal";
42381
- import { useCallback as useCallback11, useEffect as useEffect21, useLayoutEffect as useLayoutEffect5, useRef as useRef21, useState as useState26 } from "react";
42446
+ import { useCallback as useCallback11, useEffect as useEffect22, useLayoutEffect as useLayoutEffect5, useRef as useRef22, useState as useState27 } from "react";
42382
42447
  var HIGHLIGHT_MS = 1600;
42383
42448
  var TURN_NAV_HIGHLIGHT_CLASS = "blade-turn-nav-flash";
42384
42449
  var MAX_FRAMES_AFTER_LOCATE = 20;
@@ -42433,7 +42498,7 @@ function useTurnNavigation({
42433
42498
  reloadKey,
42434
42499
  rewriteKey
42435
42500
  }) {
42436
- const callbacks = useRef21({
42501
+ const callbacks = useRef22({
42437
42502
  getLoadedEntryElement,
42438
42503
  isEntryLoaded,
42439
42504
  locateEntry,
@@ -42442,27 +42507,27 @@ function useTurnNavigation({
42442
42507
  revealEntry,
42443
42508
  beforeSeek
42444
42509
  });
42445
- const [index2, setIndex] = useState26({ sessionId: null, items: [] });
42446
- const [loadingEntryId, setLoadingEntryId] = useState26(null);
42447
- const [activeEntryId, setActiveEntryId] = useState26(null);
42448
- const [failedEntryId, setFailedEntryId] = useState26(null);
42449
- const [error61, setError] = useState26(null);
42450
- const [indexRefresh, setIndexRefresh] = useState26(0);
42451
- const seekSeq = useRef21(0);
42452
- const indexSeq = useRef21(0);
42453
- const indexRef = useRef21({
42510
+ const [index2, setIndex] = useState27({ sessionId: null, items: [] });
42511
+ const [loadingEntryId, setLoadingEntryId] = useState27(null);
42512
+ const [activeEntryId, setActiveEntryId] = useState27(null);
42513
+ const [failedEntryId, setFailedEntryId] = useState27(null);
42514
+ const [error61, setError] = useState27(null);
42515
+ const [indexRefresh, setIndexRefresh] = useState27(0);
42516
+ const seekSeq = useRef22(0);
42517
+ const indexSeq = useRef22(0);
42518
+ const indexRef = useRef22({
42454
42519
  sessionId: null,
42455
42520
  items: []
42456
42521
  });
42457
- const highlightTimer = useRef21(void 0);
42458
- const highlightedRef = useRef21(null);
42522
+ const highlightTimer = useRef22(void 0);
42523
+ const highlightedRef = useRef22(null);
42459
42524
  const clearHighlight = useCallback11(() => {
42460
42525
  clearTimeout(highlightTimer.current);
42461
42526
  highlightTimer.current = void 0;
42462
42527
  highlightedRef.current?.classList.remove(TURN_NAV_HIGHLIGHT_CLASS);
42463
42528
  highlightedRef.current = null;
42464
42529
  }, []);
42465
- useEffect21(
42530
+ useEffect22(
42466
42531
  () => () => {
42467
42532
  seekSeq.current += 1;
42468
42533
  indexSeq.current += 1;
@@ -42494,7 +42559,7 @@ function useTurnNavigation({
42494
42559
  beforeSeek
42495
42560
  };
42496
42561
  });
42497
- useEffect21(() => {
42562
+ useEffect22(() => {
42498
42563
  const load2 = callbacks.current.loadTurnIndex;
42499
42564
  indexSeq.current += 1;
42500
42565
  const seq2 = indexSeq.current;
@@ -42614,7 +42679,7 @@ function useTurnNavigation({
42614
42679
  }
42615
42680
 
42616
42681
  // src/hooks/use-typewriter-reveal.ts
42617
- import { useCallback as useCallback12, useEffect as useEffect22, useRef as useRef22, useState as useState27 } from "react";
42682
+ import { useCallback as useCallback12, useEffect as useEffect23, useRef as useRef23, useState as useState28 } from "react";
42618
42683
  var REVEAL_INITIAL_CPS = 18;
42619
42684
  var REVEAL_MIN_CPS = 6;
42620
42685
  var REVEAL_MAX_CPS = 240;
@@ -42650,15 +42715,15 @@ function initialRevealState(targetText, isLive, resetKey) {
42650
42715
  };
42651
42716
  }
42652
42717
  function useTypewriterReveal(targetText, isLive, resetKey) {
42653
- const [state, setState] = useState27(() => initialRevealState(targetText, isLive, resetKey));
42654
- const targetTextRef = useRef22(targetText);
42718
+ const [state, setState] = useState28(() => initialRevealState(targetText, isLive, resetKey));
42719
+ const targetTextRef = useRef23(targetText);
42655
42720
  targetTextRef.current = targetText;
42656
- const revealedLenRef = useRef22(state.revealedLen);
42657
- const priorTargetLenRef = useRef22(targetText.length);
42658
- const emaCpsRef = useRef22(REVEAL_INITIAL_CPS);
42659
- const lastTickTsRef = useRef22(null);
42660
- const lastArrivalTsRef = useRef22(null);
42661
- const cancelRef = useRef22(null);
42721
+ const revealedLenRef = useRef23(state.revealedLen);
42722
+ const priorTargetLenRef = useRef23(targetText.length);
42723
+ const emaCpsRef = useRef23(REVEAL_INITIAL_CPS);
42724
+ const lastTickTsRef = useRef23(null);
42725
+ const lastArrivalTsRef = useRef23(null);
42726
+ const cancelRef = useRef23(null);
42662
42727
  const stopTicking = useCallback12(() => {
42663
42728
  cancelRef.current?.();
42664
42729
  cancelRef.current = null;
@@ -42690,7 +42755,7 @@ function useTypewriterReveal(targetText, isLive, resetKey) {
42690
42755
  priorTargetLenRef.current = targetText.length;
42691
42756
  setState((s) => ({ ...s, displayedText: targetText, revealedLen: targetText.length, isRevealing: false }));
42692
42757
  }
42693
- const tickRef = useRef22(null);
42758
+ const tickRef = useRef23(null);
42694
42759
  tickRef.current = (ts) => {
42695
42760
  cancelRef.current = null;
42696
42761
  const currentTargetLen = targetTextRef.current.length;
@@ -42729,7 +42794,7 @@ function useTypewriterReveal(targetText, isLive, resetKey) {
42729
42794
  cancelRef.current = scheduleAnimationFrame((nextTs) => tickRef.current?.(nextTs));
42730
42795
  }
42731
42796
  };
42732
- useEffect22(() => {
42797
+ useEffect23(() => {
42733
42798
  if (!isLive) return;
42734
42799
  if (revealedLenRef.current === 0) return;
42735
42800
  if (revealedLenRef.current >= targetText.length) return;
@@ -42737,10 +42802,10 @@ function useTypewriterReveal(targetText, isLive, resetKey) {
42737
42802
  setState((s) => s.isRevealing ? s : { ...s, isRevealing: true });
42738
42803
  cancelRef.current = scheduleAnimationFrame((ts) => tickRef.current?.(ts));
42739
42804
  }, [targetText, isLive]);
42740
- useEffect22(() => {
42805
+ useEffect23(() => {
42741
42806
  if (!isLive) stopTicking();
42742
42807
  }, [isLive, stopTicking]);
42743
- useEffect22(() => {
42808
+ useEffect23(() => {
42744
42809
  if (typeof document === "undefined") return;
42745
42810
  const handleVisibilityChange = () => {
42746
42811
  if (document.visibilityState === "visible") flushNow();
@@ -42748,12 +42813,12 @@ function useTypewriterReveal(targetText, isLive, resetKey) {
42748
42813
  document.addEventListener("visibilitychange", handleVisibilityChange);
42749
42814
  return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
42750
42815
  }, [flushNow]);
42751
- useEffect22(() => stopTicking, [stopTicking]);
42816
+ useEffect23(() => stopTicking, [stopTicking]);
42752
42817
  return { displayedText: state.displayedText, isRevealing: state.isRevealing, flushNow };
42753
42818
  }
42754
42819
 
42755
42820
  // src/chat/plan/PlanSummaryCard.tsx
42756
- import { useMemo as useMemo15, useState as useState28 } from "react";
42821
+ import { useMemo as useMemo15, useState as useState29 } from "react";
42757
42822
 
42758
42823
  // ../../node_modules/.pnpm/js-yaml@4.1.1/node_modules/js-yaml/dist/js-yaml.mjs
42759
42824
  function isNothing(subject) {
@@ -45713,7 +45778,7 @@ function extractRefs(content3) {
45713
45778
  }
45714
45779
 
45715
45780
  // src/chat/plan/PlanSummaryCard.tsx
45716
- import { Fragment as Fragment15, jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
45781
+ import { Fragment as Fragment16, jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
45717
45782
  function PlanSummaryCard({
45718
45783
  messages,
45719
45784
  sessionStatus,
@@ -45728,8 +45793,8 @@ function PlanSummaryCard({
45728
45793
  const isWaitingForInput = sessionStatus === "waiting_for_input";
45729
45794
  const canConfirm = Boolean(onConfirmPlan) && isWaitingForInput && data.lastPauseTool === "ExitPlanMode";
45730
45795
  const openPlanPanel = openPlanPanelAction && sessionId ? () => openPlanPanelAction(sessionId) : void 0;
45731
- return /* @__PURE__ */ jsxs36("div", { className: "flex w-full flex-col gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.55)] p-4", children: [
45732
- /* @__PURE__ */ jsxs36(
45796
+ return /* @__PURE__ */ jsxs37("div", { className: "flex w-full flex-col gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.55)] p-4", children: [
45797
+ /* @__PURE__ */ jsxs37(
45733
45798
  "button",
45734
45799
  {
45735
45800
  type: "button",
@@ -45737,17 +45802,17 @@ function PlanSummaryCard({
45737
45802
  disabled: isHistorical || !openPlanPanel,
45738
45803
  className: "flex w-full flex-col gap-4 text-left transition-colors hover:text-[hsl(var(--foreground))]",
45739
45804
  children: [
45740
- /* @__PURE__ */ jsxs36("div", { className: "flex items-start justify-between gap-3", children: [
45741
- /* @__PURE__ */ jsxs36("div", { className: "min-w-0 space-y-2", children: [
45742
- /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
45743
- /* @__PURE__ */ jsx42(Sparkles, { size: 12 }),
45744
- /* @__PURE__ */ jsx42("span", { children: "\u89C4\u5212\u6458\u8981" })
45805
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-start justify-between gap-3", children: [
45806
+ /* @__PURE__ */ jsxs37("div", { className: "min-w-0 space-y-2", children: [
45807
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
45808
+ /* @__PURE__ */ jsx43(Sparkles, { size: 12 }),
45809
+ /* @__PURE__ */ jsx43("span", { children: "\u89C4\u5212\u6458\u8981" })
45745
45810
  ] }),
45746
- /* @__PURE__ */ jsx42("div", { className: "truncate text-base font-medium text-[hsl(var(--foreground))]", children: data.intent || "\u5F53\u524D\u89C4\u5212" }),
45747
- /* @__PURE__ */ jsx42("div", { className: "flex flex-wrap items-center gap-2 text-xs", children: summaryState.kind === "progress" ? /* @__PURE__ */ jsxs36(Fragment15, { children: [
45748
- /* @__PURE__ */ jsx42("span", { className: "rounded-full bg-[hsl(var(--accent))] px-2.5 py-1 text-[hsl(var(--foreground))]", children: summaryState.label }),
45749
- /* @__PURE__ */ jsx42("span", { className: "font-mono tracking-[0.25em] text-[hsl(var(--muted-foreground))]", children: summaryState.dots })
45750
- ] }) : /* @__PURE__ */ jsx42(
45811
+ /* @__PURE__ */ jsx43("div", { className: "truncate text-base font-medium text-[hsl(var(--foreground))]", children: data.intent || "\u5F53\u524D\u89C4\u5212" }),
45812
+ /* @__PURE__ */ jsx43("div", { className: "flex flex-wrap items-center gap-2 text-xs", children: summaryState.kind === "progress" ? /* @__PURE__ */ jsxs37(Fragment16, { children: [
45813
+ /* @__PURE__ */ jsx43("span", { className: "rounded-full bg-[hsl(var(--accent))] px-2.5 py-1 text-[hsl(var(--foreground))]", children: summaryState.label }),
45814
+ /* @__PURE__ */ jsx43("span", { className: "font-mono tracking-[0.25em] text-[hsl(var(--muted-foreground))]", children: summaryState.dots })
45815
+ ] }) : /* @__PURE__ */ jsx43(
45751
45816
  "span",
45752
45817
  {
45753
45818
  className: cn(
@@ -45760,7 +45825,7 @@ function PlanSummaryCard({
45760
45825
  }
45761
45826
  ) })
45762
45827
  ] }),
45763
- !isHistorical && /* @__PURE__ */ jsx42(
45828
+ !isHistorical && /* @__PURE__ */ jsx43(
45764
45829
  ChevronRight,
45765
45830
  {
45766
45831
  size: 16,
@@ -45769,31 +45834,31 @@ function PlanSummaryCard({
45769
45834
  }
45770
45835
  )
45771
45836
  ] }),
45772
- summaryState.kind === "complete" && /* @__PURE__ */ jsxs36("div", { className: "flex flex-wrap items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
45773
- /* @__PURE__ */ jsxs36("span", { className: "rounded-full border border-[hsl(var(--border))] px-2.5 py-1", children: [
45837
+ summaryState.kind === "complete" && /* @__PURE__ */ jsxs37("div", { className: "flex flex-wrap items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
45838
+ /* @__PURE__ */ jsxs37("span", { className: "rounded-full border border-[hsl(var(--border))] px-2.5 py-1", children: [
45774
45839
  data.selectedSkills.length,
45775
45840
  " \u4E2A\u6280\u80FD"
45776
45841
  ] }),
45777
- /* @__PURE__ */ jsxs36("span", { className: "rounded-full border border-[hsl(var(--border))] px-2.5 py-1", children: [
45842
+ /* @__PURE__ */ jsxs37("span", { className: "rounded-full border border-[hsl(var(--border))] px-2.5 py-1", children: [
45778
45843
  stepCount,
45779
45844
  " \u4E2A\u6B65\u9AA4"
45780
45845
  ] }),
45781
- !isHistorical && /* @__PURE__ */ jsxs36("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--muted-foreground))]", children: [
45782
- /* @__PURE__ */ jsx42(CircleCheck, { size: 12 }),
45846
+ !isHistorical && /* @__PURE__ */ jsxs37("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--muted-foreground))]", children: [
45847
+ /* @__PURE__ */ jsx43(CircleCheck, { size: 12 }),
45783
45848
  "\u53F3\u4FA7\u67E5\u770B\u8BE6\u60C5"
45784
45849
  ] })
45785
45850
  ] })
45786
45851
  ]
45787
45852
  }
45788
45853
  ),
45789
- canConfirm && /* @__PURE__ */ jsx42(PlanConfirmationPanel, { onConfirmPlan })
45854
+ canConfirm && /* @__PURE__ */ jsx43(PlanConfirmationPanel, { onConfirmPlan })
45790
45855
  ] });
45791
45856
  }
45792
45857
  function PlanConfirmationPanel({
45793
45858
  onConfirmPlan
45794
45859
  }) {
45795
- const [isEditing, setIsEditing] = useState28(false);
45796
- const [revisionText, setRevisionText] = useState28("");
45860
+ const [isEditing, setIsEditing] = useState29(false);
45861
+ const [revisionText, setRevisionText] = useState29("");
45797
45862
  const submitRevision = () => {
45798
45863
  const trimmed = revisionText.trim();
45799
45864
  if (!trimmed) return;
@@ -45801,35 +45866,35 @@ function PlanConfirmationPanel({
45801
45866
  setRevisionText("");
45802
45867
  setIsEditing(false);
45803
45868
  };
45804
- return /* @__PURE__ */ jsxs36("div", { className: "space-y-3 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--background)/0.45)] p-3", children: [
45805
- /* @__PURE__ */ jsxs36("div", { className: "flex flex-wrap gap-2", children: [
45806
- /* @__PURE__ */ jsxs36(
45869
+ return /* @__PURE__ */ jsxs37("div", { className: "space-y-3 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--background)/0.45)] p-3", children: [
45870
+ /* @__PURE__ */ jsxs37("div", { className: "flex flex-wrap gap-2", children: [
45871
+ /* @__PURE__ */ jsxs37(
45807
45872
  "button",
45808
45873
  {
45809
45874
  type: "button",
45810
45875
  onClick: () => onConfirmPlan?.("execute"),
45811
45876
  className: "inline-flex items-center gap-1.5 rounded-lg bg-[hsl(var(--primary))] px-3 py-2 text-sm font-medium text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90",
45812
45877
  children: [
45813
- /* @__PURE__ */ jsx42(Play, { size: 14 }),
45878
+ /* @__PURE__ */ jsx43(Play, { size: 14 }),
45814
45879
  "\u5F00\u59CB\u6267\u884C"
45815
45880
  ]
45816
45881
  }
45817
45882
  ),
45818
- /* @__PURE__ */ jsxs36(
45883
+ /* @__PURE__ */ jsxs37(
45819
45884
  "button",
45820
45885
  {
45821
45886
  type: "button",
45822
45887
  onClick: () => setIsEditing((value) => !value),
45823
45888
  className: "inline-flex items-center gap-1.5 rounded-lg border border-[hsl(var(--border))] px-3 py-2 text-sm text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]",
45824
45889
  children: [
45825
- /* @__PURE__ */ jsx42(PencilLine, { size: 14 }),
45890
+ /* @__PURE__ */ jsx43(PencilLine, { size: 14 }),
45826
45891
  "\u4FEE\u6539"
45827
45892
  ]
45828
45893
  }
45829
45894
  )
45830
45895
  ] }),
45831
- isEditing && /* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
45832
- /* @__PURE__ */ jsx42(
45896
+ isEditing && /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
45897
+ /* @__PURE__ */ jsx43(
45833
45898
  "textarea",
45834
45899
  {
45835
45900
  value: revisionText,
@@ -45838,7 +45903,7 @@ function PlanConfirmationPanel({
45838
45903
  className: "min-h-24 w-full resize-y rounded-lg border border-[hsl(var(--border))] bg-transparent px-3 py-2 text-sm text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground))]"
45839
45904
  }
45840
45905
  ),
45841
- /* @__PURE__ */ jsx42("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx42(
45906
+ /* @__PURE__ */ jsx43("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx43(
45842
45907
  "button",
45843
45908
  {
45844
45909
  type: "button",
@@ -45955,8 +46020,8 @@ function extractPlanMessagesForTurn(messages, turnLastMessage) {
45955
46020
  }
45956
46021
 
45957
46022
  // src/chat/CompactionCard.tsx
45958
- import { useState as useState29 } from "react";
45959
- import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
46023
+ import { useState as useState30 } from "react";
46024
+ import { jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
45960
46025
  var PERCENT_FORMATTER = new Intl.NumberFormat("zh-CN", {
45961
46026
  style: "percent",
45962
46027
  maximumFractionDigits: 0
@@ -46006,7 +46071,7 @@ function CompactionCard({
46006
46071
  ...compaction,
46007
46072
  status: status ?? "completed"
46008
46073
  } : activeCompaction;
46009
- const [expanded, setExpanded] = useState29(false);
46074
+ const [expanded, setExpanded] = useState30(false);
46010
46075
  if (!source || !source.compaction_id) {
46011
46076
  return null;
46012
46077
  }
@@ -46017,9 +46082,9 @@ function CompactionCard({
46017
46082
  const hasSummary = typeof source.summary_full === "string" && source.summary_full.trim().length > 0 && !isGenericArchiveSummary(source.summary_full);
46018
46083
  const hasFailureReason = source.status === "failed" && Boolean(source.failure_reason);
46019
46084
  const canExpand = source.status === "completed" && (hasSummary || archivedToolCalls.length > 0) || hasFailureReason;
46020
- return /* @__PURE__ */ jsxs37("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: [
46021
- /* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-between gap-2", children: [
46022
- /* @__PURE__ */ jsxs37(
46085
+ return /* @__PURE__ */ jsxs38("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: [
46086
+ /* @__PURE__ */ jsxs38("div", { className: "flex items-center justify-between gap-2", children: [
46087
+ /* @__PURE__ */ jsxs38(
46023
46088
  "button",
46024
46089
  {
46025
46090
  type: "button",
@@ -46030,21 +46095,21 @@ function CompactionCard({
46030
46095
  ),
46031
46096
  "aria-expanded": expanded,
46032
46097
  children: [
46033
- canExpand ? expanded ? /* @__PURE__ */ jsx43(ChevronDown, { size: 12, className: "shrink-0" }) : /* @__PURE__ */ jsx43(ChevronRight, { size: 12, className: "shrink-0" }) : null,
46034
- /* @__PURE__ */ jsx43("span", { children: source.status === "streaming" ? /* @__PURE__ */ jsxs37("span", { className: "inline-flex items-center gap-1", children: [
46035
- /* @__PURE__ */ jsx43(LoaderCircle, { size: 12, className: "animate-spin" }),
46098
+ canExpand ? expanded ? /* @__PURE__ */ jsx44(ChevronDown, { size: 12, className: "shrink-0" }) : /* @__PURE__ */ jsx44(ChevronRight, { size: 12, className: "shrink-0" }) : null,
46099
+ /* @__PURE__ */ jsx44("span", { children: source.status === "streaming" ? /* @__PURE__ */ jsxs38("span", { className: "inline-flex items-center gap-1", children: [
46100
+ /* @__PURE__ */ jsx44(LoaderCircle, { size: 12, className: "animate-spin" }),
46036
46101
  "\u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587"
46037
- ] }) : source.status === "failed" ? /* @__PURE__ */ jsxs37("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--swf-danger))]", children: [
46038
- /* @__PURE__ */ jsx43(CircleX, { size: 12 }),
46102
+ ] }) : source.status === "failed" ? /* @__PURE__ */ jsxs38("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--swf-danger))]", children: [
46103
+ /* @__PURE__ */ jsx44(CircleX, { size: 12 }),
46039
46104
  "\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25"
46040
- ] }) : source.status === "interrupted" ? /* @__PURE__ */ jsxs37("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--swf-warning))]", children: [
46041
- /* @__PURE__ */ jsx43(Square, { size: 12 }),
46105
+ ] }) : source.status === "interrupted" ? /* @__PURE__ */ jsxs38("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--swf-warning))]", children: [
46106
+ /* @__PURE__ */ jsx44(Square, { size: 12 }),
46042
46107
  "\u4E0A\u4E0B\u6587\u538B\u7F29\u5DF2\u53D6\u6D88"
46043
46108
  ] }) : "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
46044
46109
  ]
46045
46110
  }
46046
46111
  ),
46047
- canCancel ? /* @__PURE__ */ jsx43(
46112
+ canCancel ? /* @__PURE__ */ jsx44(
46048
46113
  "button",
46049
46114
  {
46050
46115
  type: "button",
@@ -46054,13 +46119,13 @@ function CompactionCard({
46054
46119
  }
46055
46120
  ) : null
46056
46121
  ] }),
46057
- expanded ? /* @__PURE__ */ jsxs37("div", { className: "mt-1 max-w-3xl rounded-lg border border-[hsl(var(--border))]/70 bg-[hsl(var(--card))]/80 px-3 py-2 text-[11px] leading-relaxed", children: [
46058
- /* @__PURE__ */ jsxs37("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-[hsl(var(--muted-foreground))]", children: [
46059
- /* @__PURE__ */ jsxs37("span", { children: [
46122
+ expanded ? /* @__PURE__ */ jsxs38("div", { className: "mt-1 max-w-3xl rounded-lg border border-[hsl(var(--border))]/70 bg-[hsl(var(--card))]/80 px-3 py-2 text-[11px] leading-relaxed", children: [
46123
+ /* @__PURE__ */ jsxs38("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-[hsl(var(--muted-foreground))]", children: [
46124
+ /* @__PURE__ */ jsxs38("span", { children: [
46060
46125
  "#",
46061
46126
  shortId(source.compaction_id)
46062
46127
  ] }),
46063
- /* @__PURE__ */ jsxs37("span", { children: [
46128
+ /* @__PURE__ */ jsxs38("span", { children: [
46064
46129
  "\u8282\u7701 ",
46065
46130
  formatSavedRatio(source.saved_ratio),
46066
46131
  "\uFF08",
@@ -46070,31 +46135,31 @@ function CompactionCard({
46070
46135
  formatTokens(source.tokens_after),
46071
46136
  " token\uFF09"
46072
46137
  ] }),
46073
- /* @__PURE__ */ jsxs37("span", { children: [
46138
+ /* @__PURE__ */ jsxs38("span", { children: [
46074
46139
  "\u5F52\u6863 ",
46075
46140
  archivedCount,
46076
46141
  " \u4E2A\u5DE5\u5177\u7ED3\u679C"
46077
46142
  ] })
46078
46143
  ] }),
46079
- archivedToolCalls.length > 0 ? /* @__PURE__ */ jsx43("div", { className: "mt-2 space-y-1.5", children: archivedToolCalls.map((item, index2) => {
46144
+ archivedToolCalls.length > 0 ? /* @__PURE__ */ jsx44("div", { className: "mt-2 space-y-1.5", children: archivedToolCalls.map((item, index2) => {
46080
46145
  const archivePath = getArchivePath(item, archivedFiles);
46081
- return /* @__PURE__ */ jsxs37(
46146
+ return /* @__PURE__ */ jsxs38(
46082
46147
  "div",
46083
46148
  {
46084
46149
  className: "rounded-md border border-[hsl(var(--border))]/70 bg-[hsl(var(--muted))]/35 px-2 py-1.5",
46085
46150
  children: [
46086
- /* @__PURE__ */ jsxs37("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-[hsl(var(--foreground))]", children: [
46087
- /* @__PURE__ */ jsx43("span", { className: "font-medium", children: getArchivedToolLabel(item) }),
46088
- item.tool_call_id ? /* @__PURE__ */ jsx43("span", { className: "font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.tool_call_id }) : null
46151
+ /* @__PURE__ */ jsxs38("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-[hsl(var(--foreground))]", children: [
46152
+ /* @__PURE__ */ jsx44("span", { className: "font-medium", children: getArchivedToolLabel(item) }),
46153
+ item.tool_call_id ? /* @__PURE__ */ jsx44("span", { className: "font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.tool_call_id }) : null
46089
46154
  ] }),
46090
- archivePath ? /* @__PURE__ */ jsx43("div", { className: "mt-0.5 break-all font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: archivePath }) : null
46155
+ archivePath ? /* @__PURE__ */ jsx44("div", { className: "mt-0.5 break-all font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: archivePath }) : null
46091
46156
  ]
46092
46157
  },
46093
46158
  item.tool_call_id || item.entry_id || `${item.tool_name}-${index2}`
46094
46159
  );
46095
46160
  }) }) : null,
46096
- hasSummary ? /* @__PURE__ */ jsx43("pre", { className: "mt-2 max-h-[360px] overflow-auto whitespace-pre-wrap rounded-md border border-[hsl(var(--border))]/70 bg-[hsl(var(--muted))]/25 px-2 py-1.5 font-mono text-[11px] leading-relaxed text-[hsl(var(--foreground))]", children: source.summary_full }) : null,
46097
- source.status === "failed" && source.failure_reason ? /* @__PURE__ */ jsxs37("div", { className: "mt-2 text-[hsl(var(--swf-danger))]", children: [
46161
+ hasSummary ? /* @__PURE__ */ jsx44("pre", { className: "mt-2 max-h-[360px] overflow-auto whitespace-pre-wrap rounded-md border border-[hsl(var(--border))]/70 bg-[hsl(var(--muted))]/25 px-2 py-1.5 font-mono text-[11px] leading-relaxed text-[hsl(var(--foreground))]", children: source.summary_full }) : null,
46162
+ source.status === "failed" && source.failure_reason ? /* @__PURE__ */ jsxs38("div", { className: "mt-2 text-[hsl(var(--swf-danger))]", children: [
46098
46163
  "\u5931\u8D25\u539F\u56E0\uFF1A",
46099
46164
  source.failure_reason
46100
46165
  ] }) : null
@@ -46103,11 +46168,11 @@ function CompactionCard({
46103
46168
  }
46104
46169
 
46105
46170
  // src/chat/PostChatFollowupBlock.tsx
46106
- import { useEffect as useEffect24, useRef as useRef24 } from "react";
46171
+ import { useEffect as useEffect25, useRef as useRef25 } from "react";
46107
46172
 
46108
46173
  // src/chat/FinalArtifactCards.tsx
46109
- import { useEffect as useEffect23, useRef as useRef23, useState as useState30 } from "react";
46110
- import { Fragment as Fragment16, jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
46174
+ import { useEffect as useEffect24, useRef as useRef24, useState as useState31 } from "react";
46175
+ import { Fragment as Fragment17, jsx as jsx45, jsxs as jsxs39 } from "react/jsx-runtime";
46111
46176
  function basename2(path2) {
46112
46177
  return path2.split("/").filter(Boolean).pop() || path2;
46113
46178
  }
@@ -46128,10 +46193,10 @@ function LinkCard({
46128
46193
  const bladeHost = useBladeHost();
46129
46194
  const host = hostOf(url2);
46130
46195
  const local = isLoopbackUrl(url2) && Boolean(bladeHost.openPreview);
46131
- const content3 = /* @__PURE__ */ jsxs38(Fragment16, { children: [
46132
- /* @__PURE__ */ jsx44("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center text-[hsl(var(--primary))]", children: /* @__PURE__ */ jsx44(Globe, { size: 15, "aria-hidden": "true" }) }),
46133
- /* @__PURE__ */ jsx44("span", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx44("span", { className: "block truncate text-xs font-medium leading-5", children: label || host }) }),
46134
- /* @__PURE__ */ jsx44(
46196
+ const content3 = /* @__PURE__ */ jsxs39(Fragment17, { children: [
46197
+ /* @__PURE__ */ jsx45("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center text-[hsl(var(--primary))]", children: /* @__PURE__ */ jsx45(Globe, { size: 15, "aria-hidden": "true" }) }),
46198
+ /* @__PURE__ */ jsx45("span", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx45("span", { className: "block truncate text-xs font-medium leading-5", children: label || host }) }),
46199
+ /* @__PURE__ */ jsx45(
46135
46200
  ArrowUpRight,
46136
46201
  {
46137
46202
  size: 13,
@@ -46141,7 +46206,7 @@ function LinkCard({
46141
46206
  )
46142
46207
  ] });
46143
46208
  if (local) {
46144
- return /* @__PURE__ */ jsx44(
46209
+ return /* @__PURE__ */ jsx45(
46145
46210
  "button",
46146
46211
  {
46147
46212
  type: "button",
@@ -46157,7 +46222,7 @@ ${url2}`,
46157
46222
  }
46158
46223
  );
46159
46224
  }
46160
- return /* @__PURE__ */ jsx44(
46225
+ return /* @__PURE__ */ jsx45(
46161
46226
  "a",
46162
46227
  {
46163
46228
  href: url2,
@@ -46177,14 +46242,14 @@ function FinalArtifactCards({
46177
46242
  sessionId,
46178
46243
  assistantEntryId
46179
46244
  }) {
46180
- const [expanded, setExpanded] = useState30(false);
46245
+ const [expanded, setExpanded] = useState31(false);
46181
46246
  const hasMore = artifacts.length > 3;
46182
46247
  const visibleArtifacts = expanded ? artifacts : artifacts.slice(0, 3);
46183
46248
  const emit = useFollowupInteraction();
46184
- const reportedShown = useRef23(/* @__PURE__ */ new Set());
46185
- const reportedOpened = useRef23(/* @__PURE__ */ new Set());
46249
+ const reportedShown = useRef24(/* @__PURE__ */ new Set());
46250
+ const reportedOpened = useRef24(/* @__PURE__ */ new Set());
46186
46251
  const visibleCount = visibleArtifacts.length;
46187
- useEffect23(() => {
46252
+ useEffect24(() => {
46188
46253
  for (let artifactIndex = 0; artifactIndex < visibleCount; artifactIndex += 1) {
46189
46254
  const artifact = artifacts[artifactIndex];
46190
46255
  if (!artifact || reportedShown.current.has(artifactIndex)) continue;
@@ -46200,8 +46265,8 @@ function FinalArtifactCards({
46200
46265
  const columnCount = Math.min(artifacts.length, 3);
46201
46266
  const gridWidth = columnCount * 180 + Math.max(0, columnCount - 1) * 6;
46202
46267
  if (artifacts.length === 0) return null;
46203
- return /* @__PURE__ */ jsxs38("div", { className: "flex max-w-full flex-col gap-1.5", children: [
46204
- /* @__PURE__ */ jsx44(
46268
+ return /* @__PURE__ */ jsxs39("div", { className: "flex max-w-full flex-col gap-1.5", children: [
46269
+ /* @__PURE__ */ jsx45(
46205
46270
  "div",
46206
46271
  {
46207
46272
  style: {
@@ -46210,7 +46275,7 @@ function FinalArtifactCards({
46210
46275
  },
46211
46276
  className: expanded && hasMore ? "grid max-h-[144px] max-w-full gap-1.5 overflow-y-auto pr-1" : "grid max-w-full gap-1.5",
46212
46277
  children: visibleArtifacts.map(
46213
- (artifact, artifactIndex) => artifact.kind === "link" ? /* @__PURE__ */ jsx44(
46278
+ (artifact, artifactIndex) => artifact.kind === "link" ? /* @__PURE__ */ jsx45(
46214
46279
  LinkCard,
46215
46280
  {
46216
46281
  url: artifact.target,
@@ -46219,7 +46284,7 @@ function FinalArtifactCards({
46219
46284
  onOpen: () => reportOpened(artifactIndex, "link")
46220
46285
  },
46221
46286
  `${artifact.kind}:${artifactIndex}`
46222
- ) : /* @__PURE__ */ jsx44(
46287
+ ) : /* @__PURE__ */ jsx45(
46223
46288
  DeliveryCard,
46224
46289
  {
46225
46290
  path: artifact.target,
@@ -46236,7 +46301,7 @@ function FinalArtifactCards({
46236
46301
  )
46237
46302
  }
46238
46303
  ),
46239
- hasMore ? /* @__PURE__ */ jsxs38(
46304
+ hasMore ? /* @__PURE__ */ jsxs39(
46240
46305
  "button",
46241
46306
  {
46242
46307
  type: "button",
@@ -46244,8 +46309,8 @@ function FinalArtifactCards({
46244
46309
  className: "flex w-fit items-center gap-0.5 text-[11px] leading-4 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
46245
46310
  "aria-expanded": expanded,
46246
46311
  children: [
46247
- /* @__PURE__ */ jsx44("span", { children: expanded ? "\u6536\u8D77" : `\u5C55\u5F00 ${artifacts.length - 3} \u4E2A` }),
46248
- /* @__PURE__ */ jsx44(
46312
+ /* @__PURE__ */ jsx45("span", { children: expanded ? "\u6536\u8D77" : `\u5C55\u5F00 ${artifacts.length - 3} \u4E2A` }),
46313
+ /* @__PURE__ */ jsx45(
46249
46314
  ChevronDown,
46250
46315
  {
46251
46316
  size: 13,
@@ -46260,7 +46325,7 @@ function FinalArtifactCards({
46260
46325
  }
46261
46326
 
46262
46327
  // src/chat/PostChatFollowupBlock.tsx
46263
- import { jsx as jsx45, jsxs as jsxs39 } from "react/jsx-runtime";
46328
+ import { jsx as jsx46, jsxs as jsxs40 } from "react/jsx-runtime";
46264
46329
  function PostChatFollowupBlock({
46265
46330
  sessionId,
46266
46331
  followup,
@@ -46270,26 +46335,26 @@ function PostChatFollowupBlock({
46270
46335
  }) {
46271
46336
  const composer = useComposerBridge(sessionId);
46272
46337
  const emit = useFollowupInteraction();
46273
- const reportedSuggestions = useRef24(false);
46274
- const adopted = useRef24(/* @__PURE__ */ new Set());
46338
+ const reportedSuggestions = useRef25(false);
46339
+ const adopted = useRef25(/* @__PURE__ */ new Set());
46275
46340
  const artifacts = followup?.final_artifacts ?? [];
46276
46341
  const assistantEntryId = followup?.assistant_entry_id ?? "";
46277
46342
  const suggestionCount = followup?.suggestions.length ?? 0;
46278
- useEffect24(() => {
46343
+ useEffect25(() => {
46279
46344
  if (reportedSuggestions.current || suggestionCount === 0) return;
46280
46345
  reportedSuggestions.current = true;
46281
46346
  emit({ type: "suggestions_shown", sessionId, assistantEntryId, count: suggestionCount });
46282
46347
  }, [assistantEntryId, emit, sessionId, suggestionCount]);
46283
46348
  if (!followup || !followup.recaption && followup.suggestions.length === 0 && artifacts.length === 0 && !followup.feedback_eligible)
46284
46349
  return null;
46285
- return /* @__PURE__ */ jsxs39("div", { part: "followup", className: "blade-chat-followup flex w-fit max-w-full flex-col gap-4 rounded-xl border border-[hsl(var(--border)/0.75)] bg-[hsl(var(--muted)/0.28)] px-3 py-3 sm:min-w-[340px] sm:max-w-[680px]", children: [
46286
- followup.recaption ? /* @__PURE__ */ jsxs39("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", className: "flex flex-col gap-2", children: [
46287
- /* @__PURE__ */ jsxs39("div", { className: "mb-1 flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]", children: [
46288
- /* @__PURE__ */ jsx45(Sparkles, { size: 14, "aria-hidden": "true" }),
46350
+ return /* @__PURE__ */ jsxs40("div", { part: "followup", className: "blade-chat-followup flex w-fit max-w-full flex-col gap-4 rounded-xl border border-[hsl(var(--border)/0.75)] bg-[hsl(var(--muted)/0.28)] px-3 py-3 sm:min-w-[340px] sm:max-w-[680px]", children: [
46351
+ followup.recaption ? /* @__PURE__ */ jsxs40("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", className: "flex flex-col gap-2", children: [
46352
+ /* @__PURE__ */ jsxs40("div", { className: "mb-1 flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]", children: [
46353
+ /* @__PURE__ */ jsx46(Sparkles, { size: 14, "aria-hidden": "true" }),
46289
46354
  "\u672C\u8F6E\u5C0F\u7ED3"
46290
46355
  ] }),
46291
- /* @__PURE__ */ jsx45("p", { className: "text-[13px] leading-5 text-[hsl(var(--foreground)/0.9)]", children: followup.recaption }),
46292
- artifacts.length > 0 ? /* @__PURE__ */ jsx45(
46356
+ /* @__PURE__ */ jsx46("p", { className: "text-[13px] leading-5 text-[hsl(var(--foreground)/0.9)]", children: followup.recaption }),
46357
+ artifacts.length > 0 ? /* @__PURE__ */ jsx46(
46293
46358
  FinalArtifactCards,
46294
46359
  {
46295
46360
  artifacts,
@@ -46298,7 +46363,7 @@ function PostChatFollowupBlock({
46298
46363
  }
46299
46364
  ) : null
46300
46365
  ] }) : null,
46301
- !followup.recaption && artifacts.length > 0 ? /* @__PURE__ */ jsx45("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", children: /* @__PURE__ */ jsx45(
46366
+ !followup.recaption && artifacts.length > 0 ? /* @__PURE__ */ jsx46("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", children: /* @__PURE__ */ jsx46(
46302
46367
  FinalArtifactCards,
46303
46368
  {
46304
46369
  artifacts,
@@ -46306,9 +46371,9 @@ function PostChatFollowupBlock({
46306
46371
  assistantEntryId
46307
46372
  }
46308
46373
  ) }) : null,
46309
- followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs39("section", { className: "flex flex-col items-start gap-1.5", "aria-label": "\u4E0B\u4E00\u6B65\u5EFA\u8BAE", children: [
46310
- /* @__PURE__ */ jsx45("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
46311
- /* @__PURE__ */ jsx45("div", { className: "grid w-fit max-w-full gap-1.5 sm:max-w-[680px]", children: followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */ jsxs39(
46374
+ followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs40("section", { className: "flex flex-col items-start gap-1.5", "aria-label": "\u4E0B\u4E00\u6B65\u5EFA\u8BAE", children: [
46375
+ /* @__PURE__ */ jsx46("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
46376
+ /* @__PURE__ */ jsx46("div", { className: "grid w-fit max-w-full gap-1.5 sm:max-w-[680px]", children: followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */ jsxs40(
46312
46377
  "button",
46313
46378
  {
46314
46379
  type: "button",
@@ -46323,8 +46388,8 @@ function PostChatFollowupBlock({
46323
46388
  part: "followup-action",
46324
46389
  className: "blade-chat-followup-action group flex w-full items-center gap-2.5 rounded-[14px] bg-[hsl(var(--muted)/0.62)] px-3.5 py-2 text-left text-[13px] font-normal leading-5 text-[hsl(var(--foreground)/0.92)] transition-colors hover:bg-[hsl(var(--muted)/0.88)] disabled:cursor-default disabled:opacity-60",
46325
46390
  children: [
46326
- /* @__PURE__ */ jsx45("span", { className: "min-w-0", children: suggestion }),
46327
- /* @__PURE__ */ jsx45(
46391
+ /* @__PURE__ */ jsx46("span", { className: "min-w-0", children: suggestion }),
46392
+ /* @__PURE__ */ jsx46(
46328
46393
  ArrowRight,
46329
46394
  {
46330
46395
  size: 14,
@@ -46338,7 +46403,7 @@ function PostChatFollowupBlock({
46338
46403
  suggestion
46339
46404
  )) })
46340
46405
  ] }) : null,
46341
- /* @__PURE__ */ jsx45(
46406
+ /* @__PURE__ */ jsx46(
46342
46407
  ResultFeedback,
46343
46408
  {
46344
46409
  sessionId,
@@ -46353,7 +46418,7 @@ function PostChatFollowupBlock({
46353
46418
 
46354
46419
  // src/chat/RenderErrorBoundary.tsx
46355
46420
  import { Component } from "react";
46356
- import { jsx as jsx46, jsxs as jsxs40 } from "react/jsx-runtime";
46421
+ import { jsx as jsx47, jsxs as jsxs41 } from "react/jsx-runtime";
46357
46422
  function getFirstComponentName(componentStack) {
46358
46423
  const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
46359
46424
  return match?.[1] ?? null;
@@ -46386,26 +46451,26 @@ var RenderErrorBoundary = class extends Component {
46386
46451
  return children;
46387
46452
  }
46388
46453
  const componentName = getFirstComponentName(componentStack);
46389
- return /* @__PURE__ */ jsx46("div", { className: "blade-chat-render-error rounded-xl border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-4 py-3 text-sm text-[hsl(var(--foreground))]", children: /* @__PURE__ */ jsxs40("div", { className: "flex items-start gap-2", children: [
46390
- /* @__PURE__ */ jsx46(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-[hsl(var(--swf-warning))]" }),
46391
- /* @__PURE__ */ jsxs40("div", { className: "min-w-0 flex-1", children: [
46392
- /* @__PURE__ */ jsxs40("div", { className: "font-medium", children: [
46454
+ return /* @__PURE__ */ jsx47("div", { className: "blade-chat-render-error rounded-xl border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-4 py-3 text-sm text-[hsl(var(--foreground))]", children: /* @__PURE__ */ jsxs41("div", { className: "flex items-start gap-2", children: [
46455
+ /* @__PURE__ */ jsx47(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-[hsl(var(--swf-warning))]" }),
46456
+ /* @__PURE__ */ jsxs41("div", { className: "min-w-0 flex-1", children: [
46457
+ /* @__PURE__ */ jsxs41("div", { className: "font-medium", children: [
46393
46458
  label,
46394
46459
  "\u6E32\u67D3\u5931\u8D25"
46395
46460
  ] }),
46396
- /* @__PURE__ */ jsxs40("div", { className: "mt-1 break-words text-xs leading-5 text-[hsl(var(--secondary-foreground))]", children: [
46461
+ /* @__PURE__ */ jsxs41("div", { className: "mt-1 break-words text-xs leading-5 text-[hsl(var(--secondary-foreground))]", children: [
46397
46462
  componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
46398
46463
  error61.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
46399
46464
  ] }),
46400
- details ? /* @__PURE__ */ jsx46("div", { className: "mt-1 truncate text-xs text-[hsl(var(--muted-foreground))]", children: details }) : null
46465
+ details ? /* @__PURE__ */ jsx47("div", { className: "mt-1 truncate text-xs text-[hsl(var(--muted-foreground))]", children: details }) : null
46401
46466
  ] })
46402
46467
  ] }) });
46403
46468
  }
46404
46469
  };
46405
46470
 
46406
46471
  // src/chat/TurnNavRail.tsx
46407
- import { useCallback as useCallback13, useEffect as useEffect25, useLayoutEffect as useLayoutEffect6, useRef as useRef25, useState as useState31 } from "react";
46408
- import { jsx as jsx47, jsxs as jsxs41 } from "react/jsx-runtime";
46472
+ import { useCallback as useCallback13, useEffect as useEffect26, useLayoutEffect as useLayoutEffect6, useRef as useRef26, useState as useState32 } from "react";
46473
+ import { jsx as jsx48, jsxs as jsxs42 } from "react/jsx-runtime";
46409
46474
  var PANEL_MAX_HEIGHT = 448;
46410
46475
  var PANEL_MARGIN = 16;
46411
46476
  function clippingAncestor(element2) {
@@ -46426,14 +46491,14 @@ function TurnNavRail({
46426
46491
  error: error61 = null,
46427
46492
  failedTurnId = null
46428
46493
  }) {
46429
- const [hoveredTurnId, setHoveredTurnId] = useState31(null);
46430
- const [panelOpen, setPanelOpen] = useState31(false);
46431
- const listRef = useRef25(null);
46432
- const markerRef = useRef25(null);
46433
- const edgeRatioRef = useRef25(0.5);
46434
- const velocityRef = useRef25(0);
46435
- const rafRef = useRef25(null);
46436
- useEffect25(() => {
46494
+ const [hoveredTurnId, setHoveredTurnId] = useState32(null);
46495
+ const [panelOpen, setPanelOpen] = useState32(false);
46496
+ const listRef = useRef26(null);
46497
+ const markerRef = useRef26(null);
46498
+ const edgeRatioRef = useRef26(0.5);
46499
+ const velocityRef = useRef26(0);
46500
+ const rafRef = useRef26(null);
46501
+ useEffect26(() => {
46437
46502
  if (!panelOpen || hoveredTurnId == null) return;
46438
46503
  const list2 = listRef.current;
46439
46504
  if (!list2) return;
@@ -46442,7 +46507,7 @@ function TurnNavRail({
46442
46507
  );
46443
46508
  row?.scrollIntoView({ block: "nearest" });
46444
46509
  }, [panelOpen, hoveredTurnId]);
46445
- useEffect25(() => {
46510
+ useEffect26(() => {
46446
46511
  const rail = markerRef.current;
46447
46512
  if (!rail || !activeTurnId) return;
46448
46513
  const activeEl = Array.from(rail.querySelectorAll("[data-nav-id]")).find(
@@ -46476,7 +46541,7 @@ function TurnNavRail({
46476
46541
  if (!panelOpen) return;
46477
46542
  clampPanel();
46478
46543
  }, [panelOpen, items, clampPanel]);
46479
- useEffect25(() => {
46544
+ useEffect26(() => {
46480
46545
  if (!panelOpen) return;
46481
46546
  const container = clippingAncestor(markerRef.current);
46482
46547
  if (!container || typeof ResizeObserver === "undefined") return;
@@ -46526,7 +46591,7 @@ function TurnNavRail({
46526
46591
  const rect = el.getBoundingClientRect();
46527
46592
  edgeRatioRef.current = Math.min(1, Math.max(0, (event.clientY - rect.top) / rect.height));
46528
46593
  }, []);
46529
- useEffect25(
46594
+ useEffect26(
46530
46595
  () => () => {
46531
46596
  if (rafRef.current != null) cancelAnimationFrame(rafRef.current);
46532
46597
  },
@@ -46535,7 +46600,7 @@ function TurnNavRail({
46535
46600
  if (items.length < 2) {
46536
46601
  return null;
46537
46602
  }
46538
- return /* @__PURE__ */ jsx47(
46603
+ return /* @__PURE__ */ jsx48(
46539
46604
  "nav",
46540
46605
  {
46541
46606
  "aria-label": "\u56DE\u5408\u5BFC\u822A",
@@ -46550,8 +46615,8 @@ function TurnNavRail({
46550
46615
  setPanelOpen(false);
46551
46616
  setHoveredTurnId(null);
46552
46617
  },
46553
- children: /* @__PURE__ */ jsxs41("div", { className: "flex flex-col items-end", children: [
46554
- /* @__PURE__ */ jsxs41(
46618
+ children: /* @__PURE__ */ jsxs42("div", { className: "flex flex-col items-end", children: [
46619
+ /* @__PURE__ */ jsxs42(
46555
46620
  "div",
46556
46621
  {
46557
46622
  ref: markerRef,
@@ -46566,10 +46631,10 @@ function TurnNavRail({
46566
46631
  maskImage: "linear-gradient(to bottom, transparent, black 10%, black 90%, transparent)"
46567
46632
  },
46568
46633
  children: [
46569
- /* @__PURE__ */ jsx47("span", { "aria-hidden": true, className: "mt-auto shrink-0" }),
46634
+ /* @__PURE__ */ jsx48("span", { "aria-hidden": true, className: "mt-auto shrink-0" }),
46570
46635
  items.map((item, index2) => {
46571
46636
  const isActive = item.id === activeTurnId;
46572
- return /* @__PURE__ */ jsx47(
46637
+ return /* @__PURE__ */ jsx48(
46573
46638
  "button",
46574
46639
  {
46575
46640
  type: "button",
@@ -46579,7 +46644,7 @@ function TurnNavRail({
46579
46644
  "aria-current": isActive ? "true" : void 0,
46580
46645
  "aria-label": item.title || `\u7B2C ${index2 + 1} \u8F6E`,
46581
46646
  className: "flex h-3.5 shrink-0 items-center",
46582
- children: /* @__PURE__ */ jsx47(
46647
+ children: /* @__PURE__ */ jsx48(
46583
46648
  "span",
46584
46649
  {
46585
46650
  className: cn(
@@ -46595,18 +46660,18 @@ function TurnNavRail({
46595
46660
  item.id
46596
46661
  );
46597
46662
  }),
46598
- /* @__PURE__ */ jsx47("span", { "aria-hidden": true, className: "mb-auto shrink-0" })
46663
+ /* @__PURE__ */ jsx48("span", { "aria-hidden": true, className: "mb-auto shrink-0" })
46599
46664
  ]
46600
46665
  }
46601
46666
  ),
46602
- error61 ? /* @__PURE__ */ jsxs41(
46667
+ error61 ? /* @__PURE__ */ jsxs42(
46603
46668
  "div",
46604
46669
  {
46605
46670
  role: "alert",
46606
46671
  className: "absolute right-full top-1/2 mr-2 flex -translate-y-1/2 items-center gap-2 whitespace-nowrap rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--popover))] px-2.5 py-1 text-xs text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)]",
46607
46672
  children: [
46608
- /* @__PURE__ */ jsx47("span", { children: error61 }),
46609
- failedTurnId ? /* @__PURE__ */ jsx47(
46673
+ /* @__PURE__ */ jsx48("span", { children: error61 }),
46674
+ failedTurnId ? /* @__PURE__ */ jsx48(
46610
46675
  "button",
46611
46676
  {
46612
46677
  type: "button",
@@ -46617,12 +46682,12 @@ function TurnNavRail({
46617
46682
  ) : null
46618
46683
  ]
46619
46684
  }
46620
- ) : loadingTurnId ? /* @__PURE__ */ jsx47("output", { className: "absolute right-full top-1/2 mr-2 -translate-y-1/2 whitespace-nowrap rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--popover))] px-2.5 py-1 text-xs text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)]", children: "\u6B63\u5728\u5B9A\u4F4D\u5230\u8FD9\u6761\u53D1\u8A00\u2026" }) : null,
46685
+ ) : loadingTurnId ? /* @__PURE__ */ jsx48("output", { className: "absolute right-full top-1/2 mr-2 -translate-y-1/2 whitespace-nowrap rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--popover))] px-2.5 py-1 text-xs text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)]", children: "\u6B63\u5728\u5B9A\u4F4D\u5230\u8FD9\u6761\u53D1\u8A00\u2026" }) : null,
46621
46686
  panelOpen ? (
46622
46687
  // pr-2 让刻度与列表之间的空隙也算悬停区域,鼠标横穿时面板不会关闭。
46623
46688
  // 与刻度轨同心:顶对齐会让接近上限高度的面板整条往下长,聊天区是 overflow: hidden,
46624
46689
  // 视口矮一点下面的条目就被裁掉、滚也滚不到。高度同时受视口约束。
46625
- /* @__PURE__ */ jsx47("div", { className: "absolute right-full top-1/2 -translate-y-1/2 pr-2", children: /* @__PURE__ */ jsx47(
46690
+ /* @__PURE__ */ jsx48("div", { className: "absolute right-full top-1/2 -translate-y-1/2 pr-2", children: /* @__PURE__ */ jsx48(
46626
46691
  "div",
46627
46692
  {
46628
46693
  ref: listRef,
@@ -46630,7 +46695,7 @@ function TurnNavRail({
46630
46695
  children: items.map((item, index2) => {
46631
46696
  const isActive = item.id === activeTurnId;
46632
46697
  const isHovered = item.id === hoveredTurnId;
46633
- return /* @__PURE__ */ jsx47(
46698
+ return /* @__PURE__ */ jsx48(
46634
46699
  "button",
46635
46700
  {
46636
46701
  type: "button",
@@ -46709,7 +46774,7 @@ function calculateAnimatedScrollTop({
46709
46774
  }
46710
46775
 
46711
46776
  // src/chat/MessageList.tsx
46712
- import { Fragment as Fragment17, jsx as jsx48, jsxs as jsxs42 } from "react/jsx-runtime";
46777
+ import { Fragment as Fragment18, jsx as jsx49, jsxs as jsxs43 } from "react/jsx-runtime";
46713
46778
  function isReasoningRevealingForMessage(message, isRevealing, isStopping = false) {
46714
46779
  if (isStopping) return false;
46715
46780
  const hasContent = message?.content != null && message.content.length > 0;
@@ -46804,8 +46869,8 @@ function MessageListBody({
46804
46869
  const sessionIsStreaming = streamingOverride ?? stateIsStreaming;
46805
46870
  const isPreparing = sessionIsStreaming && isPreparingReply(messages);
46806
46871
  const agentLoopNameSet = useMemo16(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops]);
46807
- const assistantMessagesCacheRef = useRef26(/* @__PURE__ */ new Map());
46808
- const stickContextRef = useRef26(null);
46872
+ const assistantMessagesCacheRef = useRef27(/* @__PURE__ */ new Map());
46873
+ const stickContextRef = useRef27(null);
46809
46874
  const latestAssistantIndex = (() => {
46810
46875
  for (let i2 = messages.length - 1; i2 >= 0; i2 -= 1) {
46811
46876
  const candidate = messages[i2];
@@ -46826,10 +46891,10 @@ function MessageListBody({
46826
46891
  isStopping
46827
46892
  );
46828
46893
  const isRevealingAny = contentReveal.isRevealing || reasoningReveal.isRevealing;
46829
- useEffect26(() => {
46894
+ useEffect27(() => {
46830
46895
  onRevealingChange?.(isRevealingAny);
46831
46896
  }, [isRevealingAny, onRevealingChange]);
46832
- useEffect26(() => {
46897
+ useEffect27(() => {
46833
46898
  if (isStopping) {
46834
46899
  contentReveal.flushNow();
46835
46900
  reasoningReveal.flushNow();
@@ -46907,52 +46972,52 @@ function MessageListBody({
46907
46972
  const latestUserStableId = latestUserBlock?.message.render_id ?? latestUserAnchorId;
46908
46973
  const latestUserIsOptimistic = latestUserBlock?.message.entry_id?.startsWith("local-user-") ?? false;
46909
46974
  const effectiveNewUserMessageKey = latestUserIsOptimistic ? latestUserBlock?.key ?? latestUserAnchorId : null;
46910
- const containerRef = useRef26(null);
46911
- const scrollContainerRef = useRef26(null);
46912
- const virtualPrefixRef = useRef26(null);
46913
- const visibleTurnsRef = useRef26(/* @__PURE__ */ new Map());
46914
- const visibleBlockRowsRef = useRef26(/* @__PURE__ */ new Map());
46915
- const mountedTurnElementsRef = useRef26(/* @__PURE__ */ new Map());
46916
- const turnRefCallbacksRef = useRef26(
46975
+ const containerRef = useRef27(null);
46976
+ const scrollContainerRef = useRef27(null);
46977
+ const virtualPrefixRef = useRef27(null);
46978
+ const visibleTurnsRef = useRef27(/* @__PURE__ */ new Map());
46979
+ const visibleBlockRowsRef = useRef27(/* @__PURE__ */ new Map());
46980
+ const mountedTurnElementsRef = useRef27(/* @__PURE__ */ new Map());
46981
+ const turnRefCallbacksRef = useRef27(
46917
46982
  /* @__PURE__ */ new Map()
46918
46983
  );
46919
- const intersectionObserverRef = useRef26(null);
46920
- const measuredSizeByKeyRef = useRef26(/* @__PURE__ */ new Map());
46921
- const measuredRowElementsRef = useRef26(/* @__PURE__ */ new Map());
46922
- const rowRefCallbacksRef = useRef26(
46984
+ const intersectionObserverRef = useRef27(null);
46985
+ const measuredSizeByKeyRef = useRef27(/* @__PURE__ */ new Map());
46986
+ const measuredRowElementsRef = useRef27(/* @__PURE__ */ new Map());
46987
+ const rowRefCallbacksRef = useRef27(
46923
46988
  /* @__PURE__ */ new Map()
46924
46989
  );
46925
- const rowResizeObserverRef = useRef26(null);
46926
- const boundaryAnchorRef = useRef26(null);
46927
- const previousStablePrefixEndRef = useRef26(null);
46928
- const frameRef = useRef26(null);
46929
- const startScrollFrameRef = useRef26(null);
46930
- const startScrollTimeoutRef = useRef26(null);
46931
- const entryScrollFrameRef = useRef26(null);
46932
- const entryScrollTimeoutRefs = useRef26([]);
46933
- const appliedStartScrollKeyRef = useRef26(null);
46934
- const appliedEntryScrollKeyRef = useRef26(null);
46935
- const newTurnSpacerRef = useRef26(null);
46936
- const newTurnScrollFrameRef = useRef26(null);
46937
- const newTurnScrollTimeoutRef = useRef26(null);
46938
- const newTurnSpacerFrameRef = useRef26(null);
46939
- const newTurnAnimationFrameRef = useRef26(null);
46940
- const newTurnAnimationCleanupRef = useRef26(null);
46941
- const isAnimatingNewTurnRef = useRef26(false);
46942
- const heldStickToBottomRef = useRef26(false);
46943
- const pinnedScrollTopRef = useRef26(null);
46944
- const newTurnPinActiveRef = useRef26(false);
46945
- const appliedNewUserMessageKeyRef = useRef26(null);
46946
- const observedLatestUserAnchorRef = useRef26(
46990
+ const rowResizeObserverRef = useRef27(null);
46991
+ const boundaryAnchorRef = useRef27(null);
46992
+ const previousStablePrefixEndRef = useRef27(null);
46993
+ const frameRef = useRef27(null);
46994
+ const startScrollFrameRef = useRef27(null);
46995
+ const startScrollTimeoutRef = useRef27(null);
46996
+ const entryScrollFrameRef = useRef27(null);
46997
+ const entryScrollTimeoutRefs = useRef27([]);
46998
+ const appliedStartScrollKeyRef = useRef27(null);
46999
+ const appliedEntryScrollKeyRef = useRef27(null);
47000
+ const newTurnSpacerRef = useRef27(null);
47001
+ const newTurnScrollFrameRef = useRef27(null);
47002
+ const newTurnScrollTimeoutRef = useRef27(null);
47003
+ const newTurnSpacerFrameRef = useRef27(null);
47004
+ const newTurnAnimationFrameRef = useRef27(null);
47005
+ const newTurnAnimationCleanupRef = useRef27(null);
47006
+ const isAnimatingNewTurnRef = useRef27(false);
47007
+ const heldStickToBottomRef = useRef27(false);
47008
+ const pinnedScrollTopRef = useRef27(null);
47009
+ const newTurnPinActiveRef = useRef27(false);
47010
+ const appliedNewUserMessageKeyRef = useRef27(null);
47011
+ const observedLatestUserAnchorRef = useRef27(
46947
47012
  latestUserIsOptimistic ? null : latestUserAnchorId
46948
47013
  );
46949
- const observedLatestUserStableIdRef = useRef26(
47014
+ const observedLatestUserStableIdRef = useRef27(
46950
47015
  latestUserIsOptimistic ? null : latestUserStableId
46951
47016
  );
46952
- const [activeTurnId, setActiveTurnId] = useState32(lastTurnId);
46953
- const [virtualScrollMargin, setVirtualScrollMargin] = useState32(0);
46954
- const [scrollContainerElement, setScrollContainerElement] = useState32(null);
46955
- const loadingOlderRef = useRef26(false);
47017
+ const [activeTurnId, setActiveTurnId] = useState33(lastTurnId);
47018
+ const [virtualScrollMargin, setVirtualScrollMargin] = useState33(0);
47019
+ const [scrollContainerElement, setScrollContainerElement] = useState33(null);
47020
+ const loadingOlderRef = useRef27(false);
46956
47021
  const virtualizationEnabled = Boolean(useChatEnvironment().useVirtualizer);
46957
47022
  const stablePrefixEnd = useMemo16(
46958
47023
  () => virtualizationEnabled ? findStablePrefixEnd(renderBlocks) : 0,
@@ -47099,7 +47164,7 @@ function MessageListBody({
47099
47164
  measureActiveTurn();
47100
47165
  });
47101
47166
  });
47102
- useEffect26(() => {
47167
+ useEffect27(() => {
47103
47168
  void historyLoadRevision;
47104
47169
  scrollContainerRef.current = stickContextRef.current?.scrollRef.current ?? findScrollContainer(containerRef.current);
47105
47170
  const sc = scrollContainerRef.current;
@@ -47291,7 +47356,7 @@ function MessageListBody({
47291
47356
  previousStablePrefixEndRef.current = stablePrefixEnd;
47292
47357
  boundaryAnchorRef.current = captureBoundaryAnchor();
47293
47358
  }, [captureBoundaryAnchor, stablePrefixEnd]);
47294
- useEffect26(() => {
47359
+ useEffect27(() => {
47295
47360
  scheduleMeasure();
47296
47361
  }, [lastTurnId, layoutSignature]);
47297
47362
  const stopNewTurnScrollAnimation = useCallback14(() => {
@@ -47362,7 +47427,7 @@ function MessageListBody({
47362
47427
  placeLatestUserAtTop(anchorId);
47363
47428
  });
47364
47429
  });
47365
- useEffect26(() => {
47430
+ useEffect27(() => {
47366
47431
  const observer = new ResizeObserver((entries) => {
47367
47432
  for (const entry of entries) {
47368
47433
  const element2 = entry.target;
@@ -47498,14 +47563,14 @@ function MessageListBody({
47498
47563
  }
47499
47564
  }
47500
47565
  }, [stopNewTurnScrollAnimation]);
47501
- useEffect26(
47566
+ useEffect27(
47502
47567
  () => () => {
47503
47568
  cancelPendingNewTurnScroll();
47504
47569
  stopNewTurnScrollAnimation();
47505
47570
  },
47506
47571
  [cancelPendingNewTurnScroll, stopNewTurnScrollAnimation]
47507
47572
  );
47508
- useEffect26(() => {
47573
+ useEffect27(() => {
47509
47574
  const container = scrollContainerElement;
47510
47575
  if (!container) return;
47511
47576
  const handleScroll = () => {
@@ -47520,7 +47585,7 @@ function MessageListBody({
47520
47585
  container.addEventListener("scroll", handleScroll, { passive: true });
47521
47586
  return () => container.removeEventListener("scroll", handleScroll);
47522
47587
  }, [scrollContainerElement, releaseNewTurnPin]);
47523
- useEffect26(() => {
47588
+ useEffect27(() => {
47524
47589
  if (!effectiveNewUserMessageKey) {
47525
47590
  const acknowledgedSameTarget = newTurnPinActiveRef.current && latestUserStableId != null && observedLatestUserStableIdRef.current === latestUserStableId;
47526
47591
  observedLatestUserStableIdRef.current = latestUserStableId;
@@ -47556,7 +47621,7 @@ function MessageListBody({
47556
47621
  releaseNewTurnPin,
47557
47622
  sessionIsStreaming
47558
47623
  ]);
47559
- useEffect26(() => {
47624
+ useEffect27(() => {
47560
47625
  scheduleNewTurnSpacerUpdate();
47561
47626
  return () => {
47562
47627
  if (newTurnSpacerFrameRef.current != null) {
@@ -47565,11 +47630,11 @@ function MessageListBody({
47565
47630
  }
47566
47631
  };
47567
47632
  }, [layoutSignature]);
47568
- useEffect26(() => {
47633
+ useEffect27(() => {
47569
47634
  if (!newTurnPinActiveRef.current) return;
47570
47635
  scheduleNewTurnSpacerUpdate();
47571
47636
  }, [contentReveal.displayedText, reasoningReveal.displayedText]);
47572
- useEffect26(() => () => {
47637
+ useEffect27(() => () => {
47573
47638
  if (startScrollFrameRef.current != null) {
47574
47639
  window.cancelAnimationFrame(startScrollFrameRef.current);
47575
47640
  startScrollFrameRef.current = null;
@@ -47589,7 +47654,7 @@ function MessageListBody({
47589
47654
  appliedStartScrollKeyRef.current = null;
47590
47655
  appliedEntryScrollKeyRef.current = null;
47591
47656
  }, []);
47592
- useEffect26(() => {
47657
+ useEffect27(() => {
47593
47658
  if (!scrollToStartKey || !hasMessages) {
47594
47659
  if (startScrollFrameRef.current != null) window.cancelAnimationFrame(startScrollFrameRef.current);
47595
47660
  if (startScrollTimeoutRef.current != null) window.clearTimeout(startScrollTimeoutRef.current);
@@ -47661,7 +47726,7 @@ function MessageListBody({
47661
47726
  },
47662
47727
  [scrollEntryId]
47663
47728
  );
47664
- useEffect26(() => {
47729
+ useEffect27(() => {
47665
47730
  if (appliedEntryScrollKeyRef.current !== scrollEntryId) {
47666
47731
  if (entryScrollFrameRef.current != null) window.cancelAnimationFrame(entryScrollFrameRef.current);
47667
47732
  for (const timeoutId of entryScrollTimeoutRefs.current) window.clearTimeout(timeoutId);
@@ -47713,15 +47778,15 @@ function MessageListBody({
47713
47778
  stablePrefixEnd,
47714
47779
  virtualizer
47715
47780
  ]);
47716
- return /* @__PURE__ */ jsxs42(
47781
+ return /* @__PURE__ */ jsxs43(
47717
47782
  "div",
47718
47783
  {
47719
47784
  ref: containerRef,
47720
47785
  part: "messages",
47721
47786
  className: `blade-chat-messages relative min-h-0 flex-1 ${customization?.classNames?.messageListRoot ?? ""}`,
47722
47787
  children: [
47723
- !isPreparing && (sessionIsStreaming || isRevealingAny) ? /* @__PURE__ */ jsx48("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
47724
- turnNavItems.length > 1 ? /* @__PURE__ */ jsx48(
47788
+ !isPreparing && (sessionIsStreaming || isRevealingAny) ? /* @__PURE__ */ jsx49("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
47789
+ turnNavItems.length > 1 ? /* @__PURE__ */ jsx49(
47725
47790
  TurnNavRail,
47726
47791
  {
47727
47792
  items: turnNavItems,
@@ -47732,7 +47797,7 @@ function MessageListBody({
47732
47797
  failedTurnId: navFailedEntryId
47733
47798
  }
47734
47799
  ) : null,
47735
- /* @__PURE__ */ jsxs42(
47800
+ /* @__PURE__ */ jsxs43(
47736
47801
  StickToBottom,
47737
47802
  {
47738
47803
  contextRef: stickContextRef,
@@ -47741,7 +47806,7 @@ function MessageListBody({
47741
47806
  resize: stickyTurn ? { damping: 0.8, stiffness: 0.08, mass: 1 } : "instant",
47742
47807
  targetScrollTop: shouldAnchorEntry ? getAnchorTargetScrollTop : void 0,
47743
47808
  children: [
47744
- /* @__PURE__ */ jsxs42(
47809
+ /* @__PURE__ */ jsxs43(
47745
47810
  StickToBottom.Content,
47746
47811
  {
47747
47812
  part: "messages-scroll",
@@ -47750,7 +47815,7 @@ function MessageListBody({
47750
47815
  customization?.classNames?.messageListViewport
47751
47816
  ),
47752
47817
  children: [
47753
- /* @__PURE__ */ jsx48(
47818
+ /* @__PURE__ */ jsx49(
47754
47819
  MessageListContent,
47755
47820
  {
47756
47821
  askAnswers,
@@ -47785,12 +47850,12 @@ function MessageListBody({
47785
47850
  emptyState
47786
47851
  }
47787
47852
  ),
47788
- isPreparing ? /* @__PURE__ */ jsx48("div", { className: "mx-auto mt-3 max-w-[748px] px-4", children: /* @__PURE__ */ jsx48(ChatLoadingIndicator, { preparing: true }) }) : null,
47789
- /* @__PURE__ */ jsx48("div", { ref: newTurnSpacerRef, "aria-hidden": "true", className: "pointer-events-none w-full" })
47853
+ isPreparing ? /* @__PURE__ */ jsx49("div", { className: "mx-auto mt-3 max-w-[748px] px-4", children: /* @__PURE__ */ jsx49(ChatLoadingIndicator, { preparing: true }) }) : null,
47854
+ /* @__PURE__ */ jsx49("div", { ref: newTurnSpacerRef, "aria-hidden": "true", className: "pointer-events-none w-full" })
47790
47855
  ]
47791
47856
  }
47792
47857
  ),
47793
- /* @__PURE__ */ jsx48(ScrollToBottomButton, { onBeforeScroll: releaseNewTurnPin })
47858
+ /* @__PURE__ */ jsx49(ScrollToBottomButton, { onBeforeScroll: releaseNewTurnPin })
47794
47859
  ]
47795
47860
  },
47796
47861
  scrollEntryId ?? "latest"
@@ -47854,31 +47919,31 @@ function MessageListContent({
47854
47919
  };
47855
47920
  const RenderBlockView = (block, globalBlockIndex) => {
47856
47921
  if (block.type === "message") {
47857
- return /* @__PURE__ */ jsx48(
47922
+ return /* @__PURE__ */ jsx49(
47858
47923
  "div",
47859
47924
  {
47860
47925
  id: block.anchorId ?? void 0,
47861
47926
  "data-entry-id": block.message.entry_id,
47862
47927
  className: "msg-animate scroll-mt-6",
47863
- children: isBackgroundWakeMessage3(block.message) ? /* @__PURE__ */ jsx48(BackgroundWakeNotice, {}) : isUserMessage(block.message) ? customization?.components?.UserMessage ? /* @__PURE__ */ jsx48(
47928
+ children: isBackgroundWakeMessage3(block.message) ? /* @__PURE__ */ jsx49(BackgroundWakeNotice, {}) : isUserMessage(block.message) ? customization?.components?.UserMessage ? /* @__PURE__ */ jsx49(
47864
47929
  customization.components.UserMessage,
47865
47930
  {
47866
47931
  message: block.message,
47867
47932
  className: customization.classNames?.userMessage
47868
47933
  }
47869
- ) : /* @__PURE__ */ jsx48(
47934
+ ) : /* @__PURE__ */ jsx49(
47870
47935
  UserMessageBubble,
47871
47936
  {
47872
47937
  message: block.message,
47873
47938
  className: customization?.classNames?.userMessage
47874
47939
  }
47875
- ) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */ jsx48(
47940
+ ) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */ jsx49(
47876
47941
  customization.components.ErrorMessage,
47877
47942
  {
47878
47943
  message: block.message,
47879
47944
  className: customization.classNames?.errorMessage
47880
47945
  }
47881
- ) : /* @__PURE__ */ jsx48(
47946
+ ) : /* @__PURE__ */ jsx49(
47882
47947
  ErrorMessageBlock,
47883
47948
  {
47884
47949
  message: block.message,
@@ -47901,7 +47966,7 @@ function MessageListContent({
47901
47966
  const isHistoricalPlan = globalBlockIndex !== latestPlanCardBlockIndex;
47902
47967
  const blockFeedback = displayMessages.map((message) => message.entry_id && resultFeedbackByEntry.get(message.entry_id)).find((feedback) => feedback != null);
47903
47968
  const isActiveFollowup = block.anchorId === followupTurnId;
47904
- return /* @__PURE__ */ jsxs42(
47969
+ return /* @__PURE__ */ jsxs43(
47905
47970
  "div",
47906
47971
  {
47907
47972
  ref: getTurnElementRef(block.anchorId),
@@ -47910,13 +47975,13 @@ function MessageListContent({
47910
47975
  "data-entry-id": block.messages[0]?.entry_id,
47911
47976
  className: "msg-animate flex scroll-mt-6 flex-col gap-4",
47912
47977
  children: [
47913
- /* @__PURE__ */ jsx48(
47978
+ /* @__PURE__ */ jsx49(
47914
47979
  RenderErrorBoundary,
47915
47980
  {
47916
47981
  label: "\u52A9\u624B\u6D88\u606F",
47917
47982
  details: block.key,
47918
47983
  resetKey: getMessagesResetSignature(displayMessages),
47919
- children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx48(
47984
+ children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx49(
47920
47985
  customization.components.AssistantTurn,
47921
47986
  {
47922
47987
  turnKey: block.key,
@@ -47930,7 +47995,7 @@ function MessageListContent({
47930
47995
  sessionStatus,
47931
47996
  customization
47932
47997
  }
47933
- ) : /* @__PURE__ */ jsx48(
47998
+ ) : /* @__PURE__ */ jsx49(
47934
47999
  AssistantTurnBlock,
47935
48000
  {
47936
48001
  turnKey: block.key,
@@ -47947,13 +48012,13 @@ function MessageListContent({
47947
48012
  )
47948
48013
  }
47949
48014
  ),
47950
- showPlanCard ? /* @__PURE__ */ jsx48(
48015
+ showPlanCard ? /* @__PURE__ */ jsx49(
47951
48016
  RenderErrorBoundary,
47952
48017
  {
47953
48018
  label: "\u89C4\u5212\u6458\u8981",
47954
48019
  details: block.key,
47955
48020
  resetKey: `${sessionStatus ?? ""}:${layoutSignature}`,
47956
- children: /* @__PURE__ */ jsx48(
48021
+ children: /* @__PURE__ */ jsx49(
47957
48022
  PlanSummaryCard,
47958
48023
  {
47959
48024
  messages: extractPlanMessagesForTurn(messages, block.messages.at(-1)),
@@ -47965,8 +48030,8 @@ function MessageListContent({
47965
48030
  )
47966
48031
  }
47967
48032
  ) : null,
47968
- blockFeedback && !isActiveFollowup ? /* @__PURE__ */ jsx48(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
47969
- isActiveFollowup ? /* @__PURE__ */ jsx48(
48033
+ blockFeedback && !isActiveFollowup ? /* @__PURE__ */ jsx49(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
48034
+ isActiveFollowup ? /* @__PURE__ */ jsx49(
47970
48035
  PostChatFollowupBlock,
47971
48036
  {
47972
48037
  sessionId,
@@ -47981,7 +48046,7 @@ function MessageListContent({
47981
48046
  );
47982
48047
  }
47983
48048
  if (block.type === "compaction") {
47984
- return /* @__PURE__ */ jsx48("div", { className: "msg-animate", children: /* @__PURE__ */ jsx48(
48049
+ return /* @__PURE__ */ jsx49("div", { className: "msg-animate", children: /* @__PURE__ */ jsx49(
47985
48050
  CompactionCard,
47986
48051
  {
47987
48052
  sessionId,
@@ -47992,17 +48057,17 @@ function MessageListContent({
47992
48057
  }
47993
48058
  if (block.type === "context_group") {
47994
48059
  const contexts = block.messages.map((message) => message.context).filter((context) => Boolean(context));
47995
- return contexts.length > 0 ? /* @__PURE__ */ jsx48("div", { className: "msg-animate", "data-entry-id": block.messages[0].entry_id, children: /* @__PURE__ */ jsx48(ContextGroupCard, { contexts }) }) : null;
48060
+ return contexts.length > 0 ? /* @__PURE__ */ jsx49("div", { className: "msg-animate", "data-entry-id": block.messages[0].entry_id, children: /* @__PURE__ */ jsx49(ContextGroupCard, { contexts }) }) : null;
47996
48061
  }
47997
48062
  if (block.type === "context_divider") {
47998
- return /* @__PURE__ */ jsx48(ContextDivider, {});
48063
+ return /* @__PURE__ */ jsx49(ContextDivider, {});
47999
48064
  }
48000
- return /* @__PURE__ */ jsx48(PlanningDivider, { kind: block.kind });
48065
+ return /* @__PURE__ */ jsx49(PlanningDivider, { kind: block.kind });
48001
48066
  };
48002
48067
  const renderMeasuredRow = (block, globalBlockIndex, virtualItem) => {
48003
48068
  const persistentId = getRenderBlockPersistentId(block);
48004
48069
  const isVirtual = virtualItem !== void 0;
48005
- return /* @__PURE__ */ jsxs42(
48070
+ return /* @__PURE__ */ jsxs43(
48006
48071
  "div",
48007
48072
  {
48008
48073
  ref: getMeasuredRowRef(block, globalBlockIndex, isVirtual),
@@ -48022,31 +48087,31 @@ function MessageListContent({
48022
48087
  },
48023
48088
  children: [
48024
48089
  RenderBlockView(block, globalBlockIndex),
48025
- isVirtual && globalBlockIndex < stablePrefixEnd - 1 ? /* @__PURE__ */ jsx48("div", { "aria-hidden": "true", className: "h-0 shrink-0" }) : null
48090
+ isVirtual && globalBlockIndex < stablePrefixEnd - 1 ? /* @__PURE__ */ jsx49("div", { "aria-hidden": "true", className: "h-0 shrink-0" }) : null
48026
48091
  ]
48027
48092
  },
48028
48093
  block.key
48029
48094
  );
48030
48095
  };
48031
- return /* @__PURE__ */ jsx48(
48096
+ return /* @__PURE__ */ jsx49(
48032
48097
  "div",
48033
48098
  {
48034
48099
  part: "messages-content",
48035
48100
  className: `blade-chat-messages-content mx-auto max-w-[748px] ${customization?.classNames?.messageListContent ?? ""}`,
48036
- children: /* @__PURE__ */ jsxs42("div", { className: `min-w-0 flex flex-col gap-9 ${customization?.classNames?.messageListInner ?? ""}`, children: [
48037
- renderBlocks.length === 0 && isLoadingHistory ? /* @__PURE__ */ jsx48(HistoryLoadingPlaceholder, {}) : renderBlocks.length === 0 ? emptyState ? emptyState : customization?.components?.EmptyState ? /* @__PURE__ */ jsx48(customization.components.EmptyState, {}) : /* @__PURE__ */ jsxs42(
48101
+ children: /* @__PURE__ */ jsxs43("div", { className: `min-w-0 flex flex-col gap-9 ${customization?.classNames?.messageListInner ?? ""}`, children: [
48102
+ renderBlocks.length === 0 && isLoadingHistory ? /* @__PURE__ */ jsx49(HistoryLoadingPlaceholder, {}) : renderBlocks.length === 0 ? emptyState ? emptyState : customization?.components?.EmptyState ? /* @__PURE__ */ jsx49(customization.components.EmptyState, {}) : /* @__PURE__ */ jsxs43(
48038
48103
  "div",
48039
48104
  {
48040
48105
  part: "empty",
48041
48106
  className: `blade-chat-empty flex flex-col items-center justify-center gap-3 py-24 text-[hsl(var(--muted-foreground))] ${customization?.classNames?.emptyState ?? ""}`,
48042
48107
  children: [
48043
- /* @__PURE__ */ jsx48(MessageSquare, { size: 40, strokeWidth: 1.5 }),
48044
- /* @__PURE__ */ jsx48("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
48045
- /* @__PURE__ */ jsx48("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
48108
+ /* @__PURE__ */ jsx49(MessageSquare, { size: 40, strokeWidth: 1.5 }),
48109
+ /* @__PURE__ */ jsx49("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
48110
+ /* @__PURE__ */ jsx49("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
48046
48111
  ]
48047
48112
  }
48048
- ) : /* @__PURE__ */ jsxs42(Fragment17, { children: [
48049
- stablePrefixEnd > 0 ? /* @__PURE__ */ jsx48(
48113
+ ) : /* @__PURE__ */ jsxs43(Fragment18, { children: [
48114
+ stablePrefixEnd > 0 ? /* @__PURE__ */ jsx49(
48050
48115
  "div",
48051
48116
  {
48052
48117
  ref: virtualPrefixRef,
@@ -48063,23 +48128,23 @@ function MessageListContent({
48063
48128
  (block, residentIndex) => renderMeasuredRow(block, stablePrefixEnd + residentIndex)
48064
48129
  )
48065
48130
  ] }),
48066
- sessionStatus === "interrupted" && !hasInterruptedTurn ? /* @__PURE__ */ jsx48("div", { className: "flex", children: /* @__PURE__ */ jsx48("div", { className: "rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--swf-warning))]", children: "\u5DF2\u4E2D\u65AD" }) }) : null
48131
+ sessionStatus === "interrupted" && !hasInterruptedTurn ? /* @__PURE__ */ jsx49("div", { className: "flex", children: /* @__PURE__ */ jsx49("div", { className: "rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-2.5 py-1 text-[10px] font-medium text-[hsl(var(--swf-warning))]", children: "\u5DF2\u4E2D\u65AD" }) }) : null
48067
48132
  ] })
48068
48133
  }
48069
48134
  );
48070
48135
  }
48071
48136
  function HistoryLoadingPlaceholder() {
48072
- return /* @__PURE__ */ jsxs42("div", { className: "flex flex-col gap-9", "aria-busy": "true", "aria-live": "polite", children: [
48073
- /* @__PURE__ */ jsxs42("div", { className: "flex items-center justify-center gap-2 text-sm text-[hsl(var(--muted-foreground))]", children: [
48074
- /* @__PURE__ */ jsx48("span", { className: "size-3.5 animate-spin rounded-full border-2 border-current border-t-transparent" }),
48075
- /* @__PURE__ */ jsx48("span", { children: "\u6B63\u5728\u52A0\u8F7D\u5BF9\u8BDD\u8BB0\u5F55\u2026" })
48137
+ return /* @__PURE__ */ jsxs43("div", { className: "flex flex-col gap-9", "aria-busy": "true", "aria-live": "polite", children: [
48138
+ /* @__PURE__ */ jsxs43("div", { className: "flex items-center justify-center gap-2 text-sm text-[hsl(var(--muted-foreground))]", children: [
48139
+ /* @__PURE__ */ jsx49("span", { className: "size-3.5 animate-spin rounded-full border-2 border-current border-t-transparent" }),
48140
+ /* @__PURE__ */ jsx49("span", { children: "\u6B63\u5728\u52A0\u8F7D\u5BF9\u8BDD\u8BB0\u5F55\u2026" })
48076
48141
  ] }),
48077
- [0, 1].map((index2) => /* @__PURE__ */ jsxs42("div", { className: "flex flex-col gap-4", children: [
48078
- /* @__PURE__ */ jsx48("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx48("div", { className: "h-10 w-2/5 animate-pulse rounded-2xl bg-[hsl(var(--muted))]" }) }),
48079
- /* @__PURE__ */ jsxs42("div", { className: "flex flex-col gap-2.5", children: [
48080
- /* @__PURE__ */ jsx48("div", { className: "h-4 w-1/3 animate-pulse rounded bg-[hsl(var(--muted))]" }),
48081
- /* @__PURE__ */ jsx48("div", { className: "h-4 w-4/5 animate-pulse rounded bg-[hsl(var(--muted))]" }),
48082
- /* @__PURE__ */ jsx48("div", { className: "h-4 w-3/5 animate-pulse rounded bg-[hsl(var(--muted))]" })
48142
+ [0, 1].map((index2) => /* @__PURE__ */ jsxs43("div", { className: "flex flex-col gap-4", children: [
48143
+ /* @__PURE__ */ jsx49("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx49("div", { className: "h-10 w-2/5 animate-pulse rounded-2xl bg-[hsl(var(--muted))]" }) }),
48144
+ /* @__PURE__ */ jsxs43("div", { className: "flex flex-col gap-2.5", children: [
48145
+ /* @__PURE__ */ jsx49("div", { className: "h-4 w-1/3 animate-pulse rounded bg-[hsl(var(--muted))]" }),
48146
+ /* @__PURE__ */ jsx49("div", { className: "h-4 w-4/5 animate-pulse rounded bg-[hsl(var(--muted))]" }),
48147
+ /* @__PURE__ */ jsx49("div", { className: "h-4 w-3/5 animate-pulse rounded bg-[hsl(var(--muted))]" })
48083
48148
  ] })
48084
48149
  ] }, index2))
48085
48150
  ] });
@@ -48087,7 +48152,7 @@ function HistoryLoadingPlaceholder() {
48087
48152
  function ScrollToBottomButton({ onBeforeScroll }) {
48088
48153
  const { isAtBottom, scrollToBottom } = useStickToBottomContext();
48089
48154
  if (isAtBottom) return null;
48090
- return /* @__PURE__ */ jsxs42(
48155
+ return /* @__PURE__ */ jsxs43(
48091
48156
  "button",
48092
48157
  {
48093
48158
  type: "button",
@@ -48099,40 +48164,40 @@ function ScrollToBottomButton({ onBeforeScroll }) {
48099
48164
  part: "scroll-bottom",
48100
48165
  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-[var(--swf-shadow-overlay)] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
48101
48166
  children: [
48102
- /* @__PURE__ */ jsx48(ChevronDown, { size: 14 }),
48103
- /* @__PURE__ */ jsx48("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
48167
+ /* @__PURE__ */ jsx49(ChevronDown, { size: 14 }),
48168
+ /* @__PURE__ */ jsx49("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
48104
48169
  ]
48105
48170
  }
48106
48171
  );
48107
48172
  }
48108
48173
  function PlanningDivider({ kind }) {
48109
48174
  const isEnter = kind === "enter";
48110
- return /* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-3 py-1", children: [
48111
- /* @__PURE__ */ jsx48("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
48112
- /* @__PURE__ */ jsxs42("div", { className: "inline-flex items-center gap-1.5 rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-3 py-1 text-[11px] text-[hsl(var(--swf-warning))]", children: [
48113
- /* @__PURE__ */ jsx48(Lightbulb, { size: 12 }),
48114
- /* @__PURE__ */ jsx48("span", { children: isEnter ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
48175
+ return /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-3 py-1", children: [
48176
+ /* @__PURE__ */ jsx49("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
48177
+ /* @__PURE__ */ jsxs43("div", { className: "inline-flex items-center gap-1.5 rounded-full border border-[hsl(var(--swf-warning)/0.3)] bg-[hsl(var(--swf-warning-soft))] px-3 py-1 text-[11px] text-[hsl(var(--swf-warning))]", children: [
48178
+ /* @__PURE__ */ jsx49(Lightbulb, { size: 12 }),
48179
+ /* @__PURE__ */ jsx49("span", { children: isEnter ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
48115
48180
  ] }),
48116
- /* @__PURE__ */ jsx48("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
48181
+ /* @__PURE__ */ jsx49("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
48117
48182
  ] });
48118
48183
  }
48119
48184
  function ContextDivider() {
48120
- return /* @__PURE__ */ jsx48("div", { "aria-hidden": "true", className: "h-px w-full bg-[hsl(var(--border)/0.55)]" });
48185
+ return /* @__PURE__ */ jsx49("div", { "aria-hidden": "true", className: "h-px w-full bg-[hsl(var(--border)/0.55)]" });
48121
48186
  }
48122
48187
  function MessageList(props) {
48123
- return /* @__PURE__ */ jsx48(CurrentChatSessionProvider, { sessionId: props.sessionId || null, children: /* @__PURE__ */ jsx48(MessageListBody, { ...props }) });
48188
+ return /* @__PURE__ */ jsx49(CurrentChatSessionProvider, { sessionId: props.sessionId || null, children: /* @__PURE__ */ jsx49(MessageListBody, { ...props }) });
48124
48189
  }
48125
48190
 
48126
48191
  // src/chat/runtime/use-chat-actions.ts
48127
- import { useCallback as useCallback15, useEffect as useEffect27, useRef as useRef27, useState as useState33 } from "react";
48192
+ import { useCallback as useCallback15, useEffect as useEffect28, useRef as useRef28, useState as useState34 } from "react";
48128
48193
  function useChatActions(sessionId) {
48129
48194
  const source = useSessionSource();
48130
48195
  const session = useSessionHandle(sessionId);
48131
48196
  const isStreaming = useSessionState(sessionId, (state) => state.isStreaming);
48132
- const [isStopping, setIsStopping] = useState33(false);
48133
- const [queueNotice, setQueueNotice] = useState33(null);
48134
- const [pendingQueueItemId, setPendingQueueItemId] = useState33(null);
48135
- const previousSessionIdRef = useRef27(sessionId);
48197
+ const [isStopping, setIsStopping] = useState34(false);
48198
+ const [queueNotice, setQueueNotice] = useState34(null);
48199
+ const [pendingQueueItemId, setPendingQueueItemId] = useState34(null);
48200
+ const previousSessionIdRef = useRef28(sessionId);
48136
48201
  const send = useCallback15(
48137
48202
  (msg, targetMode, askuserAnswer, options) => (
48138
48203
  // 等会话就绪再发:等待回答时要按最新状态把输入当作作答
@@ -48199,7 +48264,7 @@ function useChatActions(sessionId) {
48199
48264
  setIsStopping(false);
48200
48265
  }
48201
48266
  }, [isStopping, session, sessionId, source]);
48202
- useEffect27(() => {
48267
+ useEffect28(() => {
48203
48268
  if (previousSessionIdRef.current !== sessionId) {
48204
48269
  previousSessionIdRef.current = sessionId;
48205
48270
  setIsStopping(false);
@@ -48264,14 +48329,14 @@ function useSessionReplay(sessionId) {
48264
48329
  }
48265
48330
 
48266
48331
  // src/chat/SessionReplayBar.tsx
48267
- import { jsx as jsx49 } from "react/jsx-runtime";
48332
+ import { jsx as jsx50 } from "react/jsx-runtime";
48268
48333
  function SessionReplayBar({
48269
48334
  sessionId,
48270
48335
  className,
48271
48336
  onExit
48272
48337
  }) {
48273
48338
  const { isReplay, canControl, speed, setSpeed, exitToAutonomous } = useSessionReplay(sessionId);
48274
- return /* @__PURE__ */ jsx49(
48339
+ return /* @__PURE__ */ jsx50(
48275
48340
  ReplayBar,
48276
48341
  {
48277
48342
  isReplay,
@@ -48285,7 +48350,7 @@ function SessionReplayBar({
48285
48350
  }
48286
48351
 
48287
48352
  // src/chat/ChatPanel.tsx
48288
- import { Fragment as Fragment18, jsx as jsx50, jsxs as jsxs43 } from "react/jsx-runtime";
48353
+ import { Fragment as Fragment19, jsx as jsx51, jsxs as jsxs44 } from "react/jsx-runtime";
48289
48354
  function nextQueuedOrder(items, itemId, delta) {
48290
48355
  const pending = items.filter((item) => item.status === "pending");
48291
48356
  const index2 = pending.findIndex((item) => item.id === itemId);
@@ -48366,12 +48431,12 @@ function ChatPanel({
48366
48431
  deliverQueuedMessage,
48367
48432
  resumeQueue
48368
48433
  } = useChatActions(sessionId);
48369
- const [isRevealing, setIsRevealing] = useState34(false);
48434
+ const [isRevealing, setIsRevealing] = useState35(false);
48370
48435
  const isStreamingDisplay = isStreaming || isRevealing;
48371
48436
  const detail = useChatSessionDetail(sessionId);
48372
48437
  const { isReplay } = useSessionReplay(sessionId);
48373
48438
  const isLoadingHistory = useIsSessionHistoryLoading(sessionId);
48374
- const [queuePanelVisible, setQueuePanelVisible] = useState34(false);
48439
+ const [queuePanelVisible, setQueuePanelVisible] = useState35(false);
48375
48440
  const loadOlder = useCallback17(
48376
48441
  async (beforeCommit) => {
48377
48442
  if (!agentSession) return false;
@@ -48381,11 +48446,11 @@ function ChatPanel({
48381
48446
  },
48382
48447
  [agentSession]
48383
48448
  );
48384
- const [paginationActivation, setPaginationActivation] = useState34(() => ({
48449
+ const [paginationActivation, setPaginationActivation] = useState35(() => ({
48385
48450
  sessionId,
48386
48451
  activated: Boolean(nextBefore)
48387
48452
  }));
48388
- useEffect28(() => {
48453
+ useEffect29(() => {
48389
48454
  setPaginationActivation((current) => {
48390
48455
  if (current.sessionId !== sessionId) {
48391
48456
  return { sessionId, activated: Boolean(nextBefore) };
@@ -48402,8 +48467,8 @@ function ChatPanel({
48402
48467
  const isViewer = (viewerRole ?? detail?.viewer_role) === "viewer";
48403
48468
  const isCompacting = activeCompaction != null || compactionPending;
48404
48469
  const postChatFollowup = useMemo17(() => latestPostChatFollowup(turns), [turns]);
48405
- const [resultFeedback, setResultFeedback] = useState34([]);
48406
- useEffect28(() => {
48470
+ const [resultFeedback, setResultFeedback] = useState35([]);
48471
+ useEffect29(() => {
48407
48472
  setResultFeedback([]);
48408
48473
  if (isViewer || !sessionId) return;
48409
48474
  let cancelled = false;
@@ -48445,6 +48510,7 @@ function ChatPanel({
48445
48510
  thinkingOverride: options?.thinkingOverride,
48446
48511
  reasoningLevel: options?.reasoningLevel,
48447
48512
  refs: options?.refs,
48513
+ contextAttachments: options?.contextAttachments,
48448
48514
  topicAssetRefs: options?.topicAssetRefs,
48449
48515
  queueWhenRunning: options?.queueWhenRunning
48450
48516
  });
@@ -48513,7 +48579,7 @@ function ChatPanel({
48513
48579
  onCommand,
48514
48580
  canCreateBoardTask,
48515
48581
  canShareSession,
48516
- planPanel: !lite ? /* @__PURE__ */ jsx50(CurrentPlanPanel, { sessionId, className: "border-b border-[hsl(var(--border))] px-4" }) : null,
48582
+ planPanel: !lite ? /* @__PURE__ */ jsx51(CurrentPlanPanel, { sessionId, className: "border-b border-[hsl(var(--border))] px-4" }) : null,
48517
48583
  maxWidthClassName: cn("max-w-3xl", classNames?.chatInputInner),
48518
48584
  // 队列面板此刻占位时,输入框上两角改直角,跟它拼成一条完整轮廓。
48519
48585
  // 用面板自己上报的状态,不在宿主侧复算。
@@ -48538,14 +48604,14 @@ function ChatPanel({
48538
48604
  initialDraftKey,
48539
48605
  lite
48540
48606
  };
48541
- return /* @__PURE__ */ jsx50(CurrentChatSessionProvider, { sessionId: sessionId || null, children: /* @__PURE__ */ jsx50(ChatCustomizationProvider, { value: customization, children: /* @__PURE__ */ jsx50(FollowupInteractionProvider, { value: onFollowupInteraction, children: /* @__PURE__ */ jsx50(McpAppMessageContext.Provider, { value: handleMcpAppMessage, children: /* @__PURE__ */ jsxs43(
48607
+ return /* @__PURE__ */ jsx51(CurrentChatSessionProvider, { sessionId: sessionId || null, children: /* @__PURE__ */ jsx51(ChatCustomizationProvider, { value: customization, children: /* @__PURE__ */ jsx51(FollowupInteractionProvider, { value: onFollowupInteraction, children: /* @__PURE__ */ jsx51(McpAppMessageContext.Provider, { value: handleMcpAppMessage, children: /* @__PURE__ */ jsxs44(
48542
48608
  "div",
48543
48609
  {
48544
48610
  "data-theme": theme,
48545
48611
  part: "root",
48546
48612
  className: cn("blade-chat flex min-h-0 flex-1 flex-col overflow-hidden", classNames?.root),
48547
48613
  children: [
48548
- isViewer && /* @__PURE__ */ jsxs43(
48614
+ isViewer && /* @__PURE__ */ jsxs44(
48549
48615
  "div",
48550
48616
  {
48551
48617
  className: cn(
@@ -48553,27 +48619,27 @@ function ChatPanel({
48553
48619
  classNames?.viewerBanner
48554
48620
  ),
48555
48621
  children: [
48556
- /* @__PURE__ */ jsx50(Eye, { size: 14 }),
48622
+ /* @__PURE__ */ jsx51(Eye, { size: 14 }),
48557
48623
  "\u4F60\u6B63\u5728\u67E5\u770B\u5206\u4EAB\u7684\u4F1A\u8BDD\uFF08\u53EA\u8BFB\uFF09"
48558
48624
  ]
48559
48625
  }
48560
48626
  ),
48561
- !isViewer && /* @__PURE__ */ jsx50(ConnectionBanner, { connection }),
48627
+ !isViewer && /* @__PURE__ */ jsx51(ConnectionBanner, { connection }),
48562
48628
  banner,
48563
- /* @__PURE__ */ jsx50(SessionReplayBar, { sessionId, onExit: onExitReplay }),
48564
- errorMessage && /* @__PURE__ */ jsxs43(
48629
+ /* @__PURE__ */ jsx51(SessionReplayBar, { sessionId, onExit: onExitReplay }),
48630
+ errorMessage && /* @__PURE__ */ jsxs44(
48565
48631
  "div",
48566
48632
  {
48567
48633
  part: "error-bar",
48568
48634
  className: "blade-chat-error-bar flex items-start gap-2 border-b border-[hsl(var(--swf-danger)/0.3)] bg-[hsl(var(--swf-danger-soft))] px-4 py-3 text-sm text-[hsl(var(--swf-danger))]",
48569
48635
  children: [
48570
- /* @__PURE__ */ jsx50(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
48571
- /* @__PURE__ */ jsx50("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay3(errorMessage, developer) })
48636
+ /* @__PURE__ */ jsx51(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
48637
+ /* @__PURE__ */ jsx51("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay3(errorMessage, developer) })
48572
48638
  ]
48573
48639
  }
48574
48640
  ),
48575
48641
  header,
48576
- developer && DeveloperMessageList ? /* @__PURE__ */ jsx50(
48642
+ developer && DeveloperMessageList ? /* @__PURE__ */ jsx51(
48577
48643
  DeveloperMessageList,
48578
48644
  {
48579
48645
  sessionId,
@@ -48594,7 +48660,7 @@ function ChatPanel({
48594
48660
  isReplay
48595
48661
  },
48596
48662
  sessionId
48597
- ) : lite ? /* @__PURE__ */ jsx50(
48663
+ ) : lite ? /* @__PURE__ */ jsx51(
48598
48664
  LiteMessageList,
48599
48665
  {
48600
48666
  sessionId,
@@ -48611,7 +48677,7 @@ function ChatPanel({
48611
48677
  onAnswer: isViewer ? void 0 : answerQuestion
48612
48678
  },
48613
48679
  sessionId
48614
- ) : /* @__PURE__ */ jsx50(
48680
+ ) : /* @__PURE__ */ jsx51(
48615
48681
  MessageList,
48616
48682
  {
48617
48683
  sessionId,
@@ -48637,15 +48703,15 @@ function ChatPanel({
48637
48703
  },
48638
48704
  sessionId
48639
48705
  ),
48640
- isViewer && !lite ? /* @__PURE__ */ jsx50(
48706
+ isViewer && !lite ? /* @__PURE__ */ jsx51(
48641
48707
  CurrentPlanPanel,
48642
48708
  {
48643
48709
  sessionId,
48644
48710
  className: cn("mx-auto w-full max-w-3xl px-5 pb-3", classNames?.chatInputInner)
48645
48711
  }
48646
48712
  ) : null,
48647
- !isViewer && /* @__PURE__ */ jsxs43(Fragment18, { children: [
48648
- /* @__PURE__ */ jsx50(
48713
+ !isViewer && /* @__PURE__ */ jsxs44(Fragment19, { children: [
48714
+ /* @__PURE__ */ jsx51(
48649
48715
  SessionQueuePanel,
48650
48716
  {
48651
48717
  snapshot: queue,
@@ -48666,7 +48732,7 @@ function ChatPanel({
48666
48732
  },
48667
48733
  sessionId
48668
48734
  ),
48669
- /* @__PURE__ */ jsx50(Composer, { ...composerProps })
48735
+ /* @__PURE__ */ jsx51(Composer, { ...composerProps })
48670
48736
  ] }),
48671
48737
  footer
48672
48738
  ]
@@ -48675,15 +48741,15 @@ function ChatPanel({
48675
48741
  }
48676
48742
 
48677
48743
  // src/components/SessionPluginSelector.tsx
48678
- import { useEffect as useEffect29, useState as useState35 } from "react";
48679
- import { jsx as jsx51, jsxs as jsxs44 } from "react/jsx-runtime";
48744
+ import { useEffect as useEffect30, useState as useState36 } from "react";
48745
+ import { jsx as jsx52, jsxs as jsxs45 } from "react/jsx-runtime";
48680
48746
  function SessionPluginSelector(props) {
48681
- return /* @__PURE__ */ jsx51(PluginSelectorState, { ...props }, props.sessionId);
48747
+ return /* @__PURE__ */ jsx52(PluginSelectorState, { ...props }, props.sessionId);
48682
48748
  }
48683
48749
  function PluginSelectorState({ client, sessionId, className, side = "bottom", onChange }) {
48684
- const [open2, setOpen] = useState35(false);
48685
- return /* @__PURE__ */ jsxs44("div", { className: `relative text-xs ${className ?? ""}`, children: [
48686
- /* @__PURE__ */ jsx51(
48750
+ const [open2, setOpen] = useState36(false);
48751
+ return /* @__PURE__ */ jsxs45("div", { className: `relative text-xs ${className ?? ""}`, children: [
48752
+ /* @__PURE__ */ jsx52(
48687
48753
  "button",
48688
48754
  {
48689
48755
  type: "button",
@@ -48694,7 +48760,7 @@ function PluginSelectorState({ client, sessionId, className, side = "bottom", on
48694
48760
  children: "\u4F1A\u8BDD\u63D2\u4EF6"
48695
48761
  }
48696
48762
  ),
48697
- open2 ? /* @__PURE__ */ jsx51(PluginSelectorList, { client, sessionId, side, onChange }) : null
48763
+ open2 ? /* @__PURE__ */ jsx52(PluginSelectorList, { client, sessionId, side, onChange }) : null
48698
48764
  ] });
48699
48765
  }
48700
48766
  function PluginSelectorList({
@@ -48705,16 +48771,16 @@ function PluginSelectorList({
48705
48771
  }) {
48706
48772
  const controller = useSessionPluginActivation({ client, sessionId, onChange });
48707
48773
  const { reload } = controller;
48708
- useEffect29(() => {
48774
+ useEffect30(() => {
48709
48775
  reload();
48710
48776
  }, [reload]);
48711
- return /* @__PURE__ */ jsxs44(
48777
+ return /* @__PURE__ */ jsxs45(
48712
48778
  "div",
48713
48779
  {
48714
48780
  className: `absolute left-0 z-40 my-2 max-h-72 w-72 max-w-[calc(100vw-2rem)] overflow-y-auto rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-3 text-[hsl(var(--popover-foreground))] shadow-lg ${side === "top" ? "bottom-full" : "top-full"}`,
48715
48781
  children: [
48716
- controller.listError ? /* @__PURE__ */ jsx51("button", { type: "button", onClick: reload, children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5" }) : null,
48717
- /* @__PURE__ */ jsx51(
48782
+ controller.listError ? /* @__PURE__ */ jsx52("button", { type: "button", onClick: reload, children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5" }) : null,
48783
+ /* @__PURE__ */ jsx52(
48718
48784
  PluginConnectorList,
48719
48785
  {
48720
48786
  client,
@@ -48738,13 +48804,13 @@ function PluginSelectorList({
48738
48804
  }
48739
48805
 
48740
48806
  // src/components/AgentChat.tsx
48741
- import { Fragment as Fragment19, jsx as jsx52, jsxs as jsxs45 } from "react/jsx-runtime";
48807
+ import { Fragment as Fragment20, jsx as jsx53, jsxs as jsxs46 } from "react/jsx-runtime";
48742
48808
  function isUnauthorizedError(error61) {
48743
48809
  return error61 instanceof BladeApiError2 && error61.status === 401;
48744
48810
  }
48745
48811
  function LoginCard({ client, onLoggedIn }) {
48746
- const [loggingIn, setLoggingIn] = useState36(false);
48747
- const [loginError, setLoginError] = useState36(null);
48812
+ const [loggingIn, setLoggingIn] = useState37(false);
48813
+ const [loginError, setLoginError] = useState37(null);
48748
48814
  const handleLogin = async () => {
48749
48815
  setLoggingIn(true);
48750
48816
  setLoginError(null);
@@ -48757,11 +48823,11 @@ function LoginCard({ client, onLoggedIn }) {
48757
48823
  setLoggingIn(false);
48758
48824
  }
48759
48825
  };
48760
- return /* @__PURE__ */ jsx52("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs45("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: [
48761
- /* @__PURE__ */ jsx52(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
48762
- /* @__PURE__ */ jsx52("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
48763
- /* @__PURE__ */ jsx52("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" }),
48764
- /* @__PURE__ */ jsx52(
48826
+ return /* @__PURE__ */ jsx53("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs46("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: [
48827
+ /* @__PURE__ */ jsx53(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
48828
+ /* @__PURE__ */ jsx53("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
48829
+ /* @__PURE__ */ jsx53("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" }),
48830
+ /* @__PURE__ */ jsx53(
48765
48831
  "button",
48766
48832
  {
48767
48833
  type: "button",
@@ -48771,21 +48837,21 @@ function LoginCard({ client, onLoggedIn }) {
48771
48837
  children: loggingIn ? "\u767B\u5F55\u4E2D\u2026" : "\u767B\u5F55"
48772
48838
  }
48773
48839
  ),
48774
- loginError && /* @__PURE__ */ jsx52("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
48840
+ loginError && /* @__PURE__ */ jsx53("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
48775
48841
  ] }) });
48776
48842
  }
48777
48843
  function AgentChat(props) {
48778
48844
  const client = useBladeClient();
48779
- const [attempt, setAttempt] = useState36(0);
48780
- const [needLogin, setNeedLogin] = useState36(() => !client.hasToken());
48845
+ const [attempt, setAttempt] = useState37(0);
48846
+ const [needLogin, setNeedLogin] = useState37(() => !client.hasToken());
48781
48847
  if (needLogin) {
48782
- return /* @__PURE__ */ jsx52(
48848
+ return /* @__PURE__ */ jsx53(
48783
48849
  "div",
48784
48850
  {
48785
48851
  "data-theme": props.theme,
48786
48852
  part: "root",
48787
48853
  className: cn("blade-chat flex min-h-0 flex-1 flex-col", props.classNames?.root),
48788
- children: /* @__PURE__ */ jsx52(
48854
+ children: /* @__PURE__ */ jsx53(
48789
48855
  LoginCard,
48790
48856
  {
48791
48857
  client,
@@ -48798,7 +48864,7 @@ function AgentChat(props) {
48798
48864
  }
48799
48865
  );
48800
48866
  }
48801
- return /* @__PURE__ */ jsx52(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
48867
+ return /* @__PURE__ */ jsx53(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
48802
48868
  }
48803
48869
  function ChatSessionView({
48804
48870
  sessionId,
@@ -48822,33 +48888,33 @@ function ChatSessionView({
48822
48888
  onSessionCreated
48823
48889
  });
48824
48890
  const replay = useReplay(session);
48825
- const [notice, setNotice] = useState36(null);
48891
+ const [notice, setNotice] = useState37(null);
48826
48892
  const source = useSingleSessionSource(session, !session || state === null);
48827
48893
  const resolvedSessionId = session?.sessionId;
48828
48894
  const isViewer = state?.viewerRole === "viewer";
48829
48895
  const replaySpeed = state?.replay?.speed;
48830
48896
  const replaying = state?.replay?.isReplay;
48831
- useEffect30(() => {
48897
+ useEffect31(() => {
48832
48898
  setNotice(null);
48833
48899
  }, [resolvedSessionId, replaySpeed, replaying]);
48834
- const onSessionReadyRef = useRef28(onSessionReady);
48835
- const readySessionRef = useRef28(null);
48900
+ const onSessionReadyRef = useRef29(onSessionReady);
48901
+ const readySessionRef = useRef29(null);
48836
48902
  const hasOnSessionReady = onSessionReady !== void 0;
48837
- useEffect30(() => {
48903
+ useEffect31(() => {
48838
48904
  onSessionReadyRef.current = onSessionReady;
48839
48905
  }, [onSessionReady]);
48840
- useEffect30(() => {
48906
+ useEffect31(() => {
48841
48907
  const handler = onSessionReadyRef.current;
48842
48908
  if (!session || !hasOnSessionReady || !handler || readySessionRef.current === session) return;
48843
48909
  readySessionRef.current = session;
48844
48910
  handler(session);
48845
48911
  }, [session, hasOnSessionReady]);
48846
- useEffect30(() => {
48912
+ useEffect31(() => {
48847
48913
  if (isUnauthorizedError(error61)) {
48848
48914
  onUnauthorized();
48849
48915
  }
48850
48916
  }, [error61, onUnauthorized]);
48851
- useEffect30(() => {
48917
+ useEffect31(() => {
48852
48918
  if (!session || !commands) return;
48853
48919
  const unsubscribes = Object.entries(commands).map(
48854
48920
  ([action, handler]) => session.onCommand(action, (payload) => handler(payload))
@@ -48867,7 +48933,7 @@ function ChatSessionView({
48867
48933
  );
48868
48934
  const connectError = error61 && !isUnauthorizedError(error61) ? error61.message || "\u8FDE\u63A5\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5" : null;
48869
48935
  const sessionClient = resolvedSessionId && createOptions?.anonymous && !client.options.anonymousSessionId ? client.forAnonymousSession(resolvedSessionId) : client;
48870
- return /* @__PURE__ */ jsx52(BladeProvider, { client: sessionClient, host, children: /* @__PURE__ */ jsx52(SessionSourceProvider, { source, children: /* @__PURE__ */ jsx52(ChatEnvironmentProvider, { value: environment, children: /* @__PURE__ */ jsx52(
48936
+ return /* @__PURE__ */ jsx53(BladeProvider, { client: sessionClient, host, children: /* @__PURE__ */ jsx53(SessionSourceProvider, { source, children: /* @__PURE__ */ jsx53(ChatEnvironmentProvider, { value: environment, children: /* @__PURE__ */ jsx53(
48871
48937
  ChatPanel,
48872
48938
  {
48873
48939
  sessionId: resolvedSessionId ?? "",
@@ -48881,9 +48947,9 @@ function ChatSessionView({
48881
48947
  onFollowupInteraction,
48882
48948
  errorMessage: connectError ?? replay.error?.message ?? notice,
48883
48949
  onExitReplay: () => void replay.exitToAutonomous(),
48884
- banner: /* @__PURE__ */ jsxs45(Fragment19, { children: [
48885
- resolvedSessionId && !isViewer && (sessionPluginControls ? sessionPluginControls(resolvedSessionId) : client.options.anonymousSessionId || createOptions?.anonymous ? null : /* @__PURE__ */ jsx52(SessionPluginSelector, { client, sessionId: resolvedSessionId })),
48886
- /* @__PURE__ */ jsx52(ReplayMismatchPrompt, { mismatch: replay.mismatch })
48950
+ banner: /* @__PURE__ */ jsxs46(Fragment20, { children: [
48951
+ resolvedSessionId && !isViewer && (sessionPluginControls ? sessionPluginControls(resolvedSessionId) : client.options.anonymousSessionId || createOptions?.anonymous ? null : /* @__PURE__ */ jsx53(SessionPluginSelector, { client, sessionId: resolvedSessionId })),
48952
+ /* @__PURE__ */ jsx53(ReplayMismatchPrompt, { mismatch: replay.mismatch })
48887
48953
  ] })
48888
48954
  }
48889
48955
  ) }) }) });
@@ -48891,26 +48957,26 @@ function ChatSessionView({
48891
48957
 
48892
48958
  // src/components/LlmChat.tsx
48893
48959
  import { chatErrorForDisplay as chatErrorForDisplay4 } from "@blade-hq/agent-client/internal";
48894
- import { useEffect as useEffect31, useMemo as useMemo20, useState as useState39 } from "react";
48960
+ import { useEffect as useEffect32, useMemo as useMemo20, useState as useState40 } from "react";
48895
48961
 
48896
48962
  // src/hooks/use-llm-chat.ts
48897
- import { useCallback as useCallback18, useMemo as useMemo19, useRef as useRef29, useState as useState37 } from "react";
48963
+ import { useCallback as useCallback18, useMemo as useMemo19, useRef as useRef30, useState as useState38 } from "react";
48898
48964
  var DEFAULT_HISTORY_TURNS = 12;
48899
48965
  var DEFAULT_MAX_TOOL_ROUNDS = 4;
48900
48966
  var syntheticIdSeq = 0;
48901
48967
  function useLlmChat(options) {
48902
- const [history, setHistory] = useState37([]);
48903
- const [streamingText, setStreamingText] = useState37(null);
48904
- const [streamingCalls, setStreamingCalls] = useState37([]);
48905
- const [failedToolIds, setFailedToolIds] = useState37([]);
48906
- const [error61, setError] = useState37(null);
48907
- const [isStreaming, setIsStreaming] = useState37(false);
48908
- const abortRef = useRef29(null);
48909
- const activeStartedAtRef = useRef29(null);
48910
- const assistantTimingsRef = useRef29(/* @__PURE__ */ new WeakMap());
48911
- const generationRef = useRef29(0);
48912
- const historyRef = useRef29([]);
48913
- const optionsRef = useRef29(options);
48968
+ const [history, setHistory] = useState38([]);
48969
+ const [streamingText, setStreamingText] = useState38(null);
48970
+ const [streamingCalls, setStreamingCalls] = useState38([]);
48971
+ const [failedToolIds, setFailedToolIds] = useState38([]);
48972
+ const [error61, setError] = useState38(null);
48973
+ const [isStreaming, setIsStreaming] = useState38(false);
48974
+ const abortRef = useRef30(null);
48975
+ const activeStartedAtRef = useRef30(null);
48976
+ const assistantTimingsRef = useRef30(/* @__PURE__ */ new WeakMap());
48977
+ const generationRef = useRef30(0);
48978
+ const historyRef = useRef30([]);
48979
+ const optionsRef = useRef30(options);
48914
48980
  optionsRef.current = options;
48915
48981
  historyRef.current = history;
48916
48982
  const stop = useCallback18(() => {
@@ -49250,8 +49316,8 @@ function toToolCallInfo(call, results, failedToolIds) {
49250
49316
  }
49251
49317
 
49252
49318
  // src/components/LlmAdvancedSettings.tsx
49253
- import { useState as useState38 } from "react";
49254
- import { jsx as jsx53, jsxs as jsxs46 } from "react/jsx-runtime";
49319
+ import { useState as useState39 } from "react";
49320
+ import { jsx as jsx54, jsxs as jsxs47 } from "react/jsx-runtime";
49255
49321
  var FIELDS = [
49256
49322
  { id: "baseURL", label: "\u6A21\u578B\u670D\u52A1\u5730\u5740", placeholder: "http://\u5185\u7F51\u5730\u5740/v1" },
49257
49323
  { id: "model", label: "\u6A21\u578B", placeholder: "\u6A21\u578B\u540D\u79F0" },
@@ -49297,13 +49363,13 @@ function writeOverride(settings, baseURL, override) {
49297
49363
  }
49298
49364
  function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
49299
49365
  const normalized = normalizeAdvanced(settings);
49300
- const [open2, setOpen] = useState38(false);
49301
- const [draft, setDraft] = useState38(override);
49366
+ const [open2, setOpen] = useState39(false);
49367
+ const [draft, setDraft] = useState39(override);
49302
49368
  if (!normalized) return null;
49303
49369
  const fields = FIELDS.filter((field) => normalized[field.id]);
49304
49370
  const dirty = Object.keys(override).length > 0;
49305
- return /* @__PURE__ */ jsxs46("div", { className: "blade-chat-advanced border-t border-[hsl(var(--border))] px-4 py-2 text-xs", children: [
49306
- /* @__PURE__ */ jsxs46(
49371
+ return /* @__PURE__ */ jsxs47("div", { className: "blade-chat-advanced border-t border-[hsl(var(--border))] px-4 py-2 text-xs", children: [
49372
+ /* @__PURE__ */ jsxs47(
49307
49373
  "button",
49308
49374
  {
49309
49375
  type: "button",
@@ -49313,16 +49379,16 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
49313
49379
  },
49314
49380
  className: "flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
49315
49381
  children: [
49316
- /* @__PURE__ */ jsx53(Settings2, { size: 13 }),
49382
+ /* @__PURE__ */ jsx54(Settings2, { size: 13 }),
49317
49383
  "\u9AD8\u7EA7\u8BBE\u7F6E",
49318
- dirty && /* @__PURE__ */ jsx53("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
49384
+ dirty && /* @__PURE__ */ jsx54("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
49319
49385
  ]
49320
49386
  }
49321
49387
  ),
49322
- open2 && /* @__PURE__ */ jsxs46("div", { className: "mt-2 flex flex-col gap-2", children: [
49323
- fields.map((field) => /* @__PURE__ */ jsxs46("label", { className: "flex flex-col gap-1", children: [
49324
- /* @__PURE__ */ jsx53("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
49325
- /* @__PURE__ */ jsx53(
49388
+ open2 && /* @__PURE__ */ jsxs47("div", { className: "mt-2 flex flex-col gap-2", children: [
49389
+ fields.map((field) => /* @__PURE__ */ jsxs47("label", { className: "flex flex-col gap-1", children: [
49390
+ /* @__PURE__ */ jsx54("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
49391
+ /* @__PURE__ */ jsx54(
49326
49392
  "input",
49327
49393
  {
49328
49394
  type: field.secret ? "password" : "text",
@@ -49333,9 +49399,9 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
49333
49399
  }
49334
49400
  )
49335
49401
  ] }, field.id)),
49336
- normalized.apiKey && /* @__PURE__ */ jsx53("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" }),
49337
- /* @__PURE__ */ jsxs46("div", { className: "flex gap-2", children: [
49338
- /* @__PURE__ */ jsx53(
49402
+ normalized.apiKey && /* @__PURE__ */ jsx54("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" }),
49403
+ /* @__PURE__ */ jsxs47("div", { className: "flex gap-2", children: [
49404
+ /* @__PURE__ */ jsx54(
49339
49405
  "button",
49340
49406
  {
49341
49407
  type: "button",
@@ -49350,7 +49416,7 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
49350
49416
  children: "\u4FDD\u5B58"
49351
49417
  }
49352
49418
  ),
49353
- /* @__PURE__ */ jsx53(
49419
+ /* @__PURE__ */ jsx54(
49354
49420
  "button",
49355
49421
  {
49356
49422
  type: "button",
@@ -49369,7 +49435,7 @@ function LlmAdvancedSettingsBar({ settings, defaults, override, onChange }) {
49369
49435
  }
49370
49436
 
49371
49437
  // src/components/LlmChat.tsx
49372
- import { jsx as jsx54, jsxs as jsxs47 } from "react/jsx-runtime";
49438
+ import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
49373
49439
  function LlmChat({
49374
49440
  classNames,
49375
49441
  renderers,
@@ -49381,12 +49447,12 @@ function LlmChat({
49381
49447
  onOverrideChange,
49382
49448
  ...options
49383
49449
  }) {
49384
- const [override, setOverride] = useState39(() => readOverride(advanced, options.baseURL));
49450
+ const [override, setOverride] = useState40(() => readOverride(advanced, options.baseURL));
49385
49451
  const effective = { ...options, ...override };
49386
49452
  const { messages, isStreaming, error: error61, send, stop, reset } = useLlmChat(effective);
49387
- const [inputText, setInputText] = useState39("");
49388
- const [stopRequested, setStopRequested] = useState39(false);
49389
- const [isRevealing, setIsRevealing] = useState39(false);
49453
+ const [inputText, setInputText] = useState40("");
49454
+ const [stopRequested, setStopRequested] = useState40(false);
49455
+ const [isRevealing, setIsRevealing] = useState40(false);
49390
49456
  const isStreamingDisplay = isStreaming || isRevealing;
49391
49457
  const handle = useMemo20(
49392
49458
  () => ({
@@ -49397,30 +49463,30 @@ ${text4}` : text4),
49397
49463
  }),
49398
49464
  [send, reset]
49399
49465
  );
49400
- useEffect31(() => {
49466
+ useEffect32(() => {
49401
49467
  onReady?.(handle);
49402
49468
  }, [handle, onReady]);
49403
49469
  const customization = useMemo20(() => ({ classNames, renderers }), [classNames, renderers]);
49404
- return /* @__PURE__ */ jsx54(ChatCustomizationProvider, { value: customization, children: /* @__PURE__ */ jsxs47(
49470
+ return /* @__PURE__ */ jsx55(ChatCustomizationProvider, { value: customization, children: /* @__PURE__ */ jsxs48(
49405
49471
  "div",
49406
49472
  {
49407
49473
  "data-theme": theme,
49408
49474
  part: "root",
49409
49475
  className: cn("blade-chat flex min-h-0 flex-1 flex-col overflow-hidden", classNames?.root),
49410
49476
  children: [
49411
- error61 ? /* @__PURE__ */ jsxs47(
49477
+ error61 ? /* @__PURE__ */ jsxs48(
49412
49478
  "div",
49413
49479
  {
49414
49480
  part: "error-bar",
49415
49481
  className: "blade-chat-error-bar flex items-start gap-2 border-b border-[hsl(var(--swf-danger)/0.3)] bg-[hsl(var(--swf-danger-soft))] px-4 py-3 text-sm text-[hsl(var(--swf-danger))]",
49416
49482
  children: [
49417
- /* @__PURE__ */ jsx54(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
49418
- /* @__PURE__ */ jsx54("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay4(error61) })
49483
+ /* @__PURE__ */ jsx55(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
49484
+ /* @__PURE__ */ jsx55("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay4(error61) })
49419
49485
  ]
49420
49486
  }
49421
49487
  ) : null,
49422
49488
  slots?.header,
49423
- /* @__PURE__ */ jsx54(
49489
+ /* @__PURE__ */ jsx55(
49424
49490
  MessageList,
49425
49491
  {
49426
49492
  sessionId: "",
@@ -49432,7 +49498,7 @@ ${text4}` : text4),
49432
49498
  onRevealingChange: setIsRevealing
49433
49499
  }
49434
49500
  ),
49435
- advanced ? /* @__PURE__ */ jsx54(
49501
+ advanced ? /* @__PURE__ */ jsx55(
49436
49502
  LlmAdvancedSettingsBar,
49437
49503
  {
49438
49504
  settings: advanced,
@@ -49445,7 +49511,7 @@ ${text4}` : text4),
49445
49511
  }
49446
49512
  }
49447
49513
  ) : null,
49448
- /* @__PURE__ */ jsx54(
49514
+ /* @__PURE__ */ jsx55(
49449
49515
  ChatInput,
49450
49516
  {
49451
49517
  value: inputText,
@@ -49474,14 +49540,14 @@ ${text4}` : text4),
49474
49540
  }
49475
49541
 
49476
49542
  // src/components/ChatView.tsx
49477
- import { jsx as jsx55 } from "react/jsx-runtime";
49543
+ import { jsx as jsx56 } from "react/jsx-runtime";
49478
49544
  function ChatView(props) {
49479
49545
  const { mode, llm, onLlmReady, ...rest } = props;
49480
49546
  if (mode === "llm") {
49481
49547
  if (!llm) {
49482
49548
  throw new Error('ChatView: mode="llm" \u9700\u8981\u540C\u65F6\u4F20 llm={{ baseURL, model }}');
49483
49549
  }
49484
- return /* @__PURE__ */ jsx55(
49550
+ return /* @__PURE__ */ jsx56(
49485
49551
  LlmChat,
49486
49552
  {
49487
49553
  ...llm,
@@ -49494,12 +49560,12 @@ function ChatView(props) {
49494
49560
  }
49495
49561
  );
49496
49562
  }
49497
- return /* @__PURE__ */ jsx55(AgentChat, { ...rest });
49563
+ return /* @__PURE__ */ jsx56(AgentChat, { ...rest });
49498
49564
  }
49499
49565
 
49500
49566
  // src/components/TopicAssetSubmitDialog.tsx
49501
- import { useRef as useRef30, useState as useState40 } from "react";
49502
- import { jsx as jsx56, jsxs as jsxs48 } from "react/jsx-runtime";
49567
+ import { useRef as useRef31, useState as useState41 } from "react";
49568
+ import { jsx as jsx57, jsxs as jsxs49 } from "react/jsx-runtime";
49503
49569
  function useTopicAssetSubmissionAccess(sessionId) {
49504
49570
  const client = useBladeClient();
49505
49571
  return useAsyncValue(sessionId, async (signal) => {
@@ -49515,12 +49581,12 @@ function useTopicAssetSubmissionAccess(sessionId) {
49515
49581
  }
49516
49582
  function TopicAssetSubmitDialog({ sessionId, topicId, path: path2, onClose, onSubmitted }) {
49517
49583
  const client = useBladeClient();
49518
- const [folder, setFolder] = useState40("");
49519
- const [message, setMessage] = useState40("");
49520
- const [error61, setError] = useState40(null);
49521
- const [busy, setBusy] = useState40(false);
49522
- const submitting = useRef30(false);
49523
- const [revision, setRevision] = useState40(0);
49584
+ const [folder, setFolder] = useState41("");
49585
+ const [message, setMessage] = useState41("");
49586
+ const [error61, setError] = useState41(null);
49587
+ const [busy, setBusy] = useState41(false);
49588
+ const submitting = useRef31(false);
49589
+ const [revision, setRevision] = useState41(0);
49524
49590
  const assets = useAsyncValue(`${sessionId}:${topicId}:${revision}`, async () => {
49525
49591
  const [session, groups, result] = await Promise.all([
49526
49592
  client.sessions.getSession(sessionId),
@@ -49555,36 +49621,36 @@ function TopicAssetSubmitDialog({ sessionId, topicId, path: path2, onClose, onSu
49555
49621
  setBusy(false);
49556
49622
  }
49557
49623
  };
49558
- return /* @__PURE__ */ jsx56(Dialog, { open: true, onOpenChange: (open2) => {
49624
+ return /* @__PURE__ */ jsx57(Dialog, { open: true, onOpenChange: (open2) => {
49559
49625
  if (!open2 && !busy) onClose();
49560
- }, children: /* @__PURE__ */ jsxs48(DialogContent, { className: "max-w-md", children: [
49561
- /* @__PURE__ */ jsx56(DialogTitle, { children: "\u63D0\u4EA4\u5230\u8D44\u4EA7" }),
49562
- /* @__PURE__ */ jsx56(DialogDescription, { children: "\u5C06\u6587\u4EF6\u590D\u5236\u5230\u4E3B\u9898\u4F9B\u6210\u5458\u4F7F\u7528\uFF0C\u5DE5\u4F5C\u533A\u539F\u6587\u4EF6\u4F1A\u4FDD\u7559\u3002\u540C\u540D\u8D44\u4EA7\u4F1A\u88AB\u66FF\u6362\u3002" }),
49563
- /* @__PURE__ */ jsxs48("form", { onSubmit: (event) => {
49626
+ }, children: /* @__PURE__ */ jsxs49(DialogContent, { className: "max-w-md", children: [
49627
+ /* @__PURE__ */ jsx57(DialogTitle, { children: "\u63D0\u4EA4\u5230\u8D44\u4EA7" }),
49628
+ /* @__PURE__ */ jsx57(DialogDescription, { children: "\u5C06\u6587\u4EF6\u590D\u5236\u5230\u4E3B\u9898\u4F9B\u6210\u5458\u4F7F\u7528\uFF0C\u5DE5\u4F5C\u533A\u539F\u6587\u4EF6\u4F1A\u4FDD\u7559\u3002\u540C\u540D\u8D44\u4EA7\u4F1A\u88AB\u66FF\u6362\u3002" }),
49629
+ /* @__PURE__ */ jsxs49("form", { onSubmit: (event) => {
49564
49630
  event.preventDefault();
49565
49631
  void submit();
49566
49632
  }, className: "flex flex-col gap-4", children: [
49567
- /* @__PURE__ */ jsx56("p", { className: "break-all text-sm text-secondary-foreground", children: path2 }),
49568
- /* @__PURE__ */ jsxs48("label", { className: "flex flex-col gap-1 text-sm", children: [
49633
+ /* @__PURE__ */ jsx57("p", { className: "break-all text-sm text-secondary-foreground", children: path2 }),
49634
+ /* @__PURE__ */ jsxs49("label", { className: "flex flex-col gap-1 text-sm", children: [
49569
49635
  "\u76EE\u6807\u6587\u4EF6\u5939",
49570
- /* @__PURE__ */ jsxs48("select", { "aria-label": "\u76EE\u6807\u6587\u4EF6\u5939", value: folder, onChange: (event) => setFolder(event.target.value), disabled: busy || !assets.data, className: "rounded-md border border-border bg-background p-2", children: [
49571
- /* @__PURE__ */ jsx56("option", { value: "", children: "\u8D44\u4EA7\u6839\u76EE\u5F55" }),
49572
- assets.data?.map((item) => /* @__PURE__ */ jsx56("option", { value: item, children: item }, item))
49636
+ /* @__PURE__ */ jsxs49("select", { "aria-label": "\u76EE\u6807\u6587\u4EF6\u5939", value: folder, onChange: (event) => setFolder(event.target.value), disabled: busy || !assets.data, className: "rounded-md border border-border bg-background p-2", children: [
49637
+ /* @__PURE__ */ jsx57("option", { value: "", children: "\u8D44\u4EA7\u6839\u76EE\u5F55" }),
49638
+ assets.data?.map((item) => /* @__PURE__ */ jsx57("option", { value: item, children: item }, item))
49573
49639
  ] })
49574
49640
  ] }),
49575
- /* @__PURE__ */ jsxs48("label", { className: "flex flex-col gap-1 text-sm", children: [
49641
+ /* @__PURE__ */ jsxs49("label", { className: "flex flex-col gap-1 text-sm", children: [
49576
49642
  "\u8BF4\u660E\uFF08\u53EF\u9009\uFF09",
49577
- /* @__PURE__ */ jsx56("textarea", { "aria-label": "\u63D0\u4EA4\u8BF4\u660E", value: message, onChange: (event) => setMessage(event.target.value), maxLength: 1e3, disabled: busy, className: "min-h-20 rounded-md border border-border bg-background p-2" })
49643
+ /* @__PURE__ */ jsx57("textarea", { "aria-label": "\u63D0\u4EA4\u8BF4\u660E", value: message, onChange: (event) => setMessage(event.target.value), maxLength: 1e3, disabled: busy, className: "min-h-20 rounded-md border border-border bg-background p-2" })
49578
49644
  ] }),
49579
- assets.error ? /* @__PURE__ */ jsxs48("div", { role: "alert", className: "text-sm text-muted-foreground", children: [
49645
+ assets.error ? /* @__PURE__ */ jsxs49("div", { role: "alert", className: "text-sm text-muted-foreground", children: [
49580
49646
  assets.error instanceof Error ? assets.error.message : "\u8D44\u4EA7\u52A0\u8F7D\u5931\u8D25",
49581
49647
  " ",
49582
- /* @__PURE__ */ jsx56("button", { type: "button", onClick: () => setRevision((n2) => n2 + 1), className: "underline", children: "\u91CD\u8BD5" })
49583
- ] }) : !assets.data ? /* @__PURE__ */ jsx56("output", { className: "text-sm text-muted-foreground", children: "\u6B63\u5728\u52A0\u8F7D\u8D44\u4EA7\u2026" }) : null,
49584
- error61 ? /* @__PURE__ */ jsx56("p", { role: "alert", className: "text-sm text-muted-foreground", children: error61 }) : null,
49585
- /* @__PURE__ */ jsxs48("div", { className: "flex justify-end gap-2", children: [
49586
- /* @__PURE__ */ jsx56("button", { type: "button", disabled: busy, onClick: onClose, className: "rounded-md border border-border px-3 py-2 text-sm", children: "\u53D6\u6D88" }),
49587
- /* @__PURE__ */ jsx56("button", { type: "submit", disabled: busy || !assets.data, className: "rounded-md bg-primary px-3 py-2 text-sm text-primary-foreground disabled:opacity-50", children: busy ? "\u63D0\u4EA4\u4E2D\u2026" : "\u63D0\u4EA4" })
49648
+ /* @__PURE__ */ jsx57("button", { type: "button", onClick: () => setRevision((n2) => n2 + 1), className: "underline", children: "\u91CD\u8BD5" })
49649
+ ] }) : !assets.data ? /* @__PURE__ */ jsx57("output", { className: "text-sm text-muted-foreground", children: "\u6B63\u5728\u52A0\u8F7D\u8D44\u4EA7\u2026" }) : null,
49650
+ error61 ? /* @__PURE__ */ jsx57("p", { role: "alert", className: "text-sm text-muted-foreground", children: error61 }) : null,
49651
+ /* @__PURE__ */ jsxs49("div", { className: "flex justify-end gap-2", children: [
49652
+ /* @__PURE__ */ jsx57("button", { type: "button", disabled: busy, onClick: onClose, className: "rounded-md border border-border px-3 py-2 text-sm", children: "\u53D6\u6D88" }),
49653
+ /* @__PURE__ */ jsx57("button", { type: "submit", disabled: busy || !assets.data, className: "rounded-md bg-primary px-3 py-2 text-sm text-primary-foreground disabled:opacity-50", children: busy ? "\u63D0\u4EA4\u4E2D\u2026" : "\u63D0\u4EA4" })
49588
49654
  ] })
49589
49655
  ] })
49590
49656
  ] }) });
@@ -49644,4 +49710,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
49644
49710
  js-yaml/dist/js-yaml.mjs:
49645
49711
  (*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT *)
49646
49712
  */
49647
- //# sourceMappingURL=chunk-ZAEHTW2O.js.map
49713
+ //# sourceMappingURL=chunk-KSVVYASW.js.map