@blade-hq/agent-react 2610.0.0-beta.83 → 2610.0.0-beta.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3398,7 +3398,7 @@ var X = createLucideIcon("X", [
3398
3398
  ]);
3399
3399
 
3400
3400
  // src/components/AgentChat.tsx
3401
- import { useCallback as useCallback30, useEffect as useEffect24, useMemo as useMemo18, useRef as useRef27, useState as useState34 } from "react";
3401
+ import { useCallback as useCallback30, useEffect as useEffect25, useMemo as useMemo18, useRef as useRef28, useState as useState35 } from "react";
3402
3402
 
3403
3403
  // src/components/SessionPluginSelector.tsx
3404
3404
  import { useEffect as useEffect14, useState as useState19 } from "react";
@@ -21058,7 +21058,7 @@ function CurrentPlanPanel({
21058
21058
 
21059
21059
  // src/components/ChatSurface.tsx
21060
21060
  import { chatErrorForDisplay as chatErrorForDisplay2 } from "@blade-hq/agent-client";
21061
- import { useMemo as useMemo17, useState as useState33 } from "react";
21061
+ import { useMemo as useMemo17, useState as useState34 } from "react";
21062
21062
 
21063
21063
  // src/lib/random-id.ts
21064
21064
  function randomId() {
@@ -46395,10 +46395,10 @@ function ConnectionBanner({ connection, className }) {
46395
46395
  import { isHiddenInternalMessage as isHiddenInternalMessage2 } from "@blade-hq/agent-client";
46396
46396
  import {
46397
46397
  useCallback as useCallback29,
46398
- useEffect as useEffect23,
46398
+ useEffect as useEffect24,
46399
46399
  useMemo as useMemo16,
46400
- useRef as useRef26,
46401
- useState as useState32
46400
+ useRef as useRef27,
46401
+ useState as useState33
46402
46402
  } from "react";
46403
46403
 
46404
46404
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
@@ -46825,6 +46825,71 @@ function useStickToBottomContext() {
46825
46825
  return context;
46826
46826
  }
46827
46827
 
46828
+ // src/components/MessageImage.tsx
46829
+ import { forwardRef as forwardRef3, useEffect as useEffect19, useImperativeHandle as useImperativeHandle2, useRef as useRef21, useState as useState26 } from "react";
46830
+ import { jsx as jsx15 } from "react/jsx-runtime";
46831
+ var assetPattern = /^\/api\/(sessions|share)\/([^/]+)\/media\/([a-f0-9]{64})$/;
46832
+ var MessageImage = forwardRef3(function MessageImage2({ client: suppliedClient, src, original = false, alt, style, ...props }, ref) {
46833
+ const contextClient = useOptionalBladeClient();
46834
+ const client = suppliedClient ?? contextClient;
46835
+ const element2 = useRef21(null);
46836
+ useImperativeHandle2(ref, () => element2.current);
46837
+ const [visible, setVisible] = useState26(false);
46838
+ const [result, setResult] = useState26(null);
46839
+ const match = src?.match(assetPattern);
46840
+ const scope = match?.[1];
46841
+ const sessionId = match?.[2];
46842
+ const assetId = match?.[3];
46843
+ const identity2 = assetId && client ? client.buildAuthedUrl(src) : "";
46844
+ const source = `${src}:${original}:${identity2}`;
46845
+ useEffect19(() => {
46846
+ const node3 = element2.current;
46847
+ if (!node3 || !assetId) return;
46848
+ if (original || typeof IntersectionObserver === "undefined") {
46849
+ setVisible(true);
46850
+ return;
46851
+ }
46852
+ const observer = new IntersectionObserver((entries) => {
46853
+ if (entries.some((entry) => entry.isIntersecting)) {
46854
+ setVisible(true);
46855
+ observer.disconnect();
46856
+ }
46857
+ }, { rootMargin: "200px" });
46858
+ observer.observe(node3);
46859
+ return () => observer.disconnect();
46860
+ }, [assetId, original]);
46861
+ useEffect19(() => {
46862
+ if (!visible || !client || !sessionId || !assetId) return;
46863
+ let alive = true;
46864
+ let objectUrl = null;
46865
+ const pending = scope === "share" ? client.sessions.fetchSharedImage(sessionId, assetId, !original) : client.sessions.fetchImage(sessionId, assetId, !original);
46866
+ void pending.then((blob) => {
46867
+ if (!alive) return;
46868
+ objectUrl = URL.createObjectURL(blob);
46869
+ setResult({ source, client, url: objectUrl });
46870
+ }).catch(() => {
46871
+ if (alive) setResult({ source, client, url: null });
46872
+ });
46873
+ return () => {
46874
+ alive = false;
46875
+ if (objectUrl) URL.revokeObjectURL(objectUrl);
46876
+ };
46877
+ }, [visible, client, scope, sessionId, assetId, original, source]);
46878
+ const current = result?.source === source && result.client === client ? result : null;
46879
+ const imageStyle = { aspectRatio: props.width && props.height ? `${props.width}/${props.height}` : void 0, ...style };
46880
+ return /* @__PURE__ */ jsx15(
46881
+ "img",
46882
+ {
46883
+ ...props,
46884
+ ref: element2,
46885
+ src: assetId ? current?.url ?? void 0 : src,
46886
+ alt: assetId && current?.url === null ? "\u56FE\u7247\u52A0\u8F7D\u5931\u8D25" : alt,
46887
+ loading: original ? "eager" : "lazy",
46888
+ style: assetId && !current?.url && !props.height ? { minHeight: 64, ...imageStyle } : imageStyle
46889
+ }
46890
+ );
46891
+ });
46892
+
46828
46893
  // src/components/AssistantTurnBlock.tsx
46829
46894
  import {
46830
46895
  collectInlineToolUiCards,
@@ -46833,11 +46898,11 @@ import {
46833
46898
  getTextContent as getTextContent2,
46834
46899
  normalizeMessageContent as normalizeMessageContent2
46835
46900
  } from "@blade-hq/agent-client";
46836
- import { useEffect as useEffect21, useRef as useRef24, useState as useState30 } from "react";
46901
+ import { useEffect as useEffect22, useRef as useRef25, useState as useState31 } from "react";
46837
46902
 
46838
46903
  // src/components/AgentTaskCard.tsx
46839
- import { useEffect as useEffect19, useState as useState26 } from "react";
46840
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
46904
+ import { useEffect as useEffect20, useState as useState27 } from "react";
46905
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
46841
46906
  var STATUS_LABELS = {
46842
46907
  running: "\u8FDB\u884C\u4E2D",
46843
46908
  waiting_input: "\u7B49\u5F85\u56DE\u7B54",
@@ -46847,8 +46912,8 @@ var STATUS_LABELS = {
46847
46912
  };
46848
46913
  function AgentTaskCard({ title, status, activity, children, className, recordId }) {
46849
46914
  const waiting = status === "waiting_input";
46850
- const [open2, setOpen] = useState26(waiting);
46851
- useEffect19(() => {
46915
+ const [open2, setOpen] = useState27(waiting);
46916
+ useEffect20(() => {
46852
46917
  if (waiting) setOpen(true);
46853
46918
  }, [waiting]);
46854
46919
  return /* @__PURE__ */ jsxs13(
@@ -46866,28 +46931,28 @@ function AgentTaskCard({ title, status, activity, children, className, recordId
46866
46931
  ),
46867
46932
  children: [
46868
46933
  /* @__PURE__ */ jsxs13("summary", { className: "flex cursor-pointer list-none items-start gap-2.5 rounded-xl px-3 py-3 text-left outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] [&::-webkit-details-marker]:hidden", children: [
46869
- waiting ? /* @__PURE__ */ jsx15(CircleHelp, { size: 18, "aria-hidden": "true", className: "mt-0.5 shrink-0 text-amber-600 motion-safe:animate-pulse" }) : /* @__PURE__ */ jsx15(Bot, { size: 18, "aria-hidden": "true", className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]" }),
46934
+ waiting ? /* @__PURE__ */ jsx16(CircleHelp, { size: 18, "aria-hidden": "true", className: "mt-0.5 shrink-0 text-amber-600 motion-safe:animate-pulse" }) : /* @__PURE__ */ jsx16(Bot, { size: 18, "aria-hidden": "true", className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]" }),
46870
46935
  /* @__PURE__ */ jsxs13("span", { className: "min-w-0 flex-1", children: [
46871
46936
  /* @__PURE__ */ jsxs13("span", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
46872
- /* @__PURE__ */ jsx15("span", { children: "\u5B50\u667A\u80FD\u4F53" }),
46937
+ /* @__PURE__ */ jsx16("span", { children: "\u5B50\u667A\u80FD\u4F53" }),
46873
46938
  /* @__PURE__ */ jsxs13("span", { className: cn("inline-flex items-center gap-1", waiting && "font-semibold text-amber-600"), children: [
46874
- status === "running" ? /* @__PURE__ */ jsx15(LoaderCircle, { size: 12, "aria-hidden": "true", className: "motion-safe:animate-spin" }) : null,
46939
+ status === "running" ? /* @__PURE__ */ jsx16(LoaderCircle, { size: 12, "aria-hidden": "true", className: "motion-safe:animate-spin" }) : null,
46875
46940
  STATUS_LABELS[status]
46876
46941
  ] })
46877
46942
  ] }),
46878
- /* @__PURE__ */ jsx15("span", { className: "mt-1 block break-words text-sm font-medium text-[hsl(var(--foreground))]", children: title }),
46879
- activity ? /* @__PURE__ */ jsx15("span", { className: "mt-1 block truncate text-xs text-[hsl(var(--muted-foreground))]", title: activity, children: activity }) : null
46943
+ /* @__PURE__ */ jsx16("span", { className: "mt-1 block break-words text-sm font-medium text-[hsl(var(--foreground))]", children: title }),
46944
+ activity ? /* @__PURE__ */ jsx16("span", { className: "mt-1 block truncate text-xs text-[hsl(var(--muted-foreground))]", title: activity, children: activity }) : null
46880
46945
  ] }),
46881
- /* @__PURE__ */ jsx15(ChevronRight, { size: 15, "aria-hidden": "true", className: cn("mt-1 shrink-0 text-[hsl(var(--muted-foreground))] transition-transform motion-reduce:transition-none", open2 && "rotate-90") })
46946
+ /* @__PURE__ */ jsx16(ChevronRight, { size: 15, "aria-hidden": "true", className: cn("mt-1 shrink-0 text-[hsl(var(--muted-foreground))] transition-transform motion-reduce:transition-none", open2 && "rotate-90") })
46882
46947
  ] }),
46883
- /* @__PURE__ */ jsx15("div", { className: "min-w-0 border-t border-[hsl(var(--border))] px-3 py-2", children })
46948
+ /* @__PURE__ */ jsx16("div", { className: "min-w-0 border-t border-[hsl(var(--border))] px-3 py-2", children })
46884
46949
  ]
46885
46950
  }
46886
46951
  );
46887
46952
  }
46888
46953
 
46889
46954
  // src/components/AgentLoopBlock.tsx
46890
- import { jsx as jsx16 } from "react/jsx-runtime";
46955
+ import { jsx as jsx17 } from "react/jsx-runtime";
46891
46956
  function parseAgentDescription(argumentsJson) {
46892
46957
  try {
46893
46958
  const parsed = JSON.parse(argumentsJson);
@@ -46898,14 +46963,14 @@ function parseAgentDescription(argumentsJson) {
46898
46963
  }
46899
46964
  function AgentLoopBlock({ toolCall, className }) {
46900
46965
  const status = toolCall.status === "awaiting_answer" ? "waiting_input" : toolCall.status === "pending" ? "running" : toolCall.status === "error" ? "failed" : toolCall.status === "cancelled" ? "cancelled" : "completed";
46901
- return /* @__PURE__ */ jsx16(AgentTaskCard, { title: parseAgentDescription(toolCall.arguments), status, className, children: toolCall.result != null ? /* @__PURE__ */ jsx16("div", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap break-words text-xs text-[hsl(var(--muted-foreground))]", children: formatToolResult(toolCall.result) }) : /* @__PURE__ */ jsx16("p", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: status === "waiting_input" ? "\u8BF7\u56DE\u7B54\u5BF9\u8BDD\u4E2D\u7684\u95EE\u9898\uFF0C\u5B50\u667A\u80FD\u4F53\u4F1A\u7EE7\u7EED\u5904\u7406\u3002" : status === "running" ? "\u5B50\u667A\u80FD\u4F53\u6B63\u5728\u5904\u7406\u4EFB\u52A1\u3002" : "\u6682\u65E0\u6267\u884C\u7ED3\u679C\u3002" }) });
46966
+ return /* @__PURE__ */ jsx17(AgentTaskCard, { title: parseAgentDescription(toolCall.arguments), status, className, children: toolCall.result != null ? /* @__PURE__ */ jsx17("div", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap break-words text-xs text-[hsl(var(--muted-foreground))]", children: formatToolResult(toolCall.result) }) : /* @__PURE__ */ jsx17("p", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: status === "waiting_input" ? "\u8BF7\u56DE\u7B54\u5BF9\u8BDD\u4E2D\u7684\u95EE\u9898\uFF0C\u5B50\u667A\u80FD\u4F53\u4F1A\u7EE7\u7EED\u5904\u7406\u3002" : status === "running" ? "\u5B50\u667A\u80FD\u4F53\u6B63\u5728\u5904\u7406\u4EFB\u52A1\u3002" : "\u6682\u65E0\u6267\u884C\u7ED3\u679C\u3002" }) });
46902
46967
  }
46903
46968
 
46904
46969
  // src/components/MarkdownContent.tsx
46905
- import { isValidElement as isValidElement2, useMemo as useMemo14, useRef as useRef22, useState as useState27 } from "react";
46970
+ import { isValidElement as isValidElement2, useMemo as useMemo14, useRef as useRef23, useState as useState28 } from "react";
46906
46971
 
46907
46972
  // src/components/markdown/index.ts
46908
- import { createElement as createElement7, useRef as useRef21 } from "react";
46973
+ import { createElement as createElement7, useRef as useRef22 } from "react";
46909
46974
 
46910
46975
  // ../../node_modules/.pnpm/mdast-util-to-string@4.0.0/node_modules/mdast-util-to-string/lib/index.js
46911
46976
  var emptyOptions = {};
@@ -55791,10 +55856,10 @@ function MarkdownRenderer({
55791
55856
  codeBlockOverrides
55792
55857
  }) {
55793
55858
  const isStreaming = mode === "streaming";
55794
- const cacheRef = useRef21(createParseCache());
55795
- const blockCacheRef = useRef21(/* @__PURE__ */ new WeakMap());
55796
- const groupIdentityMapRef = useRef21(/* @__PURE__ */ new WeakMap());
55797
- const rendererConfigRef = useRef21(null);
55859
+ const cacheRef = useRef22(createParseCache());
55860
+ const blockCacheRef = useRef22(/* @__PURE__ */ new WeakMap());
55861
+ const groupIdentityMapRef = useRef22(/* @__PURE__ */ new WeakMap());
55862
+ const rendererConfigRef = useRef22(null);
55798
55863
  const previousConfig = rendererConfigRef.current;
55799
55864
  if (!previousConfig || previousConfig.allowedTags !== allowedTags || previousConfig.components !== components || previousConfig.rawHtmlPlugins !== rawHtmlPlugins || previousConfig.codeBlockOverrides !== codeBlockOverrides) {
55800
55865
  blockCacheRef.current = /* @__PURE__ */ new WeakMap();
@@ -55835,7 +55900,7 @@ function MarkdownRenderer({
55835
55900
  }
55836
55901
 
55837
55902
  // src/components/MarkdownContent.tsx
55838
- import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
55903
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
55839
55904
  var SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
55840
55905
  var INCOMPLETE_SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*$/i;
55841
55906
  function findCodeRanges(text4) {
@@ -55879,8 +55944,8 @@ function normalizeAdjacentUrlFormatting(value) {
55879
55944
  return normalized.replace(/blade-url-protected-(\d+)-marker/g, (_2, index2) => protectedSegments[Number(index2)]);
55880
55945
  }
55881
55946
  function CodeBlockPre({ children, ...props }) {
55882
- const preRef = useRef22(null);
55883
- const [copied, setCopied] = useState27(false);
55947
+ const preRef = useRef23(null);
55948
+ const [copied, setCopied] = useState28(false);
55884
55949
  const codeChild = Array.isArray(children) ? children[0] : children;
55885
55950
  const codeClassName = isValidElement2(codeChild) ? codeChild.props.className : void 0;
55886
55951
  const language = codeClassName?.match(/language-(\S+)/)?.[1] ?? "";
@@ -55893,7 +55958,7 @@ function CodeBlockPre({ children, ...props }) {
55893
55958
  };
55894
55959
  return /* @__PURE__ */ jsxs14("div", { className: "blade-chat-codeblock not-prose my-3 overflow-hidden rounded-xl border border-[hsl(var(--border))]", children: [
55895
55960
  /* @__PURE__ */ jsxs14("div", { className: "blade-chat-codeblock-header flex h-[34px] items-center justify-between border-b border-[hsl(var(--border))] bg-[hsl(var(--muted))/0.5] pl-3.5 pr-1.5", children: [
55896
- /* @__PURE__ */ jsx17("span", { className: "font-mono text-[12px] text-[hsl(var(--muted-foreground))]", children: language || "code" }),
55961
+ /* @__PURE__ */ jsx18("span", { className: "font-mono text-[12px] text-[hsl(var(--muted-foreground))]", children: language || "code" }),
55897
55962
  /* @__PURE__ */ jsxs14(
55898
55963
  "button",
55899
55964
  {
@@ -55904,13 +55969,13 @@ function CodeBlockPre({ children, ...props }) {
55904
55969
  copied ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]"
55905
55970
  ),
55906
55971
  children: [
55907
- copied ? /* @__PURE__ */ jsx17(Check, { size: 12 }) : /* @__PURE__ */ jsx17(Copy, { size: 12 }),
55908
- /* @__PURE__ */ jsx17("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
55972
+ copied ? /* @__PURE__ */ jsx18(Check, { size: 12 }) : /* @__PURE__ */ jsx18(Copy, { size: 12 }),
55973
+ /* @__PURE__ */ jsx18("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
55909
55974
  ]
55910
55975
  }
55911
55976
  )
55912
55977
  ] }),
55913
- /* @__PURE__ */ jsx17(
55978
+ /* @__PURE__ */ jsx18(
55914
55979
  "pre",
55915
55980
  {
55916
55981
  ref: preRef,
@@ -55923,9 +55988,9 @@ function CodeBlockPre({ children, ...props }) {
55923
55988
  }
55924
55989
  function ExternalAnchor({ children, href, ...props }) {
55925
55990
  if (typeof href === "string" && href.startsWith("#")) {
55926
- return /* @__PURE__ */ jsx17("a", { ...props, href, children });
55991
+ return /* @__PURE__ */ jsx18("a", { ...props, href, children });
55927
55992
  }
55928
- return /* @__PURE__ */ jsx17("a", { ...props, href, target: "_blank", rel: "noopener noreferrer", children });
55993
+ return /* @__PURE__ */ jsx18("a", { ...props, href, target: "_blank", rel: "noopener noreferrer", children });
55929
55994
  }
55930
55995
  var MARKDOWN_COMPONENTS = {
55931
55996
  pre: CodeBlockPre,
@@ -55935,7 +56000,7 @@ function MarkdownContent({ children, className, mode, sessionId }) {
55935
56000
  const resolvedChildren = useMemo14(() => {
55936
56001
  return normalizeAdjacentUrlFormatting(stripSystemReminders(children));
55937
56002
  }, [children]);
55938
- return /* @__PURE__ */ jsx17(
56003
+ return /* @__PURE__ */ jsx18(
55939
56004
  MarkdownRenderer,
55940
56005
  {
55941
56006
  className: cn("blade-chat-markdown break-words", className),
@@ -55949,17 +56014,17 @@ function MarkdownContent({ children, className, mode, sessionId }) {
55949
56014
  }
55950
56015
 
55951
56016
  // src/components/Shimmer.tsx
55952
- import { jsx as jsx18 } from "react/jsx-runtime";
56017
+ import { jsx as jsx19 } from "react/jsx-runtime";
55953
56018
  function Shimmer({ children = "\u6B63\u5728\u601D\u8003...", className }) {
55954
- return /* @__PURE__ */ jsx18("span", { className: cn("blade-shimmer-text text-sm font-medium", className), children });
56019
+ return /* @__PURE__ */ jsx19("span", { className: cn("blade-shimmer-text text-sm font-medium", className), children });
55955
56020
  }
55956
56021
 
55957
56022
  // src/components/ToolCallBlock.tsx
55958
- import { useState as useState29 } from "react";
56023
+ import { useState as useState30 } from "react";
55959
56024
 
55960
56025
  // src/components/AskUserQuestionBlock.tsx
55961
- import { useEffect as useEffect20, useMemo as useMemo15, useRef as useRef23, useState as useState28 } from "react";
55962
- import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
56026
+ import { useEffect as useEffect21, useMemo as useMemo15, useRef as useRef24, useState as useState29 } from "react";
56027
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
55963
56028
  var CUSTOM_TEXTAREA_MAX_HEIGHT = 160;
55964
56029
  function resizeCustomTextarea(textarea) {
55965
56030
  textarea.style.height = "auto";
@@ -55967,12 +56032,12 @@ function resizeCustomTextarea(textarea) {
55967
56032
  textarea.style.overflowY = textarea.scrollHeight > CUSTOM_TEXTAREA_MAX_HEIGHT ? "auto" : "hidden";
55968
56033
  }
55969
56034
  function useAutoResizeTextarea(value) {
55970
- const textareaRef = useRef23(null);
55971
- useEffect20(() => {
56035
+ const textareaRef = useRef24(null);
56036
+ useEffect21(() => {
55972
56037
  const textarea = textareaRef.current;
55973
56038
  if (textarea?.value === value) resizeCustomTextarea(textarea);
55974
56039
  }, [value]);
55975
- useEffect20(() => {
56040
+ useEffect21(() => {
55976
56041
  const textarea = textareaRef.current;
55977
56042
  if (!textarea || typeof ResizeObserver === "undefined") return;
55978
56043
  let previousWidth = textarea.clientWidth;
@@ -55999,12 +56064,12 @@ function AskUserQuestionBlock({
55999
56064
  className,
56000
56065
  optionClassName
56001
56066
  }) {
56002
- const [selections, setSelections] = useState28(/* @__PURE__ */ new Map());
56003
- const [customTexts, setCustomTexts] = useState28(/* @__PURE__ */ new Map());
56004
- const [usingCustom, setUsingCustom] = useState28(/* @__PURE__ */ new Set());
56005
- const [note, setNote] = useState28("");
56006
- const [submitted, setSubmitted] = useState28(false);
56007
- useEffect20(() => {
56067
+ const [selections, setSelections] = useState29(/* @__PURE__ */ new Map());
56068
+ const [customTexts, setCustomTexts] = useState29(/* @__PURE__ */ new Map());
56069
+ const [usingCustom, setUsingCustom] = useState29(/* @__PURE__ */ new Set());
56070
+ const [note, setNote] = useState29("");
56071
+ const [submitted, setSubmitted] = useState29(false);
56072
+ useEffect21(() => {
56008
56073
  if (sessionStatus === "failed" || sessionStatus === "interrupted") {
56009
56074
  setSubmitted(false);
56010
56075
  }
@@ -56117,7 +56182,7 @@ ${parts.join("\n")}`,
56117
56182
  data.source_loop.description,
56118
56183
  "\u300D\u5728\u7B49\u5F85\u4F60\u7684\u56DE\u7B54"
56119
56184
  ] }),
56120
- data.questions.map((q2, qIdx) => /* @__PURE__ */ jsx19(
56185
+ data.questions.map((q2, qIdx) => /* @__PURE__ */ jsx20(
56121
56186
  QuestionCard,
56122
56187
  {
56123
56188
  question: q2,
@@ -56133,7 +56198,7 @@ ${parts.join("\n")}`,
56133
56198
  },
56134
56199
  q2.question
56135
56200
  )),
56136
- /* @__PURE__ */ jsx19(
56201
+ /* @__PURE__ */ jsx20(
56137
56202
  NoteField,
56138
56203
  {
56139
56204
  answered,
@@ -56142,7 +56207,7 @@ ${parts.join("\n")}`,
56142
56207
  onChange: setNote
56143
56208
  }
56144
56209
  ),
56145
- !answered && !submitted && onAnswer && /* @__PURE__ */ jsx19(
56210
+ !answered && !submitted && onAnswer && /* @__PURE__ */ jsx20(
56146
56211
  "button",
56147
56212
  {
56148
56213
  type: "button",
@@ -56159,7 +56224,7 @@ ${parts.join("\n")}`,
56159
56224
  disabled: true,
56160
56225
  className: "flex w-full items-center justify-center gap-2 rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-xs font-semibold text-[hsl(var(--primary-foreground))] opacity-80",
56161
56226
  children: [
56162
- /* @__PURE__ */ jsx19(LoaderCircle, { size: 14, className: "animate-spin" }),
56227
+ /* @__PURE__ */ jsx20(LoaderCircle, { size: 14, className: "animate-spin" }),
56163
56228
  "\u786E\u8BA4\u4E2D"
56164
56229
  ]
56165
56230
  }
@@ -56184,21 +56249,21 @@ function QuestionCard({
56184
56249
  const customTextareaRef = useAutoResizeTextarea(customText);
56185
56250
  return /* @__PURE__ */ jsxs15("div", { children: [
56186
56251
  /* @__PURE__ */ jsxs15("div", { className: cn("flex items-start gap-2", answered ? "mb-2" : "mb-3"), children: [
56187
- /* @__PURE__ */ jsx19(
56252
+ /* @__PURE__ */ jsx20(
56188
56253
  MessageSquareMore,
56189
56254
  {
56190
56255
  size: answered ? 12 : 13,
56191
56256
  className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]"
56192
56257
  }
56193
56258
  ),
56194
- /* @__PURE__ */ jsx19(
56259
+ /* @__PURE__ */ jsx20(
56195
56260
  "div",
56196
56261
  {
56197
56262
  className: cn(
56198
56263
  "min-w-0 flex-1 font-medium text-[hsl(var(--foreground))]",
56199
56264
  answered ? "text-xs" : "text-sm"
56200
56265
  ),
56201
- children: /* @__PURE__ */ jsx19(MarkdownContent, { className: "blade-chat-prose", children: question.question })
56266
+ children: /* @__PURE__ */ jsx20(MarkdownContent, { className: "blade-chat-prose", children: question.question })
56202
56267
  }
56203
56268
  )
56204
56269
  ] }),
@@ -56221,14 +56286,14 @@ function QuestionCard({
56221
56286
  optionClassName
56222
56287
  ),
56223
56288
  children: [
56224
- multi && /* @__PURE__ */ jsx19(
56289
+ multi && /* @__PURE__ */ jsx20(
56225
56290
  "div",
56226
56291
  {
56227
56292
  className: cn(
56228
56293
  "mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors",
56229
56294
  isSel && !answered ? "border-[hsl(var(--primary-foreground)/0.6)] bg-[hsl(var(--primary-foreground)/0.2)]" : isSel ? "border-[hsl(var(--primary)/0.45)] bg-[hsl(var(--primary)/0.12)]" : "border-[hsl(var(--border))]"
56230
56295
  ),
56231
- children: isSel && /* @__PURE__ */ jsx19(
56296
+ children: isSel && /* @__PURE__ */ jsx20(
56232
56297
  Check,
56233
56298
  {
56234
56299
  size: 9,
@@ -56238,8 +56303,8 @@ function QuestionCard({
56238
56303
  }
56239
56304
  ),
56240
56305
  /* @__PURE__ */ jsxs15("div", { className: "min-w-0", children: [
56241
- /* @__PURE__ */ jsx19("div", { className: cn("font-medium", answered ? "text-xs" : "text-[13px]"), children: opt.label }),
56242
- opt.description && /* @__PURE__ */ jsx19(
56306
+ /* @__PURE__ */ jsx20("div", { className: cn("font-medium", answered ? "text-xs" : "text-[13px]"), children: opt.label }),
56307
+ opt.description && /* @__PURE__ */ jsx20(
56243
56308
  "div",
56244
56309
  {
56245
56310
  className: cn(
@@ -56266,8 +56331,8 @@ function QuestionCard({
56266
56331
  answered && "cursor-default opacity-70"
56267
56332
  ),
56268
56333
  children: [
56269
- /* @__PURE__ */ jsx19("span", { className: "shrink-0 pt-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u5176\u4ED6\uFF1A" }),
56270
- /* @__PURE__ */ jsx19(
56334
+ /* @__PURE__ */ jsx20("span", { className: "shrink-0 pt-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u5176\u4ED6\uFF1A" }),
56335
+ /* @__PURE__ */ jsx20(
56271
56336
  "textarea",
56272
56337
  {
56273
56338
  ref: customTextareaRef,
@@ -56309,8 +56374,8 @@ function NoteField({
56309
56374
  readOnly && "cursor-default opacity-70"
56310
56375
  ),
56311
56376
  children: [
56312
- /* @__PURE__ */ jsx19("span", { className: "mb-1.5 block text-xs text-[hsl(var(--muted-foreground))]", children: "\u8865\u5145\u8BF4\u660E\uFF08\u53EF\u9009\uFF09" }),
56313
- /* @__PURE__ */ jsx19(
56377
+ /* @__PURE__ */ jsx20("span", { className: "mb-1.5 block text-xs text-[hsl(var(--muted-foreground))]", children: "\u8865\u5145\u8BF4\u660E\uFF08\u53EF\u9009\uFF09" }),
56378
+ /* @__PURE__ */ jsx20(
56314
56379
  "textarea",
56315
56380
  {
56316
56381
  ref: textareaRef,
@@ -56399,7 +56464,7 @@ function normalizeOptionItem(value) {
56399
56464
  }
56400
56465
 
56401
56466
  // src/components/ToolCallBlock.tsx
56402
- import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
56467
+ import { Fragment as Fragment7, jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
56403
56468
  function resolveAskQuestionState({
56404
56469
  toolStatus,
56405
56470
  hasAnswerData,
@@ -56422,12 +56487,12 @@ function ToolCallBlock({
56422
56487
  classNames,
56423
56488
  renderers
56424
56489
  }) {
56425
- const [expanded, setExpanded] = useState29(false);
56490
+ const [expanded, setExpanded] = useState30(false);
56426
56491
  const normalizedName = formatToolName(toolCall.name);
56427
56492
  const customQuestion = normalizedName === "AskUserQuestion" ? renderers?.askUserQuestion : void 0;
56428
56493
  const customToolCall = normalizedName === "AskUserQuestion" && customQuestion ? null : renderers?.toolCall?.(toolCall);
56429
56494
  if (customToolCall !== null && customToolCall !== void 0) {
56430
- return /* @__PURE__ */ jsx20(Fragment7, { children: customToolCall });
56495
+ return /* @__PURE__ */ jsx21(Fragment7, { children: customToolCall });
56431
56496
  }
56432
56497
  if (normalizedName === "AskUserQuestion") {
56433
56498
  const askData = parseAskUserQuestion(typeof toolCall.result === "string" ? toolCall.result : null) ?? parseAskUserQuestion(buildAskUserPayload(toolCall.arguments));
@@ -56449,9 +56514,9 @@ function ToolCallBlock({
56449
56514
  };
56450
56515
  const customAsk = customQuestion?.(answerProps);
56451
56516
  if (customAsk !== null && customAsk !== void 0) {
56452
- return /* @__PURE__ */ jsx20(Fragment7, { children: customAsk });
56517
+ return /* @__PURE__ */ jsx21(Fragment7, { children: customAsk });
56453
56518
  }
56454
- return /* @__PURE__ */ jsx20(
56519
+ return /* @__PURE__ */ jsx21(
56455
56520
  AskUserQuestionBlock,
56456
56521
  {
56457
56522
  ...answerProps,
@@ -56470,8 +56535,8 @@ function ToolCallBlock({
56470
56535
  classNames?.askCard
56471
56536
  ),
56472
56537
  children: [
56473
- /* @__PURE__ */ jsx20(LoaderCircle, { size: 14, className: "animate-spin" }),
56474
- /* @__PURE__ */ jsx20("span", { children: "\u6B63\u5728\u51C6\u5907\u95EE\u9898\u2026" })
56538
+ /* @__PURE__ */ jsx21(LoaderCircle, { size: 14, className: "animate-spin" }),
56539
+ /* @__PURE__ */ jsx21("span", { children: "\u6B63\u5728\u51C6\u5907\u95EE\u9898\u2026" })
56475
56540
  ]
56476
56541
  }
56477
56542
  );
@@ -56488,11 +56553,11 @@ function ToolCallBlock({
56488
56553
  classNames?.askCard
56489
56554
  ),
56490
56555
  children: [
56491
- /* @__PURE__ */ jsx20("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
56492
- /* @__PURE__ */ jsx20("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: errorDetail?.message ?? "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" }),
56556
+ /* @__PURE__ */ jsx21("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
56557
+ /* @__PURE__ */ jsx21("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: errorDetail?.message ?? "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" }),
56493
56558
  errorDetail?.detail ? /* @__PURE__ */ jsxs16("details", { className: "mt-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
56494
- /* @__PURE__ */ jsx20("summary", { className: "cursor-pointer", children: "\u67E5\u770B\u5177\u4F53\u539F\u56E0" }),
56495
- /* @__PURE__ */ jsx20("div", { className: "mt-1 break-words font-mono", children: errorDetail.detail })
56559
+ /* @__PURE__ */ jsx21("summary", { className: "cursor-pointer", children: "\u67E5\u770B\u5177\u4F53\u539F\u56E0" }),
56560
+ /* @__PURE__ */ jsx21("div", { className: "mt-1 break-words font-mono", children: errorDetail.detail })
56496
56561
  ] }) : null
56497
56562
  ]
56498
56563
  }
@@ -56501,7 +56566,7 @@ function ToolCallBlock({
56501
56566
  const tone = getToolTone(toolCall.status);
56502
56567
  const displayName = getToolDisplayLabel(toolCall);
56503
56568
  const toneClass = tone === "red" ? "border-l-[hsl(var(--muted-foreground)/0.5)]" : tone === "amber" ? "border-l-amber-400" : tone === "blue" ? "border-l-blue-500" : "border-l-[hsl(var(--primary))]";
56504
- const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx20(LoaderCircle, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx20(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx20(X, { size: 11 }) : /* @__PURE__ */ jsx20(Check, { size: 11 });
56569
+ const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx21(LoaderCircle, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx21(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx21(X, { size: 11 }) : /* @__PURE__ */ jsx21(Check, { size: 11 });
56505
56570
  const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
56506
56571
  return /* @__PURE__ */ jsxs16("div", { className: "ml-4 text-xs", children: [
56507
56572
  /* @__PURE__ */ jsxs16("div", { className: cn("border-l-[3px] flex items-center gap-2 px-3 py-2", toneClass), children: [
@@ -56513,7 +56578,7 @@ function ToolCallBlock({
56513
56578
  className: "flex min-w-0 flex-1 items-center gap-2 text-left transition-colors hover:bg-white/3 focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
56514
56579
  "aria-expanded": expanded,
56515
56580
  children: [
56516
- /* @__PURE__ */ jsx20(
56581
+ /* @__PURE__ */ jsx21(
56517
56582
  ChevronRight,
56518
56583
  {
56519
56584
  size: 11,
@@ -56525,22 +56590,22 @@ function ToolCallBlock({
56525
56590
  ),
56526
56591
  /* @__PURE__ */ jsxs16("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
56527
56592
  statusIcon,
56528
- /* @__PURE__ */ jsx20("span", { children: getToolStatusLabel(toolCall.status) })
56593
+ /* @__PURE__ */ jsx21("span", { children: getToolStatusLabel(toolCall.status) })
56529
56594
  ] }),
56530
- /* @__PURE__ */ jsx20("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: displayName })
56595
+ /* @__PURE__ */ jsx21("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: displayName })
56531
56596
  ]
56532
56597
  }
56533
56598
  ),
56534
- typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx20("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) })
56599
+ typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx21("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) })
56535
56600
  ] }),
56536
56601
  expanded && /* @__PURE__ */ jsxs16("div", { className: "ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3", children: [
56537
- /* @__PURE__ */ jsx20("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u5DE5\u5177" }),
56538
- /* @__PURE__ */ jsx20("div", { className: "mb-3 font-mono text-[11px] text-[hsl(var(--foreground))]", children: normalizedName }),
56539
- /* @__PURE__ */ jsx20("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
56540
- /* @__PURE__ */ jsx20("pre", { className: "overflow-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolArgs(toolCall.arguments) }),
56602
+ /* @__PURE__ */ jsx21("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u5DE5\u5177" }),
56603
+ /* @__PURE__ */ jsx21("div", { className: "mb-3 font-mono text-[11px] text-[hsl(var(--foreground))]", children: normalizedName }),
56604
+ /* @__PURE__ */ jsx21("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
56605
+ /* @__PURE__ */ jsx21("pre", { className: "overflow-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolArgs(toolCall.arguments) }),
56541
56606
  toolCall.result != null && /* @__PURE__ */ jsxs16(Fragment7, { children: [
56542
- /* @__PURE__ */ jsx20("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
56543
- /* @__PURE__ */ jsx20("pre", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolResult(toolCall.result) })
56607
+ /* @__PURE__ */ jsx21("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
56608
+ /* @__PURE__ */ jsx21("pre", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolResult(toolCall.result) })
56544
56609
  ] })
56545
56610
  ] })
56546
56611
  ] });
@@ -56559,13 +56624,13 @@ function buildAskUserPayload(argumentsJson) {
56559
56624
 
56560
56625
  // src/components/ToolUiCardView.tsx
56561
56626
  import { resolveToolUiCardContent } from "@blade-hq/agent-client";
56562
- import { jsx as jsx21 } from "react/jsx-runtime";
56627
+ import { jsx as jsx22 } from "react/jsx-runtime";
56563
56628
  function ToolUiCardView({ card, sessionId }) {
56564
- if (card.mcpApp) return sessionId ? /* @__PURE__ */ jsx21(McpAppCard, { sessionId, sourceId: card.mcpApp.sourceId }) : null;
56629
+ if (card.mcpApp) return sessionId ? /* @__PURE__ */ jsx22(McpAppCard, { sessionId, sourceId: card.mcpApp.sourceId }) : null;
56565
56630
  const resolved = resolveToolUiCardContent(card);
56566
56631
  if (!resolved) return null;
56567
56632
  const sandbox = resolved.type === "resource-uri" ? "allow-scripts allow-same-origin" : "allow-scripts";
56568
- return /* @__PURE__ */ jsx21(
56633
+ return /* @__PURE__ */ jsx22(
56569
56634
  "iframe",
56570
56635
  {
56571
56636
  title: card.title ?? "\u5DE5\u5177\u754C\u9762",
@@ -56596,13 +56661,13 @@ ${html}`;
56596
56661
  }
56597
56662
 
56598
56663
  // src/components/AssistantTurnBlock.tsx
56599
- import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
56664
+ import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
56600
56665
  function ThinkingBlock({
56601
56666
  reasoning,
56602
56667
  isStreaming,
56603
56668
  className
56604
56669
  }) {
56605
- const [open2, setOpen] = useState30(false);
56670
+ const [open2, setOpen] = useState31(false);
56606
56671
  if (!isStreaming) return null;
56607
56672
  return /* @__PURE__ */ jsxs17("div", { part: "thinking", className: cn("blade-chat-thinking ml-4 text-xs", className), children: [
56608
56673
  /* @__PURE__ */ jsxs17(
@@ -56613,8 +56678,8 @@ function ThinkingBlock({
56613
56678
  "aria-expanded": open2,
56614
56679
  className: "group/thinking inline-flex items-center gap-1 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
56615
56680
  children: [
56616
- /* @__PURE__ */ jsx22(Shimmer, { className: "text-xs", children: "\u6B63\u5728\u601D\u8003" }),
56617
- /* @__PURE__ */ jsx22(
56681
+ /* @__PURE__ */ jsx23(Shimmer, { className: "text-xs", children: "\u6B63\u5728\u601D\u8003" }),
56682
+ /* @__PURE__ */ jsx23(
56618
56683
  ChevronRight,
56619
56684
  {
56620
56685
  size: 14,
@@ -56627,7 +56692,7 @@ function ThinkingBlock({
56627
56692
  ]
56628
56693
  }
56629
56694
  ),
56630
- open2 ? /* @__PURE__ */ jsx22("div", { className: "mt-1.5 whitespace-pre-wrap text-xs leading-[22px] text-[hsl(var(--muted-foreground))]", children: reasoning }) : null
56695
+ open2 ? /* @__PURE__ */ jsx23("div", { className: "mt-1.5 whitespace-pre-wrap text-xs leading-[22px] text-[hsl(var(--muted-foreground))]", children: reasoning }) : null
56631
56696
  ] });
56632
56697
  }
56633
56698
  function getMessageText(message) {
@@ -56819,7 +56884,7 @@ function ExecutionToolRow({
56819
56884
  "size-3.5 shrink-0",
56820
56885
  failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
56821
56886
  );
56822
- const icon = toolCall.status === "pending" ? /* @__PURE__ */ jsx22(LoaderCircle, { className: cn(iconClass, "animate-spin"), "aria-hidden": "true" }) : toolCall.status === "error" ? /* @__PURE__ */ jsx22(CircleAlert, { className: iconClass, "aria-hidden": "true" }) : toolCall.status === "cancelled" ? /* @__PURE__ */ jsx22(X, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "WebSearch" || normalizedName === "WebFetch" ? /* @__PURE__ */ jsx22(Earth, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Bash" || normalizedName === "BgBash" ? /* @__PURE__ */ jsx22(Terminal, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Write" || normalizedName === "Edit" || normalizedName === "MultiEdit" ? /* @__PURE__ */ jsx22(FilePenLine, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Read" || normalizedName === "ReadSkill" || normalizedName === "get_skill_content" ? /* @__PURE__ */ jsx22(BookOpen, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Grep" || normalizedName === "Glob" || normalizedName === "search_skills" ? /* @__PURE__ */ jsx22(Search, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Agent" ? /* @__PURE__ */ jsx22(Bot, { className: iconClass, "aria-hidden": "true" }) : /* @__PURE__ */ jsx22(Wrench, { className: iconClass, "aria-hidden": "true" });
56887
+ const icon = toolCall.status === "pending" ? /* @__PURE__ */ jsx23(LoaderCircle, { className: cn(iconClass, "animate-spin"), "aria-hidden": "true" }) : toolCall.status === "error" ? /* @__PURE__ */ jsx23(CircleAlert, { className: iconClass, "aria-hidden": "true" }) : toolCall.status === "cancelled" ? /* @__PURE__ */ jsx23(X, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "WebSearch" || normalizedName === "WebFetch" ? /* @__PURE__ */ jsx23(Earth, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Bash" || normalizedName === "BgBash" ? /* @__PURE__ */ jsx23(Terminal, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Write" || normalizedName === "Edit" || normalizedName === "MultiEdit" ? /* @__PURE__ */ jsx23(FilePenLine, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Read" || normalizedName === "ReadSkill" || normalizedName === "get_skill_content" ? /* @__PURE__ */ jsx23(BookOpen, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Grep" || normalizedName === "Glob" || normalizedName === "search_skills" ? /* @__PURE__ */ jsx23(Search, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Agent" ? /* @__PURE__ */ jsx23(Bot, { className: iconClass, "aria-hidden": "true" }) : /* @__PURE__ */ jsx23(Wrench, { className: iconClass, "aria-hidden": "true" });
56823
56888
  const rowClassName = cn(
56824
56889
  "flex min-w-0 items-center gap-1 py-1.5 text-xs leading-[22px]",
56825
56890
  failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
@@ -56833,7 +56898,7 @@ function ExecutionToolRow({
56833
56898
  title: label,
56834
56899
  children: [
56835
56900
  icon,
56836
- /* @__PURE__ */ jsx22("span", { className: "min-w-0 truncate", children: label })
56901
+ /* @__PURE__ */ jsx23("span", { className: "min-w-0 truncate", children: label })
56837
56902
  ]
56838
56903
  }
56839
56904
  );
@@ -56882,12 +56947,12 @@ function AssistantTurnBlock({
56882
56947
  )
56883
56948
  );
56884
56949
  const activeQuestionId = questionToolCalls.filter((toolCall) => toolCall.status === "pending").at(-1)?.id;
56885
- const [displayMode, setDisplayMode] = useState30(
56950
+ const [displayMode, setDisplayMode] = useState31(
56886
56951
  () => isStreaming || hasActionableToolCall ? "detail" : "compact"
56887
56952
  );
56888
- const userSelectedDisplayModeRef = useRef24(false);
56889
- const wasStreamingRef = useRef24(isStreaming);
56890
- useEffect21(() => {
56953
+ const userSelectedDisplayModeRef = useRef25(false);
56954
+ const wasStreamingRef = useRef25(isStreaming);
56955
+ useEffect22(() => {
56891
56956
  if (wasStreamingRef.current && !isStreaming && !userSelectedDisplayModeRef.current) {
56892
56957
  setDisplayMode(hasActionableToolCall ? "detail" : "compact");
56893
56958
  }
@@ -56895,11 +56960,11 @@ function AssistantTurnBlock({
56895
56960
  }, [hasActionableToolCall, isStreaming]);
56896
56961
  const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
56897
56962
  const executionDurationMs = getExecutionDurationMs({ messages, isStreaming });
56898
- const [clock, setClock] = useState30(() => Date.now());
56963
+ const [clock, setClock] = useState31(() => Date.now());
56899
56964
  const hasLiveStartTime = messages.some(
56900
56965
  (message) => message.timestamp != null && Number.isFinite(Date.parse(message.timestamp))
56901
56966
  );
56902
- useEffect21(() => {
56967
+ useEffect22(() => {
56903
56968
  if (!isStreaming || !hasLiveStartTime) return;
56904
56969
  const timer = window.setInterval(() => setClock(Date.now()), 1e3);
56905
56970
  return () => window.clearInterval(timer);
@@ -56915,15 +56980,15 @@ function AssistantTurnBlock({
56915
56980
  part: "assistant-turn",
56916
56981
  className: cn("blade-chat-assistant-turn flex flex-col gap-3", classNames?.assistantTurn),
56917
56982
  children: [
56918
- memoryRefs.length > 0 ? /* @__PURE__ */ jsx22(MemoryRefsHint, { refs: memoryRefs, className: classNames?.memoryRefs }) : null,
56919
- hasInterrupted && /* @__PURE__ */ jsx22("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
56920
- hasFailedWithoutContent && /* @__PURE__ */ jsx22("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
56983
+ memoryRefs.length > 0 ? /* @__PURE__ */ jsx23(MemoryRefsHint, { refs: memoryRefs, className: classNames?.memoryRefs }) : null,
56984
+ hasInterrupted && /* @__PURE__ */ jsx23("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
56985
+ hasFailedWithoutContent && /* @__PURE__ */ jsx23("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
56921
56986
  messages.map((message, index2) => {
56922
- return hasRenderableMessageContent(message) ? /* @__PURE__ */ jsx22(
56987
+ return hasRenderableMessageContent(message) ? /* @__PURE__ */ jsx23(
56923
56988
  "div",
56924
56989
  {
56925
56990
  className: "flex flex-col gap-3",
56926
- children: /* @__PURE__ */ jsx22(
56991
+ children: /* @__PURE__ */ jsx23(
56927
56992
  AssistantMessageContent,
56928
56993
  {
56929
56994
  message,
@@ -56937,7 +57002,7 @@ function AssistantTurnBlock({
56937
57002
  message.entry_id ?? `${message.timestamp ?? "assistant"}-${index2}`
56938
57003
  ) : null;
56939
57004
  }),
56940
- inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx22(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null
57005
+ inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx23(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null
56941
57006
  ]
56942
57007
  }
56943
57008
  );
@@ -56949,16 +57014,16 @@ function AssistantTurnBlock({
56949
57014
  part: "assistant-turn",
56950
57015
  className: cn("blade-chat-assistant-turn flex flex-col gap-3", classNames?.assistantTurn),
56951
57016
  children: [
56952
- memoryRefs.length > 0 ? /* @__PURE__ */ jsx22(MemoryRefsHint, { refs: memoryRefs, className: classNames?.memoryRefs }) : null,
56953
- hasInterrupted && /* @__PURE__ */ jsx22("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
56954
- hasFailedWithoutContent && /* @__PURE__ */ jsx22("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
57017
+ memoryRefs.length > 0 ? /* @__PURE__ */ jsx23(MemoryRefsHint, { refs: memoryRefs, className: classNames?.memoryRefs }) : null,
57018
+ hasInterrupted && /* @__PURE__ */ jsx23("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
57019
+ hasFailedWithoutContent && /* @__PURE__ */ jsx23("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
56955
57020
  /* @__PURE__ */ jsxs17("div", { className: "flex w-full items-start gap-2.5", children: [
56956
- /* @__PURE__ */ jsx22(
57021
+ /* @__PURE__ */ jsx23(
56957
57022
  "span",
56958
57023
  {
56959
57024
  className: "grid size-[30px] shrink-0 place-items-center rounded-full bg-[hsl(var(--muted)/0.55)] text-[hsl(var(--foreground))]",
56960
57025
  "aria-hidden": "true",
56961
- children: /* @__PURE__ */ jsx22(Bot, { size: 16 })
57026
+ children: /* @__PURE__ */ jsx23(Bot, { size: 16 })
56962
57027
  }
56963
57028
  ),
56964
57029
  /* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1 pt-0.5", children: [
@@ -56975,14 +57040,14 @@ function AssistantTurnBlock({
56975
57040
  "data-testid": "assistant-execution-summary",
56976
57041
  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",
56977
57042
  children: [
56978
- /* @__PURE__ */ jsx22("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
57043
+ /* @__PURE__ */ jsx23("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
56979
57044
  messages,
56980
57045
  isStreaming,
56981
57046
  durationMs: liveExecutionDurationMs,
56982
57047
  sessionStatus,
56983
57048
  askAnswers
56984
57049
  }) }),
56985
- /* @__PURE__ */ jsx22(
57050
+ /* @__PURE__ */ jsx23(
56986
57051
  ChevronRight,
56987
57052
  {
56988
57053
  size: 14,
@@ -56997,10 +57062,10 @@ function AssistantTurnBlock({
56997
57062
  ]
56998
57063
  }
56999
57064
  ),
57000
- /* @__PURE__ */ jsx22("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
57065
+ /* @__PURE__ */ jsx23("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
57001
57066
  ] })
57002
57067
  ] }),
57003
- effectiveMode === "detail" ? /* @__PURE__ */ jsx22("div", { className: "ml-10 flex flex-col gap-3 pt-1", children: messages.map((message, index2) => {
57068
+ effectiveMode === "detail" ? /* @__PURE__ */ jsx23("div", { className: "ml-10 flex flex-col gap-3 pt-1", children: messages.map((message, index2) => {
57004
57069
  const isLast = index2 === messages.length - 1;
57005
57070
  const streamingThis = isStreaming && isLast;
57006
57071
  const text4 = getMessageText(message);
@@ -57015,7 +57080,7 @@ function AssistantTurnBlock({
57015
57080
  {
57016
57081
  className: "flex flex-col gap-3",
57017
57082
  children: [
57018
- showReasoning && message.reasoning ? /* @__PURE__ */ jsx22(
57083
+ showReasoning && message.reasoning ? /* @__PURE__ */ jsx23(
57019
57084
  ThinkingBlock,
57020
57085
  {
57021
57086
  reasoning: message.reasoning,
@@ -57024,7 +57089,7 @@ function AssistantTurnBlock({
57024
57089
  }
57025
57090
  ) : null,
57026
57091
  orderedParts.length > 0 ? orderedParts.map(
57027
- (part) => part.type === "text" ? /* @__PURE__ */ jsx22(
57092
+ (part) => part.type === "text" ? /* @__PURE__ */ jsx23(
57028
57093
  AssistantMessageContent,
57029
57094
  {
57030
57095
  message: { ...message, content: part.content, tool_calls: turnToolCalls },
@@ -57035,9 +57100,9 @@ function AssistantTurnBlock({
57035
57100
  renderers
57036
57101
  },
57037
57102
  part.key
57038
- ) : /* @__PURE__ */ jsx22("div", { className: "flex flex-col gap-0.5", children: part.toolCalls.map((toolCall) => {
57103
+ ) : /* @__PURE__ */ jsx23("div", { className: "flex flex-col gap-0.5", children: part.toolCalls.map((toolCall) => {
57039
57104
  const custom2 = renderers?.toolCall?.(toolCall);
57040
- return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx22("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx22(AgentLoopBlock, { toolCall, className: classNames?.agentLoop }, toolCall.id) : /* @__PURE__ */ jsx22(
57105
+ return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx23("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx23(AgentLoopBlock, { toolCall, className: classNames?.agentLoop }, toolCall.id) : /* @__PURE__ */ jsx23(
57041
57106
  ExecutionToolRow,
57042
57107
  {
57043
57108
  toolCall,
@@ -57046,7 +57111,7 @@ function AssistantTurnBlock({
57046
57111
  toolCall.id
57047
57112
  );
57048
57113
  }) }, part.key)
57049
- ) : hasRenderableMessageContent(message) && message !== finalMessage ? /* @__PURE__ */ jsx22(
57114
+ ) : hasRenderableMessageContent(message) && message !== finalMessage ? /* @__PURE__ */ jsx23(
57050
57115
  AssistantMessageContent,
57051
57116
  {
57052
57117
  message,
@@ -57057,9 +57122,9 @@ function AssistantTurnBlock({
57057
57122
  renderers
57058
57123
  }
57059
57124
  ) : null,
57060
- orderedParts.length === 0 && toolCalls.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "flex flex-col gap-0.5", children: toolCalls.map((toolCall) => {
57125
+ orderedParts.length === 0 && toolCalls.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "flex flex-col gap-0.5", children: toolCalls.map((toolCall) => {
57061
57126
  const custom2 = renderers?.toolCall?.(toolCall);
57062
- return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx22("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx22(AgentLoopBlock, { toolCall, className: classNames?.agentLoop }, toolCall.id) : /* @__PURE__ */ jsx22(
57127
+ return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx23("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx23(AgentLoopBlock, { toolCall, className: classNames?.agentLoop }, toolCall.id) : /* @__PURE__ */ jsx23(
57063
57128
  ExecutionToolRow,
57064
57129
  {
57065
57130
  toolCall,
@@ -57068,14 +57133,14 @@ function AssistantTurnBlock({
57068
57133
  toolCall.id
57069
57134
  );
57070
57135
  }) }) : null,
57071
- messageToolUiCards.map((entry) => /* @__PURE__ */ jsx22(ToolUiCardView, { card: entry.card, sessionId }, entry.key))
57136
+ messageToolUiCards.map((entry) => /* @__PURE__ */ jsx23(ToolUiCardView, { card: entry.card, sessionId }, entry.key))
57072
57137
  ]
57073
57138
  },
57074
57139
  message.entry_id ?? `${message.timestamp ?? "assistant"}-${index2}`
57075
57140
  );
57076
57141
  }) }) : null,
57077
- effectiveMode === "compact" && inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "ml-10 flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx22(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null,
57078
- finalMessage && (effectiveMode === "compact" || finalOrderedParts.length === 0) ? /* @__PURE__ */ jsx22("div", { className: "ml-10", children: /* @__PURE__ */ jsx22(
57142
+ effectiveMode === "compact" && inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "ml-10 flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx23(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null,
57143
+ finalMessage && (effectiveMode === "compact" || finalOrderedParts.length === 0) ? /* @__PURE__ */ jsx23("div", { className: "ml-10", children: /* @__PURE__ */ jsx23(
57079
57144
  AssistantMessageContent,
57080
57145
  {
57081
57146
  message: finalMessage,
@@ -57085,7 +57150,7 @@ function AssistantTurnBlock({
57085
57150
  renderers
57086
57151
  }
57087
57152
  ) }) : null,
57088
- questionToolCalls.map((toolCall) => /* @__PURE__ */ jsx22(
57153
+ questionToolCalls.map((toolCall) => /* @__PURE__ */ jsx23(
57089
57154
  ToolCallBlock,
57090
57155
  {
57091
57156
  toolCall,
@@ -57111,22 +57176,22 @@ function collectMemoryRefs(messages) {
57111
57176
  return [...refs.values()];
57112
57177
  }
57113
57178
  function MemoryRefsHint({ refs, className }) {
57114
- const [expanded, setExpanded] = useState30(false);
57179
+ const [expanded, setExpanded] = useState31(false);
57115
57180
  const label = refs.some((ref) => ref.skill_name) ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
57116
57181
  return /* @__PURE__ */ jsxs17("div", { part: "memory-refs", className: cn("blade-chat-memory-refs ml-1 w-full max-w-[680px]", className), children: [
57117
57182
  /* @__PURE__ */ jsxs17("button", { type: "button", onClick: () => setExpanded((value) => !value), 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))]", children: [
57118
- /* @__PURE__ */ jsx22(BookOpen, { size: 12 }),
57183
+ /* @__PURE__ */ jsx23(BookOpen, { size: 12 }),
57119
57184
  /* @__PURE__ */ jsxs17("span", { children: [
57120
57185
  label,
57121
57186
  "\uFF08",
57122
57187
  refs.length,
57123
57188
  "\uFF09"
57124
57189
  ] }),
57125
- /* @__PURE__ */ jsx22(ChevronRight, { size: 10, className: cn("transition-transform", expanded && "rotate-90") })
57190
+ /* @__PURE__ */ jsx23(ChevronRight, { size: 10, className: cn("transition-transform", expanded && "rotate-90") })
57126
57191
  ] }),
57127
- expanded ? /* @__PURE__ */ jsx22("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: refs.map((ref) => /* @__PURE__ */ jsxs17("div", { className: "rounded-lg border border-[hsl(var(--border)/0.55)] bg-[hsl(var(--background)/0.72)] px-3 py-2.5 text-xs", children: [
57128
- /* @__PURE__ */ jsx22("p", { className: "line-clamp-2 break-words leading-5", children: ref.content_preview }),
57129
- ref.skill_name ? /* @__PURE__ */ jsx22("span", { className: "mt-1 inline-flex text-[10px] text-[hsl(var(--primary))]", children: ref.skill_name }) : null
57192
+ expanded ? /* @__PURE__ */ jsx23("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: refs.map((ref) => /* @__PURE__ */ jsxs17("div", { className: "rounded-lg border border-[hsl(var(--border)/0.55)] bg-[hsl(var(--background)/0.72)] px-3 py-2.5 text-xs", children: [
57193
+ /* @__PURE__ */ jsx23("p", { className: "line-clamp-2 break-words leading-5", children: ref.content_preview }),
57194
+ ref.skill_name ? /* @__PURE__ */ jsx23("span", { className: "mt-1 inline-flex text-[10px] text-[hsl(var(--primary))]", children: ref.skill_name }) : null
57130
57195
  ] }, ref.id)) }) : null
57131
57196
  ] });
57132
57197
  }
@@ -57142,9 +57207,9 @@ function AssistantMessageContent({
57142
57207
  const imageParts = getImageParts(message.content);
57143
57208
  const fileParts = getFileParts(message.content);
57144
57209
  const failed = message.status === "failed";
57145
- const failedBadge = failed ? /* @__PURE__ */ jsx22("div", { className: "w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }) : null;
57210
+ const failedBadge = failed ? /* @__PURE__ */ jsx23("div", { className: "w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }) : null;
57146
57211
  const customText = text4 ? renderers?.assistantText?.({ message, streaming, compact, sessionId }) : void 0;
57147
- const textContent = text4 ? customText ?? /* @__PURE__ */ jsx22(
57212
+ const textContent = text4 ? customText ?? /* @__PURE__ */ jsx23(
57148
57213
  "div",
57149
57214
  {
57150
57215
  part: "assistant-text",
@@ -57153,7 +57218,7 @@ function AssistantMessageContent({
57153
57218
  compact ? "text-xs leading-[22px] text-[hsl(var(--foreground))]" : "text-[15px] leading-8 text-[hsl(var(--foreground))]",
57154
57219
  classNames?.assistantText
57155
57220
  ),
57156
- children: /* @__PURE__ */ jsx22(
57221
+ children: /* @__PURE__ */ jsx23(
57157
57222
  MarkdownContent,
57158
57223
  {
57159
57224
  mode: streaming ? "streaming" : "static",
@@ -57173,16 +57238,18 @@ function AssistantMessageContent({
57173
57238
  }
57174
57239
  return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-3", children: [
57175
57240
  failedBadge,
57176
- imageParts.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx22(
57177
- "img",
57241
+ imageParts.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx23(
57242
+ MessageImage,
57178
57243
  {
57179
57244
  src: part.image_url.url,
57245
+ width: part.image_url.width,
57246
+ height: part.image_url.height,
57180
57247
  alt: "\u6D88\u606F\u9644\u4EF6",
57181
57248
  className: "max-h-72 rounded-xl border border-[hsl(var(--border))] object-cover"
57182
57249
  },
57183
57250
  part.image_url.url
57184
57251
  )) }) : null,
57185
- fileParts.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "flex flex-wrap gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs17(
57252
+ fileParts.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs17(
57186
57253
  "div",
57187
57254
  {
57188
57255
  part: "file-card",
@@ -57192,8 +57259,8 @@ function AssistantMessageContent({
57192
57259
  ),
57193
57260
  title: part.name,
57194
57261
  children: [
57195
- /* @__PURE__ */ jsx22(FileText, { size: 12, className: "blade-chat-file-card-icon shrink-0" }),
57196
- /* @__PURE__ */ jsx22("span", { className: "blade-chat-file-card-name max-w-56 truncate", children: part.name })
57262
+ /* @__PURE__ */ jsx23(FileText, { size: 12, className: "blade-chat-file-card-icon shrink-0" }),
57263
+ /* @__PURE__ */ jsx23("span", { className: "blade-chat-file-card-name max-w-56 truncate", children: part.name })
57197
57264
  ]
57198
57265
  },
57199
57266
  `${part.name}-${part.data.slice(0, 32)}`
@@ -57204,7 +57271,7 @@ function AssistantMessageContent({
57204
57271
 
57205
57272
  // src/components/RenderErrorBoundary.tsx
57206
57273
  import { Component as Component2 } from "react";
57207
- import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
57274
+ import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
57208
57275
  function getFirstComponentName(componentStack) {
57209
57276
  const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
57210
57277
  return match?.[1] ?? null;
@@ -57237,8 +57304,8 @@ var RenderErrorBoundary = class extends Component2 {
57237
57304
  return children;
57238
57305
  }
57239
57306
  const componentName = getFirstComponentName(componentStack);
57240
- return /* @__PURE__ */ jsx23("div", { className: "blade-chat-render-error rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2", children: [
57241
- /* @__PURE__ */ jsx23(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
57307
+ return /* @__PURE__ */ jsx24("div", { className: "blade-chat-render-error rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2", children: [
57308
+ /* @__PURE__ */ jsx24(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
57242
57309
  /* @__PURE__ */ jsxs18("div", { className: "min-w-0 flex-1", children: [
57243
57310
  /* @__PURE__ */ jsxs18("div", { className: "font-medium", children: [
57244
57311
  label,
@@ -57248,15 +57315,15 @@ var RenderErrorBoundary = class extends Component2 {
57248
57315
  componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
57249
57316
  error61.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
57250
57317
  ] }),
57251
- details ? /* @__PURE__ */ jsx23("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
57318
+ details ? /* @__PURE__ */ jsx24("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
57252
57319
  ] })
57253
57320
  ] }) });
57254
57321
  }
57255
57322
  };
57256
57323
 
57257
57324
  // src/components/PostChatFollowupBlock.tsx
57258
- import { useCallback as useCallback28, useEffect as useEffect22, useRef as useRef25, useState as useState31 } from "react";
57259
- import { Fragment as Fragment8, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
57325
+ import { useCallback as useCallback28, useEffect as useEffect23, useRef as useRef26, useState as useState32 } from "react";
57326
+ import { Fragment as Fragment8, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
57260
57327
  function emitInteraction(callback, event) {
57261
57328
  try {
57262
57329
  callback?.(event);
@@ -57275,7 +57342,7 @@ function ArtifactCard({
57275
57342
  onArtifactOpened
57276
57343
  }) {
57277
57344
  const client = useBladeClient();
57278
- const [downloading, setDownloading] = useState31(false);
57345
+ const [downloading, setDownloading] = useState32(false);
57279
57346
  const name = artifact.label || basename(artifact.target);
57280
57347
  if (artifact.kind === "link") {
57281
57348
  return /* @__PURE__ */ jsxs19(
@@ -57289,9 +57356,9 @@ function ArtifactCard({
57289
57356
  ${artifact.target}`,
57290
57357
  className: "group relative flex min-w-0 items-center gap-1.5 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2 py-1.5 text-xs text-[hsl(var(--card-foreground))] hover:bg-[hsl(var(--accent))]",
57291
57358
  children: [
57292
- /* @__PURE__ */ jsx24(Globe, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
57293
- /* @__PURE__ */ jsx24("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
57294
- /* @__PURE__ */ jsx24(ArrowUpRight, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
57359
+ /* @__PURE__ */ jsx25(Globe, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
57360
+ /* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
57361
+ /* @__PURE__ */ jsx25(ArrowUpRight, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
57295
57362
  ]
57296
57363
  }
57297
57364
  );
@@ -57326,7 +57393,7 @@ ${artifact.target}`,
57326
57393
  setDownloading(false);
57327
57394
  }
57328
57395
  };
57329
- return /* @__PURE__ */ jsx24(
57396
+ return /* @__PURE__ */ jsx25(
57330
57397
  "a",
57331
57398
  {
57332
57399
  href: downloadUrl,
@@ -57381,15 +57448,15 @@ function ResultFeedback({
57381
57448
  onFeedbackSaved
57382
57449
  }) {
57383
57450
  const client = useBladeClient();
57384
- const [saved, setSaved] = useState31(savedFeedback ?? null);
57385
- const [helpful, setHelpful] = useState31(savedFeedback?.helpful ?? null);
57386
- const [reason, setReason] = useState31(savedFeedback?.reason ?? null);
57387
- const [saving, setSaving] = useState31(false);
57388
- const [saveError, setSaveError] = useState31(false);
57389
- const reportedShown = useRef25(false);
57390
- const latestChoice = useRef25(null);
57451
+ const [saved, setSaved] = useState32(savedFeedback ?? null);
57452
+ const [helpful, setHelpful] = useState32(savedFeedback?.helpful ?? null);
57453
+ const [reason, setReason] = useState32(savedFeedback?.reason ?? null);
57454
+ const [saving, setSaving] = useState32(false);
57455
+ const [saveError, setSaveError] = useState32(false);
57456
+ const reportedShown = useRef26(false);
57457
+ const latestChoice = useRef26(null);
57391
57458
  const eligible = followup.feedback_eligible === true && Boolean(sessionId) && !isViewer;
57392
- useEffect22(() => {
57459
+ useEffect23(() => {
57393
57460
  if (!eligible || reportedShown.current) return;
57394
57461
  reportedShown.current = true;
57395
57462
  emitInteraction(onInteraction, {
@@ -57398,7 +57465,7 @@ function ResultFeedback({
57398
57465
  assistantEntryId: followup.assistant_entry_id
57399
57466
  });
57400
57467
  }, [eligible, followup.assistant_entry_id, onInteraction, sessionId]);
57401
- useEffect22(() => {
57468
+ useEffect23(() => {
57402
57469
  if (!savedFeedback || latestChoice.current) return;
57403
57470
  setSaved(savedFeedback);
57404
57471
  setHelpful(savedFeedback.helpful);
@@ -57445,9 +57512,9 @@ function ResultFeedback({
57445
57512
  "aria-label": "\u7ED3\u679C\u53CD\u9988",
57446
57513
  className: "flex flex-col gap-2 border-t border-[hsl(var(--border))] pt-3",
57447
57514
  children: [
57448
- /* @__PURE__ */ jsx24("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
57515
+ /* @__PURE__ */ jsx25("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
57449
57516
  /* @__PURE__ */ jsxs19("div", { className: "flex flex-wrap gap-1.5", children: [
57450
- /* @__PURE__ */ jsx24(
57517
+ /* @__PURE__ */ jsx25(
57451
57518
  "button",
57452
57519
  {
57453
57520
  type: "button",
@@ -57458,7 +57525,7 @@ function ResultFeedback({
57458
57525
  children: "\u6709\u5E2E\u52A9"
57459
57526
  }
57460
57527
  ),
57461
- /* @__PURE__ */ jsx24(
57528
+ /* @__PURE__ */ jsx25(
57462
57529
  "button",
57463
57530
  {
57464
57531
  type: "button",
@@ -57470,7 +57537,7 @@ function ResultFeedback({
57470
57537
  }
57471
57538
  )
57472
57539
  ] }),
57473
- helpful === false ? /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: FEEDBACK_REASONS.map((item) => /* @__PURE__ */ jsx24(
57540
+ helpful === false ? /* @__PURE__ */ jsx25("div", { className: "flex flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: FEEDBACK_REASONS.map((item) => /* @__PURE__ */ jsx25(
57474
57541
  "button",
57475
57542
  {
57476
57543
  type: "button",
@@ -57483,8 +57550,8 @@ function ResultFeedback({
57483
57550
  item.value
57484
57551
  )) }) : null,
57485
57552
  saveError ? /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--destructive))]", children: [
57486
- /* @__PURE__ */ jsx24("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
57487
- /* @__PURE__ */ jsx24(
57553
+ /* @__PURE__ */ jsx25("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
57554
+ /* @__PURE__ */ jsx25(
57488
57555
  "button",
57489
57556
  {
57490
57557
  type: "button",
@@ -57496,7 +57563,7 @@ function ResultFeedback({
57496
57563
  children: "\u91CD\u8BD5"
57497
57564
  }
57498
57565
  )
57499
- ] }) : saved ? /* @__PURE__ */ jsx24("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
57566
+ ] }) : saved ? /* @__PURE__ */ jsx25("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
57500
57567
  ]
57501
57568
  }
57502
57569
  );
@@ -57512,14 +57579,14 @@ function PostChatFollowupBlock({
57512
57579
  className,
57513
57580
  suggestionClassName
57514
57581
  }) {
57515
- const [expanded, setExpanded] = useState31(false);
57516
- const adopted = useRef25(/* @__PURE__ */ new Set());
57517
- const reportedSuggestions = useRef25(false);
57518
- const reportedArtifacts = useRef25(/* @__PURE__ */ new Set());
57519
- const openedArtifacts = useRef25(/* @__PURE__ */ new Set());
57582
+ const [expanded, setExpanded] = useState32(false);
57583
+ const adopted = useRef26(/* @__PURE__ */ new Set());
57584
+ const reportedSuggestions = useRef26(false);
57585
+ const reportedArtifacts = useRef26(/* @__PURE__ */ new Set());
57586
+ const openedArtifacts = useRef26(/* @__PURE__ */ new Set());
57520
57587
  const artifacts = followup.final_artifacts ?? [];
57521
57588
  const visibleArtifacts = expanded ? artifacts : artifacts.slice(0, 3);
57522
- useEffect22(() => {
57589
+ useEffect23(() => {
57523
57590
  if (!reportedSuggestions.current && followup.suggestions.length > 0) {
57524
57591
  reportedSuggestions.current = true;
57525
57592
  emitInteraction(onInteraction, {
@@ -57576,12 +57643,12 @@ function PostChatFollowupBlock({
57576
57643
  children: [
57577
57644
  followup.recaption || artifacts.length > 0 ? /* @__PURE__ */ jsxs19("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", className: "flex flex-col gap-2", children: [
57578
57645
  /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]", children: [
57579
- /* @__PURE__ */ jsx24(Sparkles, { size: 14 }),
57646
+ /* @__PURE__ */ jsx25(Sparkles, { size: 14 }),
57580
57647
  "\u672C\u8F6E\u5C0F\u7ED3"
57581
57648
  ] }),
57582
- followup.recaption ? /* @__PURE__ */ jsx24("p", { className: "text-[13px] leading-5", children: followup.recaption }) : null,
57649
+ followup.recaption ? /* @__PURE__ */ jsx25("p", { className: "text-[13px] leading-5", children: followup.recaption }) : null,
57583
57650
  artifacts.length > 0 ? /* @__PURE__ */ jsxs19(Fragment8, { children: [
57584
- /* @__PURE__ */ jsx24("div", { className: "grid max-w-full grid-cols-3 gap-1.5", children: visibleArtifacts.map((artifact, artifactIndex) => /* @__PURE__ */ jsx24(
57651
+ /* @__PURE__ */ jsx25("div", { className: "grid max-w-full grid-cols-3 gap-1.5", children: visibleArtifacts.map((artifact, artifactIndex) => /* @__PURE__ */ jsx25(
57585
57652
  ArtifactCard,
57586
57653
  {
57587
57654
  artifact,
@@ -57602,14 +57669,14 @@ function PostChatFollowupBlock({
57602
57669
  className: "flex w-fit items-center gap-0.5 text-[11px] text-[hsl(var(--muted-foreground))]",
57603
57670
  children: [
57604
57671
  expanded ? "\u6536\u8D77" : `\u5C55\u5F00 ${artifacts.length - 3} \u4E2A`,
57605
- /* @__PURE__ */ jsx24(ChevronDown, { size: 13, className: expanded ? "rotate-180" : void 0 })
57672
+ /* @__PURE__ */ jsx25(ChevronDown, { size: 13, className: expanded ? "rotate-180" : void 0 })
57606
57673
  ]
57607
57674
  }
57608
57675
  ) : null
57609
57676
  ] }) : null
57610
57677
  ] }) : null,
57611
57678
  followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs19("section", { "aria-label": "\u4E0B\u4E00\u6B65\u5EFA\u8BAE", className: "flex flex-col gap-1.5", children: [
57612
- /* @__PURE__ */ jsx24("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
57679
+ /* @__PURE__ */ jsx25("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
57613
57680
  followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */ jsxs19(
57614
57681
  "button",
57615
57682
  {
@@ -57633,14 +57700,14 @@ function PostChatFollowupBlock({
57633
57700
  suggestionClassName
57634
57701
  ),
57635
57702
  children: [
57636
- /* @__PURE__ */ jsx24("span", { children: suggestion }),
57637
- /* @__PURE__ */ jsx24(ArrowRight, { size: 14, className: "ml-auto shrink-0" })
57703
+ /* @__PURE__ */ jsx25("span", { children: suggestion }),
57704
+ /* @__PURE__ */ jsx25(ArrowRight, { size: 14, className: "ml-auto shrink-0" })
57638
57705
  ]
57639
57706
  },
57640
57707
  suggestion
57641
57708
  ))
57642
57709
  ] }) : null,
57643
- /* @__PURE__ */ jsx24(
57710
+ /* @__PURE__ */ jsx25(
57644
57711
  ResultFeedback,
57645
57712
  {
57646
57713
  followup,
@@ -57717,31 +57784,31 @@ function parseWhatIfPrompt(text4) {
57717
57784
  }
57718
57785
 
57719
57786
  // src/components/WhatIfUserBubble.tsx
57720
- import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
57787
+ import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
57721
57788
  function WhatIfUserBubble({ parsed, onQuoteClick }) {
57722
57789
  const { fromStep, quotes, userText } = parsed;
57723
57790
  return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col items-end gap-2", children: [
57724
57791
  /* @__PURE__ */ jsxs20("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: [
57725
- /* @__PURE__ */ jsx25(RefreshCcw, { size: 10 }),
57726
- /* @__PURE__ */ jsx25("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
57792
+ /* @__PURE__ */ jsx26(RefreshCcw, { size: 10 }),
57793
+ /* @__PURE__ */ jsx26("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
57727
57794
  ] }),
57728
- quotes.length > 0 && /* @__PURE__ */ jsx25("div", { className: "flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2", children: quotes.map((quote, index2) => {
57795
+ quotes.length > 0 && /* @__PURE__ */ jsx26("div", { className: "flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2", children: quotes.map((quote, index2) => {
57729
57796
  const clickable = quote.stepNumber != null && !!onQuoteClick;
57730
57797
  const label = quote.stepNumber != null ? `\u6B65\u9AA4${quote.stepNumber} \xB7 ${quote.label}` : quote.label;
57731
57798
  return /* @__PURE__ */ jsxs20("div", { className: "rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.8)] px-3 py-2 text-left", children: [
57732
57799
  /* @__PURE__ */ jsxs20("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: [
57733
- /* @__PURE__ */ jsx25("span", { children: "\u21B3" }),
57734
- /* @__PURE__ */ jsx25("span", { className: "truncate", children: label })
57800
+ /* @__PURE__ */ jsx26("span", { children: "\u21B3" }),
57801
+ /* @__PURE__ */ jsx26("span", { className: "truncate", children: label })
57735
57802
  ] }),
57736
- quote.snapshot ? /* @__PURE__ */ jsx25("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__ */ jsx25(MarkdownContent, { className: "blade-chat-prose", children: quote.snapshot }) }) : null
57803
+ quote.snapshot ? /* @__PURE__ */ jsx26("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__ */ jsx26(MarkdownContent, { className: "blade-chat-prose", children: quote.snapshot }) }) : null
57737
57804
  ] }, `${quote.stepNumber ?? "x"}-${index2}`);
57738
57805
  }) }),
57739
- userText && /* @__PURE__ */ jsx25("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__ */ jsx25(MarkdownContent, { className: "blade-chat-prose", children: userText }) })
57806
+ userText && /* @__PURE__ */ jsx26("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__ */ jsx26(MarkdownContent, { className: "blade-chat-prose", children: userText }) })
57740
57807
  ] });
57741
57808
  }
57742
57809
 
57743
57810
  // src/components/UserMessageBubble.tsx
57744
- import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
57811
+ import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
57745
57812
  function isUserMessage(message) {
57746
57813
  return message.role === "user";
57747
57814
  }
@@ -57756,26 +57823,28 @@ function UserMessageBubble({ message, classNames, renderers }) {
57756
57823
  const whatifParsed = text4 && imageParts.length === 0 && fileParts.length === 0 ? parseWhatIfPrompt(text4) : null;
57757
57824
  const customBubble = renderers?.userMessage?.({ message });
57758
57825
  if (whatifParsed) {
57759
- return /* @__PURE__ */ jsx26("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", classNames?.userMessage), children: /* @__PURE__ */ jsx26("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: customBubble ?? /* @__PURE__ */ jsx26(
57826
+ return /* @__PURE__ */ jsx27("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", classNames?.userMessage), children: /* @__PURE__ */ jsx27("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: customBubble ?? /* @__PURE__ */ jsx27(
57760
57827
  "div",
57761
57828
  {
57762
57829
  part: "user-bubble",
57763
57830
  className: cn("blade-chat-user-bubble", classNames?.userBubble),
57764
- children: /* @__PURE__ */ jsx26(WhatIfUserBubble, { parsed: whatifParsed })
57831
+ children: /* @__PURE__ */ jsx27(WhatIfUserBubble, { parsed: whatifParsed })
57765
57832
  }
57766
57833
  ) }) });
57767
57834
  }
57768
- return /* @__PURE__ */ jsx26("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", classNames?.userMessage), children: /* @__PURE__ */ jsxs21("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: [
57769
- imageParts.length > 0 && /* @__PURE__ */ jsx26("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx26(
57770
- "img",
57835
+ return /* @__PURE__ */ jsx27("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", classNames?.userMessage), children: /* @__PURE__ */ jsxs21("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: [
57836
+ imageParts.length > 0 && /* @__PURE__ */ jsx27("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx27(
57837
+ MessageImage,
57771
57838
  {
57772
57839
  src: part.image_url.url,
57840
+ width: part.image_url.width,
57841
+ height: part.image_url.height,
57773
57842
  alt: "\u7528\u6237\u4E0A\u4F20\u7684\u56FE\u7247",
57774
57843
  className: "max-h-64 rounded-xl border border-[hsl(var(--user-msg-border))] object-cover"
57775
57844
  },
57776
57845
  part.image_url.url
57777
57846
  )) }),
57778
- fileParts.length > 0 && /* @__PURE__ */ jsx26("div", { className: "flex flex-col items-end gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs21(
57847
+ fileParts.length > 0 && /* @__PURE__ */ jsx27("div", { className: "flex flex-col items-end gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs21(
57779
57848
  "div",
57780
57849
  {
57781
57850
  part: "file-card",
@@ -57784,13 +57853,13 @@ function UserMessageBubble({ message, classNames, renderers }) {
57784
57853
  classNames?.fileCard
57785
57854
  ),
57786
57855
  children: [
57787
- /* @__PURE__ */ jsx26(FileText, { size: 12, className: "blade-chat-file-card-icon shrink-0" }),
57788
- /* @__PURE__ */ jsx26("span", { className: "blade-chat-file-card-name max-w-56 truncate", title: part.name, children: part.name })
57856
+ /* @__PURE__ */ jsx27(FileText, { size: 12, className: "blade-chat-file-card-icon shrink-0" }),
57857
+ /* @__PURE__ */ jsx27("span", { className: "blade-chat-file-card-name max-w-56 truncate", title: part.name, children: part.name })
57789
57858
  ]
57790
57859
  },
57791
57860
  `${part.name}-${part.data.length}`
57792
57861
  )) }),
57793
- text4 && (customBubble ?? /* @__PURE__ */ jsx26(
57862
+ text4 && (customBubble ?? /* @__PURE__ */ jsx27(
57794
57863
  "div",
57795
57864
  {
57796
57865
  part: "user-bubble",
@@ -57798,12 +57867,12 @@ function UserMessageBubble({ message, classNames, renderers }) {
57798
57867
  "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))]",
57799
57868
  classNames?.userBubble
57800
57869
  ),
57801
- children: /* @__PURE__ */ jsx26(MarkdownContent, { className: "blade-chat-prose", children: text4 })
57870
+ children: /* @__PURE__ */ jsx27(MarkdownContent, { className: "blade-chat-prose", children: text4 })
57802
57871
  }
57803
57872
  )),
57804
57873
  text4 && isSending(message) && /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
57805
- /* @__PURE__ */ jsx26(LoaderCircle, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
57806
- /* @__PURE__ */ jsx26("span", { children: "\u53D1\u9001\u4E2D" })
57874
+ /* @__PURE__ */ jsx27(LoaderCircle, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
57875
+ /* @__PURE__ */ jsx27("span", { children: "\u53D1\u9001\u4E2D" })
57807
57876
  ] })
57808
57877
  ] }) });
57809
57878
  }
@@ -57812,11 +57881,11 @@ function ErrorMessageBlock({
57812
57881
  className
57813
57882
  }) {
57814
57883
  const text4 = chatErrorForDisplay(getTextContent3(message.content));
57815
- return /* @__PURE__ */ jsx26("div", { part: "error-row", className: cn("blade-chat-error-row flex min-w-0 justify-start", className), children: /* @__PURE__ */ jsx26("div", { className: "blade-chat-error-block min-w-0 max-w-full whitespace-pre-wrap break-words border-l-[3px] border-[hsl(var(--border))] px-3 py-1 text-left text-sm leading-7 text-[hsl(var(--muted-foreground))] [overflow-wrap:anywhere]", children: text4 }) });
57884
+ return /* @__PURE__ */ jsx27("div", { part: "error-row", className: cn("blade-chat-error-row flex min-w-0 justify-start", className), children: /* @__PURE__ */ jsx27("div", { className: "blade-chat-error-block min-w-0 max-w-full whitespace-pre-wrap break-words border-l-[3px] border-[hsl(var(--border))] px-3 py-1 text-left text-sm leading-7 text-[hsl(var(--muted-foreground))] [overflow-wrap:anywhere]", children: text4 }) });
57816
57885
  }
57817
57886
 
57818
57887
  // src/components/MessageList.tsx
57819
- import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
57888
+ import { jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
57820
57889
  function parseModeChange(message) {
57821
57890
  if (message.kind !== "mode_change" || typeof message.content !== "string") {
57822
57891
  return null;
@@ -57894,10 +57963,10 @@ function MessageList({
57894
57963
  const contentReveal = useTypewriterReveal(revealContentText, isRevealLive, revealTargetKey);
57895
57964
  const reasoningReveal = useTypewriterReveal(revealReasoningText, isRevealLive, revealTargetKey);
57896
57965
  const isRevealingAny = contentReveal.isRevealing || reasoningReveal.isRevealing;
57897
- useEffect23(() => {
57966
+ useEffect24(() => {
57898
57967
  onRevealingChange?.(isRevealingAny);
57899
57968
  }, [isRevealingAny, onRevealingChange]);
57900
- useEffect23(() => {
57969
+ useEffect24(() => {
57901
57970
  if (isStopping) {
57902
57971
  contentReveal.flushNow();
57903
57972
  reasoningReveal.flushNow();
@@ -57984,8 +58053,8 @@ function MessageList({
57984
58053
  }
57985
58054
  return blocks;
57986
58055
  }, [visibleRootMessages, isStreaming, isRevealingAny]);
57987
- const rootRef = useRef26(null);
57988
- const stopAutoScrollRef = useRef26(null);
58056
+ const rootRef = useRef27(null);
58057
+ const stopAutoScrollRef = useRef27(null);
57989
58058
  const {
57990
58059
  items: turnNavItems,
57991
58060
  activeEntryId: activeNavTurnId,
@@ -58005,7 +58074,7 @@ function MessageList({
58005
58074
  isEntryLoaded: (entryId) => findEntryRow(rootRef.current, entryId) !== null,
58006
58075
  beforeSeek: () => stopAutoScrollRef.current?.()
58007
58076
  });
58008
- const [viewportNavTurnId, setViewportNavTurnId] = useState32(null);
58077
+ const [viewportNavTurnId, setViewportNavTurnId] = useState33(null);
58009
58078
  const latestNavTurnId = turnNavItems.at(-1)?.id ?? null;
58010
58079
  return /* @__PURE__ */ jsxs22(
58011
58080
  "div",
@@ -58014,8 +58083,8 @@ function MessageList({
58014
58083
  part: "messages",
58015
58084
  className: cn("blade-chat-messages relative min-h-0 flex-1", classNames?.messageList),
58016
58085
  children: [
58017
- isStreaming || isRevealingAny ? /* @__PURE__ */ jsx27("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
58018
- /* @__PURE__ */ jsx27(
58086
+ isStreaming || isRevealingAny ? /* @__PURE__ */ jsx28("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
58087
+ /* @__PURE__ */ jsx28(
58019
58088
  TurnNavRail,
58020
58089
  {
58021
58090
  items: turnNavItems,
@@ -58033,23 +58102,23 @@ function MessageList({
58033
58102
  initial: "instant",
58034
58103
  resize: "instant",
58035
58104
  children: [
58036
- /* @__PURE__ */ jsx27(StickToBottom.Content, { part: "messages-scroll", className: cn("blade-chat-messages-scroll", classNames?.messagesScroll), children: /* @__PURE__ */ jsxs22("div", { part: "messages-content", className: cn("blade-chat-messages-content mx-auto max-w-[748px]", classNames?.messagesContent), children: [
58037
- historyPaging && (historyPaging.hasOlder || historyPaging.loading) ? /* @__PURE__ */ jsx27(LoadOlderSentinel, { ...historyPaging }) : null,
58105
+ /* @__PURE__ */ jsx28(StickToBottom.Content, { part: "messages-scroll", className: cn("blade-chat-messages-scroll", classNames?.messagesScroll), children: /* @__PURE__ */ jsxs22("div", { part: "messages-content", className: cn("blade-chat-messages-content mx-auto max-w-[748px]", classNames?.messagesContent), children: [
58106
+ historyPaging && (historyPaging.hasOlder || historyPaging.loading) ? /* @__PURE__ */ jsx28(LoadOlderSentinel, { ...historyPaging }) : null,
58038
58107
  /* @__PURE__ */ jsxs22("div", { className: "flex min-w-0 flex-col", children: [
58039
58108
  renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */ jsxs22("div", { part: "empty", className: cn("blade-chat-empty", classNames?.empty), children: [
58040
- /* @__PURE__ */ jsx27(MessageSquare, { size: 40, strokeWidth: 1.5 }),
58041
- /* @__PURE__ */ jsx27("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
58042
- /* @__PURE__ */ jsx27("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
58109
+ /* @__PURE__ */ jsx28(MessageSquare, { size: 40, strokeWidth: 1.5 }),
58110
+ /* @__PURE__ */ jsx28("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
58111
+ /* @__PURE__ */ jsx28("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
58043
58112
  ] }) : renderBlocks.map((block) => {
58044
58113
  if (block.type === "message") {
58045
- return /* @__PURE__ */ jsx27("div", { "data-entry-id": block.message.entry_id, children: isUserMessage(block.message) ? /* @__PURE__ */ jsx27(
58114
+ return /* @__PURE__ */ jsx28("div", { "data-entry-id": block.message.entry_id, children: isUserMessage(block.message) ? /* @__PURE__ */ jsx28(
58046
58115
  UserMessageBubble,
58047
58116
  {
58048
58117
  message: block.message,
58049
58118
  classNames,
58050
58119
  renderers
58051
58120
  }
58052
- ) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx27(
58121
+ ) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx28(
58053
58122
  ErrorMessageBlock,
58054
58123
  {
58055
58124
  message: block.message,
@@ -58067,14 +58136,14 @@ function MessageList({
58067
58136
  (message) => message.entry_id === postChatFollowup.assistant_entry_id
58068
58137
  )
58069
58138
  );
58070
- return /* @__PURE__ */ jsx27("div", { "data-entry-id": displayMessages[0]?.entry_id, children: /* @__PURE__ */ jsxs22(
58139
+ return /* @__PURE__ */ jsx28("div", { "data-entry-id": displayMessages[0]?.entry_id, children: /* @__PURE__ */ jsxs22(
58071
58140
  RenderErrorBoundary,
58072
58141
  {
58073
58142
  label: "\u52A9\u624B\u6D88\u606F",
58074
58143
  details: block.key,
58075
58144
  resetKey: getMessageResetSignature(displayMessages),
58076
58145
  children: [
58077
- /* @__PURE__ */ jsx27(
58146
+ /* @__PURE__ */ jsx28(
58078
58147
  AssistantTurnBlock,
58079
58148
  {
58080
58149
  messages: displayMessages,
@@ -58088,8 +58157,8 @@ function MessageList({
58088
58157
  sessionId
58089
58158
  }
58090
58159
  ),
58091
- blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx27(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
58092
- hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx27(
58160
+ blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx28(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
58161
+ hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx28(
58093
58162
  PostChatFollowupBlock,
58094
58163
  {
58095
58164
  followup: postChatFollowup,
@@ -58113,19 +58182,19 @@ function MessageList({
58113
58182
  {
58114
58183
  className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]",
58115
58184
  children: [
58116
- /* @__PURE__ */ jsx27(Layers, { size: 12 }),
58117
- /* @__PURE__ */ jsx27("span", { children: "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
58185
+ /* @__PURE__ */ jsx28(Layers, { size: 12 }),
58186
+ /* @__PURE__ */ jsx28("span", { children: "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
58118
58187
  ]
58119
58188
  },
58120
58189
  block.key
58121
58190
  );
58122
58191
  }
58123
- return /* @__PURE__ */ jsx27(PlanningDivider, { kind: block.kind }, block.key);
58192
+ return /* @__PURE__ */ jsx28(PlanningDivider, { kind: block.kind }, block.key);
58124
58193
  }),
58125
- sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */ jsx27("div", { className: "flex", children: /* @__PURE__ */ jsx27("div", { className: "rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }) }) : null
58194
+ sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */ jsx28("div", { className: "flex", children: /* @__PURE__ */ jsx28("div", { className: "rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }) }) : null
58126
58195
  ] })
58127
58196
  ] }) }),
58128
- /* @__PURE__ */ jsx27(
58197
+ /* @__PURE__ */ jsx28(
58129
58198
  PinLatestUserMessage,
58130
58199
  {
58131
58200
  userMessageCount: userMessages.length,
@@ -58135,9 +58204,9 @@ function MessageList({
58135
58204
  },
58136
58205
  sessionId ?? "no-session"
58137
58206
  ),
58138
- /* @__PURE__ */ jsx27(ScrollToBottomButton, { className: classNames?.scrollToBottom }),
58139
- /* @__PURE__ */ jsx27(StopAutoScrollBridge, { stopRef: stopAutoScrollRef }),
58140
- /* @__PURE__ */ jsx27(
58207
+ /* @__PURE__ */ jsx28(ScrollToBottomButton, { className: classNames?.scrollToBottom }),
58208
+ /* @__PURE__ */ jsx28(StopAutoScrollBridge, { stopRef: stopAutoScrollRef }),
58209
+ /* @__PURE__ */ jsx28(
58141
58210
  ViewportTurnBridge,
58142
58211
  {
58143
58212
  rootRef,
@@ -58159,10 +58228,10 @@ function LoadOlderSentinel({
58159
58228
  loadOlder
58160
58229
  }) {
58161
58230
  const { contentRef, scrollRef } = useStickToBottomContext();
58162
- const sentinelRef = useRef26(null);
58163
- const stateRef = useRef26({ hasOlder, loading, loadOlder });
58231
+ const sentinelRef = useRef27(null);
58232
+ const stateRef = useRef27({ hasOlder, loading, loadOlder });
58164
58233
  stateRef.current = { hasOlder, loading, loadOlder };
58165
- useEffect23(() => {
58234
+ useEffect24(() => {
58166
58235
  const sentinel = sentinelRef.current;
58167
58236
  const scroller = scrollRef.current;
58168
58237
  if (!sentinel || !scroller || typeof IntersectionObserver === "undefined") return;
@@ -58221,7 +58290,7 @@ function LoadOlderSentinel({
58221
58290
  observer.disconnect();
58222
58291
  };
58223
58292
  }, [contentRef, scrollRef]);
58224
- return /* @__PURE__ */ jsx27("div", { ref: sentinelRef, "data-history-sentinel": true, className: "flex h-6 items-center justify-center", children: loading ? /* @__PURE__ */ jsx27("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u52A0\u8F7D\u66F4\u65E9\u6D88\u606F\u2026" }) : null });
58293
+ return /* @__PURE__ */ jsx28("div", { ref: sentinelRef, "data-history-sentinel": true, className: "flex h-6 items-center justify-center", children: loading ? /* @__PURE__ */ jsx28("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u52A0\u8F7D\u66F4\u65E9\u6D88\u606F\u2026" }) : null });
58225
58294
  }
58226
58295
  function PinLatestUserMessage({
58227
58296
  userMessageCount,
@@ -58230,8 +58299,8 @@ function PinLatestUserMessage({
58230
58299
  targetKey
58231
58300
  }) {
58232
58301
  const { contentRef, scrollRef, scrollToBottom, stopScroll } = useStickToBottomContext();
58233
- const previousCountRef = useRef26(userMessageCount);
58234
- const spacerHeightRef = useRef26(0);
58302
+ const previousCountRef = useRef27(userMessageCount);
58303
+ const spacerHeightRef = useRef27(0);
58235
58304
  const getScrollElement = useCallback29(() => scrollRef.current, [scrollRef]);
58236
58305
  const getContentElement = useCallback29(() => contentRef.current, [contentRef]);
58237
58306
  const getTargetElement = useCallback29(() => {
@@ -58273,7 +58342,7 @@ function PinLatestUserMessage({
58273
58342
  stopAutoScroll: stopScroll,
58274
58343
  scrollToBottom
58275
58344
  });
58276
- useEffect23(() => {
58345
+ useEffect24(() => {
58277
58346
  if (userMessageCount > previousCountRef.current && !shouldPinLatestUser) {
58278
58347
  scrollToBottom("instant");
58279
58348
  }
@@ -58283,9 +58352,9 @@ function PinLatestUserMessage({
58283
58352
  }
58284
58353
  function ScrollToBottomButton({ className }) {
58285
58354
  const { isAtBottom, scrollToBottom } = useStickToBottomContext();
58286
- const [visible, setVisible] = useState32(false);
58287
- const hideTimerRef = useRef26(null);
58288
- useEffect23(() => {
58355
+ const [visible, setVisible] = useState33(false);
58356
+ const hideTimerRef = useRef27(null);
58357
+ useEffect24(() => {
58289
58358
  if (isAtBottom) {
58290
58359
  if (!hideTimerRef.current) {
58291
58360
  hideTimerRef.current = setTimeout(() => {
@@ -58328,20 +58397,20 @@ function ScrollToBottomButton({ className }) {
58328
58397
  className
58329
58398
  ),
58330
58399
  children: [
58331
- /* @__PURE__ */ jsx27(ChevronDown, { size: 14 }),
58332
- /* @__PURE__ */ jsx27("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
58400
+ /* @__PURE__ */ jsx28(ChevronDown, { size: 14 }),
58401
+ /* @__PURE__ */ jsx28("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
58333
58402
  ]
58334
58403
  }
58335
58404
  );
58336
58405
  }
58337
58406
  function PlanningDivider({ kind }) {
58338
58407
  return /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3 py-1", children: [
58339
- /* @__PURE__ */ jsx27("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
58408
+ /* @__PURE__ */ jsx28("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
58340
58409
  /* @__PURE__ */ jsxs22("div", { className: "inline-flex items-center gap-1.5 rounded-full border border-amber-500/30 bg-amber-500/10 px-3 py-1 text-[11px] text-amber-300", children: [
58341
- /* @__PURE__ */ jsx27(Lightbulb, { size: 12 }),
58342
- /* @__PURE__ */ jsx27("span", { children: kind === "enter" ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
58410
+ /* @__PURE__ */ jsx28(Lightbulb, { size: 12 }),
58411
+ /* @__PURE__ */ jsx28("span", { children: kind === "enter" ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
58343
58412
  ] }),
58344
- /* @__PURE__ */ jsx27("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
58413
+ /* @__PURE__ */ jsx28("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
58345
58414
  ] });
58346
58415
  }
58347
58416
  function findEntryRow(root, entryId) {
@@ -58357,13 +58426,13 @@ function ViewportTurnBridge({
58357
58426
  onActiveChange
58358
58427
  }) {
58359
58428
  const { scrollRef } = useStickToBottomContext();
58360
- const itemsRef = useRef26(items);
58361
- const updateRef = useRef26(null);
58362
- useEffect23(() => {
58429
+ const itemsRef = useRef27(items);
58430
+ const updateRef = useRef27(null);
58431
+ useEffect24(() => {
58363
58432
  itemsRef.current = items;
58364
58433
  updateRef.current?.();
58365
58434
  }, [items]);
58366
- useEffect23(() => {
58435
+ useEffect24(() => {
58367
58436
  const scroller = scrollRef.current;
58368
58437
  const root = rootRef.current;
58369
58438
  if (!scroller || !root) return;
@@ -58407,7 +58476,7 @@ function ViewportTurnBridge({
58407
58476
  var VIEWPORT_ACTIVE_OFFSET = 8;
58408
58477
  function StopAutoScrollBridge({ stopRef }) {
58409
58478
  const { stopScroll } = useStickToBottomContext();
58410
- useEffect23(() => {
58479
+ useEffect24(() => {
58411
58480
  stopRef.current = stopScroll;
58412
58481
  return () => {
58413
58482
  stopRef.current = null;
@@ -58417,7 +58486,7 @@ function StopAutoScrollBridge({ stopRef }) {
58417
58486
  }
58418
58487
 
58419
58488
  // src/components/ChatSurface.tsx
58420
- import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
58489
+ import { jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
58421
58490
  function themeAttr(theme) {
58422
58491
  return theme === "dark" ? "dark" : void 0;
58423
58492
  }
@@ -58457,7 +58526,7 @@ function ChatSurface({
58457
58526
  onRevealingChange,
58458
58527
  isReplay
58459
58528
  }) {
58460
- const [pending, setPending] = useState33([]);
58529
+ const [pending, setPending] = useState34([]);
58461
58530
  const currentPending = pending.filter((item) => item.sessionId === sessionId);
58462
58531
  const sendWithApps = async (text4) => {
58463
58532
  const content3 = [...currentPending.map((item) => `[${item.label}]
@@ -58475,7 +58544,7 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58475
58544
  return current ? parsePlanUpdate(current.arguments) : null;
58476
58545
  }, [messages, renderers?.planUpdate]);
58477
58546
  const customPlan = planForRenderer ? renderers?.planUpdate?.({ plan: planForRenderer, running: isStreaming, sessionId }) : void 0;
58478
- return /* @__PURE__ */ jsx28(McpAppMessageContext.Provider, { value: (message) => {
58547
+ return /* @__PURE__ */ jsx29(McpAppMessageContext.Provider, { value: (message) => {
58479
58548
  if (!sessionId || message.sessionId !== sessionId || isViewer) throw new Error("\u5F53\u524D\u4F1A\u8BDD\u4E0D\u80FD\u63A5\u6536\u5E94\u7528\u6D88\u606F");
58480
58549
  setPending((items) => [...items, { ...message, sessionId, id: randomId() }]);
58481
58550
  }, children: /* @__PURE__ */ jsxs23(
@@ -58488,7 +58557,7 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58488
58557
  classNames?.root
58489
58558
  ),
58490
58559
  children: [
58491
- /* @__PURE__ */ jsx28(ConnectionBanner, { connection, className: classNames?.banner }),
58560
+ /* @__PURE__ */ jsx29(ConnectionBanner, { connection, className: classNames?.banner }),
58492
58561
  banner,
58493
58562
  errorMessage && /* @__PURE__ */ jsxs23(
58494
58563
  "div",
@@ -58496,13 +58565,13 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58496
58565
  part: "error-bar",
58497
58566
  className: cn("blade-chat-error-bar flex items-start gap-2 border-b px-4 py-3 text-sm", classNames?.errorBar),
58498
58567
  children: [
58499
- /* @__PURE__ */ jsx28(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
58500
- /* @__PURE__ */ jsx28("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay2(errorMessage) })
58568
+ /* @__PURE__ */ jsx29(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
58569
+ /* @__PURE__ */ jsx29("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay2(errorMessage) })
58501
58570
  ]
58502
58571
  }
58503
58572
  ),
58504
58573
  slots?.header,
58505
- /* @__PURE__ */ jsx28(
58574
+ /* @__PURE__ */ jsx29(
58506
58575
  MessageList,
58507
58576
  {
58508
58577
  messages,
@@ -58528,7 +58597,7 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58528
58597
  turnNavigation
58529
58598
  }
58530
58599
  ),
58531
- showPlanUpdates ? customPlan ?? /* @__PURE__ */ jsx28(
58600
+ showPlanUpdates ? customPlan ?? /* @__PURE__ */ jsx29(
58532
58601
  CurrentPlanPanel,
58533
58602
  {
58534
58603
  messages,
@@ -58539,15 +58608,15 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58539
58608
  }
58540
58609
  ) : null,
58541
58610
  beforeInput,
58542
- /* @__PURE__ */ jsx28(QueuePanelAdjacencyContext.Provider, { value: currentPending.length === 0, children: queuePanel }),
58611
+ /* @__PURE__ */ jsx29(QueuePanelAdjacencyContext.Provider, { value: currentPending.length === 0, children: queuePanel }),
58543
58612
  currentPending.map((item) => /* @__PURE__ */ jsxs23("div", { style: { display: "flex", gap: 8, padding: "8px 16px" }, children: [
58544
58613
  /* @__PURE__ */ jsxs23("details", { style: { flex: 1, minWidth: 0 }, children: [
58545
- /* @__PURE__ */ jsx28("summary", { children: item.label }),
58546
- /* @__PURE__ */ jsx28("pre", { style: { whiteSpace: "pre-wrap", overflowWrap: "anywhere" }, children: item.content })
58614
+ /* @__PURE__ */ jsx29("summary", { children: item.label }),
58615
+ /* @__PURE__ */ jsx29("pre", { style: { whiteSpace: "pre-wrap", overflowWrap: "anywhere" }, children: item.content })
58547
58616
  ] }),
58548
- /* @__PURE__ */ jsx28("button", { type: "button", "aria-label": "\u79FB\u9664\u5F85\u53D1\u9001\u5185\u5BB9", title: "\u79FB\u9664", onClick: () => setPending((items) => items.filter((other) => other.id !== item.id)), children: /* @__PURE__ */ jsx28(X, { size: 16 }) })
58617
+ /* @__PURE__ */ jsx29("button", { type: "button", "aria-label": "\u79FB\u9664\u5F85\u53D1\u9001\u5185\u5BB9", title: "\u79FB\u9664", onClick: () => setPending((items) => items.filter((other) => other.id !== item.id)), children: /* @__PURE__ */ jsx29(X, { size: 16 }) })
58549
58618
  ] }, item.id)),
58550
- /* @__PURE__ */ jsx28(
58619
+ /* @__PURE__ */ jsx29(
58551
58620
  ChatInput,
58552
58621
  {
58553
58622
  value: inputText,
@@ -58574,13 +58643,13 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58574
58643
  }
58575
58644
 
58576
58645
  // src/components/AgentChat.tsx
58577
- import { Fragment as Fragment9, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
58646
+ import { Fragment as Fragment9, jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
58578
58647
  function isUnauthorizedError(error61) {
58579
58648
  return error61 instanceof BladeApiError2 && error61.status === 401;
58580
58649
  }
58581
58650
  function LoginCard({ client, onLoggedIn }) {
58582
- const [loggingIn, setLoggingIn] = useState34(false);
58583
- const [loginError, setLoginError] = useState34(null);
58651
+ const [loggingIn, setLoggingIn] = useState35(false);
58652
+ const [loginError, setLoginError] = useState35(null);
58584
58653
  const handleLogin = async () => {
58585
58654
  setLoggingIn(true);
58586
58655
  setLoginError(null);
@@ -58593,11 +58662,11 @@ function LoginCard({ client, onLoggedIn }) {
58593
58662
  setLoggingIn(false);
58594
58663
  }
58595
58664
  };
58596
- return /* @__PURE__ */ jsx29("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs24("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: [
58597
- /* @__PURE__ */ jsx29(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
58598
- /* @__PURE__ */ jsx29("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
58599
- /* @__PURE__ */ jsx29("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" }),
58600
- /* @__PURE__ */ jsx29(
58665
+ return /* @__PURE__ */ jsx30("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs24("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: [
58666
+ /* @__PURE__ */ jsx30(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
58667
+ /* @__PURE__ */ jsx30("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
58668
+ /* @__PURE__ */ jsx30("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" }),
58669
+ /* @__PURE__ */ jsx30(
58601
58670
  "button",
58602
58671
  {
58603
58672
  type: "button",
@@ -58607,21 +58676,21 @@ function LoginCard({ client, onLoggedIn }) {
58607
58676
  children: loggingIn ? "\u767B\u5F55\u4E2D\u2026" : "\u767B\u5F55"
58608
58677
  }
58609
58678
  ),
58610
- loginError && /* @__PURE__ */ jsx29("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
58679
+ loginError && /* @__PURE__ */ jsx30("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
58611
58680
  ] }) });
58612
58681
  }
58613
58682
  function AgentChat(props) {
58614
58683
  const client = useBladeClient();
58615
- const [attempt, setAttempt] = useState34(0);
58616
- const [needLogin, setNeedLogin] = useState34(() => !client.hasToken());
58684
+ const [attempt, setAttempt] = useState35(0);
58685
+ const [needLogin, setNeedLogin] = useState35(() => !client.hasToken());
58617
58686
  if (needLogin) {
58618
- return /* @__PURE__ */ jsx29(
58687
+ return /* @__PURE__ */ jsx30(
58619
58688
  "div",
58620
58689
  {
58621
58690
  "data-theme": themeAttr(props.theme),
58622
58691
  part: "root",
58623
58692
  className: cn("blade-chat flex min-h-0 flex-1 flex-col", props.classNames?.root),
58624
- children: /* @__PURE__ */ jsx29(
58693
+ children: /* @__PURE__ */ jsx30(
58625
58694
  LoginCard,
58626
58695
  {
58627
58696
  client,
@@ -58634,7 +58703,7 @@ function AgentChat(props) {
58634
58703
  }
58635
58704
  );
58636
58705
  }
58637
- return /* @__PURE__ */ jsx29(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
58706
+ return /* @__PURE__ */ jsx30(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
58638
58707
  }
58639
58708
  function ChatSessionView({
58640
58709
  sessionId,
@@ -58652,7 +58721,7 @@ function ChatSessionView({
58652
58721
  onUnauthorized
58653
58722
  }) {
58654
58723
  const client = useBladeClient();
58655
- const [planRevealRevisions, setPlanRevealRevisions] = useState34(
58724
+ const [planRevealRevisions, setPlanRevealRevisions] = useState35(
58656
58725
  () => /* @__PURE__ */ new Map()
58657
58726
  );
58658
58727
  const handleSessionConnected = useCallback30((connectedSession) => {
@@ -58673,24 +58742,24 @@ function ChatSessionView({
58673
58742
  onSessionConnected: handleSessionConnected
58674
58743
  });
58675
58744
  const replay = useReplay(session);
58676
- const [stopRequested, setStopRequested] = useState34(false);
58677
- const [isRevealing, setIsRevealing] = useState34(false);
58678
- const [inputText, setInputText] = useState34("");
58679
- const [queueNotice, setQueueNotice] = useState34(null);
58680
- const [queuePendingItemId, setQueuePendingItemId] = useState34(null);
58681
- const [queuePanelVisible, setQueuePanelVisible] = useState34(false);
58682
- const [resultFeedback, setResultFeedback] = useState34([]);
58683
- const [timelineRewrite, setTimelineRewrite] = useState34(0);
58745
+ const [stopRequested, setStopRequested] = useState35(false);
58746
+ const [isRevealing, setIsRevealing] = useState35(false);
58747
+ const [inputText, setInputText] = useState35("");
58748
+ const [queueNotice, setQueueNotice] = useState35(null);
58749
+ const [queuePendingItemId, setQueuePendingItemId] = useState35(null);
58750
+ const [queuePanelVisible, setQueuePanelVisible] = useState35(false);
58751
+ const [resultFeedback, setResultFeedback] = useState35([]);
58752
+ const [timelineRewrite, setTimelineRewrite] = useState35(0);
58684
58753
  const resolvedSessionId = session?.sessionId;
58685
58754
  const isViewer = state?.viewerRole === "viewer";
58686
58755
  const canUseQueue = !isViewer;
58687
- const onSessionReadyRef = useRef27(onSessionReady);
58688
- const readySessionRef = useRef27(null);
58756
+ const onSessionReadyRef = useRef28(onSessionReady);
58757
+ const readySessionRef = useRef28(null);
58689
58758
  const hasOnSessionReady = onSessionReady !== void 0;
58690
- useEffect24(() => {
58759
+ useEffect25(() => {
58691
58760
  onSessionReadyRef.current = onSessionReady;
58692
58761
  }, [onSessionReady]);
58693
- useEffect24(() => {
58762
+ useEffect25(() => {
58694
58763
  setResultFeedback([]);
58695
58764
  if (!resolvedSessionId || isViewer) return;
58696
58765
  let cancelled = false;
@@ -58725,13 +58794,13 @@ function ChatSessionView({
58725
58794
  saved
58726
58795
  ]);
58727
58796
  }, []);
58728
- useEffect24(() => {
58797
+ useEffect25(() => {
58729
58798
  const handler = onSessionReadyRef.current;
58730
58799
  if (!session || !hasOnSessionReady || !handler || readySessionRef.current === session) return;
58731
58800
  readySessionRef.current = session;
58732
58801
  handler(session);
58733
58802
  }, [session, hasOnSessionReady]);
58734
- useEffect24(() => {
58803
+ useEffect25(() => {
58735
58804
  if (!session) return;
58736
58805
  const offAttach = session.on("attachRequested", ({ label, content: content3 }) => {
58737
58806
  setInputText((prev) => `${prev ? `${prev}
@@ -58751,12 +58820,12 @@ ${content3}`);
58751
58820
  offRewind();
58752
58821
  };
58753
58822
  }, [session]);
58754
- useEffect24(() => {
58823
+ useEffect25(() => {
58755
58824
  if (isUnauthorizedError(error61)) {
58756
58825
  onUnauthorized();
58757
58826
  }
58758
58827
  }, [error61, onUnauthorized]);
58759
- useEffect24(() => {
58828
+ useEffect25(() => {
58760
58829
  if (!session || !commands) return;
58761
58830
  const unsubscribes = Object.entries(commands).map(
58762
58831
  ([action, handler]) => session.onCommand(action, (payload) => handler(payload))
@@ -58822,7 +58891,7 @@ ${content3}`);
58822
58891
  next[to] = item.id;
58823
58892
  handleQueueReorder(next);
58824
58893
  };
58825
- return /* @__PURE__ */ jsx29(
58894
+ return /* @__PURE__ */ jsx30(
58826
58895
  ChatSurface,
58827
58896
  {
58828
58897
  theme,
@@ -58833,8 +58902,8 @@ ${content3}`);
58833
58902
  placeholder,
58834
58903
  connection: state?.connection ?? "connecting",
58835
58904
  banner: /* @__PURE__ */ jsxs24(Fragment9, { children: [
58836
- resolvedSessionId && !isViewer && (sessionPluginControls ? sessionPluginControls(resolvedSessionId) : /* @__PURE__ */ jsx29(SessionPluginSelector, { client, sessionId: resolvedSessionId })),
58837
- /* @__PURE__ */ jsx29(
58905
+ resolvedSessionId && !isViewer && (sessionPluginControls ? sessionPluginControls(resolvedSessionId) : /* @__PURE__ */ jsx30(SessionPluginSelector, { client, sessionId: resolvedSessionId })),
58906
+ /* @__PURE__ */ jsx30(
58838
58907
  ReplayBar,
58839
58908
  {
58840
58909
  isReplay: replay.isReplay,
@@ -58844,7 +58913,7 @@ ${content3}`);
58844
58913
  onExit: () => void replay.exitToAutonomous()
58845
58914
  }
58846
58915
  ),
58847
- /* @__PURE__ */ jsx29(ReplayMismatchPrompt, { mismatch: replay.mismatch })
58916
+ /* @__PURE__ */ jsx30(ReplayMismatchPrompt, { mismatch: replay.mismatch })
58848
58917
  ] }),
58849
58918
  errorMessage,
58850
58919
  messages: state?.messages ?? [],
@@ -58856,7 +58925,7 @@ ${content3}`);
58856
58925
  planRevealRevision,
58857
58926
  queuePanel: (
58858
58927
  // 只读身份不能操作队列,藏起来免得每个按钮都弹冲突。
58859
- canUseQueue ? /* @__PURE__ */ jsx29(
58928
+ canUseQueue ? /* @__PURE__ */ jsx30(
58860
58929
  SessionQueuePanel,
58861
58930
  {
58862
58931
  rootClassName: classNames?.queuePanel,
@@ -58928,11 +58997,11 @@ ${content3}`);
58928
58997
  }
58929
58998
 
58930
58999
  // src/components/LlmChat.tsx
58931
- import { useEffect as useEffect25, useMemo as useMemo19, useState as useState36 } from "react";
59000
+ import { useEffect as useEffect26, useMemo as useMemo19, useState as useState37 } from "react";
58932
59001
 
58933
59002
  // src/components/LlmAdvancedSettings.tsx
58934
- import { useState as useState35 } from "react";
58935
- import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
59003
+ import { useState as useState36 } from "react";
59004
+ import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
58936
59005
  var FIELDS = [
58937
59006
  { id: "baseURL", label: "\u6A21\u578B\u670D\u52A1\u5730\u5740", placeholder: "http://\u5185\u7F51\u5730\u5740/v1" },
58938
59007
  { id: "model", label: "\u6A21\u578B", placeholder: "\u6A21\u578B\u540D\u79F0" },
@@ -58978,8 +59047,8 @@ function writeOverride(settings, baseURL, override) {
58978
59047
  }
58979
59048
  function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onChange }) {
58980
59049
  const normalized = normalizeAdvanced(settings);
58981
- const [open2, setOpen] = useState35(false);
58982
- const [draft, setDraft] = useState35(override);
59050
+ const [open2, setOpen] = useState36(false);
59051
+ const [draft, setDraft] = useState36(override);
58983
59052
  if (!normalized) return null;
58984
59053
  const fields2 = FIELDS.filter((field) => normalized[field.id]);
58985
59054
  const dirty = Object.keys(override).length > 0;
@@ -58994,16 +59063,16 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
58994
59063
  },
58995
59064
  className: "flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
58996
59065
  children: [
58997
- /* @__PURE__ */ jsx30(Settings2, { size: 13 }),
59066
+ /* @__PURE__ */ jsx31(Settings2, { size: 13 }),
58998
59067
  "\u9AD8\u7EA7\u8BBE\u7F6E",
58999
- dirty && /* @__PURE__ */ jsx30("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
59068
+ dirty && /* @__PURE__ */ jsx31("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
59000
59069
  ]
59001
59070
  }
59002
59071
  ),
59003
59072
  open2 && /* @__PURE__ */ jsxs25("div", { className: "mt-2 flex flex-col gap-2", children: [
59004
59073
  fields2.map((field) => /* @__PURE__ */ jsxs25("label", { className: "flex flex-col gap-1", children: [
59005
- /* @__PURE__ */ jsx30("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
59006
- /* @__PURE__ */ jsx30(
59074
+ /* @__PURE__ */ jsx31("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
59075
+ /* @__PURE__ */ jsx31(
59007
59076
  "input",
59008
59077
  {
59009
59078
  type: field.secret ? "password" : "text",
@@ -59014,9 +59083,9 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
59014
59083
  }
59015
59084
  )
59016
59085
  ] }, field.id)),
59017
- normalized.apiKey && /* @__PURE__ */ jsx30("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" }),
59086
+ normalized.apiKey && /* @__PURE__ */ jsx31("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" }),
59018
59087
  /* @__PURE__ */ jsxs25("div", { className: "flex gap-2", children: [
59019
- /* @__PURE__ */ jsx30(
59088
+ /* @__PURE__ */ jsx31(
59020
59089
  "button",
59021
59090
  {
59022
59091
  type: "button",
@@ -59031,7 +59100,7 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
59031
59100
  children: "\u4FDD\u5B58"
59032
59101
  }
59033
59102
  ),
59034
- /* @__PURE__ */ jsx30(
59103
+ /* @__PURE__ */ jsx31(
59035
59104
  "button",
59036
59105
  {
59037
59106
  type: "button",
@@ -59050,7 +59119,7 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
59050
59119
  }
59051
59120
 
59052
59121
  // src/components/LlmChat.tsx
59053
- import { jsx as jsx31 } from "react/jsx-runtime";
59122
+ import { jsx as jsx32 } from "react/jsx-runtime";
59054
59123
  function LlmChat({
59055
59124
  classNames,
59056
59125
  renderers,
@@ -59062,12 +59131,12 @@ function LlmChat({
59062
59131
  onOverrideChange,
59063
59132
  ...options
59064
59133
  }) {
59065
- const [override, setOverride] = useState36(() => readOverride(advanced, options.baseURL));
59134
+ const [override, setOverride] = useState37(() => readOverride(advanced, options.baseURL));
59066
59135
  const effective = { ...options, ...override };
59067
59136
  const { messages, isStreaming, error: error61, send, stop, reset } = useLlmChat(effective);
59068
- const [inputText, setInputText] = useState36("");
59069
- const [stopRequested, setStopRequested] = useState36(false);
59070
- const [isRevealing, setIsRevealing] = useState36(false);
59137
+ const [inputText, setInputText] = useState37("");
59138
+ const [stopRequested, setStopRequested] = useState37(false);
59139
+ const [isRevealing, setIsRevealing] = useState37(false);
59071
59140
  const isStreamingDisplay = isStreaming || isRevealing;
59072
59141
  const handle = useMemo19(
59073
59142
  () => ({
@@ -59078,10 +59147,10 @@ ${text4}` : text4),
59078
59147
  }),
59079
59148
  [send, reset]
59080
59149
  );
59081
- useEffect25(() => {
59150
+ useEffect26(() => {
59082
59151
  onReady?.(handle);
59083
59152
  }, [handle, onReady]);
59084
- return /* @__PURE__ */ jsx31(
59153
+ return /* @__PURE__ */ jsx32(
59085
59154
  ChatSurface,
59086
59155
  {
59087
59156
  theme,
@@ -59107,7 +59176,7 @@ ${text4}` : text4),
59107
59176
  setStopRequested(true);
59108
59177
  stop();
59109
59178
  },
59110
- beforeInput: advanced ? /* @__PURE__ */ jsx31(
59179
+ beforeInput: advanced ? /* @__PURE__ */ jsx32(
59111
59180
  LlmAdvancedSettingsBar,
59112
59181
  {
59113
59182
  settings: advanced,
@@ -59125,14 +59194,14 @@ ${text4}` : text4),
59125
59194
  }
59126
59195
 
59127
59196
  // src/components/ChatView.tsx
59128
- import { jsx as jsx32 } from "react/jsx-runtime";
59197
+ import { jsx as jsx33 } from "react/jsx-runtime";
59129
59198
  function ChatView(props) {
59130
59199
  const { mode, llm, onLlmReady, ...rest } = props;
59131
59200
  if (mode === "llm") {
59132
59201
  if (!llm) {
59133
59202
  throw new Error('ChatView: mode="llm" \u9700\u8981\u540C\u65F6\u4F20 llm={{ baseURL, model }}');
59134
59203
  }
59135
- return /* @__PURE__ */ jsx32(
59204
+ return /* @__PURE__ */ jsx33(
59136
59205
  LlmChat,
59137
59206
  {
59138
59207
  ...llm,
@@ -59145,11 +59214,11 @@ function ChatView(props) {
59145
59214
  }
59146
59215
  );
59147
59216
  }
59148
- return /* @__PURE__ */ jsx32(AgentChat, { ...rest });
59217
+ return /* @__PURE__ */ jsx33(AgentChat, { ...rest });
59149
59218
  }
59150
59219
 
59151
59220
  // src/components/ConnectorPanel.tsx
59152
- import { useCallback as useCallback31, useEffect as useEffect26, useMemo as useMemo20, useRef as useRef28, useState as useState37 } from "react";
59221
+ import { useCallback as useCallback31, useEffect as useEffect27, useMemo as useMemo20, useRef as useRef29, useState as useState38 } from "react";
59153
59222
 
59154
59223
  // src/components/connector-panel-types.ts
59155
59224
  function selectionFromItem(item) {
@@ -59171,12 +59240,12 @@ function triggerSummary(items) {
59171
59240
  }
59172
59241
 
59173
59242
  // src/components/ConnectorPanel.tsx
59174
- import { Fragment as Fragment10, jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
59243
+ import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs26 } from "react/jsx-runtime";
59175
59244
  function PanelDivider() {
59176
- return /* @__PURE__ */ jsx33("div", { className: "my-1 border-[hsl(var(--border))] border-t" });
59245
+ return /* @__PURE__ */ jsx34("div", { className: "my-1 border-[hsl(var(--border))] border-t" });
59177
59246
  }
59178
59247
  function PanelTitle({ children }) {
59179
- return /* @__PURE__ */ jsx33("div", { className: "px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children });
59248
+ return /* @__PURE__ */ jsx34("div", { className: "px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children });
59180
59249
  }
59181
59250
  function ConnectorPanel({
59182
59251
  client,
@@ -59191,10 +59260,10 @@ function ConnectorPanel({
59191
59260
  renderFooterActions,
59192
59261
  className
59193
59262
  }) {
59194
- const [query, setQuery] = useState37("");
59195
- const [pendingCatalog, setPendingCatalog] = useState37(null);
59196
- const [pendingLoading, setPendingLoading] = useState37(false);
59197
- const [pendingError, setPendingError] = useState37(false);
59263
+ const [query, setQuery] = useState38("");
59264
+ const [pendingCatalog, setPendingCatalog] = useState38(null);
59265
+ const [pendingLoading, setPendingLoading] = useState38(false);
59266
+ const [pendingError, setPendingError] = useState38(false);
59198
59267
  const activation = useSessionPluginActivation({
59199
59268
  client,
59200
59269
  // 首页不会走这个分支:待选在下面自己处理开关,不碰会话接口。
@@ -59202,7 +59271,7 @@ function ConnectorPanel({
59202
59271
  onChange: onPluginsChanged
59203
59272
  });
59204
59273
  const { reload, items: sessionItems } = activation;
59205
- useEffect26(() => {
59274
+ useEffect27(() => {
59206
59275
  if (sessionId) reload();
59207
59276
  }, [reload, sessionId]);
59208
59277
  const loadPendingCatalog = useCallback31(async () => {
@@ -59217,7 +59286,7 @@ function ConnectorPanel({
59217
59286
  setPendingLoading(false);
59218
59287
  }
59219
59288
  }, [client]);
59220
- useEffect26(() => {
59289
+ useEffect27(() => {
59221
59290
  if (sessionId) return;
59222
59291
  void loadPendingCatalog();
59223
59292
  }, [loadPendingCatalog, sessionId]);
@@ -59248,20 +59317,20 @@ function ConnectorPanel({
59248
59317
  () => items.filter((item) => item.active),
59249
59318
  [items]
59250
59319
  );
59251
- const onSelectedChangeRef = useRef28(onSelectedChange);
59320
+ const onSelectedChangeRef = useRef29(onSelectedChange);
59252
59321
  onSelectedChangeRef.current = onSelectedChange;
59253
- const latestSelected = useRef28(selectedItems);
59322
+ const latestSelected = useRef29(selectedItems);
59254
59323
  latestSelected.current = selectedItems;
59255
59324
  const reportSelected = useCallback31(() => {
59256
59325
  onSelectedChangeRef.current?.(latestSelected.current);
59257
59326
  }, []);
59258
59327
  const selectedNames = selectedItems.map((item) => item.name).join("\0");
59259
- useEffect26(reportSelected, [reportSelected, selectedNames]);
59328
+ useEffect27(reportSelected, [reportSelected, selectedNames]);
59260
59329
  const failed = sessionId ? activation.listError : pendingError;
59261
59330
  return /* @__PURE__ */ jsxs26("div", { className, children: [
59262
59331
  /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2 border-[hsl(var(--border))] border-b px-3 py-2", children: [
59263
- /* @__PURE__ */ jsx33(Search, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]", "aria-hidden": "true" }),
59264
- /* @__PURE__ */ jsx33(
59332
+ /* @__PURE__ */ jsx34(Search, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]", "aria-hidden": "true" }),
59333
+ /* @__PURE__ */ jsx34(
59265
59334
  "input",
59266
59335
  {
59267
59336
  value: query,
@@ -59273,21 +59342,21 @@ function ConnectorPanel({
59273
59342
  )
59274
59343
  ] }),
59275
59344
  renderComputerSection ? /* @__PURE__ */ jsxs26(Fragment10, { children: [
59276
- /* @__PURE__ */ jsx33(PanelTitle, { children: "\u7535\u8111" }),
59345
+ /* @__PURE__ */ jsx34(PanelTitle, { children: "\u7535\u8111" }),
59277
59346
  renderComputerSection(query)
59278
59347
  ] }) : null,
59279
- /* @__PURE__ */ jsx33(PanelDivider, {}),
59280
- /* @__PURE__ */ jsx33(PanelTitle, { children: "\u63D2\u4EF6" }),
59348
+ /* @__PURE__ */ jsx34(PanelDivider, {}),
59349
+ /* @__PURE__ */ jsx34(PanelTitle, { children: "\u63D2\u4EF6" }),
59281
59350
  !sessionId ? (
59282
59351
  // 首页没有会话,开关只记下「这条消息要带上谁」:不说清楚,用户会以为已经
59283
59352
  // 生效(issue 明确要求「明确为待选,不宣称已经激活」)。
59284
- /* @__PURE__ */ jsx33("div", { className: "px-3 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u5148\u9009\u4E2D\uFF0C\u53D1\u9001\u8FD9\u6761\u6D88\u606F\u65F6\u4F1A\u4E00\u5E76\u542F\u7528" })
59353
+ /* @__PURE__ */ jsx34("div", { className: "px-3 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u5148\u9009\u4E2D\uFF0C\u53D1\u9001\u8FD9\u6761\u6D88\u606F\u65F6\u4F1A\u4E00\u5E76\u542F\u7528" })
59285
59354
  ) : null,
59286
59355
  (sessionId ? activation.loading : pendingLoading) && visibleItems.length === 0 ? /* @__PURE__ */ jsxs26("div", { className: "px-3 py-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
59287
- /* @__PURE__ */ jsx33(LoaderCircle, { size: 12, className: "mr-1 inline animate-spin" }),
59356
+ /* @__PURE__ */ jsx34(LoaderCircle, { size: 12, className: "mr-1 inline animate-spin" }),
59288
59357
  "\u6B63\u5728\u83B7\u53D6\u63D2\u4EF6\u2026"
59289
59358
  ] }) : null,
59290
- failed ? /* @__PURE__ */ jsx33(
59359
+ failed ? /* @__PURE__ */ jsx34(
59291
59360
  "button",
59292
59361
  {
59293
59362
  type: "button",
@@ -59296,7 +59365,7 @@ function ConnectorPanel({
59296
59365
  children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5"
59297
59366
  }
59298
59367
  ) : null,
59299
- /* @__PURE__ */ jsx33(
59368
+ /* @__PURE__ */ jsx34(
59300
59369
  PluginConnectorList,
59301
59370
  {
59302
59371
  client,
@@ -59318,19 +59387,19 @@ function ConnectorPanel({
59318
59387
  }
59319
59388
  ),
59320
59389
  renderExternalAccounts ? /* @__PURE__ */ jsxs26(Fragment10, { children: [
59321
- /* @__PURE__ */ jsx33(PanelDivider, {}),
59322
- /* @__PURE__ */ jsx33(PanelTitle, { children: "\u5916\u90E8\u8D26\u53F7" }),
59390
+ /* @__PURE__ */ jsx34(PanelDivider, {}),
59391
+ /* @__PURE__ */ jsx34(PanelTitle, { children: "\u5916\u90E8\u8D26\u53F7" }),
59323
59392
  renderExternalAccounts(query)
59324
59393
  ] }) : null,
59325
59394
  renderFooterActions ? /* @__PURE__ */ jsxs26(Fragment10, { children: [
59326
- /* @__PURE__ */ jsx33(PanelDivider, {}),
59395
+ /* @__PURE__ */ jsx34(PanelDivider, {}),
59327
59396
  renderFooterActions()
59328
59397
  ] }) : null
59329
59398
  ] });
59330
59399
  }
59331
59400
 
59332
59401
  // src/components/PluginTriggerStack.tsx
59333
- import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
59402
+ import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
59334
59403
  var AVATAR_SIZE = 20;
59335
59404
  function hueOf(name) {
59336
59405
  let hash2 = 0;
@@ -59354,7 +59423,7 @@ function PluginTriggerStack({ client, sessionId, summary, className }) {
59354
59423
  summary.visible.map((item) => {
59355
59424
  const label = item.displayName?.trim() || item.name;
59356
59425
  const tone = AVATAR_PALETTE[hueOf(item.name) % AVATAR_PALETTE.length];
59357
- return item.icon ? /* @__PURE__ */ jsx34(
59426
+ return item.icon ? /* @__PURE__ */ jsx35(
59358
59427
  SessionPluginIcon,
59359
59428
  {
59360
59429
  client,
@@ -59365,7 +59434,7 @@ function PluginTriggerStack({ client, sessionId, summary, className }) {
59365
59434
  className: ring
59366
59435
  },
59367
59436
  item.name
59368
- ) : /* @__PURE__ */ jsx34(
59437
+ ) : /* @__PURE__ */ jsx35(
59369
59438
  "span",
59370
59439
  {
59371
59440
  title: label,
@@ -59395,7 +59464,7 @@ import {
59395
59464
  getContextDisplayState,
59396
59465
  getContextGroupDisplayState
59397
59466
  } from "@blade-hq/agent-client";
59398
- import { jsx as jsx35, jsxs as jsxs28 } from "react/jsx-runtime";
59467
+ import { jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
59399
59468
  function ContextCard({ context, className }) {
59400
59469
  const display = getContextDisplayState(context);
59401
59470
  return /* @__PURE__ */ jsxs28(
@@ -59404,7 +59473,7 @@ function ContextCard({ context, className }) {
59404
59473
  className: `blade-chat-context-card group/context-card overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
59405
59474
  children: [
59406
59475
  /* @__PURE__ */ jsxs28("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: [
59407
- /* @__PURE__ */ jsx35(
59476
+ /* @__PURE__ */ jsx36(
59408
59477
  Layers,
59409
59478
  {
59410
59479
  size: 15,
@@ -59413,10 +59482,10 @@ function ContextCard({ context, className }) {
59413
59482
  }
59414
59483
  ),
59415
59484
  /* @__PURE__ */ jsxs28("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
59416
- /* @__PURE__ */ jsx35("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
59417
- /* @__PURE__ */ jsx35("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
59485
+ /* @__PURE__ */ jsx36("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
59486
+ /* @__PURE__ */ jsx36("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
59418
59487
  ] }),
59419
- /* @__PURE__ */ jsx35(
59488
+ /* @__PURE__ */ jsx36(
59420
59489
  ChevronDown,
59421
59490
  {
59422
59491
  size: 14,
@@ -59425,7 +59494,7 @@ function ContextCard({ context, className }) {
59425
59494
  }
59426
59495
  )
59427
59496
  ] }),
59428
- /* @__PURE__ */ jsx35("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 })
59497
+ /* @__PURE__ */ jsx36("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 })
59429
59498
  ]
59430
59499
  }
59431
59500
  );
@@ -59436,7 +59505,7 @@ function ContextGroupCard({ contexts, className }) {
59436
59505
  const group = single ? null : getContextGroupDisplayState(contexts);
59437
59506
  return /* @__PURE__ */ jsxs28("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: [
59438
59507
  /* @__PURE__ */ jsxs28("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: [
59439
- /* @__PURE__ */ jsx35(
59508
+ /* @__PURE__ */ jsx36(
59440
59509
  Layers,
59441
59510
  {
59442
59511
  size: 15,
@@ -59445,10 +59514,10 @@ function ContextGroupCard({ contexts, className }) {
59445
59514
  }
59446
59515
  ),
59447
59516
  /* @__PURE__ */ jsxs28("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
59448
- /* @__PURE__ */ jsx35("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: single ? single.title : `${group?.title} \xB7 ${group?.count} \u9879` }),
59449
- /* @__PURE__ */ jsx35("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: single ? single.summary : group?.summary })
59517
+ /* @__PURE__ */ jsx36("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: single ? single.title : `${group?.title} \xB7 ${group?.count} \u9879` }),
59518
+ /* @__PURE__ */ jsx36("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: single ? single.summary : group?.summary })
59450
59519
  ] }),
59451
- /* @__PURE__ */ jsx35(
59520
+ /* @__PURE__ */ jsx36(
59452
59521
  ChevronDown,
59453
59522
  {
59454
59523
  size: 14,
@@ -59457,7 +59526,7 @@ function ContextGroupCard({ contexts, className }) {
59457
59526
  }
59458
59527
  )
59459
59528
  ] }),
59460
- single ? /* @__PURE__ */ jsx35("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__ */ jsx35("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__ */ jsx35(
59529
+ single ? /* @__PURE__ */ jsx36("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__ */ jsx36("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__ */ jsx36(
59461
59530
  ContextCard,
59462
59531
  {
59463
59532
  context
@@ -59468,8 +59537,8 @@ function ContextGroupCard({ contexts, className }) {
59468
59537
  }
59469
59538
 
59470
59539
  // src/components/SessionMemoryToggle.tsx
59471
- import { useCallback as useCallback32, useEffect as useEffect27, useRef as useRef29, useState as useState38, useSyncExternalStore as useSyncExternalStore2 } from "react";
59472
- import { jsx as jsx36, jsxs as jsxs29 } from "react/jsx-runtime";
59540
+ import { useCallback as useCallback32, useEffect as useEffect28, useRef as useRef30, useState as useState39, useSyncExternalStore as useSyncExternalStore2 } from "react";
59541
+ import { jsx as jsx37, jsxs as jsxs29 } from "react/jsx-runtime";
59473
59542
  var saveStates = /* @__PURE__ */ new WeakMap();
59474
59543
  function getSaveState(client, sessionId) {
59475
59544
  let clientStates = saveStates.get(client);
@@ -59526,10 +59595,10 @@ function SessionMemoryToggle({
59526
59595
  getSaving,
59527
59596
  getSaving
59528
59597
  );
59529
- const [draftEnabled, setDraftEnabled] = useState38(enabled);
59530
- const activeSessionIdRef = useRef29(sessionId);
59598
+ const [draftEnabled, setDraftEnabled] = useState39(enabled);
59599
+ const activeSessionIdRef = useRef30(sessionId);
59531
59600
  activeSessionIdRef.current = sessionId;
59532
- useEffect27(() => {
59601
+ useEffect28(() => {
59533
59602
  setDraftEnabled(enabled);
59534
59603
  }, [enabled, sessionId]);
59535
59604
  const update = useCallback32(
@@ -59559,8 +59628,8 @@ function SessionMemoryToggle({
59559
59628
  [client, enabled, onError, onSaved, sessionId]
59560
59629
  );
59561
59630
  return /* @__PURE__ */ jsxs29("label", { className: cn("flex items-center justify-between", className), children: [
59562
- /* @__PURE__ */ jsx36("span", { className: labelClassName, children: label }),
59563
- /* @__PURE__ */ jsx36(
59631
+ /* @__PURE__ */ jsx37("span", { className: labelClassName, children: label }),
59632
+ /* @__PURE__ */ jsx37(
59564
59633
  "input",
59565
59634
  {
59566
59635
  type: "checkbox",
@@ -59633,6 +59702,7 @@ export {
59633
59702
  MarkdownRenderer,
59634
59703
  McpAppCard,
59635
59704
  MemoryRefsHint,
59705
+ MessageImage,
59636
59706
  PLAN_AUTO_COLLAPSE_MS,
59637
59707
  PlanUpdateBlock,
59638
59708
  PluginConnectorList,