@blade-hq/agent-kit 1.0.30 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/{chunk-L4C2TY6S.js → chunk-3EVO45IN.js} +2 -2
  2. package/dist/{chunk-WOKDHXS7.js → chunk-3PX2W7II.js} +24 -12
  3. package/dist/chunk-3PX2W7II.js.map +1 -0
  4. package/dist/{chunk-GAVSC2AW.js → chunk-DSC6KQOI.js} +42 -1
  5. package/dist/chunk-DSC6KQOI.js.map +1 -0
  6. package/dist/{chunk-MJPVAXJN.js → chunk-O32JOWYM.js} +2 -2
  7. package/dist/{chunk-3XDPNPE3.js → chunk-RAWQ7LWR.js} +973 -712
  8. package/dist/chunk-RAWQ7LWR.js.map +1 -0
  9. package/dist/{chunk-7OEW3P7R.js → chunk-XUWAM6MF.js} +56 -35
  10. package/dist/chunk-XUWAM6MF.js.map +1 -0
  11. package/dist/{chunk-6G5LCDOS.js → chunk-ZPZMN7KQ.js} +2 -2
  12. package/dist/client/index.js +1 -1
  13. package/dist/react/api/published-apps.js +3 -3
  14. package/dist/react/api/sessions.js +2 -2
  15. package/dist/react/components/chat/FileDeliveryCards.d.ts +11 -0
  16. package/dist/react/components/chat/PlanningToggle.d.ts +7 -0
  17. package/dist/react/components/chat/UserMessageBubble.d.ts +1 -1
  18. package/dist/react/components/chat/index.d.ts +1 -0
  19. package/dist/react/components/chat/index.js +7 -5
  20. package/dist/react/components/plan/index.js +4 -4
  21. package/dist/react/components/session/index.js +3 -3
  22. package/dist/react/components/workspace/index.js +61 -42
  23. package/dist/react/components/workspace/index.js.map +1 -1
  24. package/dist/react/hooks/use-model-preferences.d.ts +2 -0
  25. package/dist/react/index.d.ts +1 -1
  26. package/dist/react/index.js +9 -7
  27. package/dist/react/index.js.map +1 -1
  28. package/dist/react/stores/ui-store.d.ts +5 -0
  29. package/dist/react/types/solution.d.ts +1 -0
  30. package/dist/style.css +1 -1
  31. package/package.json +1 -1
  32. package/dist/chunk-3XDPNPE3.js.map +0 -1
  33. package/dist/chunk-7OEW3P7R.js.map +0 -1
  34. package/dist/chunk-GAVSC2AW.js.map +0 -1
  35. package/dist/chunk-WOKDHXS7.js.map +0 -1
  36. /package/dist/{chunk-L4C2TY6S.js.map → chunk-3EVO45IN.js.map} +0 -0
  37. /package/dist/{chunk-MJPVAXJN.js.map → chunk-O32JOWYM.js.map} +0 -0
  38. /package/dist/{chunk-6G5LCDOS.js.map → chunk-ZPZMN7KQ.js.map} +0 -0
@@ -13,10 +13,11 @@ import {
13
13
  getCodeLanguageFromFilename,
14
14
  parseAskUserQuestion,
15
15
  useHighlightedCodeHtml
16
- } from "./chunk-7OEW3P7R.js";
16
+ } from "./chunk-XUWAM6MF.js";
17
17
  import {
18
+ getSessionFilePath,
18
19
  resolveSessionFilePreviewTarget
19
- } from "./chunk-MJPVAXJN.js";
20
+ } from "./chunk-O32JOWYM.js";
20
21
  import {
21
22
  apiFetchResponse,
22
23
  buildMessageContent,
@@ -45,6 +46,7 @@ import {
45
46
  listDir,
46
47
  listSessionSkills,
47
48
  listSessions,
49
+ normalizeMessageContent,
48
50
  resolveEffectiveTheme,
49
51
  resourceBridgeDispatch,
50
52
  searchSkills,
@@ -60,7 +62,7 @@ import {
60
62
  useUiBridgeStore,
61
63
  useUiStore,
62
64
  writeFile
63
- } from "./chunk-WOKDHXS7.js";
65
+ } from "./chunk-3PX2W7II.js";
64
66
  import {
65
67
  registerBridgeIframe,
66
68
  tapBridgeEvent
@@ -69,7 +71,7 @@ import {
69
71
  ModelOption,
70
72
  ModelsConfig,
71
73
  ModelsResource
72
- } from "./chunk-GAVSC2AW.js";
74
+ } from "./chunk-DSC6KQOI.js";
73
75
  import {
74
76
  cn,
75
77
  copyToClipboard
@@ -81,7 +83,7 @@ import {
81
83
  // src/react/components/chat/ChatView.tsx
82
84
  import { CircleAlert as CircleAlert2 } from "lucide-react";
83
85
  import { Eye } from "lucide-react";
84
- import { useCallback as useCallback13, useMemo as useMemo19 } from "react";
86
+ import { useCallback as useCallback13, useMemo as useMemo20 } from "react";
85
87
 
86
88
  // src/react/hooks/use-chat.ts
87
89
  import { useCallback, useEffect, useRef, useState } from "react";
@@ -190,7 +192,6 @@ import {
190
192
  Download,
191
193
  FlaskConical,
192
194
  Import,
193
- Lightbulb,
194
195
  Loader2 as Loader22,
195
196
  Mic,
196
197
  MicOff,
@@ -693,19 +694,20 @@ var MODEL_CONFIG_QUERY_KEY = ["model-config"];
693
694
  var PREFERRED_MODEL_QUERY_KEY = ["user-preference", PREFERRED_MODEL_KEY];
694
695
  var THINKING_ENABLED_QUERY_KEY = ["user-preference", THINKING_ENABLED_KEY];
695
696
  function useModelConfig() {
696
- const { data, isLoading } = useQuery({
697
+ const { data, isLoading, isFetching, refetch } = useQuery({
697
698
  queryKey: MODEL_CONFIG_QUERY_KEY,
698
699
  queryFn: () => getModelsConfig(),
699
- staleTime: 5 * 60 * 1e3,
700
- // 全局 QueryClient 默认关闭 refetchOnWindowFocus,这里显式开启,
701
- // 让模型列表在 staleTime 过期后能随窗口聚焦自动刷新
702
- refetchOnWindowFocus: true
700
+ staleTime: 0
703
701
  });
704
702
  return {
705
703
  models: data?.models ?? [],
706
704
  defaultModel: data?.default ?? "",
707
705
  thinkingAvailable: data?.thinkingAvailable ?? false,
708
- isLoading
706
+ isLoading,
707
+ isFetching,
708
+ refresh: async () => {
709
+ await refetch();
710
+ }
709
711
  };
710
712
  }
711
713
  function usePreferredModel() {
@@ -790,7 +792,7 @@ function ModelSelector({
790
792
  compact = false,
791
793
  placement = "bottom"
792
794
  }) {
793
- const { models, defaultModel, isLoading } = useModelConfig();
795
+ const { models, defaultModel, isLoading, isFetching, refresh } = useModelConfig();
794
796
  const [isOpen, setIsOpen] = useState3(false);
795
797
  const [query, setQuery] = useState3("");
796
798
  const rootRef = useRef4(null);
@@ -831,7 +833,10 @@ function ModelSelector({
831
833
  className: "flex min-w-0 items-center gap-1 rounded-lg px-2.5 py-[5px] text-[hsl(var(--muted-foreground))]",
832
834
  title: label,
833
835
  children: [
834
- isLoading ? /* @__PURE__ */ jsx2(Loader2, { size: 14, className: "animate-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx2(Sparkles, { size: 14, "aria-hidden": "true" }),
836
+ isLoading ? /* @__PURE__ */ jsx2(Loader2, { size: 14, className: "animate-spin", "aria-hidden": "true" }) : compact ? null : (
837
+ // compact 用于「+」菜单的「模型」行,行首已有图标,触发器内不再重复。
838
+ /* @__PURE__ */ jsx2(Sparkles, { size: 14, "aria-hidden": "true" })
839
+ ),
835
840
  /* @__PURE__ */ jsx2("span", { className: `whitespace-nowrap text-xs ${compact ? "" : "max-w-[180px]"}`, children: label })
836
841
  ]
837
842
  }
@@ -843,11 +848,18 @@ function ModelSelector({
843
848
  {
844
849
  type: "button",
845
850
  disabled,
846
- onClick: () => setIsOpen((current) => !current),
851
+ onClick: () => {
852
+ if (isOpen) {
853
+ setIsOpen(false);
854
+ return;
855
+ }
856
+ setIsOpen(true);
857
+ void refresh();
858
+ },
847
859
  className: "flex min-w-0 items-center gap-1 rounded-lg px-2.5 py-[5px] text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50",
848
860
  title: selectorTitle,
849
861
  children: [
850
- /* @__PURE__ */ jsx2(Sparkles, { size: 14, "aria-hidden": "true" }),
862
+ compact ? null : /* @__PURE__ */ jsx2(Sparkles, { size: 14, "aria-hidden": "true" }),
851
863
  /* @__PURE__ */ jsx2(
852
864
  "span",
853
865
  {
@@ -873,7 +885,16 @@ function ModelSelector({
873
885
  className: "h-8 w-full rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--background))] px-2.5 text-xs text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground))] focus:border-[hsl(var(--ring))]"
874
886
  }
875
887
  ) }),
876
- /* @__PURE__ */ jsx2("div", { className: "max-h-[220px] overflow-y-auto p-1", children: filteredModels.length === 0 ? /* @__PURE__ */ jsx2("div", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6CA1\u6709\u5339\u914D\u7684\u6A21\u578B" }) : filteredModels.map((model) => {
888
+ /* @__PURE__ */ jsx2("div", { className: "max-h-[220px] overflow-y-auto p-1", children: isFetching ? /* @__PURE__ */ jsxs(
889
+ "output",
890
+ {
891
+ className: "flex items-center justify-center gap-2 px-3 py-6 text-xs text-[hsl(var(--muted-foreground))]",
892
+ children: [
893
+ /* @__PURE__ */ jsx2(Loader2, { size: 14, className: "animate-spin", "aria-hidden": "true" }),
894
+ "\u6B63\u5728\u52A0\u8F7D\u5019\u9009\u6A21\u578B..."
895
+ ]
896
+ }
897
+ ) : filteredModels.length === 0 ? /* @__PURE__ */ jsx2("div", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6CA1\u6709\u5339\u914D\u7684\u6A21\u578B" }) : filteredModels.map((model) => {
877
898
  const inputLabel = formatInputModalities(model);
878
899
  const title = model.id === model.label ? `${model.id}\uFF0C\u652F\u6301\u8F93\u5165\uFF1A${inputLabel}` : `${model.label} (${model.id})\uFF0C\u652F\u6301\u8F93\u5165\uFF1A${inputLabel}`;
879
900
  return /* @__PURE__ */ jsxs(
@@ -2110,6 +2131,7 @@ function ThinkingToggle({ enabled, onChange, disabled }) {
2110
2131
  role: "switch",
2111
2132
  "aria-checked": enabled,
2112
2133
  "aria-label": enabled ? "\u5173\u95ED\u601D\u8003\u6A21\u5F0F" : "\u5F00\u542F\u601D\u8003\u6A21\u5F0F",
2134
+ title: "\u601D\u8003\u6A21\u5F0F\uFF1A\u8BA9\u6A21\u578B\u5728\u56DE\u7B54\u524D\u8FDB\u884C\u66F4\u6DF1\u5165\u7684\u63A8\u7406\uFF0C\u7ED3\u679C\u66F4\u4E25\u8C28\uFF0C\u4F46\u54CD\u5E94\u4F1A\u66F4\u6162",
2113
2135
  onClick: () => onChange(!enabled),
2114
2136
  disabled,
2115
2137
  className: "flex w-full items-center justify-between gap-3 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))] disabled:cursor-not-allowed disabled:opacity-50",
@@ -2134,8 +2156,44 @@ function ThinkingToggle({ enabled, onChange, disabled }) {
2134
2156
  );
2135
2157
  }
2136
2158
 
2159
+ // src/react/components/chat/PlanningToggle.tsx
2160
+ import { Lightbulb } from "lucide-react";
2161
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2162
+ function PlanningToggle({ enabled, onChange, disabled }) {
2163
+ return /* @__PURE__ */ jsxs9(
2164
+ "button",
2165
+ {
2166
+ type: "button",
2167
+ role: "switch",
2168
+ "aria-checked": enabled,
2169
+ "aria-label": enabled ? "\u5173\u95ED\u89C4\u5212\u6A21\u5F0F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
2170
+ title: "\u89C4\u5212\u6A21\u5F0F\uFF1A\u5148\u68B3\u7406\u4EFB\u52A1\u6B65\u9AA4\u548C\u8BA1\u5212\u3001\u4E0E\u4F60\u786E\u8BA4\u540E\u518D\u6267\u884C\uFF0C\u9002\u5408\u8F83\u590D\u6742\u7684\u4EFB\u52A1",
2171
+ onClick: () => onChange(!enabled),
2172
+ disabled,
2173
+ className: "flex w-full items-center justify-between gap-3 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))] disabled:cursor-not-allowed disabled:opacity-50",
2174
+ children: [
2175
+ /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2", children: [
2176
+ /* @__PURE__ */ jsx10(Lightbulb, { size: 14, className: "text-[#F97316]", "aria-hidden": "true" }),
2177
+ "\u89C4\u5212\u6A21\u5F0F"
2178
+ ] }),
2179
+ /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2", children: [
2180
+ /* @__PURE__ */ jsx10("span", { className: "text-[10px] text-[hsl(var(--muted-foreground))]", children: enabled ? "\u5F00" : "\u5173" }),
2181
+ /* @__PURE__ */ jsx10(
2182
+ "span",
2183
+ {
2184
+ className: `flex h-4 w-7 items-center rounded-full p-0.5 transition-colors ${enabled ? "justify-end bg-[hsl(var(--primary))]" : "justify-start bg-[hsl(var(--muted))]"}`,
2185
+ "aria-hidden": "true",
2186
+ children: /* @__PURE__ */ jsx10("span", { className: "h-3 w-3 rounded-full bg-[hsl(var(--background))] shadow-sm" })
2187
+ }
2188
+ )
2189
+ ] })
2190
+ ]
2191
+ }
2192
+ );
2193
+ }
2194
+
2137
2195
  // src/react/components/chat/ChatInput.tsx
2138
- import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2196
+ import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2139
2197
  var DOUBLE_ESCAPE_MS = 450;
2140
2198
  function getEditorText(editor) {
2141
2199
  return editor?.getText({ blockSeparator: "\n" }) ?? "";
@@ -2301,38 +2359,39 @@ function ComposerFilePill({
2301
2359
  const isFailed = isFile && attachment.status === "failed";
2302
2360
  const isUploading = isFile && attachment.status === "uploading";
2303
2361
  const uploadPercent = isUploading && typeof attachment.uploadProgress === "number" ? Math.max(0, Math.min(100, Math.round(attachment.uploadProgress * 100))) : null;
2304
- return /* @__PURE__ */ jsxs9(
2362
+ return /* @__PURE__ */ jsxs10(
2305
2363
  "div",
2306
2364
  {
2307
2365
  className: `relative flex shrink-0 items-center gap-1.5 overflow-hidden rounded-full border px-2.5 py-1 text-[11px] ${isFailed ? "border-red-500/30 bg-red-500/5 text-red-400" : "border-[hsl(var(--border))] bg-[hsl(var(--card))] text-[hsl(var(--foreground))]"}`,
2308
2366
  children: [
2309
- uploadPercent !== null ? /* @__PURE__ */ jsx10(
2367
+ uploadPercent !== null ? /* @__PURE__ */ jsx11(
2310
2368
  "span",
2311
2369
  {
2312
2370
  className: "absolute inset-y-0 left-0 bg-[hsl(var(--primary))]/10 transition-[width]",
2313
2371
  style: { width: `${uploadPercent}%` }
2314
2372
  }
2315
2373
  ) : null,
2316
- isUploading ? /* @__PURE__ */ jsx10(
2374
+ isUploading ? /* @__PURE__ */ jsx11(
2317
2375
  Loader22,
2318
2376
  {
2319
2377
  size: 12,
2320
2378
  className: "relative z-10 shrink-0 animate-spin text-[hsl(var(--muted-foreground))]"
2321
2379
  }
2322
- ) : /* @__PURE__ */ jsx10(Icon, { size: 12, className: "relative z-10 shrink-0 text-[hsl(var(--muted-foreground))]" }),
2323
- /* @__PURE__ */ jsx10("span", { className: "relative z-10 max-w-32 truncate", children: attachment.name }),
2324
- uploadPercent !== null ? /* @__PURE__ */ jsxs9("span", { className: "relative z-10 font-mono text-[10px] tabular-nums text-[hsl(var(--muted-foreground))]", children: [
2380
+ ) : /* @__PURE__ */ jsx11(Icon, { size: 12, className: "relative z-10 shrink-0 text-[hsl(var(--muted-foreground))]" }),
2381
+ /* @__PURE__ */ jsx11("span", { className: "relative z-10 max-w-32 truncate", children: attachment.name }),
2382
+ uploadPercent !== null ? /* @__PURE__ */ jsxs10("span", { className: "relative z-10 font-mono text-[10px] tabular-nums text-[hsl(var(--muted-foreground))]", children: [
2325
2383
  uploadPercent,
2326
2384
  "%"
2327
2385
  ] }) : null,
2328
- /* @__PURE__ */ jsx10(
2386
+ /* @__PURE__ */ jsx11(
2329
2387
  "button",
2330
2388
  {
2331
2389
  type: "button",
2332
2390
  onClick: () => onRemove(attachment.id),
2333
2391
  "aria-label": `\u79FB\u9664 ${attachment.name}`,
2392
+ title: "\u79FB\u9664",
2334
2393
  className: "relative z-10 ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-rose-400",
2335
- children: /* @__PURE__ */ jsx10(X2, { size: 10 })
2394
+ children: /* @__PURE__ */ jsx11(X2, { size: 10 })
2336
2395
  }
2337
2396
  )
2338
2397
  ]
@@ -2451,7 +2510,7 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2451
2510
  setImportingId(null);
2452
2511
  }
2453
2512
  };
2454
- return /* @__PURE__ */ jsx10(
2513
+ return /* @__PURE__ */ jsx11(
2455
2514
  "div",
2456
2515
  {
2457
2516
  className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-4",
@@ -2459,44 +2518,44 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2459
2518
  onKeyDown: (e) => {
2460
2519
  if (e.key === "Escape") onClose();
2461
2520
  },
2462
- children: /* @__PURE__ */ jsxs9(
2521
+ children: /* @__PURE__ */ jsxs10(
2463
2522
  "div",
2464
2523
  {
2465
2524
  className: "w-full max-w-lg flex flex-col rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-2xl",
2466
2525
  onClick: (e) => e.stopPropagation(),
2467
2526
  onKeyDown: (e) => e.stopPropagation(),
2468
2527
  children: [
2469
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-5 py-3", children: [
2470
- /* @__PURE__ */ jsx10("h4", { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u6DFB\u52A0\u4E0A\u4E0B\u6587" }),
2471
- /* @__PURE__ */ jsx10(
2528
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-5 py-3", children: [
2529
+ /* @__PURE__ */ jsx11("h4", { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u6DFB\u52A0\u4E0A\u4E0B\u6587" }),
2530
+ /* @__PURE__ */ jsx11(
2472
2531
  "button",
2473
2532
  {
2474
2533
  type: "button",
2475
2534
  onClick: onClose,
2476
2535
  className: "rounded-md p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
2477
- children: /* @__PURE__ */ jsx10(X2, { size: 14 })
2536
+ children: /* @__PURE__ */ jsx11(X2, { size: 14 })
2478
2537
  }
2479
2538
  )
2480
2539
  ] }),
2481
- /* @__PURE__ */ jsxs9("div", { className: "px-5 py-4 space-y-3", children: [
2482
- /* @__PURE__ */ jsxs9("div", { className: "relative", children: [
2483
- /* @__PURE__ */ jsxs9(
2540
+ /* @__PURE__ */ jsxs10("div", { className: "px-5 py-4 space-y-3", children: [
2541
+ /* @__PURE__ */ jsxs10("div", { className: "relative", children: [
2542
+ /* @__PURE__ */ jsxs10(
2484
2543
  "button",
2485
2544
  {
2486
2545
  type: "button",
2487
2546
  onClick: handleLoadSessions,
2488
2547
  className: "inline-flex items-center gap-1.5 rounded-md border border-[hsl(var(--border))] px-2.5 py-1.5 text-xs text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]",
2489
2548
  children: [
2490
- /* @__PURE__ */ jsx10(Import, { size: 12 }),
2549
+ /* @__PURE__ */ jsx11(Import, { size: 12 }),
2491
2550
  "\u4ECE\u5176\u4ED6\u4F1A\u8BDD\u5BFC\u5165",
2492
- /* @__PURE__ */ jsx10(ChevronDown, { size: 10, className: `transition-transform ${showSessionPicker ? "rotate-180" : ""}` })
2551
+ /* @__PURE__ */ jsx11(ChevronDown, { size: 10, className: `transition-transform ${showSessionPicker ? "rotate-180" : ""}` })
2493
2552
  ]
2494
2553
  }
2495
2554
  ),
2496
- showSessionPicker && /* @__PURE__ */ jsx10("div", { className: "absolute left-0 top-full z-10 mt-1 max-h-48 w-full overflow-y-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-lg", children: loadingSessions ? /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
2497
- /* @__PURE__ */ jsx10(Loader22, { size: 12, className: "animate-spin" }),
2555
+ showSessionPicker && /* @__PURE__ */ jsx11("div", { className: "absolute left-0 top-full z-10 mt-1 max-h-48 w-full overflow-y-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-lg", children: loadingSessions ? /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
2556
+ /* @__PURE__ */ jsx11(Loader22, { size: 12, className: "animate-spin" }),
2498
2557
  "\u52A0\u8F7D\u4F1A\u8BDD\u5217\u8868\u2026"
2499
- ] }) : sessions.length === 0 ? /* @__PURE__ */ jsx10("div", { className: "px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5176\u4ED6\u4F1A\u8BDD" }) : sessions.map((s) => /* @__PURE__ */ jsxs9(
2558
+ ] }) : sessions.length === 0 ? /* @__PURE__ */ jsx11("div", { className: "px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5176\u4ED6\u4F1A\u8BDD" }) : sessions.map((s) => /* @__PURE__ */ jsxs10(
2500
2559
  "button",
2501
2560
  {
2502
2561
  type: "button",
@@ -2504,16 +2563,16 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2504
2563
  onClick: () => handleImportSession(s.id),
2505
2564
  className: "flex w-full items-center gap-2 px-3 py-2 text-left text-xs text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))] disabled:opacity-50",
2506
2565
  children: [
2507
- importingId === s.id && /* @__PURE__ */ jsx10(Loader22, { size: 10, className: "shrink-0 animate-spin" }),
2508
- /* @__PURE__ */ jsx10("span", { className: "truncate", children: s.intent })
2566
+ importingId === s.id && /* @__PURE__ */ jsx11(Loader22, { size: 10, className: "shrink-0 animate-spin" }),
2567
+ /* @__PURE__ */ jsx11("span", { className: "truncate", children: s.intent })
2509
2568
  ]
2510
2569
  },
2511
2570
  s.id
2512
2571
  )) })
2513
2572
  ] }),
2514
- /* @__PURE__ */ jsxs9("div", { children: [
2515
- /* @__PURE__ */ jsx10("label", { htmlFor: "ctx-label", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u6807\u7B7E" }),
2516
- /* @__PURE__ */ jsx10(
2573
+ /* @__PURE__ */ jsxs10("div", { children: [
2574
+ /* @__PURE__ */ jsx11("label", { htmlFor: "ctx-label", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u6807\u7B7E" }),
2575
+ /* @__PURE__ */ jsx11(
2517
2576
  "input",
2518
2577
  {
2519
2578
  id: "ctx-label",
@@ -2524,13 +2583,13 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2524
2583
  }
2525
2584
  )
2526
2585
  ] }),
2527
- /* @__PURE__ */ jsxs9("div", { children: [
2528
- /* @__PURE__ */ jsx10("label", { htmlFor: "ctx-content", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u5185\u5BB9" }),
2529
- isImportProcessing && /* @__PURE__ */ jsxs9("div", { className: "mb-1.5 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
2530
- /* @__PURE__ */ jsx10(Loader22, { size: 11, className: "animate-spin" }),
2586
+ /* @__PURE__ */ jsxs10("div", { children: [
2587
+ /* @__PURE__ */ jsx11("label", { htmlFor: "ctx-content", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u5185\u5BB9" }),
2588
+ isImportProcessing && /* @__PURE__ */ jsxs10("div", { className: "mb-1.5 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
2589
+ /* @__PURE__ */ jsx11(Loader22, { size: 11, className: "animate-spin" }),
2531
2590
  "\u6B63\u5728\u5904\u7406\u5BFC\u5165\u5185\u5BB9\u5E76\u5199\u5165 workspace/context\uFF0C\u5B8C\u6210\u540E\u53EF\u70B9\u51FB\u201C\u786E\u5B9A\u201D"
2532
2591
  ] }),
2533
- /* @__PURE__ */ jsx10(
2592
+ /* @__PURE__ */ jsx11(
2534
2593
  "textarea",
2535
2594
  {
2536
2595
  id: "ctx-content",
@@ -2543,8 +2602,8 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2543
2602
  )
2544
2603
  ] })
2545
2604
  ] }),
2546
- /* @__PURE__ */ jsxs9("div", { className: "flex justify-end gap-2 border-t border-[hsl(var(--border))] px-5 py-3", children: [
2547
- /* @__PURE__ */ jsx10(
2605
+ /* @__PURE__ */ jsxs10("div", { className: "flex justify-end gap-2 border-t border-[hsl(var(--border))] px-5 py-3", children: [
2606
+ /* @__PURE__ */ jsx11(
2548
2607
  "button",
2549
2608
  {
2550
2609
  type: "button",
@@ -2553,7 +2612,7 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2553
2612
  children: "\u53D6\u6D88"
2554
2613
  }
2555
2614
  ),
2556
- /* @__PURE__ */ jsx10(
2615
+ /* @__PURE__ */ jsx11(
2557
2616
  "button",
2558
2617
  {
2559
2618
  type: "button",
@@ -2584,19 +2643,19 @@ function ComposerContextPill({
2584
2643
  }) {
2585
2644
  const [showDetail, setShowDetail] = useState8(false);
2586
2645
  const tokenK = formatTokenK(content);
2587
- return /* @__PURE__ */ jsxs9(Fragment2, { children: [
2588
- /* @__PURE__ */ jsxs9("div", { className: "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-2.5 py-1 text-[11px] text-[hsl(var(--foreground))]", children: [
2589
- imageUrl ? /* @__PURE__ */ jsx10(
2646
+ return /* @__PURE__ */ jsxs10(Fragment2, { children: [
2647
+ /* @__PURE__ */ jsxs10("div", { className: "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-2.5 py-1 text-[11px] text-[hsl(var(--foreground))]", children: [
2648
+ imageUrl ? /* @__PURE__ */ jsx11(
2590
2649
  "button",
2591
2650
  {
2592
2651
  type: "button",
2593
2652
  onClick: () => setShowDetail(true),
2594
2653
  className: "h-6 w-6 overflow-hidden rounded-md border border-[hsl(var(--border))] bg-white",
2595
2654
  title: "\u67E5\u770B\u9009\u4E2D\u533A\u57DF\u622A\u56FE",
2596
- children: /* @__PURE__ */ jsx10("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "h-full w-full object-cover" })
2655
+ children: /* @__PURE__ */ jsx11("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "h-full w-full object-cover" })
2597
2656
  }
2598
2657
  ) : null,
2599
- /* @__PURE__ */ jsx10(
2658
+ /* @__PURE__ */ jsx11(
2600
2659
  "button",
2601
2660
  {
2602
2661
  type: "button",
@@ -2606,7 +2665,7 @@ function ComposerContextPill({
2606
2665
  children: label
2607
2666
  }
2608
2667
  ),
2609
- /* @__PURE__ */ jsx10(
2668
+ /* @__PURE__ */ jsx11(
2610
2669
  "span",
2611
2670
  {
2612
2671
  className: "shrink-0 rounded bg-[hsl(var(--background))] px-1.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]",
@@ -2614,18 +2673,19 @@ function ComposerContextPill({
2614
2673
  children: tokenK
2615
2674
  }
2616
2675
  ),
2617
- /* @__PURE__ */ jsx10(
2676
+ /* @__PURE__ */ jsx11(
2618
2677
  "button",
2619
2678
  {
2620
2679
  type: "button",
2621
2680
  onClick: () => onRemove(id),
2622
2681
  "aria-label": `\u79FB\u9664\u4E0A\u4E0B\u6587 ${label}`,
2682
+ title: "\u79FB\u9664",
2623
2683
  className: "ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-rose-400",
2624
- children: /* @__PURE__ */ jsx10(X2, { size: 10 })
2684
+ children: /* @__PURE__ */ jsx11(X2, { size: 10 })
2625
2685
  }
2626
2686
  )
2627
2687
  ] }),
2628
- showDetail && /* @__PURE__ */ jsx10(
2688
+ showDetail && /* @__PURE__ */ jsx11(
2629
2689
  "div",
2630
2690
  {
2631
2691
  className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-6",
@@ -2633,31 +2693,31 @@ function ComposerContextPill({
2633
2693
  onKeyDown: (e) => {
2634
2694
  if (e.key === "Escape") setShowDetail(false);
2635
2695
  },
2636
- children: /* @__PURE__ */ jsxs9(
2696
+ children: /* @__PURE__ */ jsxs10(
2637
2697
  "div",
2638
2698
  {
2639
2699
  className: "w-full max-w-4xl max-h-[85vh] flex flex-col rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-2xl",
2640
2700
  onClick: (e) => e.stopPropagation(),
2641
2701
  onKeyDown: (e) => e.stopPropagation(),
2642
2702
  children: [
2643
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [
2644
- /* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
2645
- /* @__PURE__ */ jsx10("h4", { className: "truncate text-xs font-semibold text-[hsl(var(--foreground))]", children: label }),
2646
- imageUrl ? /* @__PURE__ */ jsx10("p", { className: "mt-0.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u9644\u52A0\u9009\u4E2D\u533A\u57DF\u622A\u56FE\uFF0C\u975E\u591A\u6A21\u6001\u6A21\u578B\u4F1A\u81EA\u52A8\u5FFD\u7565\u56FE\u7247\u3002" }) : null
2703
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [
2704
+ /* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
2705
+ /* @__PURE__ */ jsx11("h4", { className: "truncate text-xs font-semibold text-[hsl(var(--foreground))]", children: label }),
2706
+ imageUrl ? /* @__PURE__ */ jsx11("p", { className: "mt-0.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u9644\u52A0\u9009\u4E2D\u533A\u57DF\u622A\u56FE\uFF0C\u975E\u591A\u6A21\u6001\u6A21\u578B\u4F1A\u81EA\u52A8\u5FFD\u7565\u56FE\u7247\u3002" }) : null
2647
2707
  ] }),
2648
- /* @__PURE__ */ jsx10(
2708
+ /* @__PURE__ */ jsx11(
2649
2709
  "button",
2650
2710
  {
2651
2711
  type: "button",
2652
2712
  onClick: () => setShowDetail(false),
2653
2713
  className: "rounded-md p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
2654
- children: /* @__PURE__ */ jsx10(X2, { size: 14 })
2714
+ children: /* @__PURE__ */ jsx11(X2, { size: 14 })
2655
2715
  }
2656
2716
  )
2657
2717
  ] }),
2658
- /* @__PURE__ */ jsxs9("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
2659
- imageUrl ? /* @__PURE__ */ jsx10("div", { className: "mb-4 rounded-xl border border-[hsl(var(--border))] bg-white p-2", children: /* @__PURE__ */ jsx10("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "max-h-72 max-w-full rounded-lg object-contain" }) }) : null,
2660
- /* @__PURE__ */ jsx10("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground)/0.85)]", children: content })
2718
+ /* @__PURE__ */ jsxs10("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
2719
+ imageUrl ? /* @__PURE__ */ jsx11("div", { className: "mb-4 rounded-xl border border-[hsl(var(--border))] bg-white p-2", children: /* @__PURE__ */ jsx11("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "max-h-72 max-w-full rounded-lg object-contain" }) }) : null,
2720
+ /* @__PURE__ */ jsx11("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground)/0.85)]", children: content })
2661
2721
  ] })
2662
2722
  ]
2663
2723
  }
@@ -2799,24 +2859,25 @@ function HelpPopover({
2799
2859
  composerHint
2800
2860
  }) {
2801
2861
  const [hovered, setHovered] = useState8(false);
2802
- return /* @__PURE__ */ jsxs9(
2862
+ return /* @__PURE__ */ jsxs10(
2803
2863
  "div",
2804
2864
  {
2805
2865
  className: "group/help relative",
2806
2866
  onMouseEnter: () => setHovered(true),
2807
2867
  onFocusCapture: () => setHovered(true),
2808
2868
  children: [
2809
- /* @__PURE__ */ jsx10(
2869
+ /* @__PURE__ */ jsx11(
2810
2870
  "button",
2811
2871
  {
2812
2872
  type: "button",
2813
2873
  "aria-label": "\u67E5\u770B\u8F93\u5165\u63D0\u793A",
2814
- className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-lg text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
2815
- children: /* @__PURE__ */ jsx10(CircleHelp, { size: 13 })
2874
+ title: "\u8F93\u5165\u63D0\u793A",
2875
+ className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
2876
+ children: /* @__PURE__ */ jsx11(CircleHelp, { size: 19 })
2816
2877
  }
2817
2878
  ),
2818
- /* @__PURE__ */ jsx10("div", { className: "pointer-events-auto absolute bottom-full right-0 z-30 hidden pb-2 group-hover/help:block group-focus-within/help:block", children: /* @__PURE__ */ jsxs9("div", { className: "min-w-64 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-3 text-left text-[11px] leading-5 text-[hsl(var(--popover-foreground))] shadow-lg", children: [
2819
- activeSessionId && hovered ? /* @__PURE__ */ jsx10("div", { className: "mb-2 border-b border-[hsl(var(--border))] pb-2", children: /* @__PURE__ */ jsx10(
2879
+ /* @__PURE__ */ jsx11("div", { className: "pointer-events-auto absolute bottom-full right-0 z-30 hidden pb-2 group-hover/help:block group-focus-within/help:block", children: /* @__PURE__ */ jsxs10("div", { className: "min-w-64 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-3.5 text-left text-[12px] leading-5 text-[hsl(var(--popover-foreground))] shadow-lg", children: [
2880
+ activeSessionId && hovered ? /* @__PURE__ */ jsx11("div", { className: "mb-2.5 border-b border-[hsl(var(--border))] pb-2.5", children: /* @__PURE__ */ jsx11(
2820
2881
  SkillStatusBarComponent,
2821
2882
  {
2822
2883
  sessionId: activeSessionId,
@@ -2827,11 +2888,16 @@ function HelpPopover({
2827
2888
  innerClassName: skillStatusBarInnerClassName
2828
2889
  }
2829
2890
  ) }) : null,
2830
- /* @__PURE__ */ jsxs9("div", { className: "space-y-0.5", children: [
2831
- /* @__PURE__ */ jsx10("div", { children: "Shift+Enter \u6362\u884C" }),
2832
- /* @__PURE__ */ jsx10("div", { children: "/ \u8C03\u7528\u6280\u80FD" }),
2833
- /* @__PURE__ */ jsx10("div", { children: "@ \u5F15\u7528\u6587\u4EF6" }),
2834
- composerHint && /* @__PURE__ */ jsx10("div", { children: composerHint })
2891
+ /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
2892
+ [
2893
+ { keys: "Shift + Enter", label: "\u6362\u884C" },
2894
+ { keys: "/", label: "\u8C03\u7528\u6280\u80FD" },
2895
+ { keys: "@", label: "\u5F15\u7528\u6587\u4EF6" }
2896
+ ].map((item) => /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2.5", children: [
2897
+ /* @__PURE__ */ jsx11("kbd", { className: "inline-flex h-[20px] min-w-[20px] shrink-0 items-center justify-center rounded-[5px] border border-[hsl(var(--border))] bg-[hsl(var(--muted))/0.5] px-1.5 font-mono text-[11px] leading-none text-[hsl(var(--muted-foreground))]", children: item.keys }),
2898
+ /* @__PURE__ */ jsx11("span", { className: "text-[hsl(var(--foreground))]", children: item.label })
2899
+ ] }, item.keys)),
2900
+ composerHint && /* @__PURE__ */ jsx11("div", { className: "pt-0.5 text-[hsl(var(--muted-foreground))]", children: composerHint })
2835
2901
  ] })
2836
2902
  ] }) })
2837
2903
  ]
@@ -3088,7 +3154,7 @@ function ChatInput({
3088
3154
  if (!container || !root) return;
3089
3155
  updateSuggestionPosition(container, props.clientRect);
3090
3156
  root.render(
3091
- /* @__PURE__ */ jsx10(
3157
+ /* @__PURE__ */ jsx11(
3092
3158
  FileCompletionMenu,
3093
3159
  {
3094
3160
  ref: (instance) => {
@@ -3165,7 +3231,7 @@ function ChatInput({
3165
3231
  if (!container || !root) return;
3166
3232
  updateSuggestionPosition(container, props.clientRect);
3167
3233
  root.render(
3168
- /* @__PURE__ */ jsx10(
3234
+ /* @__PURE__ */ jsx11(
3169
3235
  SkillCompletionMenu,
3170
3236
  {
3171
3237
  ref: (instance) => {
@@ -3220,7 +3286,7 @@ function ChatInput({
3220
3286
  "aria-label": resolvedInputLabel,
3221
3287
  "data-testid": "chat-message-input",
3222
3288
  "data-blade-input-label": resolvedInputLabel,
3223
- class: "min-h-[40px] max-h-[240px] overflow-y-auto px-4 py-3 text-sm leading-relaxed text-[hsl(var(--foreground))] focus:outline-none [&_.file-mention-pill]:inline-flex [&_.file-mention-pill]:items-center [&_.file-mention-pill]:rounded-full [&_.file-mention-pill]:bg-[hsl(var(--accent))] [&_.file-mention-pill]:px-2 [&_.file-mention-pill]:py-0.5 [&_.file-mention-pill]:font-medium [&_.file-mention-pill]:text-[hsl(var(--primary))] [&_.file-mention-pill]:select-none [&_.file-mention-pill]:whitespace-nowrap [&_.skill-mention-pill]:inline-flex [&_.skill-mention-pill]:items-center [&_.skill-mention-pill]:rounded-full [&_.skill-mention-pill]:bg-[hsl(var(--primary)/0.15)] [&_.skill-mention-pill]:px-2 [&_.skill-mention-pill]:py-0.5 [&_.skill-mention-pill]:font-medium [&_.skill-mention-pill]:text-[hsl(var(--primary))] [&_.skill-mention-pill]:select-none [&_.skill-mention-pill]:whitespace-nowrap [&_p:first-child]:mt-0 [&_p:last-child]:mb-0"
3289
+ class: "min-h-[34px] max-h-[240px] overflow-y-auto px-4 py-2 text-sm leading-relaxed text-[hsl(var(--foreground))] focus:outline-none [&_.file-mention-pill]:inline-flex [&_.file-mention-pill]:items-center [&_.file-mention-pill]:rounded-full [&_.file-mention-pill]:bg-[hsl(var(--accent))] [&_.file-mention-pill]:px-2 [&_.file-mention-pill]:py-0.5 [&_.file-mention-pill]:font-medium [&_.file-mention-pill]:text-[hsl(var(--primary))] [&_.file-mention-pill]:select-none [&_.file-mention-pill]:whitespace-nowrap [&_.skill-mention-pill]:inline-flex [&_.skill-mention-pill]:items-center [&_.skill-mention-pill]:rounded-full [&_.skill-mention-pill]:bg-[hsl(var(--primary)/0.15)] [&_.skill-mention-pill]:px-2 [&_.skill-mention-pill]:py-0.5 [&_.skill-mention-pill]:font-medium [&_.skill-mention-pill]:text-[hsl(var(--primary))] [&_.skill-mention-pill]:select-none [&_.skill-mention-pill]:whitespace-nowrap [&_p:first-child]:mt-0 [&_p:last-child]:mb-0"
3224
3290
  },
3225
3291
  handleDOMEvents: {
3226
3292
  focus: () => {
@@ -3590,11 +3656,11 @@ function ChatInput({
3590
3656
  );
3591
3657
  const hasValidAttachments = composerAttachments.some((attachment) => attachment.status !== "failed");
3592
3658
  const isSendDisabled = connectionStatus !== "connected" || isModelLoading || !hasAvailableModel || isSubmitting || hasUploadingFiles || !input.trim() && !hasValidAttachments && !hasRenderedAttachments && !hasPendingContexts;
3593
- return /* @__PURE__ */ jsxs9(Fragment2, { children: [
3594
- /* @__PURE__ */ jsx10("div", { className: `bg-[hsl(var(--background))] px-5 py-3 ${className ?? ""}`, children: /* @__PURE__ */ jsxs9("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: [
3595
- activeSessionId ? /* @__PURE__ */ jsx10(BackgroundTasksPill, { sessionId: activeSessionId }) : null,
3596
- !isModelLoading && !hasAvailableModel ? /* @__PURE__ */ jsx10("div", { className: "mb-2 rounded-lg border border-[hsl(var(--destructive))]/30 bg-[hsl(var(--destructive))]/8 px-3 py-2 text-xs text-[hsl(var(--destructive))]", children: "\u6CA1\u6709\u53EF\u7528\u6A21\u578B\uFF0C\u8BF7\u68C0\u67E5\u6A21\u578B\u670D\u52A1\u914D\u7F6E" }) : null,
3597
- /* @__PURE__ */ jsx10(
3659
+ return /* @__PURE__ */ jsxs10(Fragment2, { children: [
3660
+ /* @__PURE__ */ jsx11("div", { className: `bg-[hsl(var(--background))] px-5 py-3 ${className ?? ""}`, children: /* @__PURE__ */ jsxs10("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: [
3661
+ activeSessionId ? /* @__PURE__ */ jsx11(BackgroundTasksPill, { sessionId: activeSessionId }) : null,
3662
+ !isModelLoading && !hasAvailableModel ? /* @__PURE__ */ jsx11("div", { className: "mb-2 rounded-lg border border-[hsl(var(--destructive))]/30 bg-[hsl(var(--destructive))]/8 px-3 py-2 text-xs text-[hsl(var(--destructive))]", children: "\u6CA1\u6709\u53EF\u7528\u6A21\u578B\uFF0C\u8BF7\u68C0\u67E5\u6A21\u578B\u670D\u52A1\u914D\u7F6E" }) : null,
3663
+ /* @__PURE__ */ jsx11(
3598
3664
  "div",
3599
3665
  {
3600
3666
  className: "relative",
@@ -3628,19 +3694,19 @@ function ChatInput({
3628
3694
  if (files.length > 0) void stableAppendFiles(files);
3629
3695
  });
3630
3696
  },
3631
- children: /* @__PURE__ */ jsxs9(
3697
+ children: /* @__PURE__ */ jsxs10(
3632
3698
  "div",
3633
3699
  {
3634
- className: `overflow-visible rounded-2xl border bg-[hsl(var(--card))] transition-[box-shadow,border-color] duration-300 ${isRecording ? "border-emerald-400/70! shadow-[0_0_0_3px_rgba(52,211,153,0.18),0_0_24px_rgba(52,211,153,0.28)]" : dragging ? isPlanning ? "border-amber-400/60" : "border-[hsl(var(--primary)/0.6)]" : isEditorFocused ? isPlanning ? "border-amber-400/60" : "border-[hsl(var(--primary)/0.6)]" : isPlanning ? "border-amber-400/30" : "border-[hsl(var(--border))]"}`,
3700
+ className: `overflow-visible rounded-[22px] border bg-[hsl(var(--card))] transition-[box-shadow,border-color] duration-300 ${isRecording ? "border-emerald-400/70! shadow-[0_0_0_3px_rgba(52,211,153,0.18),0_0_24px_rgba(52,211,153,0.28)]" : dragging ? isPlanning ? "border-amber-400/60" : "border-[hsl(var(--primary)/0.6)]" : isEditorFocused ? isPlanning ? "border-amber-400/60" : "border-[hsl(var(--primary)/0.6)]" : isPlanning ? "border-amber-400/30" : "border-[hsl(var(--border))]"}`,
3635
3701
  children: [
3636
- dragging && /* @__PURE__ */ jsx10("div", { className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-2xl bg-[hsl(var(--primary)/0.06)]", children: /* @__PURE__ */ jsx10("span", { className: "rounded-full bg-[hsl(var(--primary)/0.12)] px-4 py-2 text-sm font-medium text-[hsl(var(--primary))]", children: "\u677E\u624B\u5F15\u7528\u6587\u4EF6" }) }),
3637
- composerAttachments.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "flex max-h-40 flex-col gap-2 overflow-y-auto border-b border-[hsl(var(--border))] px-3 py-2", children: [
3638
- imageAttachments.length > 0 && /* @__PURE__ */ jsx10("div", { className: "grid grid-cols-3 gap-2", children: imageAttachments.map((attachment) => /* @__PURE__ */ jsxs9(
3702
+ dragging && /* @__PURE__ */ jsx11("div", { className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-2xl bg-[hsl(var(--primary)/0.06)]", children: /* @__PURE__ */ jsx11("span", { className: "rounded-full bg-[hsl(var(--primary)/0.12)] px-4 py-2 text-sm font-medium text-[hsl(var(--primary))]", children: "\u677E\u624B\u5F15\u7528\u6587\u4EF6" }) }),
3703
+ composerAttachments.length > 0 && /* @__PURE__ */ jsxs10("div", { className: "flex max-h-40 flex-col gap-2 overflow-y-auto border-b border-[hsl(var(--border))] px-3 py-2", children: [
3704
+ imageAttachments.length > 0 && /* @__PURE__ */ jsx11("div", { className: "grid grid-cols-3 gap-2", children: imageAttachments.map((attachment) => /* @__PURE__ */ jsxs10(
3639
3705
  "div",
3640
3706
  {
3641
3707
  className: "relative overflow-hidden rounded-xl border border-[hsl(var(--border))]",
3642
3708
  children: [
3643
- /* @__PURE__ */ jsx10(
3709
+ /* @__PURE__ */ jsx11(
3644
3710
  "img",
3645
3711
  {
3646
3712
  src: getImagePreviewUrl(attachment, activeSessionId, localImageUrls),
@@ -3648,21 +3714,22 @@ function ChatInput({
3648
3714
  className: "h-24 w-full object-cover"
3649
3715
  }
3650
3716
  ),
3651
- /* @__PURE__ */ jsx10(
3717
+ /* @__PURE__ */ jsx11(
3652
3718
  "button",
3653
3719
  {
3654
3720
  type: "button",
3655
3721
  onClick: () => removeAttachment(attachment.id),
3656
3722
  "aria-label": `\u79FB\u9664 ${attachment.name || "\u56FE\u7247"}`,
3723
+ title: "\u79FB\u9664",
3657
3724
  className: "absolute right-1.5 top-1.5 flex h-6 w-6 items-center justify-center rounded-full bg-[hsl(var(--background)/0.85)] text-[hsl(var(--foreground))]",
3658
- children: /* @__PURE__ */ jsx10(X2, { size: 12 })
3725
+ children: /* @__PURE__ */ jsx11(X2, { size: 12 })
3659
3726
  }
3660
3727
  )
3661
3728
  ]
3662
3729
  },
3663
3730
  attachment.id
3664
3731
  )) }),
3665
- fileAttachments.length > 0 && /* @__PURE__ */ jsx10("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => /* @__PURE__ */ jsx10(
3732
+ fileAttachments.length > 0 && /* @__PURE__ */ jsx11("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => /* @__PURE__ */ jsx11(
3666
3733
  ComposerFilePill,
3667
3734
  {
3668
3735
  attachment,
@@ -3671,8 +3738,8 @@ function ChatInput({
3671
3738
  attachment.id
3672
3739
  )) })
3673
3740
  ] }),
3674
- hasPendingContexts || isSkillEditor ? /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1.5 border-b border-[hsl(var(--border))] px-3 py-2", children: [
3675
- pendingContexts?.map((context) => /* @__PURE__ */ jsx10(
3741
+ hasPendingContexts || isSkillEditor ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-1.5 border-b border-[hsl(var(--border))] px-3 py-2", children: [
3742
+ pendingContexts?.map((context) => /* @__PURE__ */ jsx11(
3676
3743
  ComposerContextPill,
3677
3744
  {
3678
3745
  id: context.id,
@@ -3688,18 +3755,18 @@ function ChatInput({
3688
3755
  },
3689
3756
  context.id
3690
3757
  )),
3691
- isSkillEditor && /* @__PURE__ */ jsx10(
3758
+ isSkillEditor && /* @__PURE__ */ jsx11(
3692
3759
  "button",
3693
3760
  {
3694
3761
  type: "button",
3695
3762
  onClick: () => setShowAddContext(true),
3696
3763
  title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
3697
3764
  className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-dashed border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))]",
3698
- children: /* @__PURE__ */ jsx10(Plus, { size: 12 })
3765
+ children: /* @__PURE__ */ jsx11(Plus, { size: 12 })
3699
3766
  }
3700
3767
  )
3701
3768
  ] }) : null,
3702
- showAddContext && activeSessionId && /* @__PURE__ */ jsx10(
3769
+ showAddContext && activeSessionId && /* @__PURE__ */ jsx11(
3703
3770
  AddContextDialog,
3704
3771
  {
3705
3772
  sessionId: activeSessionId,
@@ -3711,15 +3778,15 @@ function ChatInput({
3711
3778
  }
3712
3779
  }
3713
3780
  ),
3714
- attachments ? /* @__PURE__ */ jsx10("div", { className: "border-b border-[hsl(var(--border))] px-3 py-3", children: attachments }) : null,
3715
- slotAboveTextarea ? /* @__PURE__ */ jsx10("div", { className: "border-b border-[hsl(var(--border))] px-3 py-2", children: slotAboveTextarea }) : null,
3716
- /* @__PURE__ */ jsxs9("div", { className: "relative", children: [
3717
- input.length === 0 && /* @__PURE__ */ jsx10("div", { className: "pointer-events-none absolute left-4 top-3 text-sm leading-relaxed text-[hsl(var(--muted-foreground))]", children: placeholder }),
3718
- /* @__PURE__ */ jsx10(EditorContent, { editor })
3781
+ attachments ? /* @__PURE__ */ jsx11("div", { className: "border-b border-[hsl(var(--border))] px-3 py-3", children: attachments }) : null,
3782
+ slotAboveTextarea ? /* @__PURE__ */ jsx11("div", { className: "border-b border-[hsl(var(--border))] px-3 py-2", children: slotAboveTextarea }) : null,
3783
+ /* @__PURE__ */ jsxs10("div", { className: "relative", children: [
3784
+ input.length === 0 && /* @__PURE__ */ jsx11("div", { className: "pointer-events-none absolute left-4 top-2 text-sm leading-relaxed text-[hsl(var(--muted-foreground)/0.6)]", children: placeholder }),
3785
+ /* @__PURE__ */ jsx11(EditorContent, { editor })
3719
3786
  ] }),
3720
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between border-t border-[hsl(var(--border))] px-3 py-1.5", children: [
3721
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
3722
- /* @__PURE__ */ jsx10(
3787
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between px-3 pb-2.5 pt-1", children: [
3788
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
3789
+ /* @__PURE__ */ jsx11(
3723
3790
  "input",
3724
3791
  {
3725
3792
  ref: fileInputRef,
@@ -3735,7 +3802,7 @@ function ChatInput({
3735
3802
  className: "hidden"
3736
3803
  }
3737
3804
  ),
3738
- /* @__PURE__ */ jsx10(
3805
+ /* @__PURE__ */ jsx11(
3739
3806
  "input",
3740
3807
  {
3741
3808
  ref: folderInputRef,
@@ -3751,18 +3818,18 @@ function ChatInput({
3751
3818
  ...{ webkitdirectory: "" }
3752
3819
  }
3753
3820
  ),
3754
- /* @__PURE__ */ jsxs9("details", { ref: actionMenuRef, className: "group relative", children: [
3755
- /* @__PURE__ */ jsx10(
3821
+ /* @__PURE__ */ jsxs10("details", { ref: actionMenuRef, className: "group relative", children: [
3822
+ /* @__PURE__ */ jsx11(
3756
3823
  "summary",
3757
3824
  {
3758
3825
  "aria-label": "\u6DFB\u52A0\u5185\u5BB9",
3759
3826
  title: "\u6DFB\u52A0\u5185\u5BB9",
3760
- className: "flex h-7 w-7 shrink-0 cursor-pointer list-none items-center justify-center rounded-lg border border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))] [&::-webkit-details-marker]:hidden",
3761
- children: /* @__PURE__ */ jsx10(Plus, { size: 14 })
3827
+ className: "flex h-9 w-9 shrink-0 cursor-pointer list-none items-center justify-center rounded-full border border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))] [&::-webkit-details-marker]:hidden",
3828
+ children: /* @__PURE__ */ jsx11(Plus, { size: 14 })
3762
3829
  }
3763
3830
  ),
3764
- /* @__PURE__ */ jsxs9("div", { className: "absolute bottom-full left-0 z-30 mb-2 min-w-36 overflow-visible rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 text-[11px] text-[hsl(var(--popover-foreground))] shadow-lg", children: [
3765
- /* @__PURE__ */ jsxs9(
3831
+ /* @__PURE__ */ jsxs10("div", { className: "absolute bottom-full left-0 z-30 mb-2 min-w-36 overflow-visible rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 text-[11px] text-[hsl(var(--popover-foreground))] shadow-lg", children: [
3832
+ /* @__PURE__ */ jsxs10(
3766
3833
  "button",
3767
3834
  {
3768
3835
  type: "button",
@@ -3772,12 +3839,12 @@ function ChatInput({
3772
3839
  },
3773
3840
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3774
3841
  children: [
3775
- /* @__PURE__ */ jsx10(Paperclip, { size: 13 }),
3842
+ /* @__PURE__ */ jsx11(Paperclip, { size: 13 }),
3776
3843
  "\u4E0A\u4F20\u6587\u4EF6"
3777
3844
  ]
3778
3845
  }
3779
3846
  ),
3780
- /* @__PURE__ */ jsxs9(
3847
+ /* @__PURE__ */ jsxs10(
3781
3848
  "button",
3782
3849
  {
3783
3850
  type: "button",
@@ -3787,12 +3854,12 @@ function ChatInput({
3787
3854
  },
3788
3855
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3789
3856
  children: [
3790
- /* @__PURE__ */ jsx10(FolderUp, { size: 13 }),
3857
+ /* @__PURE__ */ jsx11(FolderUp, { size: 13 }),
3791
3858
  "\u4E0A\u4F20\u6587\u4EF6\u5939"
3792
3859
  ]
3793
3860
  }
3794
3861
  ),
3795
- onDoubleEscape ? /* @__PURE__ */ jsxs9(
3862
+ onDoubleEscape ? /* @__PURE__ */ jsxs10(
3796
3863
  "button",
3797
3864
  {
3798
3865
  type: "button",
@@ -3804,13 +3871,13 @@ function ChatInput({
3804
3871
  },
3805
3872
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3806
3873
  children: [
3807
- /* @__PURE__ */ jsx10(RotateCcw, { size: 13 }),
3874
+ /* @__PURE__ */ jsx11(RotateCcw, { size: 13 }),
3808
3875
  "\u56DE\u5230\u4E4B\u524D\u7684\u67D0\u4E00\u6B65"
3809
3876
  ]
3810
3877
  }
3811
3878
  ) : null,
3812
- onCommand ? /* @__PURE__ */ jsxs9(Fragment2, { children: [
3813
- /* @__PURE__ */ jsxs9(
3879
+ onCommand ? /* @__PURE__ */ jsxs10(Fragment2, { children: [
3880
+ /* @__PURE__ */ jsxs10(
3814
3881
  "button",
3815
3882
  {
3816
3883
  type: "button",
@@ -3821,12 +3888,12 @@ function ChatInput({
3821
3888
  disabled: isStreaming,
3822
3889
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))] disabled:cursor-not-allowed disabled:opacity-50",
3823
3890
  children: [
3824
- isStreaming ? /* @__PURE__ */ jsx10(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx10(Scissors, { size: 13 }),
3891
+ isStreaming ? /* @__PURE__ */ jsx11(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx11(Scissors, { size: 13 }),
3825
3892
  "\u6574\u7406\u5BF9\u8BDD"
3826
3893
  ]
3827
3894
  }
3828
3895
  ),
3829
- /* @__PURE__ */ jsxs9(
3896
+ /* @__PURE__ */ jsxs10(
3830
3897
  "button",
3831
3898
  {
3832
3899
  type: "button",
@@ -3836,12 +3903,12 @@ function ChatInput({
3836
3903
  },
3837
3904
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3838
3905
  children: [
3839
- /* @__PURE__ */ jsx10(Download, { size: 13 }),
3906
+ /* @__PURE__ */ jsx11(Download, { size: 13 }),
3840
3907
  "\u5BFC\u51FA\u4F1A\u8BDD"
3841
3908
  ]
3842
3909
  }
3843
3910
  ),
3844
- canShareSession ? /* @__PURE__ */ jsxs9(
3911
+ canShareSession ? /* @__PURE__ */ jsxs10(
3845
3912
  "button",
3846
3913
  {
3847
3914
  type: "button",
@@ -3851,12 +3918,12 @@ function ChatInput({
3851
3918
  },
3852
3919
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3853
3920
  children: [
3854
- /* @__PURE__ */ jsx10(Share2, { size: 13 }),
3921
+ /* @__PURE__ */ jsx11(Share2, { size: 13 }),
3855
3922
  "\u5206\u4EAB\u4F1A\u8BDD"
3856
3923
  ]
3857
3924
  }
3858
3925
  ) : null,
3859
- /* @__PURE__ */ jsxs9(
3926
+ /* @__PURE__ */ jsxs10(
3860
3927
  "button",
3861
3928
  {
3862
3929
  type: "button",
@@ -3866,12 +3933,12 @@ function ChatInput({
3866
3933
  },
3867
3934
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3868
3935
  children: [
3869
- /* @__PURE__ */ jsx10(FlaskConical, { size: 13 }),
3936
+ /* @__PURE__ */ jsx11(FlaskConical, { size: 13 }),
3870
3937
  "\u63D0\u53D6\u6280\u80FD"
3871
3938
  ]
3872
3939
  }
3873
3940
  ),
3874
- /* @__PURE__ */ jsxs9(
3941
+ /* @__PURE__ */ jsxs10(
3875
3942
  "button",
3876
3943
  {
3877
3944
  type: "button",
@@ -3881,13 +3948,24 @@ function ChatInput({
3881
3948
  },
3882
3949
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3883
3950
  children: [
3884
- /* @__PURE__ */ jsx10(Rocket, { size: 13 }),
3951
+ /* @__PURE__ */ jsx11(Rocket, { size: 13 }),
3885
3952
  "\u751F\u6210\u5E94\u7528"
3886
3953
  ]
3887
3954
  }
3888
3955
  )
3889
3956
  ] }) : null,
3890
- thinkingAvailable ? /* @__PURE__ */ jsx10(
3957
+ onToggleMode ? /* @__PURE__ */ jsx11(
3958
+ PlanningToggle,
3959
+ {
3960
+ enabled: isPlanning,
3961
+ onChange: () => {
3962
+ actionMenuRef.current?.removeAttribute("open");
3963
+ onToggleMode();
3964
+ },
3965
+ disabled: isStreaming
3966
+ }
3967
+ ) : null,
3968
+ thinkingAvailable ? /* @__PURE__ */ jsx11(
3891
3969
  ThinkingToggle,
3892
3970
  {
3893
3971
  enabled: thinkingEnabled,
@@ -3897,10 +3975,10 @@ function ChatInput({
3897
3975
  }
3898
3976
  }
3899
3977
  ) : null,
3900
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 px-3 py-2", children: [
3901
- /* @__PURE__ */ jsx10(Sparkles2, { size: 13 }),
3902
- /* @__PURE__ */ jsx10("span", { className: "shrink-0", children: "\u6A21\u578B" }),
3903
- /* @__PURE__ */ jsx10(
3978
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 px-3 py-2", children: [
3979
+ /* @__PURE__ */ jsx11(Sparkles2, { size: 14, className: "shrink-0", "aria-hidden": "true" }),
3980
+ /* @__PURE__ */ jsx11("span", { className: "shrink-0", children: "\u6A21\u578B" }),
3981
+ /* @__PURE__ */ jsx11(
3904
3982
  ModelSelector,
3905
3983
  {
3906
3984
  value: selectedModel,
@@ -3917,23 +3995,10 @@ function ChatInput({
3917
3995
  )
3918
3996
  ] })
3919
3997
  ] })
3920
- ] }),
3921
- /* @__PURE__ */ jsx10(
3922
- "button",
3923
- {
3924
- type: "button",
3925
- onClick: onToggleMode,
3926
- disabled: isStreaming || !onToggleMode,
3927
- "aria-pressed": isPlanning,
3928
- "aria-label": isPlanning ? "\u5173\u95ED\u89C4\u5212\u6A21\u5F0F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
3929
- title: isPlanning ? "\u89C4\u5212\u6A21\u5F0F\u5DF2\u5F00\u542F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
3930
- className: `flex h-7 w-7 shrink-0 items-center justify-center rounded-lg border transition-colors ${isPlanning ? "border-amber-500/45 bg-amber-500/15 text-amber-400" : "border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] hover:border-amber-500/35 hover:text-[hsl(var(--foreground))]"} disabled:cursor-not-allowed disabled:opacity-50`,
3931
- children: /* @__PURE__ */ jsx10(Lightbulb, { size: 13 })
3932
- }
3933
- )
3998
+ ] })
3934
3999
  ] }),
3935
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5", children: [
3936
- /* @__PURE__ */ jsx10(
4000
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1.5", children: [
4001
+ /* @__PURE__ */ jsx11(
3937
4002
  HelpPopover,
3938
4003
  {
3939
4004
  activeSessionId,
@@ -3945,7 +4010,7 @@ function ChatInput({
3945
4010
  composerHint
3946
4011
  }
3947
4012
  ),
3948
- /* @__PURE__ */ jsx10(
4013
+ /* @__PURE__ */ jsx11(
3949
4014
  "button",
3950
4015
  {
3951
4016
  type: "button",
@@ -3953,22 +4018,23 @@ function ChatInput({
3953
4018
  disabled: isStreaming,
3954
4019
  "aria-label": !asrEnabled ? "\u8BED\u97F3\u8F93\u5165\u672A\u5F00\u542F" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u5F00\u59CB\u8BED\u97F3\u8F93\u5165",
3955
4020
  title: !asrEnabled ? "\u8BED\u97F3\u8F93\u5165\u672A\u5F00\u542F" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u8BED\u97F3\u8F93\u5165",
3956
- className: `flex items-center justify-center rounded-lg border transition-[width,height,border-color,background-color,color,box-shadow] duration-300 disabled:opacity-40 ${!asrEnabled ? "h-7 w-7 border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))]/50 hover:text-[hsl(var(--muted-foreground))]" : isRecording ? "h-9 w-9 border-emerald-400/80! bg-emerald-400/15 text-emerald-400 shadow-[0_0_0_2px_rgba(52,211,153,0.2),0_0_12px_rgba(52,211,153,0.35)]" : "h-7 w-7 border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))]"}`,
3957
- children: !asrEnabled ? /* @__PURE__ */ jsx10(MicOff, { size: 13 }) : isRecording ? /* @__PURE__ */ jsx10(VoiceWaveform, { level: voiceLevel, size: 18 }) : /* @__PURE__ */ jsx10(Mic, { size: 13 })
4021
+ className: `flex items-center justify-center rounded-full transition-[width,height,background-color,color,box-shadow] duration-300 disabled:opacity-40 ${!asrEnabled ? "h-9 w-9 text-[hsl(var(--muted-foreground))]/50 hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--muted-foreground))]" : isRecording ? "h-10 w-10 bg-emerald-400/15 text-emerald-400 shadow-[0_0_0_2px_rgba(52,211,153,0.2),0_0_12px_rgba(52,211,153,0.35)]" : "h-9 w-9 text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]"}`,
4022
+ children: !asrEnabled ? /* @__PURE__ */ jsx11(MicOff, { size: 19 }) : isRecording ? /* @__PURE__ */ jsx11(VoiceWaveform, { level: voiceLevel, size: 20 }) : /* @__PURE__ */ jsx11(Mic, { size: 19 })
3958
4023
  }
3959
4024
  ),
3960
4025
  slotBeforeSend,
3961
- isStreaming ? /* @__PURE__ */ jsx10(
4026
+ isStreaming ? /* @__PURE__ */ jsx11(
3962
4027
  "button",
3963
4028
  {
3964
4029
  type: "button",
3965
4030
  onClick: () => void onStop(),
3966
4031
  disabled: isStopping,
3967
4032
  "aria-label": isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u751F\u6210",
3968
- className: "flex h-7 w-7 items-center justify-center rounded-lg bg-[hsl(var(--destructive))] text-[hsl(var(--destructive-foreground))] transition-opacity hover:opacity-80 disabled:cursor-wait disabled:opacity-70",
3969
- children: isStopping ? /* @__PURE__ */ jsx10(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx10(Square2, { size: 13 })
4033
+ title: isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u751F\u6210",
4034
+ className: "flex h-10 w-10 items-center justify-center rounded-full bg-[hsl(var(--destructive))] text-[hsl(var(--destructive-foreground))] transition-opacity hover:opacity-80 disabled:cursor-wait disabled:opacity-70",
4035
+ children: isStopping ? /* @__PURE__ */ jsx11(Loader22, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx11(Square2, { size: 16 })
3970
4036
  }
3971
- ) : /* @__PURE__ */ jsx10(
4037
+ ) : /* @__PURE__ */ jsx11(
3972
4038
  "button",
3973
4039
  {
3974
4040
  type: "button",
@@ -3976,8 +4042,8 @@ function ChatInput({
3976
4042
  disabled: isSendDisabled || isRecording,
3977
4043
  "aria-label": "\u53D1\u9001\u6D88\u606F",
3978
4044
  title: isModelLoading ? "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u914D\u7F6E" : !hasAvailableModel ? "\u6CA1\u6709\u53EF\u7528\u6A21\u578B\uFF0C\u8BF7\u68C0\u67E5\u6A21\u578B\u670D\u52A1\u914D\u7F6E" : "\u53D1\u9001\u6D88\u606F",
3979
- className: "flex h-7 w-7 items-center justify-center rounded-lg bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-80 disabled:opacity-25",
3980
- children: isSubmitting ? /* @__PURE__ */ jsx10(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx10(Send, { size: 13 })
4045
+ className: "flex h-10 w-10 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] shadow-[0_8px_18px_-8px_rgba(20,87,255,0.7)] transition-opacity hover:opacity-80 disabled:opacity-25 disabled:shadow-none",
4046
+ children: isSubmitting ? /* @__PURE__ */ jsx11(Loader22, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx11(Send, { size: 16 })
3981
4047
  }
3982
4048
  )
3983
4049
  ] })
@@ -3988,7 +4054,7 @@ function ChatInput({
3988
4054
  }
3989
4055
  )
3990
4056
  ] }) }),
3991
- /* @__PURE__ */ jsx10(
4057
+ /* @__PURE__ */ jsx11(
3992
4058
  FileSizeLimitDialog,
3993
4059
  {
3994
4060
  open: oversizedFiles.length > 0,
@@ -4006,18 +4072,18 @@ function ChatInput({
4006
4072
 
4007
4073
  // src/react/components/chat/ConnectionBanner.tsx
4008
4074
  import { AlertTriangle, LoaderCircle } from "lucide-react";
4009
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
4075
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
4010
4076
  function getBannerCopy(status, reconnectAttempt, hasEverConnected) {
4011
4077
  if (status === "connecting") {
4012
4078
  return {
4013
- icon: /* @__PURE__ */ jsx11(LoaderCircle, { size: 14, className: "animate-spin" }),
4079
+ icon: /* @__PURE__ */ jsx12(LoaderCircle, { size: 14, className: "animate-spin" }),
4014
4080
  toneClass: "border-amber-500/25 bg-amber-500/10 text-amber-100",
4015
4081
  title: "\u8FDE\u63A5\u5DF2\u65AD\u5F00\uFF0C\u6B63\u5728\u91CD\u8FDE\u2026",
4016
4082
  detail: reconnectAttempt > 0 ? `\u6B63\u5728\u5C1D\u8BD5\u6062\u590D\u5B9E\u65F6\u8FDE\u63A5\uFF08\u7B2C ${reconnectAttempt} \u6B21\uFF09` : "\u6B63\u5728\u5C1D\u8BD5\u6062\u590D\u5B9E\u65F6\u8FDE\u63A5\uFF0C\u8BF7\u7A0D\u5019"
4017
4083
  };
4018
4084
  }
4019
4085
  return {
4020
- icon: /* @__PURE__ */ jsx11(AlertTriangle, { size: 14 }),
4086
+ icon: /* @__PURE__ */ jsx12(AlertTriangle, { size: 14 }),
4021
4087
  toneClass: "border-rose-500/25 bg-rose-500/10 text-rose-100",
4022
4088
  title: hasEverConnected ? "\u8FDE\u63A5\u5DF2\u65AD\u5F00\uFF0C\u6B63\u5728\u7B49\u5F85\u91CD\u8FDE\u2026" : "\u6682\u65F6\u65E0\u6CD5\u5EFA\u7ACB\u8FDE\u63A5",
4023
4089
  detail: hasEverConnected ? "\u6D88\u606F\u540C\u6B65\u53EF\u80FD\u4F1A\u5EF6\u8FDF\uFF0C\u7CFB\u7EDF\u4F1A\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5" : "\u8BF7\u68C0\u67E5\u670D\u52A1\u662F\u5426\u53EF\u7528\uFF0C\u7CFB\u7EDF\u4F1A\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5"
@@ -4032,7 +4098,7 @@ function ConnectionBanner() {
4032
4098
  return null;
4033
4099
  }
4034
4100
  const copy = getBannerCopy(status, reconnectAttempt, hasEverConnected);
4035
- return /* @__PURE__ */ jsx11("div", { className: "bg-[hsl(var(--background))] px-5 pt-3", children: /* @__PURE__ */ jsxs10(
4101
+ return /* @__PURE__ */ jsx12("div", { className: "bg-[hsl(var(--background))] px-5 pt-3", children: /* @__PURE__ */ jsxs11(
4036
4102
  "div",
4037
4103
  {
4038
4104
  className: cn(
@@ -4040,10 +4106,10 @@ function ConnectionBanner() {
4040
4106
  copy.toneClass
4041
4107
  ),
4042
4108
  children: [
4043
- /* @__PURE__ */ jsx11("span", { className: "mt-0.5 shrink-0", children: copy.icon }),
4044
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
4045
- /* @__PURE__ */ jsx11("div", { className: "text-sm font-medium", children: copy.title }),
4046
- /* @__PURE__ */ jsx11("div", { className: "text-xs opacity-80", children: copy.detail })
4109
+ /* @__PURE__ */ jsx12("span", { className: "mt-0.5 shrink-0", children: copy.icon }),
4110
+ /* @__PURE__ */ jsxs11("div", { className: "min-w-0", children: [
4111
+ /* @__PURE__ */ jsx12("div", { className: "text-sm font-medium", children: copy.title }),
4112
+ /* @__PURE__ */ jsx12("div", { className: "text-xs opacity-80", children: copy.detail })
4047
4113
  ] })
4048
4114
  ]
4049
4115
  }
@@ -4051,14 +4117,14 @@ function ConnectionBanner() {
4051
4117
  }
4052
4118
 
4053
4119
  // src/react/components/chat/MessageList.tsx
4054
- import { ChevronDown as ChevronDown3, Lightbulb as Lightbulb2, MessageSquare } from "lucide-react";
4120
+ import { ChevronDown as ChevronDown4, Lightbulb as Lightbulb2, MessageSquare } from "lucide-react";
4055
4121
  import {
4056
4122
  useCallback as useCallback12,
4057
4123
  useEffect as useEffect18,
4058
4124
  useEffectEvent as useEffectEvent4,
4059
- useMemo as useMemo18,
4125
+ useMemo as useMemo19,
4060
4126
  useRef as useRef13,
4061
- useState as useState21
4127
+ useState as useState22
4062
4128
  } from "react";
4063
4129
 
4064
4130
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
@@ -4486,8 +4552,8 @@ function useStickToBottomContext() {
4486
4552
  }
4487
4553
 
4488
4554
  // src/react/components/chat/AssistantTurnBlock.tsx
4489
- import { AlertCircle, BookOpen, Check as Check5, ChevronRight as ChevronRight5 } from "lucide-react";
4490
- import { memo as memo3, useCallback as useCallback11, useEffect as useEffect16, useMemo as useMemo16, useRef as useRef12, useState as useState18 } from "react";
4555
+ import { AlertCircle, BookOpen, Check as Check5, ChevronDown as ChevronDown2, ChevronRight as ChevronRight5 } from "lucide-react";
4556
+ import { memo as memo3, useCallback as useCallback11, useEffect as useEffect16, useMemo as useMemo17, useRef as useRef12, useState as useState19 } from "react";
4491
4557
 
4492
4558
  // src/react/routes.ts
4493
4559
  var MEMORIES_ROUTE = "/memories";
@@ -4514,7 +4580,7 @@ import { Streamdown } from "streamdown";
4514
4580
  // src/react/components/ai-elements/shimmer.tsx
4515
4581
  import { motion } from "motion/react";
4516
4582
  import { memo, useMemo as useMemo11 } from "react";
4517
- import { jsx as jsx12 } from "react/jsx-runtime";
4583
+ import { jsx as jsx13 } from "react/jsx-runtime";
4518
4584
  var motionComponentCache = /* @__PURE__ */ new Map();
4519
4585
  var getMotionComponent = (element) => {
4520
4586
  let component = motionComponentCache.get(element);
@@ -4538,7 +4604,7 @@ var ShimmerComponent = ({
4538
4604
  () => (children?.length ?? 0) * spread,
4539
4605
  [children, spread]
4540
4606
  );
4541
- return /* @__PURE__ */ jsx12(
4607
+ return /* @__PURE__ */ jsx13(
4542
4608
  MotionComponent,
4543
4609
  {
4544
4610
  animate: { backgroundPosition: "0% center" },
@@ -4564,7 +4630,7 @@ var ShimmerComponent = ({
4564
4630
  var Shimmer = memo(ShimmerComponent);
4565
4631
 
4566
4632
  // src/react/components/ai-elements/reasoning.tsx
4567
- import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
4633
+ import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
4568
4634
  var ReasoningContext = createContext2(null);
4569
4635
  var useReasoning = () => {
4570
4636
  const context = useContext2(ReasoningContext);
@@ -4615,7 +4681,7 @@ var Reasoning = memo2(
4615
4681
  () => ({ duration, isOpen, isStreaming, setIsOpen }),
4616
4682
  [duration, isOpen, isStreaming, setIsOpen]
4617
4683
  );
4618
- return /* @__PURE__ */ jsx13(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx13(
4684
+ return /* @__PURE__ */ jsx14(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx14(
4619
4685
  Collapsible,
4620
4686
  {
4621
4687
  className: cn("not-prose", className),
@@ -4640,7 +4706,7 @@ var ReasoningTrigger = memo2(
4640
4706
  const { isStreaming, isOpen, duration } = useReasoning();
4641
4707
  const status = isStreaming || duration === 0 ? "\u6B63\u5728\u601D\u8003" : "\u5DF2\u601D\u8003";
4642
4708
  const detail = `${formatWordCount(wordCount)} \u5B57`;
4643
- return /* @__PURE__ */ jsx13(
4709
+ return /* @__PURE__ */ jsx14(
4644
4710
  CollapsibleTrigger,
4645
4711
  {
4646
4712
  className: cn(
@@ -4648,16 +4714,16 @@ var ReasoningTrigger = memo2(
4648
4714
  className
4649
4715
  ),
4650
4716
  ...props,
4651
- children: children ?? /* @__PURE__ */ jsxs11(Fragment3, { children: [
4652
- /* @__PURE__ */ jsx13(BrainIcon, { className: "size-4" }),
4653
- /* @__PURE__ */ jsxs11("span", { className: "inline-flex items-center gap-1.5", children: [
4654
- isStreaming || duration === 0 ? /* @__PURE__ */ jsx13(Shimmer, { duration: 1, children: status }) : /* @__PURE__ */ jsx13("span", { children: status }),
4655
- /* @__PURE__ */ jsxs11("span", { className: "text-[hsl(var(--muted-foreground))]/70", children: [
4717
+ children: children ?? /* @__PURE__ */ jsxs12(Fragment3, { children: [
4718
+ /* @__PURE__ */ jsx14(BrainIcon, { className: "size-4" }),
4719
+ /* @__PURE__ */ jsxs12("span", { className: "inline-flex items-center gap-1.5", children: [
4720
+ isStreaming || duration === 0 ? /* @__PURE__ */ jsx14(Shimmer, { duration: 1, children: status }) : /* @__PURE__ */ jsx14("span", { children: status }),
4721
+ /* @__PURE__ */ jsxs12("span", { className: "text-[hsl(var(--muted-foreground))]/70", children: [
4656
4722
  "\xB7 ",
4657
4723
  detail
4658
4724
  ] })
4659
4725
  ] }),
4660
- /* @__PURE__ */ jsx13(
4726
+ /* @__PURE__ */ jsx14(
4661
4727
  ChevronDownIcon,
4662
4728
  {
4663
4729
  className: cn(
@@ -4674,7 +4740,7 @@ var ReasoningTrigger = memo2(
4674
4740
  var streamdownPlugins = { cjk, math, mermaid };
4675
4741
  var streamdownComponents = { code: CardCodeBlock };
4676
4742
  var ReasoningContent = memo2(
4677
- ({ className, children, ...props }) => /* @__PURE__ */ jsx13(
4743
+ ({ className, children, ...props }) => /* @__PURE__ */ jsx14(
4678
4744
  CollapsibleContent,
4679
4745
  {
4680
4746
  className: cn(
@@ -4683,7 +4749,7 @@ var ReasoningContent = memo2(
4683
4749
  className
4684
4750
  ),
4685
4751
  ...props,
4686
- children: /* @__PURE__ */ jsx13(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children })
4752
+ children: /* @__PURE__ */ jsx14(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children })
4687
4753
  }
4688
4754
  )
4689
4755
  );
@@ -4693,7 +4759,7 @@ function compactReasoningText(text) {
4693
4759
  function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
4694
4760
  const compactReasoning = compactReasoningText(reasoning);
4695
4761
  const [open, setOpen] = useState10(false);
4696
- return /* @__PURE__ */ jsxs11(
4762
+ return /* @__PURE__ */ jsxs12(
4697
4763
  "span",
4698
4764
  {
4699
4765
  className: cn(
@@ -4701,7 +4767,7 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
4701
4767
  variant === "inline" ? "ml-1" : "ml-1 shrink-0"
4702
4768
  ),
4703
4769
  children: [
4704
- /* @__PURE__ */ jsx13(
4770
+ /* @__PURE__ */ jsx14(
4705
4771
  "button",
4706
4772
  {
4707
4773
  type: "button",
@@ -4716,7 +4782,7 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
4716
4782
  }
4717
4783
  ),
4718
4784
  open ? createPortal2(
4719
- /* @__PURE__ */ jsx13(
4785
+ /* @__PURE__ */ jsx14(
4720
4786
  "div",
4721
4787
  {
4722
4788
  className: "fixed inset-0 z-[70] flex items-center justify-center bg-black/10 p-6",
@@ -4732,26 +4798,26 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
4732
4798
  setOpen(false);
4733
4799
  }
4734
4800
  },
4735
- children: /* @__PURE__ */ jsxs11(
4801
+ children: /* @__PURE__ */ jsxs12(
4736
4802
  "div",
4737
4803
  {
4738
4804
  className: "m-0 flex max-h-[min(520px,calc(100vh-48px))] w-[min(760px,calc(100vw-48px))] flex-col overflow-hidden rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] text-left text-[13px] leading-6 text-[hsl(var(--popover-foreground))] shadow-xl",
4739
4805
  "aria-label": "\u601D\u8003\u8BE6\u60C5",
4740
4806
  children: [
4741
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-2", children: [
4742
- /* @__PURE__ */ jsx13("span", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u601D\u8003\u8BE6\u60C5" }),
4743
- /* @__PURE__ */ jsx13(
4807
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-2", children: [
4808
+ /* @__PURE__ */ jsx14("span", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u601D\u8003\u8BE6\u60C5" }),
4809
+ /* @__PURE__ */ jsx14(
4744
4810
  "button",
4745
4811
  {
4746
4812
  type: "button",
4747
4813
  onClick: () => setOpen(false),
4748
4814
  className: "inline-flex h-6 w-6 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
4749
4815
  "aria-label": "\u5173\u95ED\u601D\u8003\u8BE6\u60C5",
4750
- children: /* @__PURE__ */ jsx13(XIcon, { size: 14, "aria-hidden": "true" })
4816
+ children: /* @__PURE__ */ jsx14(XIcon, { size: 14, "aria-hidden": "true" })
4751
4817
  }
4752
4818
  )
4753
4819
  ] }),
4754
- /* @__PURE__ */ jsx13("div", { className: "overflow-auto px-4 py-3 whitespace-normal [&_*]:whitespace-normal [&_p]:my-1.5 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0 [&_ul]:my-1.5 [&_ol]:my-1.5", children: /* @__PURE__ */ jsx13(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children: compactReasoning }) })
4820
+ /* @__PURE__ */ jsx14("div", { className: "overflow-auto px-4 py-3 whitespace-normal [&_*]:whitespace-normal [&_p]:my-1.5 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0 [&_ul]:my-1.5 [&_ol]:my-1.5", children: /* @__PURE__ */ jsx14(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children: compactReasoning }) })
4755
4821
  ]
4756
4822
  }
4757
4823
  )
@@ -4773,7 +4839,7 @@ import { useEffect as useEffect15, useMemo as useMemo15, useState as useState17
4773
4839
 
4774
4840
  // src/react/components/chat/ResourceIframe.tsx
4775
4841
  import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef9, useState as useState11 } from "react";
4776
- import { jsx as jsx14 } from "react/jsx-runtime";
4842
+ import { jsx as jsx15 } from "react/jsx-runtime";
4777
4843
  function isResourceBridgeMessage(value) {
4778
4844
  return typeof value === "object" && value !== null && value.__resourceBridge === true && typeof value.action === "string";
4779
4845
  }
@@ -4880,7 +4946,7 @@ function ResourceIframe({ ui, sessionId }) {
4880
4946
  const inlineHeight = autoHeight ?? ui.height;
4881
4947
  const sandbox = resourceUri ? "allow-scripts allow-same-origin" : "allow-scripts";
4882
4948
  const srcDoc = ui.resourceHTML ? injectBaseTag(ui.resourceHTML) : void 0;
4883
- return /* @__PURE__ */ jsx14(
4949
+ return /* @__PURE__ */ jsx15(
4884
4950
  "iframe",
4885
4951
  {
4886
4952
  ref: iframeRef,
@@ -4919,7 +4985,7 @@ import { Check as Check2, ChevronRight as ChevronRight3, Loader2 as Loader23, Me
4919
4985
  import { useEffect as useEffect12, useMemo as useMemo13, useState as useState14 } from "react";
4920
4986
 
4921
4987
  // src/react/components/chat/tool-renderers/shared.tsx
4922
- import { jsx as jsx15 } from "react/jsx-runtime";
4988
+ import { jsx as jsx16 } from "react/jsx-runtime";
4923
4989
  function getResultText(result) {
4924
4990
  if (typeof result === "string") return result;
4925
4991
  if (Array.isArray(result)) {
@@ -4986,7 +5052,7 @@ function CodePreview({
4986
5052
  }) {
4987
5053
  const { highlightedHtml } = useHighlightedCodeHtml(content, getCodeLanguage(filePath));
4988
5054
  if (!content.trim()) {
4989
- return /* @__PURE__ */ jsx15(
5055
+ return /* @__PURE__ */ jsx16(
4990
5056
  "pre",
4991
5057
  {
4992
5058
  className: cn(
@@ -4994,11 +5060,11 @@ function CodePreview({
4994
5060
  "bg-[hsl(var(--muted))]/35 p-3 font-mono text-[11px] text-[hsl(var(--muted-foreground))]",
4995
5061
  className
4996
5062
  ),
4997
- children: /* @__PURE__ */ jsx15("code", { children: emptyLabel })
5063
+ children: /* @__PURE__ */ jsx16("code", { children: emptyLabel })
4998
5064
  }
4999
5065
  );
5000
5066
  }
5001
- return /* @__PURE__ */ jsx15(
5067
+ return /* @__PURE__ */ jsx16(
5002
5068
  "pre",
5003
5069
  {
5004
5070
  className: cn(
@@ -5006,19 +5072,19 @@ function CodePreview({
5006
5072
  "bg-[hsl(var(--muted))]/35 p-3 text-[11px]",
5007
5073
  className
5008
5074
  ),
5009
- children: highlightedHtml ? /* @__PURE__ */ jsx15(
5075
+ children: highlightedHtml ? /* @__PURE__ */ jsx16(
5010
5076
  "code",
5011
5077
  {
5012
5078
  className: "font-mono",
5013
5079
  dangerouslySetInnerHTML: { __html: highlightedHtml }
5014
5080
  }
5015
- ) : /* @__PURE__ */ jsx15("code", { className: "whitespace-pre-wrap break-words font-mono text-[hsl(var(--foreground))]", children: content })
5081
+ ) : /* @__PURE__ */ jsx16("code", { className: "whitespace-pre-wrap break-words font-mono text-[hsl(var(--foreground))]", children: content })
5016
5082
  }
5017
5083
  );
5018
5084
  }
5019
5085
 
5020
5086
  // src/react/components/chat/tool-renderers/BashRenderer.tsx
5021
- import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
5087
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
5022
5088
  function pickOutputField(data) {
5023
5089
  if (!data) return null;
5024
5090
  for (const key of ["output", "stdout", "stderr"]) {
@@ -5028,7 +5094,7 @@ function pickOutputField(data) {
5028
5094
  return null;
5029
5095
  }
5030
5096
  function MetaPill({ label }) {
5031
- return /* @__PURE__ */ jsx16("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-[10px] text-secondary-foreground", children: label });
5097
+ return /* @__PURE__ */ jsx17("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-[10px] text-secondary-foreground", children: label });
5032
5098
  }
5033
5099
  function BashRenderer({ toolCall }) {
5034
5100
  const argsValue = parseJsonValue(toolCall.arguments);
@@ -5051,16 +5117,16 @@ function BashRenderer({ toolCall }) {
5051
5117
  const rawFallbackOutput = result === null && typeof resultStr === "string" && resultStr.trim().length > 0 ? resultStr : null;
5052
5118
  const output = structuredOutput !== null ? structuredOutput : errorMessage ?? rawFallbackOutput ?? (normalizedName === "BgBash" ? "" : null);
5053
5119
  const hasFailure = toolCall.status === "error" || timedOut || exitCode !== null && exitCode !== 0;
5054
- return /* @__PURE__ */ jsxs12("div", { className: "space-y-3", children: [
5055
- (description || cwd) && /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5056
- description ? /* @__PURE__ */ jsx16("span", { children: description }) : null,
5057
- cwd ? /* @__PURE__ */ jsx16("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: cwd }) : null
5120
+ return /* @__PURE__ */ jsxs13("div", { className: "space-y-3", children: [
5121
+ (description || cwd) && /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5122
+ description ? /* @__PURE__ */ jsx17("span", { children: description }) : null,
5123
+ cwd ? /* @__PURE__ */ jsx17("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: cwd }) : null
5058
5124
  ] }),
5059
- /* @__PURE__ */ jsxs12("div", { className: "overflow-hidden rounded-lg border border-border bg-card", children: [
5060
- /* @__PURE__ */ jsx16("div", { className: "border-b border-border px-3 py-2 text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u547D\u4EE4" }),
5061
- /* @__PURE__ */ jsx16("pre", { className: "overflow-x-auto px-3 py-3 font-mono text-[11px] leading-5 text-foreground", children: /* @__PURE__ */ jsx16("code", { children: `$ ${command || "\uFF08\u672A\u63D0\u4F9B\u547D\u4EE4\uFF09"}` }) })
5125
+ /* @__PURE__ */ jsxs13("div", { className: "overflow-hidden rounded-lg border border-border bg-card", children: [
5126
+ /* @__PURE__ */ jsx17("div", { className: "border-b border-border px-3 py-2 text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u547D\u4EE4" }),
5127
+ /* @__PURE__ */ jsx17("pre", { className: "overflow-x-auto px-3 py-3 font-mono text-[11px] leading-5 text-foreground", children: /* @__PURE__ */ jsx17("code", { children: `$ ${command || "\uFF08\u672A\u63D0\u4F9B\u547D\u4EE4\uFF09"}` }) })
5062
5128
  ] }),
5063
- /* @__PURE__ */ jsxs12(
5129
+ /* @__PURE__ */ jsxs13(
5064
5130
  "div",
5065
5131
  {
5066
5132
  className: cn(
@@ -5068,26 +5134,26 @@ function BashRenderer({ toolCall }) {
5068
5134
  hasFailure ? "border-red-500/50" : "border-border"
5069
5135
  ),
5070
5136
  children: [
5071
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center justify-between gap-2 border-b border-border px-3 py-2", children: [
5072
- /* @__PURE__ */ jsx16("div", { className: "text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u8F93\u51FA" }),
5073
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-1.5", children: [
5074
- taskId ? /* @__PURE__ */ jsx16(MetaPill, { label: `\u4EFB\u52A1 ${taskId}` }) : null,
5075
- exitCode !== null ? /* @__PURE__ */ jsx16(MetaPill, { label: `\u9000\u51FA\u7801 ${exitCode}` }) : null,
5076
- timedOut ? /* @__PURE__ */ jsx16(MetaPill, { label: "\u5DF2\u8D85\u65F6" }) : null,
5077
- truncated ? /* @__PURE__ */ jsx16(MetaPill, { label: "\u8F93\u51FA\u5DF2\u622A\u65AD" }) : null,
5078
- normalizedName === "BgBash" && !taskId ? /* @__PURE__ */ jsx16(MetaPill, { label: "\u540E\u53F0\u4EFB\u52A1" }) : null
5137
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center justify-between gap-2 border-b border-border px-3 py-2", children: [
5138
+ /* @__PURE__ */ jsx17("div", { className: "text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u8F93\u51FA" }),
5139
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-1.5", children: [
5140
+ taskId ? /* @__PURE__ */ jsx17(MetaPill, { label: `\u4EFB\u52A1 ${taskId}` }) : null,
5141
+ exitCode !== null ? /* @__PURE__ */ jsx17(MetaPill, { label: `\u9000\u51FA\u7801 ${exitCode}` }) : null,
5142
+ timedOut ? /* @__PURE__ */ jsx17(MetaPill, { label: "\u5DF2\u8D85\u65F6" }) : null,
5143
+ truncated ? /* @__PURE__ */ jsx17(MetaPill, { label: "\u8F93\u51FA\u5DF2\u622A\u65AD" }) : null,
5144
+ normalizedName === "BgBash" && !taskId ? /* @__PURE__ */ jsx17(MetaPill, { label: "\u540E\u53F0\u4EFB\u52A1" }) : null
5079
5145
  ] })
5080
5146
  ] }),
5081
- /* @__PURE__ */ jsx16("pre", { className: "max-h-[280px] overflow-auto px-3 py-3 font-mono text-[11px] leading-5 text-foreground", children: /* @__PURE__ */ jsx16("code", { className: "whitespace-pre-wrap break-words", children: output !== null && output.trim().length > 0 ? output : normalizedName === "BgBash" ? "\u4EFB\u52A1\u5DF2\u8FDB\u5165\u540E\u53F0\u6267\u884C\uFF0C\u8F93\u51FA\u4F1A\u5728\u540E\u53F0\u4EFB\u52A1\u9762\u677F\u4E2D\u7EE7\u7EED\u66F4\u65B0\u3002" : output !== null && output.trim().length === 0 && hasFailure ? "\u547D\u4EE4\u5DF2\u7ED3\u675F\uFF0C\u4F46\u672A\u6355\u83B7\u5230\u7EC8\u7AEF\u8F93\u51FA\uFF08\u8BF7\u67E5\u770B\u9000\u51FA\u7801\uFF09\u3002" : "\u547D\u4EE4\u672A\u8FD4\u56DE\u8F93\u51FA\u3002" }) })
5147
+ /* @__PURE__ */ jsx17("pre", { className: "max-h-[280px] overflow-auto px-3 py-3 font-mono text-[11px] leading-5 text-foreground", children: /* @__PURE__ */ jsx17("code", { className: "whitespace-pre-wrap break-words", children: output !== null && output.trim().length > 0 ? output : normalizedName === "BgBash" ? "\u4EFB\u52A1\u5DF2\u8FDB\u5165\u540E\u53F0\u6267\u884C\uFF0C\u8F93\u51FA\u4F1A\u5728\u540E\u53F0\u4EFB\u52A1\u9762\u677F\u4E2D\u7EE7\u7EED\u66F4\u65B0\u3002" : output !== null && output.trim().length === 0 && hasFailure ? "\u547D\u4EE4\u5DF2\u7ED3\u675F\uFF0C\u4F46\u672A\u6355\u83B7\u5230\u7EC8\u7AEF\u8F93\u51FA\uFF08\u8BF7\u67E5\u770B\u9000\u51FA\u7801\uFF09\u3002" : "\u547D\u4EE4\u672A\u8FD4\u56DE\u8F93\u51FA\u3002" }) })
5082
5148
  ]
5083
5149
  }
5084
5150
  ),
5085
- cwdResetNote ? /* @__PURE__ */ jsx16("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: cwdResetNote }) : null
5151
+ cwdResetNote ? /* @__PURE__ */ jsx17("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: cwdResetNote }) : null
5086
5152
  ] });
5087
5153
  }
5088
5154
 
5089
5155
  // src/react/components/chat/tool-renderers/FileEditRenderer.tsx
5090
- import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
5156
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
5091
5157
  var MAX_DIFF_LINES = 200;
5092
5158
  var FILE_PATH_FIELDS = ["file_path", "path"];
5093
5159
  function computeDiff(oldText, newText) {
@@ -5294,21 +5360,21 @@ function FileEditRenderer({ toolCall }) {
5294
5360
  const diffLines = normalizedName === "Write" ? buildWritePreview(writeContent) : buildEditPreview(args, rawArguments);
5295
5361
  const resultStr = typeof toolCall.result === "string" ? toolCall.result : null;
5296
5362
  const summaryText = resultStr?.trim() && !errorMessage ? resultStr.trim() : null;
5297
- return /* @__PURE__ */ jsxs13("div", { className: "space-y-3", children: [
5298
- /* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-3", children: [
5299
- /* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
5300
- /* @__PURE__ */ jsx17("div", { className: "text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: normalizedName === "Write" ? "\u5199\u5165\u6587\u4EF6" : "\u7F16\u8F91\u6587\u4EF6" }),
5301
- /* @__PURE__ */ jsx17("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: filePath ?? fileName })
5363
+ return /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
5364
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-start justify-between gap-3", children: [
5365
+ /* @__PURE__ */ jsxs14("div", { className: "min-w-0", children: [
5366
+ /* @__PURE__ */ jsx18("div", { className: "text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: normalizedName === "Write" ? "\u5199\u5165\u6587\u4EF6" : "\u7F16\u8F91\u6587\u4EF6" }),
5367
+ /* @__PURE__ */ jsx18("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: filePath ?? fileName })
5302
5368
  ] }),
5303
- checksum ? /* @__PURE__ */ jsx17("span", { className: "rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-2 py-0.5 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: checksum }) : null
5369
+ checksum ? /* @__PURE__ */ jsx18("span", { className: "rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-2 py-0.5 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: checksum }) : null
5304
5370
  ] }),
5305
- description ? /* @__PURE__ */ jsx17("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: description }) : null,
5306
- errorMessage ? /* @__PURE__ */ jsx17("div", { className: "rounded-lg border border-red-500/30 bg-red-500/8 px-3 py-2 text-[11px] text-red-300", children: errorMessage }) : null,
5307
- /* @__PURE__ */ jsxs13("div", { className: "overflow-hidden rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20", children: [
5308
- /* @__PURE__ */ jsx17("div", { className: "border-b border-[hsl(var(--border))] px-3 py-2 text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: normalizedName === "Write" ? "\u5185\u5BB9\u9884\u89C8" : "\u53D8\u66F4\u9884\u89C8" }),
5309
- /* @__PURE__ */ jsx17("pre", { className: "max-h-[320px] overflow-auto p-0 font-mono text-[11px] leading-5", children: diffLines.length > 0 ? diffLines.map((line, index) => {
5371
+ description ? /* @__PURE__ */ jsx18("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: description }) : null,
5372
+ errorMessage ? /* @__PURE__ */ jsx18("div", { className: "rounded-lg border border-red-500/30 bg-red-500/8 px-3 py-2 text-[11px] text-red-300", children: errorMessage }) : null,
5373
+ /* @__PURE__ */ jsxs14("div", { className: "overflow-hidden rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20", children: [
5374
+ /* @__PURE__ */ jsx18("div", { className: "border-b border-[hsl(var(--border))] px-3 py-2 text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: normalizedName === "Write" ? "\u5185\u5BB9\u9884\u89C8" : "\u53D8\u66F4\u9884\u89C8" }),
5375
+ /* @__PURE__ */ jsx18("pre", { className: "max-h-[320px] overflow-auto p-0 font-mono text-[11px] leading-5", children: diffLines.length > 0 ? diffLines.map((line, index) => {
5310
5376
  const prefix = line.type === "added" ? "+ " : line.type === "removed" ? "- " : " ";
5311
- return /* @__PURE__ */ jsxs13(
5377
+ return /* @__PURE__ */ jsxs14(
5312
5378
  "div",
5313
5379
  {
5314
5380
  className: cn(
@@ -5318,9 +5384,9 @@ function FileEditRenderer({ toolCall }) {
5318
5384
  line.type === "unchanged" && "text-[hsl(var(--foreground))]"
5319
5385
  ),
5320
5386
  children: [
5321
- /* @__PURE__ */ jsx17("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.oldLine ?? "" }),
5322
- /* @__PURE__ */ jsx17("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.newLine ?? "" }),
5323
- /* @__PURE__ */ jsxs13("span", { className: "min-w-0 whitespace-pre-wrap break-words py-0.5", children: [
5387
+ /* @__PURE__ */ jsx18("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.oldLine ?? "" }),
5388
+ /* @__PURE__ */ jsx18("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.newLine ?? "" }),
5389
+ /* @__PURE__ */ jsxs14("span", { className: "min-w-0 whitespace-pre-wrap break-words py-0.5", children: [
5324
5390
  prefix,
5325
5391
  line.value
5326
5392
  ] })
@@ -5328,9 +5394,9 @@ function FileEditRenderer({ toolCall }) {
5328
5394
  },
5329
5395
  `${line.type}-${line.oldLine}-${line.newLine}-${index}`
5330
5396
  );
5331
- }) : /* @__PURE__ */ jsx17("div", { className: "px-3 py-4 text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u672A\u68C0\u6D4B\u5230\u53EF\u9884\u89C8\u7684\u53D8\u66F4\u3002" }) })
5397
+ }) : /* @__PURE__ */ jsx18("div", { className: "px-3 py-4 text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u672A\u68C0\u6D4B\u5230\u53EF\u9884\u89C8\u7684\u53D8\u66F4\u3002" }) })
5332
5398
  ] }),
5333
- summaryText ? /* @__PURE__ */ jsx17("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: summaryText }) : null
5399
+ summaryText ? /* @__PURE__ */ jsx18("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: summaryText }) : null
5334
5400
  ] });
5335
5401
  }
5336
5402
 
@@ -5341,7 +5407,7 @@ import { useState as useState13 } from "react";
5341
5407
  import { ChevronLeft, ChevronRight as ChevronRight2, Download as Download2, ExternalLink, Minus, Plus as Plus2, RotateCcw as RotateCcw2, X as X3 } from "lucide-react";
5342
5408
  import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef10, useState as useState12 } from "react";
5343
5409
  import { createPortal as createPortal3 } from "react-dom";
5344
- import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
5410
+ import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
5345
5411
  function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
5346
5412
  const [currentIndex, setCurrentIndex] = useState12(initialIndex);
5347
5413
  const [scale, setScale] = useState12(1);
@@ -5451,22 +5517,22 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
5451
5517
  if (images.length === 0) {
5452
5518
  return createPortal3(
5453
5519
  // biome-ignore lint/a11y/useKeyWithClickEvents: ESC handler is registered via useEffect
5454
- /* @__PURE__ */ jsxs14(
5520
+ /* @__PURE__ */ jsxs15(
5455
5521
  "div",
5456
5522
  {
5457
5523
  className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80",
5458
5524
  onClick: close,
5459
5525
  children: [
5460
- /* @__PURE__ */ jsx18(
5526
+ /* @__PURE__ */ jsx19(
5461
5527
  "button",
5462
5528
  {
5463
5529
  type: "button",
5464
5530
  onClick: close,
5465
5531
  className: "absolute right-4 top-4 z-10 rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
5466
- children: /* @__PURE__ */ jsx18(X3, { size: 20 })
5532
+ children: /* @__PURE__ */ jsx19(X3, { size: 20 })
5467
5533
  }
5468
5534
  ),
5469
- /* @__PURE__ */ jsx18("span", { className: "text-sm text-white/60", children: "\u52A0\u8F7D\u4E2D..." })
5535
+ /* @__PURE__ */ jsx19("span", { className: "text-sm text-white/60", children: "\u52A0\u8F7D\u4E2D..." })
5470
5536
  ]
5471
5537
  }
5472
5538
  ),
@@ -5477,46 +5543,46 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
5477
5543
  const showNav = images.length > 1;
5478
5544
  return createPortal3(
5479
5545
  // biome-ignore lint/a11y/useKeyWithClickEvents: ESC handler is registered via useEffect
5480
- /* @__PURE__ */ jsxs14("div", { className: "fixed inset-0 z-50 bg-black/80", onClick: handleAreaClick, children: [
5481
- /* @__PURE__ */ jsxs14(
5546
+ /* @__PURE__ */ jsxs15("div", { className: "fixed inset-0 z-50 bg-black/80", onClick: handleAreaClick, children: [
5547
+ /* @__PURE__ */ jsxs15(
5482
5548
  "div",
5483
5549
  {
5484
5550
  className: "absolute right-4 top-4 z-10 flex items-center gap-1.5",
5485
5551
  onClick: (e) => e.stopPropagation(),
5486
5552
  children: [
5487
- /* @__PURE__ */ jsx18(
5553
+ /* @__PURE__ */ jsx19(
5488
5554
  "button",
5489
5555
  {
5490
5556
  type: "button",
5491
5557
  onClick: handleDownload,
5492
5558
  title: "\u4E0B\u8F7D\u56FE\u7247",
5493
5559
  className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
5494
- children: /* @__PURE__ */ jsx18(Download2, { size: 18 })
5560
+ children: /* @__PURE__ */ jsx19(Download2, { size: 18 })
5495
5561
  }
5496
5562
  ),
5497
- /* @__PURE__ */ jsx18(
5563
+ /* @__PURE__ */ jsx19(
5498
5564
  "button",
5499
5565
  {
5500
5566
  type: "button",
5501
5567
  onClick: handleOpenInNewTab,
5502
5568
  title: "\u65B0\u6807\u7B7E\u9875\u6253\u5F00",
5503
5569
  className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
5504
- children: /* @__PURE__ */ jsx18(ExternalLink, { size: 18 })
5570
+ children: /* @__PURE__ */ jsx19(ExternalLink, { size: 18 })
5505
5571
  }
5506
5572
  ),
5507
- /* @__PURE__ */ jsx18(
5573
+ /* @__PURE__ */ jsx19(
5508
5574
  "button",
5509
5575
  {
5510
5576
  type: "button",
5511
5577
  onClick: close,
5512
5578
  className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
5513
- children: /* @__PURE__ */ jsx18(X3, { size: 20 })
5579
+ children: /* @__PURE__ */ jsx19(X3, { size: 20 })
5514
5580
  }
5515
5581
  )
5516
5582
  ]
5517
5583
  }
5518
5584
  ),
5519
- showNav && currentIndex > 0 && /* @__PURE__ */ jsx18(
5585
+ showNav && currentIndex > 0 && /* @__PURE__ */ jsx19(
5520
5586
  "button",
5521
5587
  {
5522
5588
  type: "button",
@@ -5525,10 +5591,10 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
5525
5591
  goPrev();
5526
5592
  },
5527
5593
  className: "absolute left-4 top-1/2 z-10 -translate-y-1/2 rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
5528
- children: /* @__PURE__ */ jsx18(ChevronLeft, { size: 24 })
5594
+ children: /* @__PURE__ */ jsx19(ChevronLeft, { size: 24 })
5529
5595
  }
5530
5596
  ),
5531
- showNav && currentIndex < images.length - 1 && /* @__PURE__ */ jsx18(
5597
+ showNav && currentIndex < images.length - 1 && /* @__PURE__ */ jsx19(
5532
5598
  "button",
5533
5599
  {
5534
5600
  type: "button",
@@ -5537,51 +5603,51 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
5537
5603
  goNext();
5538
5604
  },
5539
5605
  className: "absolute right-4 top-1/2 z-10 -translate-y-1/2 rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
5540
- children: /* @__PURE__ */ jsx18(ChevronRight2, { size: 24 })
5606
+ children: /* @__PURE__ */ jsx19(ChevronRight2, { size: 24 })
5541
5607
  }
5542
5608
  ),
5543
- /* @__PURE__ */ jsxs14("div", { className: "absolute bottom-6 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1 rounded-full bg-black/50 px-2 py-1", children: [
5544
- /* @__PURE__ */ jsx18(
5609
+ /* @__PURE__ */ jsxs15("div", { className: "absolute bottom-6 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1 rounded-full bg-black/50 px-2 py-1", children: [
5610
+ /* @__PURE__ */ jsx19(
5545
5611
  "button",
5546
5612
  {
5547
5613
  type: "button",
5548
5614
  onClick: zoomOut,
5549
5615
  className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
5550
- children: /* @__PURE__ */ jsx18(Minus, { size: 16 })
5616
+ children: /* @__PURE__ */ jsx19(Minus, { size: 16 })
5551
5617
  }
5552
5618
  ),
5553
- /* @__PURE__ */ jsxs14("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
5619
+ /* @__PURE__ */ jsxs15("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
5554
5620
  Math.round(scale * 100),
5555
5621
  "%"
5556
5622
  ] }),
5557
- /* @__PURE__ */ jsx18(
5623
+ /* @__PURE__ */ jsx19(
5558
5624
  "button",
5559
5625
  {
5560
5626
  type: "button",
5561
5627
  onClick: zoomIn,
5562
5628
  className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
5563
- children: /* @__PURE__ */ jsx18(Plus2, { size: 16 })
5629
+ children: /* @__PURE__ */ jsx19(Plus2, { size: 16 })
5564
5630
  }
5565
5631
  ),
5566
- /* @__PURE__ */ jsx18(
5632
+ /* @__PURE__ */ jsx19(
5567
5633
  "button",
5568
5634
  {
5569
5635
  type: "button",
5570
5636
  onClick: reset,
5571
5637
  className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
5572
- children: /* @__PURE__ */ jsx18(RotateCcw2, { size: 16 })
5638
+ children: /* @__PURE__ */ jsx19(RotateCcw2, { size: 16 })
5573
5639
  }
5574
5640
  ),
5575
- showNav && /* @__PURE__ */ jsxs14(Fragment4, { children: [
5576
- /* @__PURE__ */ jsx18("div", { className: "mx-1 h-4 w-px bg-white/20" }),
5577
- /* @__PURE__ */ jsxs14("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
5641
+ showNav && /* @__PURE__ */ jsxs15(Fragment4, { children: [
5642
+ /* @__PURE__ */ jsx19("div", { className: "mx-1 h-4 w-px bg-white/20" }),
5643
+ /* @__PURE__ */ jsxs15("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
5578
5644
  currentIndex + 1,
5579
5645
  " / ",
5580
5646
  images.length
5581
5647
  ] })
5582
5648
  ] })
5583
5649
  ] }),
5584
- /* @__PURE__ */ jsx18(
5650
+ /* @__PURE__ */ jsx19(
5585
5651
  "div",
5586
5652
  {
5587
5653
  className: "flex h-full w-full items-center justify-center overflow-hidden p-12",
@@ -5592,7 +5658,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
5592
5658
  onMouseUp: handleMouseUp,
5593
5659
  onMouseLeave: handleMouseUp,
5594
5660
  onDoubleClick: handleDoubleClick,
5595
- children: /* @__PURE__ */ jsx18(
5661
+ children: /* @__PURE__ */ jsx19(
5596
5662
  "img",
5597
5663
  {
5598
5664
  ref: imgRef,
@@ -5614,7 +5680,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
5614
5680
  }
5615
5681
 
5616
5682
  // src/react/components/chat/tool-renderers/FileReadRenderer.tsx
5617
- import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
5683
+ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
5618
5684
  var NUMBERED_LINE_RE = /^(\s*\d+)\t([\s\S]*)$/;
5619
5685
  function parseReadResult(result) {
5620
5686
  if (!result) {
@@ -5674,28 +5740,28 @@ function FileReadRenderer({ toolCall }) {
5674
5740
  const resolvedStartLine = startLine ?? (lineCount > 0 ? fallbackStart : null);
5675
5741
  const resolvedEndLine = endLine ?? (resolvedStartLine !== null && lineCount > 0 ? resolvedStartLine + lineCount - 1 : null);
5676
5742
  const lineRange = formatLineRange(resolvedStartLine, resolvedEndLine);
5677
- return /* @__PURE__ */ jsxs15("div", { className: "space-y-3", children: [
5678
- /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-3", children: [
5679
- /* @__PURE__ */ jsxs15("div", { className: "min-w-0", children: [
5680
- /* @__PURE__ */ jsx19("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: fileName }),
5681
- filePath ? /* @__PURE__ */ jsx19("div", { className: "truncate text-[10px] text-[hsl(var(--muted-foreground))]", children: filePath }) : null
5743
+ return /* @__PURE__ */ jsxs16("div", { className: "space-y-3", children: [
5744
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between gap-3", children: [
5745
+ /* @__PURE__ */ jsxs16("div", { className: "min-w-0", children: [
5746
+ /* @__PURE__ */ jsx20("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: fileName }),
5747
+ filePath ? /* @__PURE__ */ jsx20("div", { className: "truncate text-[10px] text-[hsl(var(--muted-foreground))]", children: filePath }) : null
5682
5748
  ] }),
5683
- /* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center justify-end gap-1.5", children: [
5684
- lineRange ? /* @__PURE__ */ jsx19("span", { className: "rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-2 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: lineRange }) : null,
5685
- checksum ? /* @__PURE__ */ jsx19("span", { className: "rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-2 py-0.5 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: checksum }) : null
5749
+ /* @__PURE__ */ jsxs16("div", { className: "flex flex-wrap items-center justify-end gap-1.5", children: [
5750
+ lineRange ? /* @__PURE__ */ jsx20("span", { className: "rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-2 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: lineRange }) : null,
5751
+ checksum ? /* @__PURE__ */ jsx20("span", { className: "rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-2 py-0.5 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: checksum }) : null
5686
5752
  ] })
5687
5753
  ] }),
5688
- description ? /* @__PURE__ */ jsx19("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: description }) : null,
5689
- errorMessage ? /* @__PURE__ */ jsx19("div", { className: "rounded-lg border border-red-500/30 bg-red-500/8 px-3 py-2 text-[11px] text-red-300", children: errorMessage }) : null,
5690
- isImageResult ? /* @__PURE__ */ jsxs15("div", { className: "grid gap-2", children: [
5691
- imageUrls.map((url, idx) => /* @__PURE__ */ jsx19(
5754
+ description ? /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: description }) : null,
5755
+ errorMessage ? /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-red-500/30 bg-red-500/8 px-3 py-2 text-[11px] text-red-300", children: errorMessage }) : null,
5756
+ isImageResult ? /* @__PURE__ */ jsxs16("div", { className: "grid gap-2", children: [
5757
+ imageUrls.map((url, idx) => /* @__PURE__ */ jsx20(
5692
5758
  "button",
5693
5759
  {
5694
5760
  type: "button",
5695
5761
  onClick: () => setLightboxIndex(idx),
5696
5762
  className: "cursor-zoom-in",
5697
5763
  title: "\u67E5\u770B\u5927\u56FE",
5698
- children: /* @__PURE__ */ jsx19(
5764
+ children: /* @__PURE__ */ jsx20(
5699
5765
  "img",
5700
5766
  {
5701
5767
  src: url,
@@ -5706,7 +5772,7 @@ function FileReadRenderer({ toolCall }) {
5706
5772
  },
5707
5773
  url.slice(0, 64)
5708
5774
  )),
5709
- /* @__PURE__ */ jsx19(
5775
+ /* @__PURE__ */ jsx20(
5710
5776
  ImageLightbox,
5711
5777
  {
5712
5778
  open: lightboxIndex != null,
@@ -5717,15 +5783,15 @@ function FileReadRenderer({ toolCall }) {
5717
5783
  initialIndex: lightboxIndex ?? 0
5718
5784
  }
5719
5785
  ),
5720
- content ? /* @__PURE__ */ jsx19("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: content }) : null
5721
- ] }) : !errorMessage ? /* @__PURE__ */ jsx19(CodePreview, { content, filePath, className: "max-h-[360px]" }) : null,
5722
- note ? /* @__PURE__ */ jsx19("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: note }) : null
5786
+ content ? /* @__PURE__ */ jsx20("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: content }) : null
5787
+ ] }) : !errorMessage ? /* @__PURE__ */ jsx20(CodePreview, { content, filePath, className: "max-h-[360px]" }) : null,
5788
+ note ? /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/35 px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: note }) : null
5723
5789
  ] });
5724
5790
  }
5725
5791
 
5726
5792
  // src/react/components/chat/tool-renderers/SearchRenderer.tsx
5727
5793
  import { ExternalLink as ExternalLink2, FileText as FileText3, Folder as Folder2, Globe2 } from "lucide-react";
5728
- import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
5794
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
5729
5795
  function toRecordArray(value) {
5730
5796
  return Array.isArray(value) ? value.filter(isPlainObject) : [];
5731
5797
  }
@@ -5787,7 +5853,7 @@ function parseWebFetchResult(result) {
5787
5853
  };
5788
5854
  }
5789
5855
  function renderEmptyState(label) {
5790
- return /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-dashed border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-4 text-[11px] text-[hsl(var(--muted-foreground))]", children: label });
5856
+ return /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-dashed border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-4 text-[11px] text-[hsl(var(--muted-foreground))]", children: label });
5791
5857
  }
5792
5858
  function SearchRenderer({ toolCall }) {
5793
5859
  const normalizedName = formatToolName(toolCall.name);
@@ -5796,26 +5862,26 @@ function SearchRenderer({ toolCall }) {
5796
5862
  const resultStr = getResultText(toolCall.result);
5797
5863
  const errorMessage = extractErrorMessage(resultStr);
5798
5864
  if (errorMessage) {
5799
- return /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-red-500/30 bg-red-500/8 px-3 py-2 text-[11px] text-red-300", children: errorMessage });
5865
+ return /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-red-500/30 bg-red-500/8 px-3 py-2 text-[11px] text-red-300", children: errorMessage });
5800
5866
  }
5801
5867
  if (normalizedName === "Ls" || normalizedName === "Glob") {
5802
5868
  const items = parseDirectoryItems(resultStr);
5803
5869
  const path = getStringValue(args, "path");
5804
- return /* @__PURE__ */ jsxs16("div", { className: "space-y-3", children: [
5805
- path ? /* @__PURE__ */ jsxs16("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5870
+ return /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
5871
+ path ? /* @__PURE__ */ jsxs17("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5806
5872
  "\u76EE\u5F55\uFF1A",
5807
5873
  path
5808
5874
  ] }) : null,
5809
- items.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "grid gap-2", children: items.map((item) => /* @__PURE__ */ jsxs16(
5875
+ items.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "grid gap-2", children: items.map((item) => /* @__PURE__ */ jsxs17(
5810
5876
  "div",
5811
5877
  {
5812
5878
  className: "flex items-center justify-between gap-3 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-2",
5813
5879
  children: [
5814
- /* @__PURE__ */ jsxs16("div", { className: "flex min-w-0 items-center gap-2", children: [
5815
- item.isDir ? /* @__PURE__ */ jsx20(Folder2, { size: 14, className: "shrink-0 text-blue-300" }) : /* @__PURE__ */ jsx20(FileText3, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
5816
- /* @__PURE__ */ jsx20("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: item.name })
5880
+ /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 items-center gap-2", children: [
5881
+ item.isDir ? /* @__PURE__ */ jsx21(Folder2, { size: 14, className: "shrink-0 text-blue-300" }) : /* @__PURE__ */ jsx21(FileText3, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
5882
+ /* @__PURE__ */ jsx21("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: item.name })
5817
5883
  ] }),
5818
- /* @__PURE__ */ jsx20("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: item.isDir ? "\u76EE\u5F55" : formatBytes(item.size) ?? "\u6587\u4EF6" })
5884
+ /* @__PURE__ */ jsx21("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: item.isDir ? "\u76EE\u5F55" : formatBytes(item.size) ?? "\u6587\u4EF6" })
5819
5885
  ]
5820
5886
  },
5821
5887
  `${item.name}-${item.size}-${item.isDir}`
@@ -5825,28 +5891,28 @@ function SearchRenderer({ toolCall }) {
5825
5891
  if (normalizedName === "Grep") {
5826
5892
  const { matches, searchPath } = parseGrepResult(resultStr);
5827
5893
  const pattern = getStringValue(args, "pattern");
5828
- return /* @__PURE__ */ jsxs16("div", { className: "space-y-3", children: [
5829
- /* @__PURE__ */ jsxs16("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5830
- pattern ? /* @__PURE__ */ jsx20("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: pattern }) : null,
5831
- searchPath ? /* @__PURE__ */ jsxs16("span", { children: [
5894
+ return /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
5895
+ /* @__PURE__ */ jsxs17("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5896
+ pattern ? /* @__PURE__ */ jsx21("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: pattern }) : null,
5897
+ searchPath ? /* @__PURE__ */ jsxs17("span", { children: [
5832
5898
  "\u8303\u56F4\uFF1A",
5833
5899
  searchPath
5834
5900
  ] }) : null
5835
5901
  ] }),
5836
- matches.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "grid gap-2", children: matches.map((match) => /* @__PURE__ */ jsxs16(
5902
+ matches.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "grid gap-2", children: matches.map((match) => /* @__PURE__ */ jsxs17(
5837
5903
  "div",
5838
5904
  {
5839
5905
  className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-2",
5840
5906
  children: [
5841
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-3", children: [
5842
- /* @__PURE__ */ jsx20("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: match.path }),
5843
- match.lineNumber !== null ? /* @__PURE__ */ jsxs16("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
5907
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between gap-3", children: [
5908
+ /* @__PURE__ */ jsx21("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: match.path }),
5909
+ match.lineNumber !== null ? /* @__PURE__ */ jsxs17("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
5844
5910
  "\u7B2C ",
5845
5911
  match.lineNumber,
5846
5912
  " \u884C"
5847
5913
  ] }) : null
5848
5914
  ] }),
5849
- /* @__PURE__ */ jsx20("pre", { className: "mt-2 overflow-x-auto whitespace-pre-wrap font-mono text-[11px] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx20("code", { children: match.line }) })
5915
+ /* @__PURE__ */ jsx21("pre", { className: "mt-2 overflow-x-auto whitespace-pre-wrap font-mono text-[11px] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx21("code", { children: match.line }) })
5850
5916
  ]
5851
5917
  },
5852
5918
  `${match.path}-${match.lineNumber}-${match.line}`
@@ -5855,16 +5921,16 @@ function SearchRenderer({ toolCall }) {
5855
5921
  }
5856
5922
  const { results, summary } = normalizedName === "WebFetch" ? parseWebFetchResult(resultStr) : { results: parseWebResults(resultStr), summary: null };
5857
5923
  const query = getStringValue(args, "query");
5858
- return /* @__PURE__ */ jsxs16("div", { className: "space-y-3", children: [
5859
- query ? /* @__PURE__ */ jsxs16("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5924
+ return /* @__PURE__ */ jsxs17("div", { className: "space-y-3", children: [
5925
+ query ? /* @__PURE__ */ jsxs17("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5860
5926
  "\u67E5\u8BE2\uFF1A",
5861
5927
  query
5862
5928
  ] }) : null,
5863
- summary ? /* @__PURE__ */ jsxs16("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-3", children: [
5864
- /* @__PURE__ */ jsx20("div", { className: "mb-2 text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: "\u6458\u8981" }),
5865
- /* @__PURE__ */ jsx20("p", { className: "whitespace-pre-wrap text-[11px] leading-5 text-[hsl(var(--foreground))]", children: summary })
5929
+ summary ? /* @__PURE__ */ jsxs17("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-3", children: [
5930
+ /* @__PURE__ */ jsx21("div", { className: "mb-2 text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: "\u6458\u8981" }),
5931
+ /* @__PURE__ */ jsx21("p", { className: "whitespace-pre-wrap text-[11px] leading-5 text-[hsl(var(--foreground))]", children: summary })
5866
5932
  ] }) : null,
5867
- results.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "grid gap-2", children: results.map((item, index) => /* @__PURE__ */ jsx20(
5933
+ results.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "grid gap-2", children: results.map((item, index) => /* @__PURE__ */ jsx21(
5868
5934
  "a",
5869
5935
  {
5870
5936
  href: item.url ?? void 0,
@@ -5874,12 +5940,12 @@ function SearchRenderer({ toolCall }) {
5874
5940
  "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-3 transition-colors",
5875
5941
  item.url && "hover:border-[hsl(var(--ring))] hover:bg-[hsl(var(--muted))]/35"
5876
5942
  ),
5877
- children: /* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-3", children: [
5878
- /* @__PURE__ */ jsx20(Globe2, { size: 15, className: "mt-0.5 shrink-0 text-blue-300" }),
5879
- /* @__PURE__ */ jsxs16("div", { className: "min-w-0 flex-1", children: [
5880
- /* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between gap-3", children: [
5881
- /* @__PURE__ */ jsx20("span", { className: "line-clamp-2 text-[11px] font-medium text-[hsl(var(--foreground))]", children: item.title ?? item.url ?? "\u672A\u547D\u540D\u7ED3\u679C" }),
5882
- item.url ? /* @__PURE__ */ jsx20(
5943
+ children: /* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-3", children: [
5944
+ /* @__PURE__ */ jsx21(Globe2, { size: 15, className: "mt-0.5 shrink-0 text-blue-300" }),
5945
+ /* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1", children: [
5946
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-start justify-between gap-3", children: [
5947
+ /* @__PURE__ */ jsx21("span", { className: "line-clamp-2 text-[11px] font-medium text-[hsl(var(--foreground))]", children: item.title ?? item.url ?? "\u672A\u547D\u540D\u7ED3\u679C" }),
5948
+ item.url ? /* @__PURE__ */ jsx21(
5883
5949
  ExternalLink2,
5884
5950
  {
5885
5951
  size: 12,
@@ -5887,8 +5953,8 @@ function SearchRenderer({ toolCall }) {
5887
5953
  }
5888
5954
  ) : null
5889
5955
  ] }),
5890
- item.url ? /* @__PURE__ */ jsx20("div", { className: "mt-1 truncate font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.url }) : null,
5891
- item.description ? /* @__PURE__ */ jsx20("p", { className: "mt-2 line-clamp-3 text-[11px] leading-5 text-[hsl(var(--muted-foreground))]", children: item.description }) : null
5956
+ item.url ? /* @__PURE__ */ jsx21("div", { className: "mt-1 truncate font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.url }) : null,
5957
+ item.description ? /* @__PURE__ */ jsx21("p", { className: "mt-2 line-clamp-3 text-[11px] leading-5 text-[hsl(var(--muted-foreground))]", children: item.description }) : null
5892
5958
  ] })
5893
5959
  ] })
5894
5960
  },
@@ -5899,7 +5965,7 @@ function SearchRenderer({ toolCall }) {
5899
5965
 
5900
5966
  // src/react/components/chat/tool-renderers/SubmitResultRenderer.tsx
5901
5967
  import { CheckCircle2, CircleAlert } from "lucide-react";
5902
- import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
5968
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
5903
5969
  function extractText(value, key) {
5904
5970
  if (!isPlainObject(value)) return null;
5905
5971
  const field = value[key];
@@ -5920,25 +5986,25 @@ function SubmitResultRenderer({ toolCall }) {
5920
5986
  const { description, result, error, status } = parsePayload(toolCall);
5921
5987
  const isError = toolCall.status === "error" || Boolean(error);
5922
5988
  const Icon = isError ? CircleAlert : CheckCircle2;
5923
- return /* @__PURE__ */ jsxs17("div", { className: "overflow-hidden rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-sm", children: [
5924
- /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3 border-b border-[hsl(var(--border))] bg-[hsl(var(--muted))]/25 px-4 py-3", children: [
5925
- /* @__PURE__ */ jsx21("div", { className: isError ? "text-red-500" : "text-emerald-500", children: /* @__PURE__ */ jsx21(Icon, { size: 18 }) }),
5926
- /* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1", children: [
5927
- /* @__PURE__ */ jsx21("div", { className: "font-medium text-[hsl(var(--foreground))]", children: description || (isError ? "\u4EFB\u52A1\u6267\u884C\u5931\u8D25" : "\u4EFB\u52A1\u7ED3\u679C\u5DF2\u63D0\u4EA4") }),
5928
- description ? /* @__PURE__ */ jsx21("div", { className: "mt-0.5 text-xs text-[hsl(var(--muted-foreground))]", children: isError ? "\u4EFB\u52A1\u6267\u884C\u5931\u8D25" : "\u4EFB\u52A1\u7ED3\u679C\u5DF2\u63D0\u4EA4" }) : null,
5929
- status ? /* @__PURE__ */ jsxs17("div", { className: "mt-0.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
5989
+ return /* @__PURE__ */ jsxs18("div", { className: "overflow-hidden rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-sm", children: [
5990
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3 border-b border-[hsl(var(--border))] bg-[hsl(var(--muted))]/25 px-4 py-3", children: [
5991
+ /* @__PURE__ */ jsx22("div", { className: isError ? "text-red-500" : "text-emerald-500", children: /* @__PURE__ */ jsx22(Icon, { size: 18 }) }),
5992
+ /* @__PURE__ */ jsxs18("div", { className: "min-w-0 flex-1", children: [
5993
+ /* @__PURE__ */ jsx22("div", { className: "font-medium text-[hsl(var(--foreground))]", children: description || (isError ? "\u4EFB\u52A1\u6267\u884C\u5931\u8D25" : "\u4EFB\u52A1\u7ED3\u679C\u5DF2\u63D0\u4EA4") }),
5994
+ description ? /* @__PURE__ */ jsx22("div", { className: "mt-0.5 text-xs text-[hsl(var(--muted-foreground))]", children: isError ? "\u4EFB\u52A1\u6267\u884C\u5931\u8D25" : "\u4EFB\u52A1\u7ED3\u679C\u5DF2\u63D0\u4EA4" }) : null,
5995
+ status ? /* @__PURE__ */ jsxs18("div", { className: "mt-0.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
5930
5996
  "\u72B6\u6001\uFF1A",
5931
5997
  status
5932
5998
  ] }) : null
5933
5999
  ] })
5934
6000
  ] }),
5935
- /* @__PURE__ */ jsxs17("div", { className: "space-y-3 px-4 py-4 text-sm leading-6 text-[hsl(var(--foreground))]", children: [
5936
- result ? /* @__PURE__ */ jsx21("p", { className: "whitespace-pre-wrap", children: result }) : null,
5937
- error ? /* @__PURE__ */ jsxs17("div", { className: "rounded-xl border border-red-500/30 bg-red-500/10 px-3 py-2 text-sm text-red-700 dark:text-red-200", children: [
5938
- /* @__PURE__ */ jsx21("div", { className: "mb-1 font-medium", children: "\u9519\u8BEF\u4FE1\u606F" }),
5939
- /* @__PURE__ */ jsx21("div", { className: "whitespace-pre-wrap", children: error })
6001
+ /* @__PURE__ */ jsxs18("div", { className: "space-y-3 px-4 py-4 text-sm leading-6 text-[hsl(var(--foreground))]", children: [
6002
+ result ? /* @__PURE__ */ jsx22("p", { className: "whitespace-pre-wrap", children: result }) : null,
6003
+ error ? /* @__PURE__ */ jsxs18("div", { className: "rounded-xl border border-red-500/30 bg-red-500/10 px-3 py-2 text-sm text-red-700 dark:text-red-200", children: [
6004
+ /* @__PURE__ */ jsx22("div", { className: "mb-1 font-medium", children: "\u9519\u8BEF\u4FE1\u606F" }),
6005
+ /* @__PURE__ */ jsx22("div", { className: "whitespace-pre-wrap", children: error })
5940
6006
  ] }) : null,
5941
- !result && !error ? /* @__PURE__ */ jsx21("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u667A\u80FD\u4F53\u5DF2\u7ED3\u675F\u672C\u8F6E\u4EFB\u52A1\u3002" }) : null
6007
+ !result && !error ? /* @__PURE__ */ jsx22("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u667A\u80FD\u4F53\u5DF2\u7ED3\u675F\u672C\u8F6E\u4EFB\u52A1\u3002" }) : null
5942
6008
  ] })
5943
6009
  ] });
5944
6010
  }
@@ -5962,7 +6028,7 @@ function getRenderer(toolName) {
5962
6028
  }
5963
6029
 
5964
6030
  // src/react/components/chat/ToolCallBlock.tsx
5965
- import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
6031
+ import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
5966
6032
  function FilePathLink({ filePath, sessionId }) {
5967
6033
  const activeSessionId = useSessionStore((s) => s.activeSessionId);
5968
6034
  const pushArtifact = useUiStore((s) => s.pushArtifact);
@@ -5980,14 +6046,14 @@ function FilePathLink({ filePath, sessionId }) {
5980
6046
  } catch {
5981
6047
  }
5982
6048
  };
5983
- return /* @__PURE__ */ jsx22(
6049
+ return /* @__PURE__ */ jsx23(
5984
6050
  "button",
5985
6051
  {
5986
6052
  type: "button",
5987
6053
  onClick: handleClick,
5988
6054
  className: "flex min-w-0 items-center gap-1 text-blue-400 hover:text-blue-300 hover:underline cursor-pointer font-mono",
5989
6055
  title: `\u9884\u89C8 ${filePath}`,
5990
- children: /* @__PURE__ */ jsx22("span", { className: "truncate", children: fileName })
6056
+ children: /* @__PURE__ */ jsx23("span", { className: "truncate", children: fileName })
5991
6057
  }
5992
6058
  );
5993
6059
  }
@@ -6038,7 +6104,7 @@ function ToolCallBlock({
6038
6104
  const askData = parseAskUserQuestion(typeof toolCall.result === "string" ? toolCall.result : null) ?? parseAskUserQuestion(buildAskUserPayload(toolCall.arguments));
6039
6105
  const canAnswer = toolCall.status === "awaiting_answer" && resolvedSessionStatus === "waiting_for_input" && Boolean(resolvedOnAnswer);
6040
6106
  if (askData) {
6041
- const questionBlock = /* @__PURE__ */ jsx22(
6107
+ const questionBlock = /* @__PURE__ */ jsx23(
6042
6108
  AskUserQuestionBlock,
6043
6109
  {
6044
6110
  data: askData,
@@ -6052,16 +6118,28 @@ function ToolCallBlock({
6052
6118
  if (!reasoning) {
6053
6119
  return questionBlock;
6054
6120
  }
6055
- return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
6121
+ return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-1", children: [
6056
6122
  questionBlock,
6057
- /* @__PURE__ */ jsx22("div", { className: "ml-4", children: /* @__PURE__ */ jsx22(ThinkingBadge, { reasoning, variant: "block" }) })
6123
+ /* @__PURE__ */ jsx23("div", { className: "ml-4", children: /* @__PURE__ */ jsx23(ThinkingBadge, { reasoning, variant: "block" }) })
6124
+ ] });
6125
+ }
6126
+ if (toolCall.status === "error") {
6127
+ return /* @__PURE__ */ jsxs19("div", { className: "ml-4 max-w-lg rounded-xl border border-red-500/30 bg-red-500/10 p-4 text-sm text-[hsl(var(--foreground))]", children: [
6128
+ /* @__PURE__ */ jsx23("div", { className: "font-semibold", children: "\u8FD9\u6B21\u63D0\u95EE\u672A\u80FD\u751F\u6210" }),
6129
+ /* @__PURE__ */ jsx23("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: "\u63D0\u95EE\u9009\u9879\u7684\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u5F53\u524D\u6CA1\u6709\u7B49\u5F85\u4F60\u56DE\u7B54\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" })
6130
+ ] });
6131
+ }
6132
+ if (toolCall.status === "pending") {
6133
+ return /* @__PURE__ */ jsxs19("div", { className: "ml-4 flex max-w-lg items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-4 text-sm text-[hsl(var(--muted-foreground))]", children: [
6134
+ /* @__PURE__ */ jsx23(Loader23, { size: 14, className: "animate-spin" }),
6135
+ /* @__PURE__ */ jsx23("span", { children: "\u6B63\u5728\u51C6\u5907\u95EE\u9898\u2026" })
6058
6136
  ] });
6059
6137
  }
6060
- return /* @__PURE__ */ jsxs18("div", { className: "ml-4 max-w-lg rounded-xl border border-amber-500/35 bg-amber-500/10 p-4 text-sm text-[hsl(var(--foreground))]", children: [
6061
- /* @__PURE__ */ jsx22("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
6062
- /* @__PURE__ */ jsxs18("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: [
6138
+ return /* @__PURE__ */ jsxs19("div", { className: "ml-4 max-w-lg rounded-xl border border-amber-500/35 bg-amber-500/10 p-4 text-sm text-[hsl(var(--foreground))]", children: [
6139
+ /* @__PURE__ */ jsx23("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
6140
+ /* @__PURE__ */ jsxs19("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: [
6063
6141
  "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u6216\u7248\u672C\u4E0D\u517C\u5BB9\u3002\u8BF7\u91CD\u8BD5\uFF1B\u82E5\u95EE\u9898\u6301\u7EED\uFF0C\u8BF7\u63D0\u4F9B\u4EA4\u4E92\u7F16\u53F7",
6064
- /* @__PURE__ */ jsx22("span", { className: "ml-1 font-mono", children: toolCall.id }),
6142
+ /* @__PURE__ */ jsx23("span", { className: "ml-1 font-mono", children: toolCall.id }),
6065
6143
  "\u3002"
6066
6144
  ] })
6067
6145
  ] });
@@ -6073,11 +6151,11 @@ function ToolCallBlock({
6073
6151
  const borderWidthClass = level === 2 ? "border-l-[2px]" : "border-l-[3px]";
6074
6152
  const indentClass = level === 2 ? "ml-3" : "ml-4";
6075
6153
  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))]";
6076
- const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx22(Loader23, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx22(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx22(X4, { size: 11 }) : /* @__PURE__ */ jsx22(Check2, { size: 11 });
6154
+ const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx23(Loader23, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx23(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx23(X4, { size: 11 }) : /* @__PURE__ */ jsx23(Check2, { size: 11 });
6077
6155
  const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
6078
- return /* @__PURE__ */ jsxs18("div", { className: cn(indentClass, "text-xs", customization?.classNames?.toolCall), children: [
6079
- /* @__PURE__ */ jsxs18("div", { className: cn(borderWidthClass, toneClass, "flex items-center gap-2 px-3 py-2"), children: [
6080
- /* @__PURE__ */ jsxs18(
6156
+ return /* @__PURE__ */ jsxs19("div", { className: cn(indentClass, "text-xs", customization?.classNames?.toolCall), children: [
6157
+ /* @__PURE__ */ jsxs19("div", { className: cn(borderWidthClass, toneClass, "flex items-center gap-2 px-3 py-2"), children: [
6158
+ /* @__PURE__ */ jsxs19(
6081
6159
  "button",
6082
6160
  {
6083
6161
  type: "button",
@@ -6085,7 +6163,7 @@ function ToolCallBlock({
6085
6163
  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",
6086
6164
  "aria-expanded": expanded,
6087
6165
  children: [
6088
- /* @__PURE__ */ jsx22(
6166
+ /* @__PURE__ */ jsx23(
6089
6167
  ChevronRight3,
6090
6168
  {
6091
6169
  size: 11,
@@ -6095,21 +6173,21 @@ function ToolCallBlock({
6095
6173
  )
6096
6174
  }
6097
6175
  ),
6098
- /* @__PURE__ */ jsxs18("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
6176
+ /* @__PURE__ */ jsxs19("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
6099
6177
  statusIcon,
6100
- /* @__PURE__ */ jsx22("span", { children: getToolStatusLabel(toolCall.status) })
6178
+ /* @__PURE__ */ jsx23("span", { children: getToolStatusLabel(toolCall.status) })
6101
6179
  ] }),
6102
- /* @__PURE__ */ jsxs18("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: [
6180
+ /* @__PURE__ */ jsxs19("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: [
6103
6181
  displayName,
6104
6182
  toolCall.status === "error" ? "\uFF08\u5F85\u91CD\u8BD5\uFF09" : ""
6105
6183
  ] })
6106
6184
  ]
6107
6185
  }
6108
6186
  ),
6109
- filePath && /* @__PURE__ */ jsx22("span", { className: "flex min-w-0 max-w-[50%] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx22(FilePathLink, { filePath, sessionId: resolvedSessionId }) }),
6110
- reasoning ? /* @__PURE__ */ jsx22(ThinkingBadge, { reasoning, variant: "block" }) : null,
6111
- typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx22("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) }),
6112
- uiMeta?.target === "preview" && resolvedSessionId && !isInternalStatusPreview(uiMeta) ? /* @__PURE__ */ jsxs18(
6187
+ filePath && /* @__PURE__ */ jsx23("span", { className: "flex min-w-0 max-w-[50%] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx23(FilePathLink, { filePath, sessionId: resolvedSessionId }) }),
6188
+ reasoning ? /* @__PURE__ */ jsx23(ThinkingBadge, { reasoning, variant: "block" }) : null,
6189
+ typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx23("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) }),
6190
+ uiMeta?.target === "preview" && resolvedSessionId && !isInternalStatusPreview(uiMeta) ? /* @__PURE__ */ jsxs19(
6113
6191
  "button",
6114
6192
  {
6115
6193
  type: "button",
@@ -6127,20 +6205,20 @@ function ToolCallBlock({
6127
6205
  className: "inline-flex shrink-0 items-center gap-1 text-blue-400 hover:text-blue-300 hover:underline cursor-pointer",
6128
6206
  title: `\u6253\u5F00 ${uiMeta.title ?? displayName}`,
6129
6207
  children: [
6130
- /* @__PURE__ */ jsx22(PanelRightOpen, { size: 11 }),
6131
- /* @__PURE__ */ jsx22("span", { children: uiMeta.title ?? displayName })
6208
+ /* @__PURE__ */ jsx23(PanelRightOpen, { size: 11 }),
6209
+ /* @__PURE__ */ jsx23("span", { children: uiMeta.title ?? displayName })
6132
6210
  ]
6133
6211
  }
6134
6212
  ) : null
6135
6213
  ] }),
6136
- expanded && /* @__PURE__ */ jsx22("div", { className: "ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3", children: Renderer ? /* @__PURE__ */ jsx22(Renderer, { toolCall, sessionId: resolvedSessionId }) : /* @__PURE__ */ jsxs18(Fragment5, { children: [
6137
- /* @__PURE__ */ jsx22("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u5DE5\u5177" }),
6138
- /* @__PURE__ */ jsx22("div", { className: "mb-3 font-mono text-[11px] text-[hsl(var(--foreground))]", children: normalizedName }),
6139
- /* @__PURE__ */ jsx22("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
6140
- /* @__PURE__ */ jsx22("pre", { className: "overflow-x-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatArgs(toolCall.arguments) }),
6141
- toolCall.result != null && /* @__PURE__ */ jsxs18(Fragment5, { children: [
6142
- /* @__PURE__ */ jsx22("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
6143
- /* @__PURE__ */ jsx22(
6214
+ expanded && /* @__PURE__ */ jsx23("div", { className: "ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3", children: Renderer ? /* @__PURE__ */ jsx23(Renderer, { toolCall, sessionId: resolvedSessionId }) : /* @__PURE__ */ jsxs19(Fragment5, { children: [
6215
+ /* @__PURE__ */ jsx23("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u5DE5\u5177" }),
6216
+ /* @__PURE__ */ jsx23("div", { className: "mb-3 font-mono text-[11px] text-[hsl(var(--foreground))]", children: normalizedName }),
6217
+ /* @__PURE__ */ jsx23("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
6218
+ /* @__PURE__ */ jsx23("pre", { className: "overflow-x-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatArgs(toolCall.arguments) }),
6219
+ toolCall.result != null && /* @__PURE__ */ jsxs19(Fragment5, { children: [
6220
+ /* @__PURE__ */ jsx23("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
6221
+ /* @__PURE__ */ jsx23(
6144
6222
  "pre",
6145
6223
  {
6146
6224
  className: cn(
@@ -6332,7 +6410,7 @@ import { Download as Download3, X as X5 } from "lucide-react";
6332
6410
  import { useEffect as useEffect13 } from "react";
6333
6411
  import { createPortal as createPortal4 } from "react-dom";
6334
6412
  import { useQuery as useQuery6 } from "@tanstack/react-query";
6335
- import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
6413
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
6336
6414
  function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
6337
6415
  useEffect13(() => {
6338
6416
  if (!open) return;
@@ -6360,7 +6438,7 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
6360
6438
  staleTime: 6e4
6361
6439
  });
6362
6440
  if (!open) return null;
6363
- const body = /* @__PURE__ */ jsx23(
6441
+ const body = /* @__PURE__ */ jsx24(
6364
6442
  "div",
6365
6443
  {
6366
6444
  className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",
@@ -6371,17 +6449,17 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
6371
6449
  role: "dialog",
6372
6450
  "aria-modal": "true",
6373
6451
  "aria-labelledby": "attachment-preview-title",
6374
- children: /* @__PURE__ */ jsxs19(
6452
+ children: /* @__PURE__ */ jsxs20(
6375
6453
  "div",
6376
6454
  {
6377
6455
  className: "max-h-[90vh] w-full max-w-3xl overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--background))] shadow-2xl",
6378
6456
  onClick: (e) => e.stopPropagation(),
6379
6457
  onKeyDown: (e) => e.stopPropagation(),
6380
6458
  children: [
6381
- /* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
6382
- /* @__PURE__ */ jsx23("h3", { id: "attachment-preview-title", className: "truncate text-sm font-semibold text-[hsl(var(--foreground))]", children: filename }),
6383
- /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1", children: [
6384
- url && /* @__PURE__ */ jsx23(
6459
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
6460
+ /* @__PURE__ */ jsx24("h3", { id: "attachment-preview-title", className: "truncate text-sm font-semibold text-[hsl(var(--foreground))]", children: filename }),
6461
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-1", children: [
6462
+ url && /* @__PURE__ */ jsx24(
6385
6463
  "a",
6386
6464
  {
6387
6465
  href: url,
@@ -6390,22 +6468,22 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
6390
6468
  rel: "noopener noreferrer",
6391
6469
  title: "\u4E0B\u8F7D",
6392
6470
  className: "flex h-7 w-7 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
6393
- children: /* @__PURE__ */ jsx23(Download3, { size: 14 })
6471
+ children: /* @__PURE__ */ jsx24(Download3, { size: 14 })
6394
6472
  }
6395
6473
  ),
6396
- /* @__PURE__ */ jsx23(
6474
+ /* @__PURE__ */ jsx24(
6397
6475
  "button",
6398
6476
  {
6399
6477
  type: "button",
6400
6478
  onClick: () => onOpenChange(false),
6401
6479
  title: "\u5173\u95ED",
6402
6480
  className: "flex h-7 w-7 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
6403
- children: /* @__PURE__ */ jsx23(X5, { size: 14 })
6481
+ children: /* @__PURE__ */ jsx24(X5, { size: 14 })
6404
6482
  }
6405
6483
  )
6406
6484
  ] })
6407
6485
  ] }),
6408
- /* @__PURE__ */ jsx23("div", { className: "max-h-[calc(90vh-56px)] overflow-auto px-4 py-3 text-sm text-[hsl(var(--foreground))]", children: renderContent({ mode, url, content, error }) })
6486
+ /* @__PURE__ */ jsx24("div", { className: "max-h-[calc(90vh-56px)] overflow-auto px-4 py-3 text-sm text-[hsl(var(--foreground))]", children: renderContent({ mode, url, content, error }) })
6409
6487
  ]
6410
6488
  }
6411
6489
  )
@@ -6420,43 +6498,43 @@ function renderContent({
6420
6498
  error
6421
6499
  }) {
6422
6500
  if (!url) {
6423
- return /* @__PURE__ */ jsx23("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u6B64\u9644\u4EF6\u6682\u65E0\u53EF\u7528\u9884\u89C8\u5730\u5740\u3002" });
6501
+ return /* @__PURE__ */ jsx24("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u6B64\u9644\u4EF6\u6682\u65E0\u53EF\u7528\u9884\u89C8\u5730\u5740\u3002" });
6424
6502
  }
6425
6503
  if (mode === "default") {
6426
- return /* @__PURE__ */ jsxs19("p", { className: "text-[hsl(var(--muted-foreground))]", children: [
6504
+ return /* @__PURE__ */ jsxs20("p", { className: "text-[hsl(var(--muted-foreground))]", children: [
6427
6505
  "\u6B64\u7C7B\u578B\u6682\u4E0D\u652F\u6301\u5185\u5D4C\u9884\u89C8\u3002\u8BF7\u70B9\u51FB\u53F3\u4E0A\u89D2",
6428
- /* @__PURE__ */ jsx23("span", { className: "mx-1 font-medium text-[hsl(var(--foreground))]", children: "\u4E0B\u8F7D" }),
6506
+ /* @__PURE__ */ jsx24("span", { className: "mx-1 font-medium text-[hsl(var(--foreground))]", children: "\u4E0B\u8F7D" }),
6429
6507
  "\u6309\u94AE\u67E5\u770B\u3002"
6430
6508
  ] });
6431
6509
  }
6432
6510
  if (error) {
6433
- return /* @__PURE__ */ jsxs19("p", { className: "text-[hsl(var(--destructive))]", children: [
6511
+ return /* @__PURE__ */ jsxs20("p", { className: "text-[hsl(var(--destructive))]", children: [
6434
6512
  "\u52A0\u8F7D\u5931\u8D25\uFF1A",
6435
6513
  String(error?.message ?? error)
6436
6514
  ] });
6437
6515
  }
6438
6516
  if (content == null) {
6439
- return /* @__PURE__ */ jsx23("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u52A0\u8F7D\u4E2D\u2026" });
6517
+ return /* @__PURE__ */ jsx24("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u52A0\u8F7D\u4E2D\u2026" });
6440
6518
  }
6441
6519
  if (mode === "markdown") {
6442
- return /* @__PURE__ */ jsx23(MarkdownContent, { className: "prose prose-sm prose-invert max-w-none", children: content });
6520
+ return /* @__PURE__ */ jsx24(MarkdownContent, { className: "prose prose-sm prose-invert max-w-none", children: content });
6443
6521
  }
6444
- return /* @__PURE__ */ jsx23("pre", { className: "whitespace-pre-wrap font-mono text-xs leading-relaxed", children: content });
6522
+ return /* @__PURE__ */ jsx24("pre", { className: "whitespace-pre-wrap font-mono text-xs leading-relaxed", children: content });
6445
6523
  }
6446
6524
 
6447
6525
  // src/react/components/chat/MessageContextPills.tsx
6448
6526
  import { Bookmark } from "lucide-react";
6449
- import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
6527
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
6450
6528
  function MessageContextPills({ contexts }) {
6451
6529
  if (contexts.length === 0) return null;
6452
- return /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-1.5", children: contexts.map((ctx, index) => /* @__PURE__ */ jsxs20(
6530
+ return /* @__PURE__ */ jsx25("div", { className: "flex flex-wrap gap-1.5", children: contexts.map((ctx, index) => /* @__PURE__ */ jsxs21(
6453
6531
  "div",
6454
6532
  {
6455
6533
  className: "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--primary)/0.25)] bg-[hsl(var(--primary)/0.1)] px-2.5 py-1 text-[11px] text-[hsl(var(--primary)/0.85)]",
6456
6534
  title: ctx.content,
6457
6535
  children: [
6458
- /* @__PURE__ */ jsx24(Bookmark, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.65)]" }),
6459
- /* @__PURE__ */ jsx24("span", { className: "max-w-56 truncate", children: ctx.label })
6536
+ /* @__PURE__ */ jsx25(Bookmark, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.65)]" }),
6537
+ /* @__PURE__ */ jsx25("span", { className: "max-w-56 truncate", children: ctx.label })
6460
6538
  ]
6461
6539
  },
6462
6540
  `${ctx.label}:${index}`
@@ -6465,7 +6543,7 @@ function MessageContextPills({ contexts }) {
6465
6543
 
6466
6544
  // src/react/components/chat/MessageFileAttachmentList.tsx
6467
6545
  import { Archive as Archive2, File as File3, FileCode2 as FileCode22, FileText as FileText4, Film as Film2, Music as Music2 } from "lucide-react";
6468
- import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
6546
+ import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
6469
6547
  function getFileIcon(fileName) {
6470
6548
  const lowerName = fileName.toLowerCase();
6471
6549
  if (/\.(zip|rar|7z|tar|gz|bz2|xz)$/.test(lowerName)) {
@@ -6494,15 +6572,15 @@ function MessageFileAttachmentList({
6494
6572
  return null;
6495
6573
  }
6496
6574
  const pillClass = "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2.5 py-1 text-[11px] text-[hsl(var(--foreground))]";
6497
- return /* @__PURE__ */ jsx25("div", { className: cn("flex flex-wrap gap-1.5", className), children: files.map((file) => {
6575
+ return /* @__PURE__ */ jsx26("div", { className: cn("flex flex-wrap gap-1.5", className), children: files.map((file) => {
6498
6576
  const Icon = getFileIcon(file.name);
6499
6577
  const key = `${file.name}-${file.data.slice(0, 32)}`;
6500
- const content = /* @__PURE__ */ jsxs21(Fragment6, { children: [
6501
- /* @__PURE__ */ jsx25(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
6502
- /* @__PURE__ */ jsx25("span", { className: "max-w-32 truncate", children: file.name })
6578
+ const content = /* @__PURE__ */ jsxs22(Fragment6, { children: [
6579
+ /* @__PURE__ */ jsx26(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
6580
+ /* @__PURE__ */ jsx26("span", { className: "max-w-32 truncate", children: file.name })
6503
6581
  ] });
6504
6582
  if (onPreview) {
6505
- return /* @__PURE__ */ jsx25(
6583
+ return /* @__PURE__ */ jsx26(
6506
6584
  "button",
6507
6585
  {
6508
6586
  type: "button",
@@ -6514,14 +6592,14 @@ function MessageFileAttachmentList({
6514
6592
  key
6515
6593
  );
6516
6594
  }
6517
- return /* @__PURE__ */ jsx25("div", { className: pillClass, title: file.name, children: content }, key);
6595
+ return /* @__PURE__ */ jsx26("div", { className: pillClass, title: file.name, children: content }, key);
6518
6596
  }) });
6519
6597
  }
6520
6598
 
6521
6599
  // src/react/components/chat/MessageActions.tsx
6522
6600
  import { Check as Check3, Copy } from "lucide-react";
6523
6601
  import { useState as useState15 } from "react";
6524
- import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
6602
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
6525
6603
  function MessageActions({ content, className }) {
6526
6604
  const [copied, setCopied] = useState15(false);
6527
6605
  const handleCopy = async () => {
@@ -6531,7 +6609,7 @@ function MessageActions({ content, className }) {
6531
6609
  setTimeout(() => setCopied(false), 2e3);
6532
6610
  }
6533
6611
  };
6534
- return /* @__PURE__ */ jsx26("div", { className: cn("flex items-center gap-1 mt-1.5", className), children: /* @__PURE__ */ jsxs22(
6612
+ return /* @__PURE__ */ jsx27("div", { className: cn("flex items-center gap-1 mt-1.5", className), children: /* @__PURE__ */ jsxs23(
6535
6613
  "button",
6536
6614
  {
6537
6615
  type: "button",
@@ -6541,8 +6619,8 @@ function MessageActions({ content, className }) {
6541
6619
  copied ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--accent))]"
6542
6620
  ),
6543
6621
  children: [
6544
- copied ? /* @__PURE__ */ jsx26(Check3, { size: 12 }) : /* @__PURE__ */ jsx26(Copy, { size: 12 }),
6545
- /* @__PURE__ */ jsx26("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
6622
+ copied ? /* @__PURE__ */ jsx27(Check3, { size: 12 }) : /* @__PURE__ */ jsx27(Copy, { size: 12 }),
6623
+ /* @__PURE__ */ jsx27("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
6546
6624
  ]
6547
6625
  }
6548
6626
  ) });
@@ -6550,7 +6628,7 @@ function MessageActions({ content, className }) {
6550
6628
 
6551
6629
  // src/react/components/chat/TextAttachmentPills.tsx
6552
6630
  import { Archive as Archive3, File as File4, FileCode2 as FileCode23, FileText as FileText5, Film as Film3, Music as Music3, FileSpreadsheet, Image } from "lucide-react";
6553
- import { Fragment as Fragment7, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
6631
+ import { Fragment as Fragment7, jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
6554
6632
  function getFileIcon2(fileName) {
6555
6633
  const lower2 = fileName.toLowerCase();
6556
6634
  if (/\.(zip|rar|7z|tar|gz)$/.test(lower2)) return Archive3;
@@ -6565,15 +6643,15 @@ function getFileIcon2(fileName) {
6565
6643
  function TextAttachmentPills({ attachments, onPreview }) {
6566
6644
  if (attachments.length === 0) return null;
6567
6645
  const pillClass = "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--primary)/0.2)] bg-[hsl(var(--primary)/0.08)] px-2.5 py-1 text-[11px] text-[hsl(var(--primary)/0.8)]";
6568
- return /* @__PURE__ */ jsx27("div", { className: "flex flex-wrap gap-1.5", children: attachments.map((att, index) => {
6646
+ return /* @__PURE__ */ jsx28("div", { className: "flex flex-wrap gap-1.5", children: attachments.map((att, index) => {
6569
6647
  const Icon = getFileIcon2(att.name);
6570
6648
  const key = `${att.uploadedPath ?? att.name}:${att.name}:${index}`;
6571
- const content = /* @__PURE__ */ jsxs23(Fragment7, { children: [
6572
- /* @__PURE__ */ jsx27(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.6)]" }),
6573
- /* @__PURE__ */ jsx27("span", { className: "max-w-40 truncate", children: att.name })
6649
+ const content = /* @__PURE__ */ jsxs24(Fragment7, { children: [
6650
+ /* @__PURE__ */ jsx28(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.6)]" }),
6651
+ /* @__PURE__ */ jsx28("span", { className: "max-w-40 truncate", children: att.name })
6574
6652
  ] });
6575
6653
  if (onPreview) {
6576
- return /* @__PURE__ */ jsx27(
6654
+ return /* @__PURE__ */ jsx28(
6577
6655
  "button",
6578
6656
  {
6579
6657
  type: "button",
@@ -6585,7 +6663,7 @@ function TextAttachmentPills({ attachments, onPreview }) {
6585
6663
  key
6586
6664
  );
6587
6665
  }
6588
- return /* @__PURE__ */ jsx27("div", { className: pillClass, title: att.name, children: content }, key);
6666
+ return /* @__PURE__ */ jsx28("div", { className: pillClass, title: att.name, children: content }, key);
6589
6667
  }) });
6590
6668
  }
6591
6669
 
@@ -6594,34 +6672,34 @@ import { RefreshCcw } from "lucide-react";
6594
6672
 
6595
6673
  // src/react/components/chat/whatif-quote-context.tsx
6596
6674
  import { createContext as createContext3, useContext as useContext3, useMemo as useMemo14 } from "react";
6597
- import { jsx as jsx28 } from "react/jsx-runtime";
6675
+ import { jsx as jsx29 } from "react/jsx-runtime";
6598
6676
  var WhatIfQuoteContext = createContext3({});
6599
6677
  function WhatIfQuoteProvider({
6600
6678
  onJumpToStep,
6601
6679
  children
6602
6680
  }) {
6603
6681
  const value = useMemo14(() => ({ onJumpToStep }), [onJumpToStep]);
6604
- return /* @__PURE__ */ jsx28(WhatIfQuoteContext.Provider, { value, children });
6682
+ return /* @__PURE__ */ jsx29(WhatIfQuoteContext.Provider, { value, children });
6605
6683
  }
6606
6684
  function useWhatIfQuoteContext() {
6607
6685
  return useContext3(WhatIfQuoteContext);
6608
6686
  }
6609
6687
 
6610
6688
  // src/react/components/chat/WhatIfUserBubble.tsx
6611
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
6689
+ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
6612
6690
  function WhatIfUserBubble({ parsed, onQuoteClick }) {
6613
6691
  const { onJumpToStep } = useWhatIfQuoteContext();
6614
6692
  const handleQuoteClick = onQuoteClick ?? onJumpToStep;
6615
6693
  const { fromStep, quotes, userText } = parsed;
6616
- return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-end gap-2", children: [
6617
- /* @__PURE__ */ jsxs24("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: [
6618
- /* @__PURE__ */ jsx29(RefreshCcw, { size: 10 }),
6619
- /* @__PURE__ */ jsx29("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
6694
+ return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col items-end gap-2", children: [
6695
+ /* @__PURE__ */ jsxs25("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: [
6696
+ /* @__PURE__ */ jsx30(RefreshCcw, { size: 10 }),
6697
+ /* @__PURE__ */ jsx30("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
6620
6698
  ] }),
6621
- quotes.length > 0 && /* @__PURE__ */ jsx29("div", { className: "flex flex-wrap justify-end gap-1.5", children: quotes.map((q, i) => {
6699
+ quotes.length > 0 && /* @__PURE__ */ jsx30("div", { className: "flex flex-wrap justify-end gap-1.5", children: quotes.map((q, i) => {
6622
6700
  const clickable = q.stepNumber != null && !!handleQuoteClick;
6623
6701
  const label = q.stepNumber != null ? `\u6B65\u9AA4${q.stepNumber} \xB7 ${q.label}` : q.label;
6624
- return /* @__PURE__ */ jsxs24(
6702
+ return /* @__PURE__ */ jsxs25(
6625
6703
  "button",
6626
6704
  {
6627
6705
  type: "button",
@@ -6630,14 +6708,14 @@ function WhatIfUserBubble({ parsed, onQuoteClick }) {
6630
6708
  className: "inline-flex items-center gap-1 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2.5 py-0.5 text-[11px] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring)/0.5)] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] disabled:cursor-default disabled:hover:border-[hsl(var(--border))] disabled:hover:bg-[hsl(var(--card))]",
6631
6709
  title: clickable ? "\u8DF3\u8F6C\u5230\u5BF9\u5E94\u6B65\u9AA4\u5361\u7247" : void 0,
6632
6710
  children: [
6633
- /* @__PURE__ */ jsx29("span", { children: "\u21B3" }),
6634
- /* @__PURE__ */ jsx29("span", { className: "max-w-[14rem] truncate", children: label })
6711
+ /* @__PURE__ */ jsx30("span", { children: "\u21B3" }),
6712
+ /* @__PURE__ */ jsx30("span", { className: "max-w-[14rem] truncate", children: label })
6635
6713
  ]
6636
6714
  },
6637
6715
  `${q.stepNumber ?? "x"}-${i}`
6638
6716
  );
6639
6717
  }) }),
6640
- userText && /* @__PURE__ */ jsx29("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))] shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]", children: /* @__PURE__ */ jsx29(
6718
+ userText && /* @__PURE__ */ jsx30("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))] shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]", children: /* @__PURE__ */ jsx30(
6641
6719
  MarkdownContent,
6642
6720
  {
6643
6721
  className: "prose prose-sm prose-invert max-w-none [&_li>p]:inline [&_p]:mb-3 [&_p:last-child]:mb-0",
@@ -6649,14 +6727,14 @@ function WhatIfUserBubble({ parsed, onQuoteClick }) {
6649
6727
  }
6650
6728
 
6651
6729
  // src/react/components/chat/UserMessageBubble.tsx
6652
- import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
6730
+ import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
6653
6731
  function isUserMessage(message) {
6654
6732
  return message.role === "user";
6655
6733
  }
6656
6734
  function isErrorMessage(message) {
6657
6735
  return message.role === "error";
6658
6736
  }
6659
- var USER_MESSAGE_MARKDOWN_CLASS = "prose prose-sm prose-invert max-w-none [&_li>p]:inline [&_li>p]:whitespace-pre-wrap [&_p]:mb-3 [&_p]:whitespace-pre-wrap [&_p:last-child]:mb-0";
6737
+ var USER_MESSAGE_MARKDOWN_CLASS = "prose prose-invert chat-prose max-w-none [&_li>p]:inline [&_li>p]:whitespace-pre-wrap [&_p]:whitespace-pre-wrap";
6660
6738
  function isImageTextAttachment(name, uploadedPath) {
6661
6739
  return isImageFilename(name) || isImageFilename(uploadedPath ?? "");
6662
6740
  }
@@ -6679,9 +6757,9 @@ function UserMessageBubble({ message, className }) {
6679
6757
  const trimmedClean = cleanText.trim();
6680
6758
  const whatifParsed = trimmedClean && imageParts.length === 0 && fileParts.length === 0 && textAttachments.length === 0 ? parseWhatIfPrompt(cleanText) : null;
6681
6759
  if (whatifParsed) {
6682
- return /* @__PURE__ */ jsx30("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs25("div", { className: "group flex max-w-[72%] flex-col items-end gap-2", children: [
6683
- /* @__PURE__ */ jsx30(WhatIfUserBubble, { parsed: whatifParsed }),
6684
- whatifParsed.userText && /* @__PURE__ */ jsx30(
6760
+ return /* @__PURE__ */ jsx31("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs26("div", { className: "group flex max-w-[72%] flex-col items-end gap-2", children: [
6761
+ /* @__PURE__ */ jsx31(WhatIfUserBubble, { parsed: whatifParsed }),
6762
+ whatifParsed.userText && /* @__PURE__ */ jsx31(
6685
6763
  MessageActions,
6686
6764
  {
6687
6765
  content: whatifParsed.userText,
@@ -6753,16 +6831,16 @@ function UserMessageBubble({ message, className }) {
6753
6831
  const mode = kind === "text" ? lower2.endsWith(".md") ? "markdown" : "text" : "default";
6754
6832
  setPreview({ filename: attachment.name, url, mode });
6755
6833
  };
6756
- return /* @__PURE__ */ jsx30("div", { className: cn("flex justify-end", className), children: /* @__PURE__ */ jsxs25("div", { className: "group flex max-w-[72%] flex-col items-end gap-3", children: [
6757
- (imageParts.length > 0 || imageTextAttachmentMeta.length > 0) && /* @__PURE__ */ jsxs25("div", { className: "grid gap-2", children: [
6758
- imageParts.map((part, idx) => /* @__PURE__ */ jsx30(
6834
+ return /* @__PURE__ */ jsx31("div", { className: cn("flex justify-end", className), children: /* @__PURE__ */ jsxs26("div", { className: "group flex max-w-[72%] flex-col items-end gap-3", children: [
6835
+ (imageParts.length > 0 || imageTextAttachmentMeta.length > 0) && /* @__PURE__ */ jsxs26("div", { className: "grid gap-2", children: [
6836
+ imageParts.map((part, idx) => /* @__PURE__ */ jsx31(
6759
6837
  "button",
6760
6838
  {
6761
6839
  type: "button",
6762
6840
  onClick: () => setLightboxIndex(idx),
6763
6841
  className: "cursor-zoom-in",
6764
6842
  title: "\u67E5\u770B\u5927\u56FE",
6765
- children: /* @__PURE__ */ jsx30(
6843
+ children: /* @__PURE__ */ jsx31(
6766
6844
  "img",
6767
6845
  {
6768
6846
  src: part.image_url.url,
@@ -6775,14 +6853,14 @@ function UserMessageBubble({ message, className }) {
6775
6853
  )),
6776
6854
  imageTextAttachmentMeta.map((att, idx) => {
6777
6855
  const blobUrl = imageAttachmentQueries[idx]?.data;
6778
- return blobUrl ? /* @__PURE__ */ jsx30(
6856
+ return blobUrl ? /* @__PURE__ */ jsx31(
6779
6857
  "button",
6780
6858
  {
6781
6859
  type: "button",
6782
6860
  onClick: () => setLightboxIndex(imageParts.length + idx),
6783
6861
  className: "cursor-zoom-in",
6784
6862
  title: "\u67E5\u770B\u5927\u56FE",
6785
- children: /* @__PURE__ */ jsx30(
6863
+ children: /* @__PURE__ */ jsx31(
6786
6864
  "img",
6787
6865
  {
6788
6866
  src: blobUrl,
@@ -6792,7 +6870,7 @@ function UserMessageBubble({ message, className }) {
6792
6870
  )
6793
6871
  },
6794
6872
  `${att.uploadedPath}:${att.name}`
6795
- ) : imageAttachmentQueries[idx]?.isError ? null : /* @__PURE__ */ jsx30(
6873
+ ) : imageAttachmentQueries[idx]?.isError ? null : /* @__PURE__ */ jsx31(
6796
6874
  "div",
6797
6875
  {
6798
6876
  className: "flex h-20 items-center justify-center rounded-xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--muted)/0.3)] text-xs text-[hsl(var(--muted-foreground))]",
@@ -6802,7 +6880,7 @@ function UserMessageBubble({ message, className }) {
6802
6880
  );
6803
6881
  })
6804
6882
  ] }),
6805
- lightboxImages.length > 0 && /* @__PURE__ */ jsx30(
6883
+ lightboxImages.length > 0 && /* @__PURE__ */ jsx31(
6806
6884
  ImageLightbox,
6807
6885
  {
6808
6886
  open: lightboxIndex != null,
@@ -6813,15 +6891,15 @@ function UserMessageBubble({ message, className }) {
6813
6891
  initialIndex: lightboxIndex ?? 0
6814
6892
  }
6815
6893
  ),
6816
- /* @__PURE__ */ jsx30(MessageFileAttachmentList, { files: fileParts }),
6817
- /* @__PURE__ */ jsx30(
6894
+ /* @__PURE__ */ jsx31(MessageFileAttachmentList, { files: fileParts }),
6895
+ /* @__PURE__ */ jsx31(
6818
6896
  TextAttachmentPills,
6819
6897
  {
6820
6898
  attachments: nonImageTextAttachments,
6821
6899
  onPreview: handleTextAttachmentPreview
6822
6900
  }
6823
6901
  ),
6824
- preview && /* @__PURE__ */ jsx30(
6902
+ preview && /* @__PURE__ */ jsx31(
6825
6903
  AttachmentPreviewDialog,
6826
6904
  {
6827
6905
  open: preview != null,
@@ -6833,8 +6911,9 @@ function UserMessageBubble({ message, className }) {
6833
6911
  mode: preview.mode
6834
6912
  }
6835
6913
  ),
6836
- /* @__PURE__ */ jsx30(MessageContextPills, { contexts: textContexts }),
6837
- trimmedClean && /* @__PURE__ */ jsx30("div", { className: "max-w-full 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))] shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]", children: /* @__PURE__ */ jsx30(
6914
+ /* @__PURE__ */ jsx31(MessageContextPills, { contexts: textContexts }),
6915
+ trimmedClean && // 原型:不对称圆角(指向发送侧的一角收窄),无边框、无内阴影。
6916
+ /* @__PURE__ */ jsx31("div", { className: "max-w-full rounded-[20px] rounded-br-[6px] border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-[18px] py-[13px] text-sm leading-[1.65] text-[hsl(var(--user-msg-fg))]", children: /* @__PURE__ */ jsx31(
6838
6917
  MarkdownContent,
6839
6918
  {
6840
6919
  className: USER_MESSAGE_MARKDOWN_CLASS,
@@ -6842,10 +6921,10 @@ function UserMessageBubble({ message, className }) {
6842
6921
  children: cleanText
6843
6922
  }
6844
6923
  ) }),
6845
- trimmedClean && (isSending(message) ? /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-1.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
6846
- /* @__PURE__ */ jsx30(Loader24, { size: 12, className: "animate-spin" }),
6847
- /* @__PURE__ */ jsx30("span", { children: "\u53D1\u9001\u4E2D" })
6848
- ] }) : /* @__PURE__ */ jsx30(
6924
+ trimmedClean && (isSending(message) ? /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
6925
+ /* @__PURE__ */ jsx31(Loader24, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
6926
+ /* @__PURE__ */ jsx31("span", { children: "\u53D1\u9001\u4E2D" })
6927
+ ] }) : /* @__PURE__ */ jsx31(
6849
6928
  MessageActions,
6850
6929
  {
6851
6930
  content: cleanText,
@@ -6860,14 +6939,14 @@ function ErrorMessageBlock({
6860
6939
  }) {
6861
6940
  const text = getTextContent(message.content);
6862
6941
  const looksLikeModelUnavailable = /no source matches this model|404/i.test(text);
6863
- return /* @__PURE__ */ jsx30("div", { className: cn("flex justify-center", className), children: /* @__PURE__ */ jsxs25("div", { className: "max-w-[85%] border-l-[3px] border-[hsl(var(--destructive))] px-4 py-1 text-sm leading-7 text-[hsl(var(--destructive))]", children: [
6942
+ return /* @__PURE__ */ jsx31("div", { className: cn("flex justify-center", className), children: /* @__PURE__ */ jsxs26("div", { className: "max-w-[85%] border-l-[3px] border-[hsl(var(--destructive))] px-4 py-1 text-sm leading-7 text-[hsl(var(--destructive))]", children: [
6864
6943
  text,
6865
- looksLikeModelUnavailable ? /* @__PURE__ */ jsx30("div", { className: "mt-1 opacity-80", children: "\u6A21\u578B\u53EF\u80FD\u672A\u542F\u52A8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" }) : null
6944
+ looksLikeModelUnavailable ? /* @__PURE__ */ jsx31("div", { className: "mt-1 opacity-80", children: "\u6A21\u578B\u53EF\u80FD\u672A\u542F\u52A8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" }) : null
6866
6945
  ] }) });
6867
6946
  }
6868
6947
 
6869
6948
  // src/react/components/chat/AgentLoopBlock.tsx
6870
- import { Fragment as Fragment8, jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
6949
+ import { Fragment as Fragment8, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
6871
6950
  var EMPTY_MESSAGES2 = [];
6872
6951
  var EMPTY_AGENT_LOOPS = {};
6873
6952
  var COLLAPSED_SUMMARY_HIDDEN_TOOLS = /* @__PURE__ */ new Set(["ReadSkill", "Read"]);
@@ -6967,7 +7046,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6967
7046
  const description = safeParseDescription(toolCall.arguments);
6968
7047
  const status = hasAwaitingAnswer || toolCall.status === "awaiting_answer" ? "awaiting_answer" : toolCall.status === "pending" || loopEntry?.info.status === "running" ? "running" : "done";
6969
7048
  const cardStyles = getLoopCardStyles(status);
6970
- return /* @__PURE__ */ jsxs26(
7049
+ return /* @__PURE__ */ jsxs27(
6971
7050
  "div",
6972
7051
  {
6973
7052
  className: cn(
@@ -6975,8 +7054,8 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6975
7054
  cardStyles.borderClass
6976
7055
  ),
6977
7056
  children: [
6978
- status === "running" || status === "awaiting_answer" ? /* @__PURE__ */ jsxs26(Fragment8, { children: [
6979
- /* @__PURE__ */ jsxs26(
7057
+ status === "running" || status === "awaiting_answer" ? /* @__PURE__ */ jsxs27(Fragment8, { children: [
7058
+ /* @__PURE__ */ jsxs27(
6980
7059
  "div",
6981
7060
  {
6982
7061
  className: cn(
@@ -6984,24 +7063,24 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6984
7063
  cardStyles.headerClass
6985
7064
  ),
6986
7065
  children: [
6987
- /* @__PURE__ */ jsx31(
7066
+ /* @__PURE__ */ jsx32(
6988
7067
  "button",
6989
7068
  {
6990
7069
  type: "button",
6991
7070
  onClick: toggleExpanded,
6992
7071
  "aria-expanded": expanded,
6993
7072
  className: "flex min-w-0 flex-1 items-center gap-2 text-left focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
6994
- children: /* @__PURE__ */ jsxs26("span", { className: "min-w-0 flex items-center gap-2", children: [
6995
- status === "awaiting_answer" ? /* @__PURE__ */ jsx31(MessageSquareMore2, { size: 14, className: "shrink-0 text-amber-500" }) : /* @__PURE__ */ jsx31(Bot, { size: 14, className: "shrink-0 text-blue-500" }),
6996
- /* @__PURE__ */ jsxs26("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: [
7073
+ children: /* @__PURE__ */ jsxs27("span", { className: "min-w-0 flex items-center gap-2", children: [
7074
+ status === "awaiting_answer" ? /* @__PURE__ */ jsx32(MessageSquareMore2, { size: 14, className: "shrink-0 text-amber-500" }) : /* @__PURE__ */ jsx32(Bot, { size: 14, className: "shrink-0 text-blue-500" }),
7075
+ /* @__PURE__ */ jsxs27("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: [
6997
7076
  description,
6998
7077
  status === "awaiting_answer" ? " \u2014 \u7B49\u5F85\u56DE\u7B54" : ""
6999
7078
  ] })
7000
7079
  ] })
7001
7080
  }
7002
7081
  ),
7003
- reasoning ? /* @__PURE__ */ jsx31(ThinkingBadge, { reasoning, variant: "block" }) : null,
7004
- /* @__PURE__ */ jsx31(
7082
+ reasoning ? /* @__PURE__ */ jsx32(ThinkingBadge, { reasoning, variant: "block" }) : null,
7083
+ /* @__PURE__ */ jsx32(
7005
7084
  Bot,
7006
7085
  {
7007
7086
  size: 13,
@@ -7009,14 +7088,14 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7009
7088
  "aria-label": "\u5B50\u667A\u80FD\u4F53"
7010
7089
  }
7011
7090
  ),
7012
- /* @__PURE__ */ jsx31(
7091
+ /* @__PURE__ */ jsx32(
7013
7092
  "button",
7014
7093
  {
7015
7094
  type: "button",
7016
7095
  onClick: toggleExpanded,
7017
7096
  "aria-expanded": expanded,
7018
7097
  className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
7019
- children: /* @__PURE__ */ jsx31(
7098
+ children: /* @__PURE__ */ jsx32(
7020
7099
  ChevronRight4,
7021
7100
  {
7022
7101
  size: 14,
@@ -7031,7 +7110,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7031
7110
  ]
7032
7111
  }
7033
7112
  ),
7034
- !expanded ? /* @__PURE__ */ jsx31("div", { className: "flex flex-col gap-1 py-2", children: visibleLoopToolCalls.length > 0 ? visibleLoopToolCalls.map((childToolCall) => /* @__PURE__ */ jsx31(
7113
+ !expanded ? /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-1 py-2", children: visibleLoopToolCalls.length > 0 ? visibleLoopToolCalls.map((childToolCall) => /* @__PURE__ */ jsx32(
7035
7114
  ToolCallBlock,
7036
7115
  {
7037
7116
  toolCall: childToolCall,
@@ -7039,12 +7118,12 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7039
7118
  level: 2
7040
7119
  },
7041
7120
  childToolCall.id
7042
- )) : /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
7043
- /* @__PURE__ */ jsx31(Loader25, { size: 12, className: "shrink-0 animate-spin text-blue-500" }),
7044
- /* @__PURE__ */ jsx31("span", { children: "\u6B63\u5728\u542F\u52A8..." })
7045
- ] }) }) : status === "awaiting_answer" ? /* @__PURE__ */ jsx31("div", { className: "flex flex-col gap-1 py-2", children: /* @__PURE__ */ jsx31("div", { className: "px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u8BF7\u5728\u4E0B\u65B9\u5B50\u667A\u80FD\u4F53\u5BF9\u8BDD\u4E2D\u5B8C\u6210\u786E\u8BA4" }) }) : null
7046
- ] }) : /* @__PURE__ */ jsxs26(Fragment8, { children: [
7047
- /* @__PURE__ */ jsxs26(
7121
+ )) : /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
7122
+ /* @__PURE__ */ jsx32(Loader25, { size: 12, className: "shrink-0 animate-spin text-blue-500" }),
7123
+ /* @__PURE__ */ jsx32("span", { children: "\u6B63\u5728\u542F\u52A8..." })
7124
+ ] }) }) : status === "awaiting_answer" ? /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-1 py-2", children: /* @__PURE__ */ jsx32("div", { className: "px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u8BF7\u5728\u4E0B\u65B9\u5B50\u667A\u80FD\u4F53\u5BF9\u8BDD\u4E2D\u5B8C\u6210\u786E\u8BA4" }) }) : null
7125
+ ] }) : /* @__PURE__ */ jsxs27(Fragment8, { children: [
7126
+ /* @__PURE__ */ jsxs27(
7048
7127
  "div",
7049
7128
  {
7050
7129
  className: cn(
@@ -7052,21 +7131,21 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7052
7131
  cardStyles.headerClass
7053
7132
  ),
7054
7133
  children: [
7055
- /* @__PURE__ */ jsx31(
7134
+ /* @__PURE__ */ jsx32(
7056
7135
  "button",
7057
7136
  {
7058
7137
  type: "button",
7059
7138
  onClick: toggleExpanded,
7060
7139
  "aria-expanded": expanded,
7061
7140
  className: "flex min-w-0 flex-1 items-center gap-2 text-left focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
7062
- children: /* @__PURE__ */ jsxs26("span", { className: "min-w-0 flex items-center gap-2", children: [
7063
- /* @__PURE__ */ jsx31(Check4, { size: 14, className: "shrink-0 text-emerald-500" }),
7064
- /* @__PURE__ */ jsx31("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: description })
7141
+ children: /* @__PURE__ */ jsxs27("span", { className: "min-w-0 flex items-center gap-2", children: [
7142
+ /* @__PURE__ */ jsx32(Check4, { size: 14, className: "shrink-0 text-emerald-500" }),
7143
+ /* @__PURE__ */ jsx32("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: description })
7065
7144
  ] })
7066
7145
  }
7067
7146
  ),
7068
- reasoning ? /* @__PURE__ */ jsx31(ThinkingBadge, { reasoning, variant: "block" }) : null,
7069
- /* @__PURE__ */ jsx31(
7147
+ reasoning ? /* @__PURE__ */ jsx32(ThinkingBadge, { reasoning, variant: "block" }) : null,
7148
+ /* @__PURE__ */ jsx32(
7070
7149
  Bot,
7071
7150
  {
7072
7151
  size: 13,
@@ -7074,14 +7153,14 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7074
7153
  "aria-label": "\u5B50\u667A\u80FD\u4F53"
7075
7154
  }
7076
7155
  ),
7077
- /* @__PURE__ */ jsx31(
7156
+ /* @__PURE__ */ jsx32(
7078
7157
  "button",
7079
7158
  {
7080
7159
  type: "button",
7081
7160
  onClick: toggleExpanded,
7082
7161
  "aria-expanded": expanded,
7083
7162
  className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
7084
- children: /* @__PURE__ */ jsx31(
7163
+ children: /* @__PURE__ */ jsx32(
7085
7164
  ChevronRight4,
7086
7165
  {
7087
7166
  size: 14,
@@ -7096,9 +7175,9 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7096
7175
  ]
7097
7176
  }
7098
7177
  ),
7099
- !expanded ? /* @__PURE__ */ jsxs26(Fragment8, { children: [
7100
- /* @__PURE__ */ jsx31("div", { className: "flex flex-wrap gap-1.5 px-4 py-2", children: completedToolLabels.length > 0 ? completedToolLabels.map(
7101
- (item) => item.kind === "file" ? /* @__PURE__ */ jsxs26(
7178
+ !expanded ? /* @__PURE__ */ jsxs27(Fragment8, { children: [
7179
+ /* @__PURE__ */ jsx32("div", { className: "flex flex-wrap gap-1.5 px-4 py-2", children: completedToolLabels.length > 0 ? completedToolLabels.map(
7180
+ (item) => item.kind === "file" ? /* @__PURE__ */ jsxs27(
7102
7181
  "span",
7103
7182
  {
7104
7183
  className: "inline-flex min-w-0 items-center gap-1 rounded-md border px-2 py-0.5 text-xs font-semibold dark:border-emerald-500/25 dark:bg-emerald-500/10 dark:text-emerald-300",
@@ -7109,12 +7188,12 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7109
7188
  },
7110
7189
  title: item.label,
7111
7190
  children: [
7112
- /* @__PURE__ */ jsx31(FileText6, { size: 12, className: "shrink-0", "aria-hidden": "true" }),
7113
- /* @__PURE__ */ jsx31("span", { className: "truncate", children: item.label })
7191
+ /* @__PURE__ */ jsx32(FileText6, { size: 12, className: "shrink-0", "aria-hidden": "true" }),
7192
+ /* @__PURE__ */ jsx32("span", { className: "truncate", children: item.label })
7114
7193
  ]
7115
7194
  },
7116
7195
  item.key
7117
- ) : /* @__PURE__ */ jsx31(
7196
+ ) : /* @__PURE__ */ jsx32(
7118
7197
  "span",
7119
7198
  {
7120
7199
  className: "inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-semibold dark:border-blue-300 dark:bg-blue-400/10 dark:text-blue-300",
@@ -7127,20 +7206,20 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7127
7206
  },
7128
7207
  item.key
7129
7208
  )
7130
- ) : /* @__PURE__ */ jsx31("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5DE5\u5177\u8C03\u7528" }) }),
7131
- inlineToolUiBlocks.length > 0 ? /* @__PURE__ */ jsx31("div", { className: "flex flex-col gap-2 px-4 pb-3", children: inlineToolUiBlocks.map((block) => /* @__PURE__ */ jsx31(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null
7209
+ ) : /* @__PURE__ */ jsx32("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5DE5\u5177\u8C03\u7528" }) }),
7210
+ inlineToolUiBlocks.length > 0 ? /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-2 px-4 pb-3", children: inlineToolUiBlocks.map((block) => /* @__PURE__ */ jsx32(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null
7132
7211
  ] }) : null
7133
7212
  ] }),
7134
- expanded && /* @__PURE__ */ jsxs26("div", { className: "border-t border-[hsl(var(--border))] py-2", children: [
7213
+ expanded && /* @__PURE__ */ jsxs27("div", { className: "border-t border-[hsl(var(--border))] py-2", children: [
7135
7214
  (() => {
7136
7215
  const taskPrompt = safeParsePrompt(toolCall.arguments);
7137
- return taskPrompt ? /* @__PURE__ */ jsxs26("details", { className: "mx-3 mb-2 rounded-md bg-[hsl(var(--muted))]/40", children: [
7138
- /* @__PURE__ */ jsx31("summary", { className: "cursor-pointer px-3 py-1.5 text-[11px] font-medium text-[hsl(var(--muted-foreground))]", children: "\u4EFB\u52A1" }),
7139
- /* @__PURE__ */ jsx31("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsx31("pre", { className: "whitespace-pre-wrap text-[11px] leading-relaxed text-[hsl(var(--foreground))]", children: taskPrompt }) })
7216
+ return taskPrompt ? /* @__PURE__ */ jsxs27("details", { className: "mx-3 mb-2 rounded-md bg-[hsl(var(--muted))]/40", children: [
7217
+ /* @__PURE__ */ jsx32("summary", { className: "cursor-pointer px-3 py-1.5 text-[11px] font-medium text-[hsl(var(--muted-foreground))]", children: "\u4EFB\u52A1" }),
7218
+ /* @__PURE__ */ jsx32("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsx32("pre", { className: "whitespace-pre-wrap text-[11px] leading-relaxed text-[hsl(var(--foreground))]", children: taskPrompt }) })
7140
7219
  ] }) : null;
7141
7220
  })(),
7142
- childMessages.length > 0 ? /* @__PURE__ */ jsx31("div", { className: "flex flex-col gap-3 px-3", children: childMessages.map(
7143
- (message, index) => message.role === "assistant" ? /* @__PURE__ */ jsx31(
7221
+ childMessages.length > 0 ? /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-3 px-3", children: childMessages.map(
7222
+ (message, index) => message.role === "assistant" ? /* @__PURE__ */ jsx32(
7144
7223
  ExpandedChildAssistantMessage,
7145
7224
  {
7146
7225
  message,
@@ -7148,13 +7227,13 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7148
7227
  isStreaming: message.status === "streaming"
7149
7228
  },
7150
7229
  message.entry_id ?? `${message.timestamp ?? "child"}-${index}`
7151
- ) : message.role === "user" ? /* @__PURE__ */ jsx31(
7230
+ ) : message.role === "user" ? /* @__PURE__ */ jsx32(
7152
7231
  ExpandedChildUserMessage,
7153
7232
  {
7154
7233
  message
7155
7234
  },
7156
7235
  message.entry_id ?? `${message.timestamp ?? "user"}-${index}`
7157
- ) : message.role === "error" ? /* @__PURE__ */ jsx31(
7236
+ ) : message.role === "error" ? /* @__PURE__ */ jsx32(
7158
7237
  "div",
7159
7238
  {
7160
7239
  className: "border-l-[2px] border-l-red-500 px-3 py-2 text-[11px] text-red-200",
@@ -7162,17 +7241,17 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
7162
7241
  },
7163
7242
  message.entry_id ?? `${message.timestamp ?? "error"}-${index}`
7164
7243
  ) : null
7165
- ) }) : status === "running" ? /* @__PURE__ */ jsxs26("div", { className: "px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
7166
- /* @__PURE__ */ jsx31(Loader25, { size: 12, className: "mr-1.5 inline animate-spin" }),
7244
+ ) }) : status === "running" ? /* @__PURE__ */ jsxs27("div", { className: "px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
7245
+ /* @__PURE__ */ jsx32(Loader25, { size: 12, className: "mr-1.5 inline animate-spin" }),
7167
7246
  "\u6B63\u5728\u542F\u52A8..."
7168
- ] }) : toolCall.result ? /* @__PURE__ */ jsx31("pre", { className: "max-h-[400px] overflow-auto px-3 py-2 whitespace-pre-wrap text-[11px] text-[hsl(var(--muted-foreground))]", children: typeof toolCall.result === "string" ? toolCall.result : JSON.stringify(toolCall.result, null, 2) }) : null
7247
+ ] }) : toolCall.result ? /* @__PURE__ */ jsx32("pre", { className: "max-h-[400px] overflow-auto px-3 py-2 whitespace-pre-wrap text-[11px] text-[hsl(var(--muted-foreground))]", children: typeof toolCall.result === "string" ? toolCall.result : JSON.stringify(toolCall.result, null, 2) }) : null
7169
7248
  ] })
7170
7249
  ]
7171
7250
  }
7172
7251
  );
7173
7252
  }
7174
7253
  function ExpandedChildUserMessage({ message }) {
7175
- return /* @__PURE__ */ jsx31("div", { className: "pl-8", children: /* @__PURE__ */ jsx31(UserMessageBubble, { message }) });
7254
+ return /* @__PURE__ */ jsx32("div", { className: "pl-8", children: /* @__PURE__ */ jsx32(UserMessageBubble, { message }) });
7176
7255
  }
7177
7256
  function ExpandedChildAssistantMessage({
7178
7257
  message,
@@ -7182,12 +7261,12 @@ function ExpandedChildAssistantMessage({
7182
7261
  const text = typeof message.content === "string" ? message.content.trim() : message.content.filter((part) => part.type === "text").map((part) => part.text).join("").trim();
7183
7262
  const toolCalls = message.tool_calls ?? [];
7184
7263
  const hasToolCalls = toolCalls.length > 0;
7185
- return /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-2", children: [
7186
- message.reasoning && /* @__PURE__ */ jsxs26(Reasoning, { isStreaming, children: [
7187
- /* @__PURE__ */ jsx31(ReasoningTrigger, { wordCount: message.reasoning.length }),
7188
- /* @__PURE__ */ jsx31(ReasoningContent, { children: message.reasoning })
7264
+ return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-2", children: [
7265
+ message.reasoning && /* @__PURE__ */ jsxs27(Reasoning, { isStreaming, children: [
7266
+ /* @__PURE__ */ jsx32(ReasoningTrigger, { wordCount: message.reasoning.length }),
7267
+ /* @__PURE__ */ jsx32(ReasoningContent, { children: message.reasoning })
7189
7268
  ] }),
7190
- text ? /* @__PURE__ */ jsx31(
7269
+ text ? /* @__PURE__ */ jsx32(
7191
7270
  ChildText,
7192
7271
  {
7193
7272
  text,
@@ -7196,9 +7275,9 @@ function ExpandedChildAssistantMessage({
7196
7275
  reasoning: void 0
7197
7276
  }
7198
7277
  ) : null,
7199
- !text && isStreaming && /* @__PURE__ */ jsx31("span", { className: "pl-8 text-[12px] text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
7200
- hasToolCalls && /* @__PURE__ */ jsx31("div", { className: "flex flex-col gap-2", children: toolCalls.map(
7201
- (toolCall) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx31(
7278
+ !text && isStreaming && /* @__PURE__ */ jsx32("span", { className: "pl-8 text-[12px] text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
7279
+ hasToolCalls && /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-2", children: toolCalls.map(
7280
+ (toolCall) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx32(
7202
7281
  AgentLoopBlock,
7203
7282
  {
7204
7283
  toolCall,
@@ -7206,7 +7285,7 @@ function ExpandedChildAssistantMessage({
7206
7285
  reasoning: void 0
7207
7286
  },
7208
7287
  toolCall.id
7209
- ) : /* @__PURE__ */ jsx31(
7288
+ ) : /* @__PURE__ */ jsx32(
7210
7289
  ToolCallBlock,
7211
7290
  {
7212
7291
  toolCall,
@@ -7218,8 +7297,8 @@ function ExpandedChildAssistantMessage({
7218
7297
  toolCall.id
7219
7298
  )
7220
7299
  ) }),
7221
- message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx31("div", { className: "flex flex-col gap-2", children: message.blocks.map(
7222
- (block, index) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx31("div", { className: "ml-4", children: /* @__PURE__ */ jsx31(ResourceIframe, { ui: block.content, sessionId }) }, `${block.tool_call_id}-${index}`) : null
7300
+ message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-2", children: message.blocks.map(
7301
+ (block, index) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx32("div", { className: "ml-4", children: /* @__PURE__ */ jsx32(ResourceIframe, { ui: block.content, sessionId }) }, `${block.tool_call_id}-${index}`) : null
7223
7302
  ) }) : null
7224
7303
  ] });
7225
7304
  }
@@ -7229,8 +7308,8 @@ function ChildText({
7229
7308
  sessionId,
7230
7309
  reasoning
7231
7310
  }) {
7232
- return /* @__PURE__ */ jsxs26("div", { className: "pl-8 text-[12px] leading-6 text-[hsl(var(--foreground))]", children: [
7233
- /* @__PURE__ */ jsx31(
7311
+ return /* @__PURE__ */ jsxs27("div", { className: "pl-8 text-[12px] leading-6 text-[hsl(var(--foreground))]", children: [
7312
+ /* @__PURE__ */ jsx32(
7234
7313
  MarkdownContent,
7235
7314
  {
7236
7315
  mode: "streaming",
@@ -7240,8 +7319,8 @@ function ChildText({
7240
7319
  children: text
7241
7320
  }
7242
7321
  ),
7243
- isStreaming && /* @__PURE__ */ jsx31("span", { className: "ml-0.5 inline-block h-[1em] w-[3px] animate-pulse rounded-sm bg-current opacity-60" }),
7244
- reasoning ? /* @__PURE__ */ jsx31(ThinkingBadge, { reasoning }) : null
7322
+ isStreaming && /* @__PURE__ */ jsx32("span", { className: "ml-0.5 inline-block h-[1em] w-[3px] animate-pulse rounded-sm bg-current opacity-60" }),
7323
+ reasoning ? /* @__PURE__ */ jsx32(ThinkingBadge, { reasoning }) : null
7245
7324
  ] });
7246
7325
  }
7247
7326
  function getLoopCardStyles(status) {
@@ -7280,8 +7359,155 @@ function getLoopCardStyles(status) {
7280
7359
  };
7281
7360
  }
7282
7361
 
7362
+ // src/react/components/chat/FileDeliveryCards.tsx
7363
+ import { Download as Download4, Loader2 as Loader26 } from "lucide-react";
7364
+ import { useMemo as useMemo16, useState as useState18 } from "react";
7365
+ import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
7366
+ var AGENT_WORKSPACE_DIR_NAME = "\u667A\u80FD\u52A9\u624B\u5DE5\u4F5C\u7A7A\u95F4";
7367
+ var EXT_LABELS = {
7368
+ py: "Python",
7369
+ js: "JavaScript",
7370
+ ts: "TypeScript",
7371
+ tsx: "TypeScript",
7372
+ jsx: "JavaScript",
7373
+ md: "Markdown",
7374
+ html: "HTML",
7375
+ css: "CSS",
7376
+ json: "JSON",
7377
+ csv: "CSV",
7378
+ xlsx: "Excel",
7379
+ docx: "Word",
7380
+ pptx: "PPT",
7381
+ pdf: "PDF",
7382
+ sh: "Shell",
7383
+ sql: "SQL"
7384
+ };
7385
+ function toWorkspaceRelPath(rawPath, sessionId) {
7386
+ const sessionRoot = `/root/${AGENT_WORKSPACE_DIR_NAME}/${sessionId}`;
7387
+ let relPath;
7388
+ if (rawPath.startsWith(`${sessionRoot}/`)) {
7389
+ relPath = rawPath.slice(sessionRoot.length + 1);
7390
+ } else if (!rawPath.startsWith("/")) {
7391
+ relPath = rawPath.replace(/^\.\//, "");
7392
+ } else {
7393
+ return null;
7394
+ }
7395
+ if (!relPath || relPath.startsWith("../") || relPath.includes("/../")) return null;
7396
+ if (relPath.split("/").some((segment) => segment.startsWith("."))) return null;
7397
+ return relPath;
7398
+ }
7399
+ function basename(path) {
7400
+ return path.split("/").filter(Boolean).pop() || path;
7401
+ }
7402
+ function getExtLabel(name) {
7403
+ const ext = name.split(".").pop()?.toLowerCase() ?? "";
7404
+ if (!ext || ext === name.toLowerCase()) return "\u6587\u4EF6";
7405
+ return EXT_LABELS[ext] ?? ext.toUpperCase();
7406
+ }
7407
+ function collectDeliveredFiles(toolCalls, sessionId) {
7408
+ const seen = /* @__PURE__ */ new Set();
7409
+ const files = [];
7410
+ for (const toolCall of toolCalls) {
7411
+ if (toolCall.status !== "done") continue;
7412
+ const toolName = formatToolName(toolCall.name);
7413
+ if (toolName !== "Write" && toolName !== "Edit") continue;
7414
+ const rawPath = extractToolFilePath(toolCall);
7415
+ if (!rawPath) continue;
7416
+ const relPath = toWorkspaceRelPath(rawPath, sessionId);
7417
+ if (!relPath || seen.has(relPath)) continue;
7418
+ seen.add(relPath);
7419
+ files.push({ relPath, name: basename(relPath) });
7420
+ }
7421
+ return files;
7422
+ }
7423
+ function DeliveryCard({ relPath, name, sessionId }) {
7424
+ const [opening, setOpening] = useState18(false);
7425
+ const handleOpen = async () => {
7426
+ if (opening) return;
7427
+ setOpening(true);
7428
+ try {
7429
+ const target = await resolveSessionFilePreviewTarget(sessionId, relPath, name);
7430
+ const uiStore = useUiStore.getState();
7431
+ uiStore.setRightPanelCollapsed(false);
7432
+ uiStore.setActiveRightTab("preview");
7433
+ uiStore.pushArtifact(target);
7434
+ } finally {
7435
+ setOpening(false);
7436
+ }
7437
+ };
7438
+ const downloadUrl = useMemo16(
7439
+ () => getAuthedUrl(getSessionFilePath(sessionId, relPath)),
7440
+ [sessionId, relPath]
7441
+ );
7442
+ return /* @__PURE__ */ jsxs28("div", { className: "group/delivery relative flex w-[320px] max-w-full items-center self-start rounded-[14px] border border-[hsl(var(--border))] bg-[hsl(var(--card))] transition-colors duration-150 hover:border-[hsl(var(--primary)/0.3)] hover:bg-[hsl(var(--muted)/0.6)] focus-within:ring-1 focus-within:ring-[hsl(var(--ring))]", children: [
7443
+ /* @__PURE__ */ jsxs28(
7444
+ "button",
7445
+ {
7446
+ type: "button",
7447
+ onClick: () => void handleOpen(),
7448
+ disabled: opening,
7449
+ className: "flex min-w-0 flex-1 items-center gap-3 rounded-[14px] px-[15px] py-[13px] text-left focus:outline-none disabled:cursor-wait",
7450
+ "aria-label": `\u6253\u5F00\u6587\u4EF6\uFF1A${name}`,
7451
+ children: [
7452
+ /* @__PURE__ */ jsx33("span", { className: "flex h-[42px] w-[42px] shrink-0 items-center justify-center rounded-[11px] bg-gradient-to-br from-[hsl(var(--primary))/0.1] to-[hsl(var(--primary))/0.2] text-[hsl(var(--primary))]", children: opening ? /* @__PURE__ */ jsx33(Loader26, { size: 21, className: "animate-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx33(FileGlyph, {}) }),
7453
+ /* @__PURE__ */ jsxs28("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
7454
+ /* @__PURE__ */ jsx33("span", { className: "truncate text-[15px] font-semibold text-[hsl(var(--foreground))]", children: name }),
7455
+ /* @__PURE__ */ jsxs28("span", { className: "flex items-center gap-1.5 text-[12.5px] text-[hsl(var(--muted-foreground))]", children: [
7456
+ /* @__PURE__ */ jsx33("span", { className: "font-mono", children: getExtLabel(name) }),
7457
+ /* @__PURE__ */ jsx33("span", { "aria-hidden": "true", children: "\xB7" }),
7458
+ /* @__PURE__ */ jsx33("span", { className: "text-[hsl(var(--primary))]", children: "AI \u751F\u6210" })
7459
+ ] })
7460
+ ] })
7461
+ ]
7462
+ }
7463
+ ),
7464
+ /* @__PURE__ */ jsx33(
7465
+ "a",
7466
+ {
7467
+ href: downloadUrl,
7468
+ download: name,
7469
+ onClick: (event) => event.stopPropagation(),
7470
+ className: "absolute right-3 top-1/2 grid h-8 w-8 -translate-y-1/2 place-items-center rounded-lg text-[hsl(var(--muted-foreground))] opacity-0 transition-opacity hover:bg-[hsl(var(--background))] hover:text-[hsl(var(--foreground))] focus:opacity-100 focus:outline-none group-hover/delivery:opacity-100",
7471
+ title: "\u4E0B\u8F7D\u6587\u4EF6",
7472
+ "aria-label": `\u4E0B\u8F7D\u6587\u4EF6\uFF1A${name}`,
7473
+ children: /* @__PURE__ */ jsx33(Download4, { size: 16, "aria-hidden": "true" })
7474
+ }
7475
+ )
7476
+ ] });
7477
+ }
7478
+ function FileGlyph() {
7479
+ return /* @__PURE__ */ jsxs28(
7480
+ "svg",
7481
+ {
7482
+ width: "21",
7483
+ height: "21",
7484
+ viewBox: "0 0 24 24",
7485
+ fill: "none",
7486
+ stroke: "currentColor",
7487
+ strokeWidth: "1.9",
7488
+ strokeLinecap: "round",
7489
+ strokeLinejoin: "round",
7490
+ "aria-hidden": "true",
7491
+ children: [
7492
+ /* @__PURE__ */ jsx33("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z" }),
7493
+ /* @__PURE__ */ jsx33("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
7494
+ /* @__PURE__ */ jsx33("path", { d: "m10 13-2 2 2 2" }),
7495
+ /* @__PURE__ */ jsx33("path", { d: "m14 17 2-2-2-2" })
7496
+ ]
7497
+ }
7498
+ );
7499
+ }
7500
+ function FileDeliveryCards({
7501
+ toolCalls,
7502
+ sessionId
7503
+ }) {
7504
+ const files = useMemo16(() => collectDeliveredFiles(toolCalls, sessionId), [toolCalls, sessionId]);
7505
+ if (files.length === 0) return null;
7506
+ return /* @__PURE__ */ jsx33("div", { className: "flex flex-col gap-2", children: files.map((file) => /* @__PURE__ */ jsx33(DeliveryCard, { relPath: file.relPath, name: file.name, sessionId }, file.relPath)) });
7507
+ }
7508
+
7283
7509
  // src/react/components/chat/AssistantTurnBlock.tsx
7284
- import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
7510
+ import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
7285
7511
  var EMPTY_MESSAGES3 = [];
7286
7512
  var EMPTY_AGENT_LOOPS2 = {};
7287
7513
  function defaultTurnDisplayMode({
@@ -7413,18 +7639,18 @@ function AssistantTurnBlockBase({
7413
7639
  customization
7414
7640
  }) {
7415
7641
  const messages = Array.isArray(rawMessages) ? rawMessages : [];
7416
- const allToolCalls = useMemo16(() => messages.flatMap((m) => m.tool_calls ?? []), [messages]);
7417
- const hasAgentToolCall = useMemo16(
7642
+ const allToolCalls = useMemo17(() => messages.flatMap((m) => m.tool_calls ?? []), [messages]);
7643
+ const hasAgentToolCall = useMemo17(
7418
7644
  () => allToolCalls.some((toolCall) => formatToolName(toolCall.name) === "Agent"),
7419
7645
  [allToolCalls]
7420
7646
  );
7421
- const hasActionableToolCall = useMemo16(
7647
+ const hasActionableToolCall = useMemo17(
7422
7648
  () => allToolCalls.some(
7423
7649
  (tc) => tc.status === "error" || tc.status === "cancelled" || formatToolName(tc.name) === "AskUserQuestion" && tc.status === "awaiting_answer"
7424
7650
  ),
7425
7651
  [allToolCalls]
7426
7652
  );
7427
- const [displayMode, setDisplayMode] = useState18(
7653
+ const [displayMode, setDisplayMode] = useState19(
7428
7654
  defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall })
7429
7655
  );
7430
7656
  const wasStreamingRef = useRef12(isStreaming);
@@ -7440,16 +7666,24 @@ function AssistantTurnBlockBase({
7440
7666
  const agentLoops = useChatStore(
7441
7667
  (state) => hasAgentToolCall ? state.agentLoops[sessionId] ?? EMPTY_AGENT_LOOPS2 : EMPTY_AGENT_LOOPS2
7442
7668
  );
7443
- const turnMessages = useMemo16(
7669
+ const turnMessages = useMemo17(
7444
7670
  () => hasAgentToolCall ? collectTurnMessages({ rootMessages: messages, sessionMessages, agentLoops }) : messages,
7445
7671
  [agentLoops, hasAgentToolCall, messages, sessionMessages]
7446
7672
  );
7447
- const resourceBlocks = useMemo16(() => getInlineResourceBlocks(turnMessages), [turnMessages]);
7448
- const finalMessage = useMemo16(() => getLastTextMessage(turnMessages), [turnMessages]);
7673
+ const turnToolCalls = useMemo17(
7674
+ () => turnMessages.flatMap((m) => m.tool_calls ?? []),
7675
+ [turnMessages]
7676
+ );
7677
+ const resourceBlocks = useMemo17(() => getInlineResourceBlocks(turnMessages), [turnMessages]);
7678
+ const finalMessage = useMemo17(() => getLastTextMessage(turnMessages), [turnMessages]);
7679
+ const finalMessageText = useMemo17(
7680
+ () => finalMessage ? getTextContent(normalizeMessageContent(finalMessage.content)).trim() : "",
7681
+ [finalMessage]
7682
+ );
7449
7683
  const hasInterruptedState = messages.some((message) => message.status === "interrupted");
7450
7684
  const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
7451
7685
  const memoryRefs = Array.isArray(messages[0]?.memory_refs) ? messages[0].memory_refs : [];
7452
- return /* @__PURE__ */ jsxs27(
7686
+ return /* @__PURE__ */ jsxs29(
7453
7687
  "div",
7454
7688
  {
7455
7689
  className: cn(
@@ -7458,48 +7692,68 @@ function AssistantTurnBlockBase({
7458
7692
  customization?.classNames?.assistantTurn
7459
7693
  ),
7460
7694
  children: [
7461
- memoryRefs.length > 0 && /* @__PURE__ */ jsx32(MemoryRefsHint, { refs: memoryRefs }),
7462
- hasInterruptedState && /* @__PURE__ */ jsx32("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" }),
7463
- !isStreaming && /* @__PURE__ */ jsx32("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs27(
7695
+ memoryRefs.length > 0 && /* @__PURE__ */ jsx34(MemoryRefsHint, { refs: memoryRefs }),
7696
+ hasInterruptedState && /* @__PURE__ */ jsx34("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" }),
7697
+ !isStreaming && allToolCalls.length > 0 && // 详情药丸(原型):左对齐,展示步骤数;展开后是带左边线的步骤卡。
7698
+ /* @__PURE__ */ jsxs29(
7464
7699
  "button",
7465
7700
  {
7466
7701
  type: "button",
7467
7702
  onClick: () => setDisplayMode(displayMode === "detail" ? "compact" : "detail"),
7468
- className: "inline-flex shrink-0 items-center gap-1 text-xs text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
7703
+ "aria-expanded": effectiveMode === "detail",
7704
+ className: "inline-flex h-[30px] shrink-0 select-none items-center gap-1.5 self-start rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.35)] pl-2.5 pr-3 text-[13px] text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
7469
7705
  children: [
7470
- /* @__PURE__ */ jsx32("span", { children: effectiveMode === "detail" ? "\u7CBE\u7B80" : "\u8BE6\u7EC6" }),
7471
- /* @__PURE__ */ jsx32(
7472
- ChevronRight5,
7706
+ /* @__PURE__ */ jsx34(Check5, { size: 14, className: "shrink-0 text-emerald-500", "aria-hidden": "true" }),
7707
+ /* @__PURE__ */ jsxs29("span", { children: [
7708
+ "\u8BE6\u60C5 \xB7 ",
7709
+ allToolCalls.length,
7710
+ " \u4E2A\u6B65\u9AA4"
7711
+ ] }),
7712
+ /* @__PURE__ */ jsx34(
7713
+ ChevronDown2,
7473
7714
  {
7474
- size: 18,
7475
- className: cn("transition-transform", effectiveMode === "detail" && "rotate-180")
7715
+ size: 14,
7716
+ className: cn("shrink-0 transition-transform", effectiveMode === "detail" && "rotate-180"),
7717
+ "aria-hidden": "true"
7476
7718
  }
7477
7719
  )
7478
7720
  ]
7479
7721
  }
7480
- ) }),
7481
- effectiveMode === "detail" ? /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx32(
7482
- AssistantMessages,
7483
- {
7484
- messages,
7485
- isStreaming,
7486
- sessionId,
7487
- askAnswers,
7488
- onAnswer,
7489
- sessionStatus,
7490
- level,
7491
- showToolDetails: true,
7492
- customization
7493
- }
7494
- ) }) : /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-4", children: [
7495
- resourceBlocks.length > 0 ? /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-3", children: resourceBlocks.map((block) => /* @__PURE__ */ jsx32(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null,
7496
- finalMessage ? /* @__PURE__ */ jsx32(
7722
+ ),
7723
+ effectiveMode === "detail" ? (
7724
+ // 展开态:左边线把步骤收拢成一组,和正文拉开层次(原型)。
7725
+ /* @__PURE__ */ jsx34(
7726
+ "div",
7727
+ {
7728
+ className: cn(
7729
+ "flex flex-col gap-3",
7730
+ allToolCalls.length > 0 && "ml-1.5 border-l-2 border-[hsl(var(--border))] pl-4"
7731
+ ),
7732
+ children: /* @__PURE__ */ jsx34(
7733
+ AssistantMessages,
7734
+ {
7735
+ messages,
7736
+ isStreaming,
7737
+ sessionId,
7738
+ askAnswers,
7739
+ onAnswer,
7740
+ sessionStatus,
7741
+ level,
7742
+ showToolDetails: true,
7743
+ customization
7744
+ }
7745
+ )
7746
+ }
7747
+ )
7748
+ ) : /* @__PURE__ */ jsx34("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-4", children: [
7749
+ resourceBlocks.length > 0 ? /* @__PURE__ */ jsx34("div", { className: "flex flex-col gap-3", children: resourceBlocks.map((block) => /* @__PURE__ */ jsx34(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null,
7750
+ finalMessage ? /* @__PURE__ */ jsx34(
7497
7751
  "div",
7498
7752
  {
7499
7753
  className: cn(
7500
7754
  resourceBlocks.length > 0 && "border-t border-[hsl(var(--border))] pt-4"
7501
7755
  ),
7502
- children: /* @__PURE__ */ jsx32(
7756
+ children: /* @__PURE__ */ jsx34(
7503
7757
  AssistantMessageContent,
7504
7758
  {
7505
7759
  message: finalMessage,
@@ -7510,8 +7764,14 @@ function AssistantTurnBlockBase({
7510
7764
  }
7511
7765
  )
7512
7766
  }
7513
- ) : isStreaming ? /* @__PURE__ */ jsx32("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }) : null
7514
- ] }) })
7767
+ ) : isStreaming ? /* @__PURE__ */ jsx34("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }) : null
7768
+ ] }) }),
7769
+ level === 1 && // 用合并后的轮次消息:子智能体(fork Agent)写入的文件也要出交付卡片。
7770
+ /* @__PURE__ */ jsx34(FileDeliveryCards, { toolCalls: turnToolCalls, sessionId }),
7771
+ level === 1 && !isStreaming && finalMessageText ? (
7772
+ // 反馈行(原型):轮次底部的复制入口。
7773
+ /* @__PURE__ */ jsx34(MessageActions, { content: finalMessageText, className: "-mt-1.5" })
7774
+ ) : null
7515
7775
  ]
7516
7776
  }
7517
7777
  );
@@ -7539,16 +7799,16 @@ function AssistantMessages({
7539
7799
  const toolCalls = message.tool_calls ?? [];
7540
7800
  const hasToolCalls = toolCalls.length > 0;
7541
7801
  const toolRenderItems = groupDetailedToolCalls(toolCalls);
7542
- return /* @__PURE__ */ jsxs27(
7802
+ return /* @__PURE__ */ jsxs29(
7543
7803
  "div",
7544
7804
  {
7545
7805
  className: "flex flex-col gap-3",
7546
7806
  children: [
7547
- hasReasoning && /* @__PURE__ */ jsxs27(Reasoning, { isStreaming: isStreamingLastMessage, children: [
7548
- /* @__PURE__ */ jsx32(ReasoningTrigger, { wordCount: reasoning.length }),
7549
- /* @__PURE__ */ jsx32(ReasoningContent, { children: reasoning })
7807
+ hasReasoning && /* @__PURE__ */ jsxs29(Reasoning, { isStreaming: isStreamingLastMessage, children: [
7808
+ /* @__PURE__ */ jsx34(ReasoningTrigger, { wordCount: reasoning.length }),
7809
+ /* @__PURE__ */ jsx34(ReasoningContent, { children: reasoning })
7550
7810
  ] }),
7551
- /* @__PURE__ */ jsx32(
7811
+ /* @__PURE__ */ jsx34(
7552
7812
  AssistantMessageContent,
7553
7813
  {
7554
7814
  message,
@@ -7558,9 +7818,9 @@ function AssistantMessages({
7558
7818
  className: customization?.classNames?.assistantText
7559
7819
  }
7560
7820
  ),
7561
- hasToolCalls && showToolDetails && /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-2", children: toolRenderItems.map((item) => {
7821
+ hasToolCalls && showToolDetails && /* @__PURE__ */ jsx34("div", { className: "flex flex-col gap-2", children: toolRenderItems.map((item) => {
7562
7822
  if (item.kind === "read_group") {
7563
- return /* @__PURE__ */ jsx32(
7823
+ return /* @__PURE__ */ jsx34(
7564
7824
  CompactToolGroupBlock,
7565
7825
  {
7566
7826
  toolCalls: item.toolCalls,
@@ -7577,7 +7837,7 @@ function AssistantMessages({
7577
7837
  );
7578
7838
  }
7579
7839
  const { toolCall } = item;
7580
- return formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx32(
7840
+ return formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx34(
7581
7841
  AgentLoopBlock,
7582
7842
  {
7583
7843
  toolCall,
@@ -7585,7 +7845,7 @@ function AssistantMessages({
7585
7845
  reasoning: void 0
7586
7846
  },
7587
7847
  toolCall.id
7588
- ) : customization?.components?.ToolCall ? /* @__PURE__ */ jsx32(
7848
+ ) : customization?.components?.ToolCall ? /* @__PURE__ */ jsx34(
7589
7849
  customization.components.ToolCall,
7590
7850
  {
7591
7851
  toolCall,
@@ -7600,7 +7860,7 @@ function AssistantMessages({
7600
7860
  customization
7601
7861
  },
7602
7862
  toolCall.id
7603
- ) : /* @__PURE__ */ jsx32(
7863
+ ) : /* @__PURE__ */ jsx34(
7604
7864
  ToolCallBlock,
7605
7865
  {
7606
7866
  toolCall,
@@ -7617,8 +7877,8 @@ function AssistantMessages({
7617
7877
  toolCall.id
7618
7878
  );
7619
7879
  }) }),
7620
- showToolDetails && message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx32("div", { className: "flex flex-col gap-2", children: message.blocks.map(
7621
- (block, blockIndex) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx32("div", { className: "ml-4", children: /* @__PURE__ */ jsx32(ResourceIframe, { ui: block.content, sessionId }) }, `${block.tool_call_id}-${blockIndex}`) : null
7880
+ showToolDetails && message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx34("div", { className: "flex flex-col gap-2", children: message.blocks.map(
7881
+ (block, blockIndex) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx34("div", { className: "ml-4", children: /* @__PURE__ */ jsx34(ResourceIframe, { ui: block.content, sessionId }) }, `${block.tool_call_id}-${blockIndex}`) : null
7622
7882
  ) }) : null
7623
7883
  ]
7624
7884
  },
@@ -7652,7 +7912,7 @@ function CompactToolGroupBlock({
7652
7912
  level,
7653
7913
  customization
7654
7914
  }) {
7655
- const [expanded, setExpanded] = useState18(false);
7915
+ const [expanded, setExpanded] = useState19(false);
7656
7916
  const indentClass = level === 2 ? "ml-3" : "ml-4";
7657
7917
  const hasError = toolCalls.some(
7658
7918
  (tc) => tc.status === "error" || tc.status === "cancelled"
@@ -7666,12 +7926,12 @@ function CompactToolGroupBlock({
7666
7926
  return filePath ? formatFileName(filePath) : "\u672A\u77E5\u6587\u4EF6";
7667
7927
  });
7668
7928
  const title = `\u8BFB\u53D6 ${toolCalls.length} \u4E2A\u6587\u4EF6`;
7669
- return /* @__PURE__ */ jsxs27("div", { className: cn(indentClass, "text-xs"), children: [
7670
- /* @__PURE__ */ jsxs27("div", { className: cn(
7929
+ return /* @__PURE__ */ jsxs29("div", { className: cn(indentClass, "text-xs"), children: [
7930
+ /* @__PURE__ */ jsxs29("div", { className: cn(
7671
7931
  "flex items-center gap-2 border-l-[3px] px-3 py-2",
7672
7932
  hasError ? "border-l-[hsl(var(--destructive))]" : "border-l-[hsl(var(--primary))]"
7673
7933
  ), children: [
7674
- /* @__PURE__ */ jsxs27(
7934
+ /* @__PURE__ */ jsxs29(
7675
7935
  "button",
7676
7936
  {
7677
7937
  type: "button",
@@ -7679,7 +7939,7 @@ function CompactToolGroupBlock({
7679
7939
  className: "flex min-w-0 shrink-0 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",
7680
7940
  "aria-expanded": expanded,
7681
7941
  children: [
7682
- /* @__PURE__ */ jsx32(
7942
+ /* @__PURE__ */ jsx34(
7683
7943
  ChevronRight5,
7684
7944
  {
7685
7945
  size: 11,
@@ -7689,18 +7949,18 @@ function CompactToolGroupBlock({
7689
7949
  )
7690
7950
  }
7691
7951
  ),
7692
- hasError ? /* @__PURE__ */ jsxs27("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--destructive))]", children: [
7693
- /* @__PURE__ */ jsx32(AlertCircle, { size: 11 }),
7694
- /* @__PURE__ */ jsx32("span", { children: "\u5931\u8D25" })
7695
- ] }) : /* @__PURE__ */ jsxs27("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--primary))]", children: [
7696
- /* @__PURE__ */ jsx32(Check5, { size: 11 }),
7697
- /* @__PURE__ */ jsx32("span", { children: "\u5B8C\u6210" })
7952
+ hasError ? /* @__PURE__ */ jsxs29("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--destructive))]", children: [
7953
+ /* @__PURE__ */ jsx34(AlertCircle, { size: 11 }),
7954
+ /* @__PURE__ */ jsx34("span", { children: "\u5931\u8D25" })
7955
+ ] }) : /* @__PURE__ */ jsxs29("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--primary))]", children: [
7956
+ /* @__PURE__ */ jsx34(Check5, { size: 11 }),
7957
+ /* @__PURE__ */ jsx34("span", { children: "\u5B8C\u6210" })
7698
7958
  ] }),
7699
- /* @__PURE__ */ jsx32("span", { className: "min-w-0 shrink-0 font-medium text-[hsl(var(--foreground))]", children: title })
7959
+ /* @__PURE__ */ jsx34("span", { className: "min-w-0 shrink-0 font-medium text-[hsl(var(--foreground))]", children: title })
7700
7960
  ]
7701
7961
  }
7702
7962
  ),
7703
- /* @__PURE__ */ jsx32("div", { className: "flex min-w-0 flex-1 flex-wrap gap-1.5", children: tags.map((tag, index) => /* @__PURE__ */ jsx32(
7963
+ /* @__PURE__ */ jsx34("div", { className: "flex min-w-0 flex-1 flex-wrap gap-1.5", children: tags.map((tag, index) => /* @__PURE__ */ jsx34(
7704
7964
  "span",
7705
7965
  {
7706
7966
  className: "max-w-40 truncate rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.35)] px-1.5 py-0.5 font-mono text-[10px] text-[hsl(var(--muted-foreground))]",
@@ -7709,12 +7969,12 @@ function CompactToolGroupBlock({
7709
7969
  },
7710
7970
  `${tag}-${index}`
7711
7971
  )) }),
7712
- reasoning ? /* @__PURE__ */ jsx32(ThinkingBadge, { reasoning, variant: "block" }) : null,
7713
- totalDurationMs > 0 ? /* @__PURE__ */ jsx32("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration2(totalDurationMs) }) : null
7972
+ reasoning ? /* @__PURE__ */ jsx34(ThinkingBadge, { reasoning, variant: "block" }) : null,
7973
+ totalDurationMs > 0 ? /* @__PURE__ */ jsx34("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration2(totalDurationMs) }) : null
7714
7974
  ] }),
7715
- expanded ? /* @__PURE__ */ jsx32("div", { className: "mt-1 flex flex-col gap-1", children: toolCalls.map((toolCall) => {
7975
+ expanded ? /* @__PURE__ */ jsx34("div", { className: "mt-1 flex flex-col gap-1", children: toolCalls.map((toolCall) => {
7716
7976
  const CustomToolCall = customization?.components?.ToolCall;
7717
- return CustomToolCall ? /* @__PURE__ */ jsx32(
7977
+ return CustomToolCall ? /* @__PURE__ */ jsx34(
7718
7978
  CustomToolCall,
7719
7979
  {
7720
7980
  toolCall,
@@ -7728,7 +7988,7 @@ function CompactToolGroupBlock({
7728
7988
  customization
7729
7989
  },
7730
7990
  toolCall.id
7731
- ) : /* @__PURE__ */ jsx32(
7991
+ ) : /* @__PURE__ */ jsx34(
7732
7992
  ToolCallBlock,
7733
7993
  {
7734
7994
  toolCall,
@@ -7759,8 +8019,8 @@ function AssistantMessageContent({
7759
8019
  if (!text && imageParts.length === 0 && fileParts.length === 0 && !isStreaming && !reasoning) {
7760
8020
  return null;
7761
8021
  }
7762
- return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-3", children: [
7763
- imageParts.length > 0 && /* @__PURE__ */ jsx32("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx32(
8022
+ return /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-3", children: [
8023
+ imageParts.length > 0 && /* @__PURE__ */ jsx34("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx34(
7764
8024
  "img",
7765
8025
  {
7766
8026
  src: part.image_url.url,
@@ -7769,8 +8029,8 @@ function AssistantMessageContent({
7769
8029
  },
7770
8030
  part.image_url.url
7771
8031
  )) }),
7772
- /* @__PURE__ */ jsx32(MessageFileAttachmentList, { files: fileParts }),
7773
- text ? /* @__PURE__ */ jsx32(
8032
+ /* @__PURE__ */ jsx34(MessageFileAttachmentList, { files: fileParts }),
8033
+ text ? /* @__PURE__ */ jsx34(
7774
8034
  AssistantText,
7775
8035
  {
7776
8036
  text,
@@ -7780,8 +8040,8 @@ function AssistantMessageContent({
7780
8040
  className
7781
8041
  }
7782
8042
  ) : null,
7783
- !text && isStreaming && /* @__PURE__ */ jsx32("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
7784
- !text && reasoning ? /* @__PURE__ */ jsx32(ThinkingBadge, { reasoning, variant: "block" }) : null
8043
+ !text && isStreaming && /* @__PURE__ */ jsx34("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
8044
+ !text && reasoning ? /* @__PURE__ */ jsx34(ThinkingBadge, { reasoning, variant: "block" }) : null
7785
8045
  ] });
7786
8046
  }
7787
8047
  function AssistantText({
@@ -7797,45 +8057,45 @@ function AssistantText({
7797
8057
  },
7798
8058
  [sessionId]
7799
8059
  );
7800
- const cardCtx = useMemo16(
8060
+ const cardCtx = useMemo17(
7801
8061
  () => ({ sessionId, messageId, sendMessage }),
7802
8062
  [sessionId, messageId, sendMessage]
7803
8063
  );
7804
- return /* @__PURE__ */ jsxs27("div", { className: cn("text-[15px] leading-8 text-[hsl(var(--foreground))]", className), children: [
7805
- /* @__PURE__ */ jsx32(CardContext.Provider, { value: cardCtx, children: /* @__PURE__ */ jsx32(
8064
+ return /* @__PURE__ */ jsxs29("div", { className: cn("text-[15px] leading-8 text-[hsl(var(--foreground))]", className), children: [
8065
+ /* @__PURE__ */ jsx34(CardContext.Provider, { value: cardCtx, children: /* @__PURE__ */ jsx34(
7806
8066
  MarkdownContent,
7807
8067
  {
7808
8068
  mode: "streaming",
7809
8069
  sessionId,
7810
- className: "prose prose-sm prose-invert inline max-w-none [&_li>p]:inline [&_p]:mb-3 [&_p:last-child]:mb-0 [&_p:last-child]:inline",
8070
+ className: "prose prose-invert chat-prose inline max-w-none [&_li>p]:inline [&_p:last-child]:inline",
7811
8071
  controls: { code: true },
7812
8072
  children: text
7813
8073
  }
7814
8074
  ) }),
7815
- reasoning ? /* @__PURE__ */ jsx32(ThinkingBadge, { reasoning }) : null
8075
+ reasoning ? /* @__PURE__ */ jsx34(ThinkingBadge, { reasoning }) : null
7816
8076
  ] });
7817
8077
  }
7818
8078
  function MemoryRefsHint({ refs: rawRefs }) {
7819
8079
  const refs = Array.isArray(rawRefs) ? rawRefs : [];
7820
- const [expanded, setExpanded] = useState18(false);
8080
+ const [expanded, setExpanded] = useState19(false);
7821
8081
  const hasSkill = refs.some((r3) => r3.skill_name);
7822
8082
  const label = hasSkill ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
7823
- return /* @__PURE__ */ jsxs27("div", { className: "ml-4", children: [
7824
- /* @__PURE__ */ jsxs27(
8083
+ return /* @__PURE__ */ jsxs29("div", { className: "ml-4", children: [
8084
+ /* @__PURE__ */ jsxs29(
7825
8085
  "button",
7826
8086
  {
7827
8087
  type: "button",
7828
8088
  onClick: () => setExpanded(!expanded),
7829
8089
  className: "inline-flex items-center gap-1.5 rounded-md border border-[hsl(var(--primary)/0.25)] bg-[hsl(var(--primary)/0.08)] px-2.5 py-1 text-[11px] text-[hsl(var(--primary))] transition-colors hover:bg-[hsl(var(--primary)/0.12)]",
7830
8090
  children: [
7831
- /* @__PURE__ */ jsx32(BookOpen, { size: 12 }),
7832
- /* @__PURE__ */ jsxs27("span", { children: [
8091
+ /* @__PURE__ */ jsx34(BookOpen, { size: 12 }),
8092
+ /* @__PURE__ */ jsxs29("span", { children: [
7833
8093
  label,
7834
8094
  "\uFF08",
7835
8095
  refs.length,
7836
8096
  "\uFF09"
7837
8097
  ] }),
7838
- /* @__PURE__ */ jsx32(
8098
+ /* @__PURE__ */ jsx34(
7839
8099
  ChevronRight5,
7840
8100
  {
7841
8101
  size: 10,
@@ -7845,13 +8105,13 @@ function MemoryRefsHint({ refs: rawRefs }) {
7845
8105
  ]
7846
8106
  }
7847
8107
  ),
7848
- expanded && /* @__PURE__ */ jsxs27("div", { className: "mt-1.5 flex flex-col gap-1 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.45)] px-3 py-2", children: [
7849
- refs.map((ref) => /* @__PURE__ */ jsxs27("div", { className: "flex items-start gap-2 text-[11px] text-[hsl(var(--foreground)/0.82)]", children: [
7850
- /* @__PURE__ */ jsx32("span", { className: "mt-0.5 shrink-0 text-[hsl(var(--primary)/0.75)]", children: "\u2022" }),
7851
- /* @__PURE__ */ jsx32("span", { className: "line-clamp-1", children: ref.content_preview }),
7852
- ref.skill_name && /* @__PURE__ */ jsx32("span", { className: "ml-auto shrink-0 rounded bg-[hsl(var(--primary)/0.12)] px-1.5 py-0.5 text-[10px] text-[hsl(var(--primary))]", children: ref.skill_name })
8108
+ expanded && /* @__PURE__ */ jsxs29("div", { className: "mt-1.5 flex flex-col gap-1 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.45)] px-3 py-2", children: [
8109
+ refs.map((ref) => /* @__PURE__ */ jsxs29("div", { className: "flex items-start gap-2 text-[11px] text-[hsl(var(--foreground)/0.82)]", children: [
8110
+ /* @__PURE__ */ jsx34("span", { className: "mt-0.5 shrink-0 text-[hsl(var(--primary)/0.75)]", children: "\u2022" }),
8111
+ /* @__PURE__ */ jsx34("span", { className: "line-clamp-1", children: ref.content_preview }),
8112
+ ref.skill_name && /* @__PURE__ */ jsx34("span", { className: "ml-auto shrink-0 rounded bg-[hsl(var(--primary)/0.12)] px-1.5 py-0.5 text-[10px] text-[hsl(var(--primary))]", children: ref.skill_name })
7853
8113
  ] }, ref.id)),
7854
- /* @__PURE__ */ jsx32(
8114
+ /* @__PURE__ */ jsx34(
7855
8115
  "a",
7856
8116
  {
7857
8117
  href: MEMORIES_ROUTE,
@@ -7864,9 +8124,9 @@ function MemoryRefsHint({ refs: rawRefs }) {
7864
8124
  }
7865
8125
 
7866
8126
  // src/react/components/chat/CompactionCard.tsx
7867
- import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight6, Loader2 as Loader26, Square as Square3, XCircle } from "lucide-react";
7868
- import { useState as useState19 } from "react";
7869
- import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
8127
+ import { ChevronDown as ChevronDown3, ChevronRight as ChevronRight6, Loader2 as Loader27, Square as Square3, XCircle } from "lucide-react";
8128
+ import { useState as useState20 } from "react";
8129
+ import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
7870
8130
  var PERCENT_FORMATTER = new Intl.NumberFormat("zh-CN", {
7871
8131
  style: "percent",
7872
8132
  maximumFractionDigits: 0
@@ -7915,7 +8175,7 @@ function CompactionCard({
7915
8175
  ...compaction,
7916
8176
  status: status ?? "completed"
7917
8177
  } : activeCompaction;
7918
- const [expanded, setExpanded] = useState19(false);
8178
+ const [expanded, setExpanded] = useState20(false);
7919
8179
  if (!source || !source.compaction_id) {
7920
8180
  return null;
7921
8181
  }
@@ -7926,9 +8186,9 @@ function CompactionCard({
7926
8186
  const hasSummary = typeof source.summary_full === "string" && source.summary_full.trim().length > 0 && !isGenericArchiveSummary(source.summary_full);
7927
8187
  const hasFailureReason = source.status === "failed" && Boolean(source.failure_reason);
7928
8188
  const canExpand = source.status === "completed" && (hasSummary || archivedToolCalls.length > 0) || hasFailureReason;
7929
- return /* @__PURE__ */ jsxs28("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: [
7930
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center justify-between gap-2", children: [
7931
- /* @__PURE__ */ jsxs28(
8189
+ return /* @__PURE__ */ jsxs30("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: [
8190
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-2", children: [
8191
+ /* @__PURE__ */ jsxs30(
7932
8192
  "button",
7933
8193
  {
7934
8194
  type: "button",
@@ -7939,21 +8199,21 @@ function CompactionCard({
7939
8199
  ),
7940
8200
  "aria-expanded": expanded,
7941
8201
  children: [
7942
- canExpand ? expanded ? /* @__PURE__ */ jsx33(ChevronDown2, { size: 12, className: "shrink-0" }) : /* @__PURE__ */ jsx33(ChevronRight6, { size: 12, className: "shrink-0" }) : null,
7943
- /* @__PURE__ */ jsx33("span", { children: source.status === "streaming" ? /* @__PURE__ */ jsxs28("span", { className: "inline-flex items-center gap-1", children: [
7944
- /* @__PURE__ */ jsx33(Loader26, { size: 12, className: "animate-spin" }),
8202
+ canExpand ? expanded ? /* @__PURE__ */ jsx35(ChevronDown3, { size: 12, className: "shrink-0" }) : /* @__PURE__ */ jsx35(ChevronRight6, { size: 12, className: "shrink-0" }) : null,
8203
+ /* @__PURE__ */ jsx35("span", { children: source.status === "streaming" ? /* @__PURE__ */ jsxs30("span", { className: "inline-flex items-center gap-1", children: [
8204
+ /* @__PURE__ */ jsx35(Loader27, { size: 12, className: "animate-spin" }),
7945
8205
  "\u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587"
7946
- ] }) : source.status === "failed" ? /* @__PURE__ */ jsxs28("span", { className: "inline-flex items-center gap-1 text-rose-500/80", children: [
7947
- /* @__PURE__ */ jsx33(XCircle, { size: 12 }),
8206
+ ] }) : source.status === "failed" ? /* @__PURE__ */ jsxs30("span", { className: "inline-flex items-center gap-1 text-rose-500/80", children: [
8207
+ /* @__PURE__ */ jsx35(XCircle, { size: 12 }),
7948
8208
  "\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25"
7949
- ] }) : source.status === "interrupted" ? /* @__PURE__ */ jsxs28("span", { className: "inline-flex items-center gap-1 text-amber-500/80", children: [
7950
- /* @__PURE__ */ jsx33(Square3, { size: 11 }),
8209
+ ] }) : source.status === "interrupted" ? /* @__PURE__ */ jsxs30("span", { className: "inline-flex items-center gap-1 text-amber-500/80", children: [
8210
+ /* @__PURE__ */ jsx35(Square3, { size: 11 }),
7951
8211
  "\u4E0A\u4E0B\u6587\u538B\u7F29\u5DF2\u53D6\u6D88"
7952
8212
  ] }) : "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
7953
8213
  ]
7954
8214
  }
7955
8215
  ),
7956
- canCancel ? /* @__PURE__ */ jsx33(
8216
+ canCancel ? /* @__PURE__ */ jsx35(
7957
8217
  "button",
7958
8218
  {
7959
8219
  type: "button",
@@ -7963,13 +8223,13 @@ function CompactionCard({
7963
8223
  }
7964
8224
  ) : null
7965
8225
  ] }),
7966
- expanded ? /* @__PURE__ */ jsxs28("div", { className: "mt-1 max-w-3xl rounded-lg border border-[hsl(var(--border))]/70 bg-[hsl(var(--card))]/80 px-3 py-2 text-[11px] leading-relaxed shadow-sm", children: [
7967
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-[hsl(var(--muted-foreground))]", children: [
7968
- /* @__PURE__ */ jsxs28("span", { children: [
8226
+ expanded ? /* @__PURE__ */ jsxs30("div", { className: "mt-1 max-w-3xl rounded-lg border border-[hsl(var(--border))]/70 bg-[hsl(var(--card))]/80 px-3 py-2 text-[11px] leading-relaxed shadow-sm", children: [
8227
+ /* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-[hsl(var(--muted-foreground))]", children: [
8228
+ /* @__PURE__ */ jsxs30("span", { children: [
7969
8229
  "#",
7970
8230
  shortId(source.compaction_id)
7971
8231
  ] }),
7972
- /* @__PURE__ */ jsxs28("span", { children: [
8232
+ /* @__PURE__ */ jsxs30("span", { children: [
7973
8233
  "\u8282\u7701 ",
7974
8234
  formatSavedRatio(source.saved_ratio),
7975
8235
  "\uFF08",
@@ -7979,31 +8239,31 @@ function CompactionCard({
7979
8239
  formatTokens(source.tokens_after),
7980
8240
  " token\uFF09"
7981
8241
  ] }),
7982
- /* @__PURE__ */ jsxs28("span", { children: [
8242
+ /* @__PURE__ */ jsxs30("span", { children: [
7983
8243
  "\u5F52\u6863 ",
7984
8244
  archivedCount,
7985
8245
  " \u4E2A\u5DE5\u5177\u7ED3\u679C"
7986
8246
  ] })
7987
8247
  ] }),
7988
- archivedToolCalls.length > 0 ? /* @__PURE__ */ jsx33("div", { className: "mt-2 space-y-1.5", children: archivedToolCalls.map((item, index) => {
8248
+ archivedToolCalls.length > 0 ? /* @__PURE__ */ jsx35("div", { className: "mt-2 space-y-1.5", children: archivedToolCalls.map((item, index) => {
7989
8249
  const archivePath = getArchivePath(item, archivedFiles);
7990
- return /* @__PURE__ */ jsxs28(
8250
+ return /* @__PURE__ */ jsxs30(
7991
8251
  "div",
7992
8252
  {
7993
8253
  className: "rounded-md border border-[hsl(var(--border))]/70 bg-[hsl(var(--muted))]/35 px-2 py-1.5",
7994
8254
  children: [
7995
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-[hsl(var(--foreground))]", children: [
7996
- /* @__PURE__ */ jsx33("span", { className: "font-medium", children: getArchivedToolLabel(item) }),
7997
- item.tool_call_id ? /* @__PURE__ */ jsx33("span", { className: "font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.tool_call_id }) : null
8255
+ /* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-[hsl(var(--foreground))]", children: [
8256
+ /* @__PURE__ */ jsx35("span", { className: "font-medium", children: getArchivedToolLabel(item) }),
8257
+ item.tool_call_id ? /* @__PURE__ */ jsx35("span", { className: "font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.tool_call_id }) : null
7998
8258
  ] }),
7999
- archivePath ? /* @__PURE__ */ jsx33("div", { className: "mt-0.5 break-all font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: archivePath }) : null
8259
+ archivePath ? /* @__PURE__ */ jsx35("div", { className: "mt-0.5 break-all font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: archivePath }) : null
8000
8260
  ]
8001
8261
  },
8002
8262
  item.tool_call_id || item.entry_id || `${item.tool_name}-${index}`
8003
8263
  );
8004
8264
  }) }) : null,
8005
- hasSummary ? /* @__PURE__ */ jsx33("pre", { className: "mt-2 max-h-[360px] overflow-auto whitespace-pre-wrap rounded-md border border-[hsl(var(--border))]/70 bg-[hsl(var(--muted))]/25 px-2 py-1.5 font-mono text-[11px] leading-relaxed text-[hsl(var(--foreground))]", children: source.summary_full }) : null,
8006
- source.status === "failed" && source.failure_reason ? /* @__PURE__ */ jsxs28("div", { className: "mt-2 text-rose-500/90", children: [
8265
+ hasSummary ? /* @__PURE__ */ jsx35("pre", { className: "mt-2 max-h-[360px] overflow-auto whitespace-pre-wrap rounded-md border border-[hsl(var(--border))]/70 bg-[hsl(var(--muted))]/25 px-2 py-1.5 font-mono text-[11px] leading-relaxed text-[hsl(var(--foreground))]", children: source.summary_full }) : null,
8266
+ source.status === "failed" && source.failure_reason ? /* @__PURE__ */ jsxs30("div", { className: "mt-2 text-rose-500/90", children: [
8007
8267
  "\u5931\u8D25\u539F\u56E0\uFF1A",
8008
8268
  source.failure_reason
8009
8269
  ] }) : null
@@ -8014,7 +8274,7 @@ function CompactionCard({
8014
8274
  // src/react/components/chat/RenderErrorBoundary.tsx
8015
8275
  import { AlertTriangle as AlertTriangle2 } from "lucide-react";
8016
8276
  import { Component } from "react";
8017
- import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
8277
+ import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
8018
8278
  function getFirstComponentName(componentStack) {
8019
8279
  const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
8020
8280
  return match?.[1] ?? null;
@@ -8047,18 +8307,18 @@ var RenderErrorBoundary = class extends Component {
8047
8307
  return children;
8048
8308
  }
8049
8309
  const componentName = getFirstComponentName(componentStack);
8050
- return /* @__PURE__ */ jsx34("div", { className: "rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs29("div", { className: "flex items-start gap-2", children: [
8051
- /* @__PURE__ */ jsx34(AlertTriangle2, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
8052
- /* @__PURE__ */ jsxs29("div", { className: "min-w-0 flex-1", children: [
8053
- /* @__PURE__ */ jsxs29("div", { className: "font-medium", children: [
8310
+ return /* @__PURE__ */ jsx36("div", { className: "rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs31("div", { className: "flex items-start gap-2", children: [
8311
+ /* @__PURE__ */ jsx36(AlertTriangle2, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
8312
+ /* @__PURE__ */ jsxs31("div", { className: "min-w-0 flex-1", children: [
8313
+ /* @__PURE__ */ jsxs31("div", { className: "font-medium", children: [
8054
8314
  label,
8055
8315
  "\u6E32\u67D3\u5931\u8D25"
8056
8316
  ] }),
8057
- /* @__PURE__ */ jsxs29("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
8317
+ /* @__PURE__ */ jsxs31("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
8058
8318
  componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
8059
8319
  error.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
8060
8320
  ] }),
8061
- details ? /* @__PURE__ */ jsx34("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
8321
+ details ? /* @__PURE__ */ jsx36("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
8062
8322
  ] })
8063
8323
  ] }) });
8064
8324
  }
@@ -8076,8 +8336,8 @@ import {
8076
8336
  TerminalSquare,
8077
8337
  WandSparkles
8078
8338
  } from "lucide-react";
8079
- import { useEffect as useEffect17, useMemo as useMemo17, useState as useState20 } from "react";
8080
- import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
8339
+ import { useEffect as useEffect17, useMemo as useMemo18, useState as useState21 } from "react";
8340
+ import { jsx as jsx37, jsxs as jsxs32 } from "react/jsx-runtime";
8081
8341
  var EMPTY_EVENTS = [];
8082
8342
  function formatElapsedDuration(durationMs) {
8083
8343
  if (durationMs == null) return null;
@@ -8155,7 +8415,7 @@ function getTurnStartedAt(events) {
8155
8415
  return null;
8156
8416
  }
8157
8417
  function useElapsedDuration(startedAt, active) {
8158
- const [now, setNow] = useState20(() => Date.now());
8418
+ const [now, setNow] = useState21(() => Date.now());
8159
8419
  useEffect17(() => {
8160
8420
  if (!active || startedAt == null) {
8161
8421
  return;
@@ -8179,30 +8439,30 @@ function StickyStatusBar({
8179
8439
  onJumpToLatest
8180
8440
  }) {
8181
8441
  const events = useRuntimeStore((state) => state.events[sessionId] ?? EMPTY_EVENTS);
8182
- const startedAt = useMemo17(() => getTurnStartedAt(events), [events]);
8442
+ const startedAt = useMemo18(() => getTurnStartedAt(events), [events]);
8183
8443
  const elapsedDuration = useElapsedDuration(startedAt, isStreaming && isLastTurn);
8184
- const action = useMemo17(() => getCurrentAction(messages), [messages]);
8444
+ const action = useMemo18(() => getCurrentAction(messages), [messages]);
8185
8445
  if (!isStreaming || !isLastTurn) {
8186
8446
  return null;
8187
8447
  }
8188
8448
  const elapsedLabel = formatElapsedDuration(elapsedDuration);
8189
8449
  const Icon = action.Icon;
8190
- return /* @__PURE__ */ jsxs30(
8450
+ return /* @__PURE__ */ jsxs32(
8191
8451
  "button",
8192
8452
  {
8193
8453
  type: "button",
8194
8454
  onClick: onJumpToLatest,
8195
8455
  className: "sticky top-0 z-20 mb-4 flex w-full items-center gap-3 rounded-2xl border border-[hsl(var(--primary)/0.2)] bg-[hsl(var(--background)/0.92)] px-4 py-3 text-left shadow-[0_12px_32px_-24px_hsl(var(--foreground)/0.6)] backdrop-blur",
8196
8456
  children: [
8197
- /* @__PURE__ */ jsx35("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl bg-[hsl(var(--primary)/0.12)] text-[hsl(var(--primary))]", children: /* @__PURE__ */ jsx35(Icon, { size: 18, className: Icon === LoaderCircle2 ? "animate-spin" : void 0 }) }),
8198
- /* @__PURE__ */ jsxs30("div", { className: "min-w-0 flex-1", children: [
8199
- /* @__PURE__ */ jsx35("div", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: action.label }),
8200
- /* @__PURE__ */ jsxs30("div", { className: "mt-1 flex flex-wrap items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
8201
- elapsedLabel ? /* @__PURE__ */ jsxs30("span", { className: "font-mono", children: [
8457
+ /* @__PURE__ */ jsx37("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl bg-[hsl(var(--primary)/0.12)] text-[hsl(var(--primary))]", children: /* @__PURE__ */ jsx37(Icon, { size: 18, className: Icon === LoaderCircle2 ? "animate-spin" : void 0 }) }),
8458
+ /* @__PURE__ */ jsxs32("div", { className: "min-w-0 flex-1", children: [
8459
+ /* @__PURE__ */ jsx37("div", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: action.label }),
8460
+ /* @__PURE__ */ jsxs32("div", { className: "mt-1 flex flex-wrap items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
8461
+ elapsedLabel ? /* @__PURE__ */ jsxs32("span", { className: "font-mono", children: [
8202
8462
  "\u5DF2\u6301\u7EED ",
8203
8463
  elapsedLabel
8204
8464
  ] }) : null,
8205
- /* @__PURE__ */ jsx35("span", { children: "\u70B9\u51FB\u8DF3\u5230\u6700\u65B0\u4F4D\u7F6E" })
8465
+ /* @__PURE__ */ jsx37("span", { children: "\u70B9\u51FB\u8DF3\u5230\u6700\u65B0\u4F4D\u7F6E" })
8206
8466
  ] })
8207
8467
  ] })
8208
8468
  ]
@@ -8211,7 +8471,7 @@ function StickyStatusBar({
8211
8471
  }
8212
8472
 
8213
8473
  // src/react/components/chat/TurnNavRail.tsx
8214
- import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
8474
+ import { jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
8215
8475
  function TurnNavRail({
8216
8476
  items,
8217
8477
  activeTurnId,
@@ -8220,14 +8480,14 @@ function TurnNavRail({
8220
8480
  if (items.length < 2) {
8221
8481
  return null;
8222
8482
  }
8223
- return /* @__PURE__ */ jsx36(
8483
+ return /* @__PURE__ */ jsx38(
8224
8484
  "nav",
8225
8485
  {
8226
8486
  "aria-label": "\u56DE\u5408\u5BFC\u822A",
8227
8487
  className: "absolute right-2 top-4 z-10 hidden flex-col items-end gap-0.5 md:flex",
8228
8488
  children: items.map((item, index) => {
8229
8489
  const isActive = item.id === activeTurnId;
8230
- return /* @__PURE__ */ jsxs31(
8490
+ return /* @__PURE__ */ jsxs33(
8231
8491
  "button",
8232
8492
  {
8233
8493
  type: "button",
@@ -8235,8 +8495,8 @@ function TurnNavRail({
8235
8495
  "aria-current": isActive ? "true" : void 0,
8236
8496
  className: "group relative flex h-3.5 items-center",
8237
8497
  children: [
8238
- /* @__PURE__ */ jsx36("span", { className: "pointer-events-none absolute right-full mr-2 hidden max-w-48 truncate whitespace-nowrap rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] px-2.5 py-1.5 text-xs text-[hsl(var(--popover-foreground))] shadow-lg group-hover:block", children: item.title || `\u7B2C ${index + 1} \u8F6E` }),
8239
- /* @__PURE__ */ jsx36(
8498
+ /* @__PURE__ */ jsx38("span", { className: "pointer-events-none absolute right-full mr-2 hidden max-w-48 truncate whitespace-nowrap rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] px-2.5 py-1.5 text-xs text-[hsl(var(--popover-foreground))] shadow-lg group-hover:block", children: item.title || `\u7B2C ${index + 1} \u8F6E` }),
8499
+ /* @__PURE__ */ jsx38(
8240
8500
  "span",
8241
8501
  {
8242
8502
  className: cn(
@@ -8270,7 +8530,7 @@ function calculateAnchoredScrollTop({
8270
8530
  }
8271
8531
 
8272
8532
  // src/react/components/chat/MessageList.tsx
8273
- import { jsx as jsx37, jsxs as jsxs32 } from "react/jsx-runtime";
8533
+ import { jsx as jsx39, jsxs as jsxs34 } from "react/jsx-runtime";
8274
8534
  function parseModeChange(message) {
8275
8535
  if (message.kind !== "mode_change" || typeof message.content !== "string") {
8276
8536
  return null;
@@ -8366,10 +8626,10 @@ function MessageList({
8366
8626
  const agentLoops = useChatStore((state) => state.agentLoops[sessionId]);
8367
8627
  const askAnswers = useChatStore((state) => state.askAnswers[sessionId]);
8368
8628
  const sessionIsStreaming = useChatStore((state) => !!state.isStreaming[sessionId]);
8369
- const agentLoopNameSet = useMemo18(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops]);
8629
+ const agentLoopNameSet = useMemo19(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops]);
8370
8630
  const assistantMessagesCacheRef = useRef13(/* @__PURE__ */ new Map());
8371
8631
  const stickContextRef = useRef13(null);
8372
- const renderBlocks = useMemo18(() => {
8632
+ const renderBlocks = useMemo19(() => {
8373
8633
  const stableAssistantMessages = (key, buffer) => {
8374
8634
  const previous = assistantMessagesCacheRef.current.get(key);
8375
8635
  if (previous && previous.length === buffer.length && previous.every((message, index) => message === buffer[index])) {
@@ -8461,13 +8721,13 @@ function MessageList({
8461
8721
  }
8462
8722
  return blocks;
8463
8723
  }, [agentLoopNameSet, messages, sessionIsStreaming]);
8464
- const hasInterruptedTurn = useMemo18(
8724
+ const hasInterruptedTurn = useMemo19(
8465
8725
  () => renderBlocks.some(
8466
8726
  (block) => block.type === "assistant_turn" && block.messages.some((message) => message.status === "interrupted")
8467
8727
  ),
8468
8728
  [renderBlocks]
8469
8729
  );
8470
- const lastTurnId = useMemo18(() => {
8730
+ const lastTurnId = useMemo19(() => {
8471
8731
  for (let index = renderBlocks.length - 1; index >= 0; index -= 1) {
8472
8732
  const block = renderBlocks[index];
8473
8733
  if (block.type === "assistant_turn") return block.anchorId;
@@ -8475,20 +8735,20 @@ function MessageList({
8475
8735
  }
8476
8736
  return null;
8477
8737
  }, [renderBlocks]);
8478
- const turnNavItems = useMemo18(
8738
+ const turnNavItems = useMemo19(
8479
8739
  () => renderBlocks.filter((block) => block.type === "assistant_turn").map((block) => ({
8480
8740
  id: block.anchorId,
8481
8741
  title: block.railTitle
8482
8742
  })),
8483
8743
  [renderBlocks]
8484
8744
  );
8485
- const stickyTurn = useMemo18(
8745
+ const stickyTurn = useMemo19(
8486
8746
  () => renderBlocks.find(
8487
8747
  (block) => block.type === "assistant_turn" && block.anchorId === lastTurnId && block.isStreaming
8488
8748
  ) ?? null,
8489
8749
  [lastTurnId, renderBlocks]
8490
8750
  );
8491
- const scrollEntryId = useMemo18(() => normalizeScrollEntryKey(scrollToEntryKey), [scrollToEntryKey]);
8751
+ const scrollEntryId = useMemo19(() => normalizeScrollEntryKey(scrollToEntryKey), [scrollToEntryKey]);
8492
8752
  const shouldAnchorEntry = Boolean(scrollEntryId);
8493
8753
  const hasMessages = messages.length > 0;
8494
8754
  const containerRef = useRef13(null);
@@ -8500,8 +8760,8 @@ function MessageList({
8500
8760
  const entryScrollTimeoutRefs = useRef13([]);
8501
8761
  const appliedStartScrollKeyRef = useRef13(null);
8502
8762
  const appliedEntryScrollKeyRef = useRef13(null);
8503
- const [activeTurnId, setActiveTurnId] = useState21(lastTurnId);
8504
- const layoutSignature = useMemo18(
8763
+ const [activeTurnId, setActiveTurnId] = useState22(lastTurnId);
8764
+ const layoutSignature = useMemo19(
8505
8765
  () => getMessagesMeasureSignature(messages),
8506
8766
  [messages]
8507
8767
  );
@@ -8680,13 +8940,13 @@ function MessageList({
8680
8940
  const handleSelectTurn = useCallback12((turnId) => {
8681
8941
  document.getElementById(turnId)?.scrollIntoView({ behavior: "smooth", block: "start" });
8682
8942
  }, []);
8683
- return /* @__PURE__ */ jsxs32(
8943
+ return /* @__PURE__ */ jsxs34(
8684
8944
  "div",
8685
8945
  {
8686
8946
  ref: containerRef,
8687
8947
  className: `relative min-h-0 flex-1 ${customization?.classNames?.messageListRoot ?? ""}`,
8688
8948
  children: [
8689
- turnNavItems.length > 1 ? /* @__PURE__ */ jsx37(
8949
+ turnNavItems.length > 1 ? /* @__PURE__ */ jsx39(
8690
8950
  TurnNavRail,
8691
8951
  {
8692
8952
  items: turnNavItems,
@@ -8694,7 +8954,7 @@ function MessageList({
8694
8954
  onSelectTurn: handleSelectTurn
8695
8955
  }
8696
8956
  ) : null,
8697
- /* @__PURE__ */ jsxs32(
8957
+ /* @__PURE__ */ jsxs34(
8698
8958
  StickToBottom,
8699
8959
  {
8700
8960
  contextRef: stickContextRef,
@@ -8703,7 +8963,7 @@ function MessageList({
8703
8963
  resize: stickyTurn ? { damping: 0.8, stiffness: 0.08, mass: 1 } : "instant",
8704
8964
  targetScrollTop: shouldAnchorEntry ? getAnchorTargetScrollTop : void 0,
8705
8965
  children: [
8706
- /* @__PURE__ */ jsx37(StickToBottom.Content, { className: "px-5 py-6", children: /* @__PURE__ */ jsx37(
8966
+ /* @__PURE__ */ jsx39(StickToBottom.Content, { className: "px-5 pb-7 pt-8 sm:px-10 sm:pt-10", children: /* @__PURE__ */ jsx39(
8707
8967
  MessageListContent,
8708
8968
  {
8709
8969
  askAnswers,
@@ -8720,7 +8980,7 @@ function MessageList({
8720
8980
  customization
8721
8981
  }
8722
8982
  ) }),
8723
- /* @__PURE__ */ jsx37(ScrollToBottomButton, {})
8983
+ /* @__PURE__ */ jsx39(ScrollToBottomButton, {})
8724
8984
  ]
8725
8985
  },
8726
8986
  scrollEntryId ?? "latest"
@@ -8751,8 +9011,8 @@ function MessageListContent({
8751
9011
  }
8752
9012
  scrollToBottom();
8753
9013
  }, [lastTurnId, scrollToBottom]);
8754
- return /* @__PURE__ */ jsx37("div", { className: `mx-auto max-w-3xl ${customization?.classNames?.messageListContent ?? ""}`, children: /* @__PURE__ */ jsxs32("div", { className: `min-w-0 flex flex-col gap-8 ${customization?.classNames?.messageListInner ?? ""}`, children: [
8755
- stickyTurn ? /* @__PURE__ */ jsx37(
9014
+ return /* @__PURE__ */ jsx39("div", { className: `mx-auto max-w-[748px] ${customization?.classNames?.messageListContent ?? ""}`, children: /* @__PURE__ */ jsxs34("div", { className: `min-w-0 flex flex-col gap-9 ${customization?.classNames?.messageListInner ?? ""}`, children: [
9015
+ stickyTurn ? /* @__PURE__ */ jsx39(
8756
9016
  StickyStatusBar,
8757
9017
  {
8758
9018
  sessionId,
@@ -8762,37 +9022,37 @@ function MessageListContent({
8762
9022
  onJumpToLatest: handleJumpToLatest
8763
9023
  }
8764
9024
  ) : null,
8765
- renderBlocks.length === 0 ? customization?.components?.EmptyState ? /* @__PURE__ */ jsx37(customization.components.EmptyState, {}) : /* @__PURE__ */ jsxs32("div", { className: `flex flex-col items-center justify-center gap-3 py-24 text-[hsl(var(--muted-foreground))] ${customization?.classNames?.emptyState ?? ""}`, children: [
8766
- /* @__PURE__ */ jsx37(MessageSquare, { size: 40, strokeWidth: 1.5 }),
8767
- /* @__PURE__ */ jsx37("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
8768
- /* @__PURE__ */ jsx37("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
9025
+ renderBlocks.length === 0 ? customization?.components?.EmptyState ? /* @__PURE__ */ jsx39(customization.components.EmptyState, {}) : /* @__PURE__ */ jsxs34("div", { className: `flex flex-col items-center justify-center gap-3 py-24 text-[hsl(var(--muted-foreground))] ${customization?.classNames?.emptyState ?? ""}`, children: [
9026
+ /* @__PURE__ */ jsx39(MessageSquare, { size: 40, strokeWidth: 1.5 }),
9027
+ /* @__PURE__ */ jsx39("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
9028
+ /* @__PURE__ */ jsx39("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
8769
9029
  ] }) : renderBlocks.map((block, blockIndex) => {
8770
9030
  if (block.type === "message") {
8771
- return /* @__PURE__ */ jsx37(
9031
+ return /* @__PURE__ */ jsx39(
8772
9032
  "div",
8773
9033
  {
8774
9034
  id: block.anchorId ?? void 0,
8775
9035
  "data-entry-id": block.message.entry_id,
8776
9036
  className: "msg-animate scroll-mt-6",
8777
- children: isUserMessage(block.message) ? customization?.components?.UserMessage ? /* @__PURE__ */ jsx37(
9037
+ children: isUserMessage(block.message) ? customization?.components?.UserMessage ? /* @__PURE__ */ jsx39(
8778
9038
  customization.components.UserMessage,
8779
9039
  {
8780
9040
  message: block.message,
8781
9041
  className: customization.classNames?.userMessage
8782
9042
  }
8783
- ) : /* @__PURE__ */ jsx37(
9043
+ ) : /* @__PURE__ */ jsx39(
8784
9044
  UserMessageBubble,
8785
9045
  {
8786
9046
  message: block.message,
8787
9047
  className: customization?.classNames?.userMessage
8788
9048
  }
8789
- ) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */ jsx37(
9049
+ ) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */ jsx39(
8790
9050
  customization.components.ErrorMessage,
8791
9051
  {
8792
9052
  message: block.message,
8793
9053
  className: customization.classNames?.errorMessage
8794
9054
  }
8795
- ) : /* @__PURE__ */ jsx37(
9055
+ ) : /* @__PURE__ */ jsx39(
8796
9056
  ErrorMessageBlock,
8797
9057
  {
8798
9058
  message: block.message,
@@ -8812,7 +9072,7 @@ function MessageListContent({
8812
9072
  );
8813
9073
  const isFollowedByPlanningExit = nextBlock?.type === "planning_divider" && nextBlock.kind === "exit";
8814
9074
  const showPlanCard = (hasExitPlan || isFollowedByPlanningExit) && onConfirmPlan && sessionStatus === "waiting_for_input";
8815
- return /* @__PURE__ */ jsxs32(
9075
+ return /* @__PURE__ */ jsxs34(
8816
9076
  "div",
8817
9077
  {
8818
9078
  id: block.anchorId,
@@ -8820,13 +9080,13 @@ function MessageListContent({
8820
9080
  "data-entry-id": block.messages[0]?.entry_id,
8821
9081
  className: "msg-animate flex scroll-mt-6 flex-col gap-4",
8822
9082
  children: [
8823
- /* @__PURE__ */ jsx37(
9083
+ /* @__PURE__ */ jsx39(
8824
9084
  RenderErrorBoundary,
8825
9085
  {
8826
9086
  label: "\u52A9\u624B\u6D88\u606F",
8827
9087
  details: block.key,
8828
9088
  resetKey: getMessagesResetSignature(block.messages),
8829
- children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx37(
9089
+ children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx39(
8830
9090
  customization.components.AssistantTurn,
8831
9091
  {
8832
9092
  turnKey: block.key,
@@ -8839,7 +9099,7 @@ function MessageListContent({
8839
9099
  sessionStatus,
8840
9100
  customization
8841
9101
  }
8842
- ) : /* @__PURE__ */ jsx37(
9102
+ ) : /* @__PURE__ */ jsx39(
8843
9103
  AssistantTurnBlock,
8844
9104
  {
8845
9105
  turnKey: block.key,
@@ -8855,13 +9115,13 @@ function MessageListContent({
8855
9115
  )
8856
9116
  }
8857
9117
  ),
8858
- showPlanCard ? /* @__PURE__ */ jsx37(
9118
+ showPlanCard ? /* @__PURE__ */ jsx39(
8859
9119
  RenderErrorBoundary,
8860
9120
  {
8861
9121
  label: "\u89C4\u5212\u6458\u8981",
8862
9122
  details: block.key,
8863
9123
  resetKey: `${sessionStatus ?? ""}:${layoutSignature}`,
8864
- children: /* @__PURE__ */ jsx37(
9124
+ children: /* @__PURE__ */ jsx39(
8865
9125
  PlanSummaryCard,
8866
9126
  {
8867
9127
  messages: extractLatestPlanMessages(messages),
@@ -8877,7 +9137,7 @@ function MessageListContent({
8877
9137
  );
8878
9138
  }
8879
9139
  if (block.type === "compaction") {
8880
- return /* @__PURE__ */ jsx37("div", { className: "msg-animate", children: /* @__PURE__ */ jsx37(
9140
+ return /* @__PURE__ */ jsx39("div", { className: "msg-animate", children: /* @__PURE__ */ jsx39(
8881
9141
  CompactionCard,
8882
9142
  {
8883
9143
  sessionId,
@@ -8886,41 +9146,41 @@ function MessageListContent({
8886
9146
  }
8887
9147
  ) }, block.key);
8888
9148
  }
8889
- return /* @__PURE__ */ jsx37(PlanningDivider, { kind: block.kind }, block.key);
9149
+ return /* @__PURE__ */ jsx39(PlanningDivider, { kind: block.kind }, block.key);
8890
9150
  }),
8891
- sessionStatus === "interrupted" && !hasInterruptedTurn ? /* @__PURE__ */ jsx37("div", { className: "flex", children: /* @__PURE__ */ jsx37("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
9151
+ sessionStatus === "interrupted" && !hasInterruptedTurn ? /* @__PURE__ */ jsx39("div", { className: "flex", children: /* @__PURE__ */ jsx39("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
8892
9152
  ] }) });
8893
9153
  }
8894
9154
  function ScrollToBottomButton() {
8895
9155
  const { isAtBottom, scrollToBottom } = useStickToBottomContext();
8896
9156
  if (isAtBottom) return null;
8897
- return /* @__PURE__ */ jsxs32(
9157
+ return /* @__PURE__ */ jsxs34(
8898
9158
  "button",
8899
9159
  {
8900
9160
  type: "button",
8901
9161
  onClick: () => scrollToBottom(),
8902
9162
  className: "absolute bottom-4 right-4 flex items-center gap-1 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-1.5 text-xs text-[hsl(var(--muted-foreground))] shadow-lg transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
8903
9163
  children: [
8904
- /* @__PURE__ */ jsx37(ChevronDown3, { size: 14 }),
8905
- /* @__PURE__ */ jsx37("span", { children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
9164
+ /* @__PURE__ */ jsx39(ChevronDown4, { size: 14 }),
9165
+ /* @__PURE__ */ jsx39("span", { children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
8906
9166
  ]
8907
9167
  }
8908
9168
  );
8909
9169
  }
8910
9170
  function PlanningDivider({ kind }) {
8911
9171
  const isEnter = kind === "enter";
8912
- return /* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-3 py-1", children: [
8913
- /* @__PURE__ */ jsx37("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
8914
- /* @__PURE__ */ jsxs32("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: [
8915
- /* @__PURE__ */ jsx37(Lightbulb2, { size: 12 }),
8916
- /* @__PURE__ */ jsx37("span", { children: isEnter ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
9172
+ return /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-3 py-1", children: [
9173
+ /* @__PURE__ */ jsx39("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
9174
+ /* @__PURE__ */ jsxs34("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: [
9175
+ /* @__PURE__ */ jsx39(Lightbulb2, { size: 12 }),
9176
+ /* @__PURE__ */ jsx39("span", { children: isEnter ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
8917
9177
  ] }),
8918
- /* @__PURE__ */ jsx37("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
9178
+ /* @__PURE__ */ jsx39("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
8919
9179
  ] });
8920
9180
  }
8921
9181
 
8922
9182
  // src/react/components/chat/ChatView.tsx
8923
- import { jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
9183
+ import { jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
8924
9184
  function ChatView({
8925
9185
  sessionId,
8926
9186
  renderAttachments,
@@ -8965,22 +9225,22 @@ function ChatView({
8965
9225
  },
8966
9226
  [send]
8967
9227
  );
8968
- const customization = useMemo19(
9228
+ const customization = useMemo20(
8969
9229
  () => ({ classNames, components, renderers }),
8970
9230
  [classNames, components, renderers]
8971
9231
  );
8972
9232
  const SkillStatus = components?.SkillStatusBar;
8973
- return /* @__PURE__ */ jsxs33("div", { className: `flex min-h-0 flex-1 flex-col overflow-hidden ${classNames?.root ?? ""}`, children: [
8974
- isViewer && /* @__PURE__ */ jsxs33("div", { className: `flex items-center justify-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--card))] py-2 text-xs text-[hsl(var(--muted-foreground))] ${classNames?.viewerBanner ?? ""}`, children: [
8975
- /* @__PURE__ */ jsx38(Eye, { size: 14 }),
9233
+ return /* @__PURE__ */ jsxs35("div", { className: `flex min-h-0 flex-1 flex-col overflow-hidden ${classNames?.root ?? ""}`, children: [
9234
+ isViewer && /* @__PURE__ */ jsxs35("div", { className: `flex items-center justify-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--card))] py-2 text-xs text-[hsl(var(--muted-foreground))] ${classNames?.viewerBanner ?? ""}`, children: [
9235
+ /* @__PURE__ */ jsx40(Eye, { size: 14 }),
8976
9236
  "\u4F60\u6B63\u5728\u67E5\u770B\u5206\u4EAB\u7684\u4F1A\u8BDD\uFF08\u53EA\u8BFB\uFF09"
8977
9237
  ] }),
8978
- !isViewer && /* @__PURE__ */ jsx38(ConnectionBanner, {}),
8979
- errorMessage && /* @__PURE__ */ jsxs33("div", { className: "flex items-start gap-2 border-b border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800 dark:border-red-800/30 dark:bg-red-950/30 dark:text-red-300", children: [
8980
- /* @__PURE__ */ jsx38(CircleAlert2, { size: 16, className: "mt-0.5 shrink-0" }),
8981
- /* @__PURE__ */ jsx38("span", { children: errorMessage })
9238
+ !isViewer && /* @__PURE__ */ jsx40(ConnectionBanner, {}),
9239
+ errorMessage && /* @__PURE__ */ jsxs35("div", { className: "flex items-start gap-2 border-b border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800 dark:border-red-800/30 dark:bg-red-950/30 dark:text-red-300", children: [
9240
+ /* @__PURE__ */ jsx40(CircleAlert2, { size: 16, className: "mt-0.5 shrink-0" }),
9241
+ /* @__PURE__ */ jsx40("span", { children: errorMessage })
8982
9242
  ] }),
8983
- /* @__PURE__ */ jsx38(
9243
+ /* @__PURE__ */ jsx40(
8984
9244
  MessageList,
8985
9245
  {
8986
9246
  sessionId,
@@ -8994,7 +9254,7 @@ function ChatView({
8994
9254
  },
8995
9255
  sessionId
8996
9256
  ),
8997
- !isViewer && /* @__PURE__ */ jsx38(
9257
+ !isViewer && /* @__PURE__ */ jsx40(
8998
9258
  ChatInput,
8999
9259
  {
9000
9260
  onSend: (msg, options) => send(msg, mode, void 0, {
@@ -9053,6 +9313,7 @@ export {
9053
9313
  skillMentionSuggestionKey,
9054
9314
  SkillMention,
9055
9315
  ThinkingToggle,
9316
+ PlanningToggle,
9056
9317
  ChatInput,
9057
9318
  ResourceIframe,
9058
9319
  ImageLightbox,
@@ -9079,4 +9340,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
9079
9340
  * Licensed under the MIT License. See License.txt in the project root for license information.
9080
9341
  *--------------------------------------------------------------------------------------------*)
9081
9342
  */
9082
- //# sourceMappingURL=chunk-3XDPNPE3.js.map
9343
+ //# sourceMappingURL=chunk-RAWQ7LWR.js.map