@blade-hq/agent-kit 0.4.23 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,13 +8,13 @@ import {
8
8
  getCodeLanguageFromFilename,
9
9
  parseAskUserQuestion,
10
10
  useHighlightedCodeHtml
11
- } from "./chunk-WZT2DOBJ.js";
11
+ } from "./chunk-DAFIIANJ.js";
12
12
  import {
13
13
  Collapsible,
14
14
  CollapsibleContent,
15
15
  CollapsibleTrigger,
16
16
  resolveSessionFilePreviewTarget
17
- } from "./chunk-47YVQZQ7.js";
17
+ } from "./chunk-UPHYN7CQ.js";
18
18
  import {
19
19
  buildMessageContent,
20
20
  buildToolPreviewKey,
@@ -23,6 +23,7 @@ import {
23
23
  extractToolFilePath,
24
24
  formatToolName,
25
25
  getAuthedUrl,
26
+ getBackgroundTask,
26
27
  getClient,
27
28
  getFileParts,
28
29
  getImageParts,
@@ -56,7 +57,7 @@ import {
56
57
  useUiBridgeStore,
57
58
  useUiStore,
58
59
  writeFile
59
- } from "./chunk-LKNU4NUC.js";
60
+ } from "./chunk-DSBIKYKQ.js";
60
61
  import {
61
62
  registerBridgeIframe,
62
63
  tapBridgeEvent
@@ -152,7 +153,7 @@ import {
152
153
  ChevronDown,
153
154
  File as File2,
154
155
  FileCode2,
155
- FileText,
156
+ FileText as FileText2,
156
157
  Film,
157
158
  FolderUp,
158
159
  CircleHelp,
@@ -171,7 +172,7 @@ import {
171
172
  Send,
172
173
  Sparkles as Sparkles2,
173
174
  Share2,
174
- Square,
175
+ Square as Square2,
175
176
  X as X2
176
177
  } from "lucide-react";
177
178
  import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
@@ -180,7 +181,7 @@ import {
180
181
  useEffectEvent as useEffectEvent2,
181
182
  useMemo as useMemo7,
182
183
  useRef as useRef4,
183
- useState as useState6
184
+ useState as useState7
184
185
  } from "react";
185
186
  import { createRoot } from "react-dom/client";
186
187
  import { toast } from "sonner";
@@ -1258,11 +1259,177 @@ var SkillCompletionMenu = forwardRef2(
1258
1259
  }
1259
1260
  );
1260
1261
 
1262
+ // src/react/components/chat/BackgroundTasksPill.tsx
1263
+ import { FileText, Square, Terminal } from "lucide-react";
1264
+ import { useState as useState6 } from "react";
1265
+
1266
+ // src/react/hooks/use-background-tasks.ts
1267
+ import { useQuery as useQuery2 } from "@tanstack/react-query";
1268
+ var EMPTY_TASKS = [];
1269
+ function useBackgroundTasks(sessionId) {
1270
+ const setTasks = useBackgroundStore((state) => state.setTasks);
1271
+ const tasks = useBackgroundStore((state) => sessionId ? state.tasks[sessionId] : void 0);
1272
+ const query = useQuery2({
1273
+ queryKey: ["background-tasks", sessionId],
1274
+ queryFn: ({ signal }) => listBackgroundTasks(sessionId, { signal }).then((items) => {
1275
+ setTasks(sessionId, items);
1276
+ return items;
1277
+ }),
1278
+ enabled: Boolean(sessionId)
1279
+ });
1280
+ return {
1281
+ data: tasks ?? query.data ?? EMPTY_TASKS,
1282
+ loading: query.isLoading,
1283
+ error: query.error,
1284
+ refetch: query.refetch
1285
+ };
1286
+ }
1287
+
1288
+ // src/react/components/chat/BackgroundTasksPill.tsx
1289
+ import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1290
+ function formatStartedAt(value) {
1291
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
1292
+ return "\u542F\u52A8\u65F6\u95F4\u672A\u77E5";
1293
+ }
1294
+ return new Intl.DateTimeFormat("zh-CN", {
1295
+ hour: "2-digit",
1296
+ minute: "2-digit"
1297
+ }).format(new Date(value * 1e3));
1298
+ }
1299
+ function statusLabel(status) {
1300
+ if (status === "running") return "\u8FD0\u884C\u4E2D";
1301
+ if (status === "failed") return "\u5931\u8D25";
1302
+ if (status === "cancelled") return "\u5DF2\u505C\u6B62";
1303
+ if (status === "done" || status === "succeeded") return "\u5DF2\u7ED3\u675F";
1304
+ return status || "\u672A\u77E5";
1305
+ }
1306
+ function statusClass(status) {
1307
+ if (status === "running") return "border-amber-500/35 bg-amber-500/10 text-amber-500";
1308
+ if (status === "failed") return "border-rose-500/35 bg-rose-500/10 text-rose-500";
1309
+ return "border-[hsl(var(--border))] bg-[hsl(var(--muted))]/40 text-[hsl(var(--muted-foreground))]";
1310
+ }
1311
+ function BackgroundTasksPill({ sessionId }) {
1312
+ const { data: tasks } = useBackgroundTasks(sessionId);
1313
+ const [open, setOpen] = useState6(false);
1314
+ const [logTask, setLogTask] = useState6(null);
1315
+ if (tasks.length === 0) return null;
1316
+ const runningCount = tasks.filter((task) => task.status === "running").length;
1317
+ const openTaskLog = async (task) => {
1318
+ const title = `${task.id} ${task.description || task.command || "\u540E\u53F0\u4EFB\u52A1"}`;
1319
+ setLogTask({ id: task.id, title, output: "", loading: true, error: null });
1320
+ try {
1321
+ const detail = await getBackgroundTask(sessionId, task.id, 300);
1322
+ setLogTask({
1323
+ id: task.id,
1324
+ title,
1325
+ output: detail.output || "\u6682\u65E0\u8F93\u51FA",
1326
+ loading: false,
1327
+ error: null
1328
+ });
1329
+ } catch (error) {
1330
+ setLogTask({
1331
+ id: task.id,
1332
+ title,
1333
+ output: "",
1334
+ loading: false,
1335
+ error: error instanceof Error ? error.message : "\u65E5\u5FD7\u52A0\u8F7D\u5931\u8D25"
1336
+ });
1337
+ }
1338
+ };
1339
+ const requestStopTask = (task) => {
1340
+ const name = `${task.id}\uFF08${task.description || task.command || "\u540E\u53F0\u4EFB\u52A1"}\uFF09`;
1341
+ getSocket().send(
1342
+ sessionId,
1343
+ `\u8BF7\u5148\u5411\u6211\u4E8C\u6B21\u786E\u8BA4\uFF0C\u7136\u540E\u5E2E\u6211\u505C\u6B62\u540E\u53F0\u4EFB\u52A1 ${name}\u3002`,
1344
+ "executing"
1345
+ );
1346
+ setOpen(false);
1347
+ };
1348
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
1349
+ logTask ? /* @__PURE__ */ jsx5("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/55 p-4", children: /* @__PURE__ */ jsxs4("div", { className: "flex max-h-[82vh] w-full max-w-3xl flex-col overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-2xl", children: [
1350
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-3", children: [
1351
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
1352
+ /* @__PURE__ */ jsx5("div", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: logTask.title }),
1353
+ /* @__PURE__ */ jsx5("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u540E\u53F0\u4EFB\u52A1\u65E5\u5FD7" })
1354
+ ] }),
1355
+ /* @__PURE__ */ jsx5(
1356
+ "button",
1357
+ {
1358
+ type: "button",
1359
+ onClick: () => setLogTask(null),
1360
+ className: "rounded-md border border-[hsl(var(--border))] px-2.5 py-1 text-xs text-[hsl(var(--foreground))] hover:bg-[hsl(var(--accent))]",
1361
+ children: "\u5173\u95ED"
1362
+ }
1363
+ )
1364
+ ] }),
1365
+ /* @__PURE__ */ jsx5("pre", { className: "min-h-64 flex-1 overflow-auto whitespace-pre-wrap p-4 font-mono text-xs leading-5 text-[hsl(var(--foreground))]", children: logTask.loading ? "\u52A0\u8F7D\u4E2D..." : logTask.error || logTask.output })
1366
+ ] }) }) : null,
1367
+ /* @__PURE__ */ jsxs4("div", { className: "relative mb-2 flex justify-start", children: [
1368
+ /* @__PURE__ */ jsxs4(
1369
+ "button",
1370
+ {
1371
+ type: "button",
1372
+ onClick: () => setOpen((value) => !value),
1373
+ className: cn(
1374
+ "inline-flex h-8 items-center gap-2 rounded-full border px-3 text-xs font-medium shadow-sm transition-colors",
1375
+ runningCount > 0 ? "border-amber-500/35 bg-amber-500/10 text-amber-600" : "border-[hsl(var(--border))] bg-[hsl(var(--card))] text-[hsl(var(--muted-foreground))]"
1376
+ ),
1377
+ children: [
1378
+ /* @__PURE__ */ jsx5(Terminal, { size: 13 }),
1379
+ "\u540E\u53F0\u4EFB\u52A1 ",
1380
+ tasks.length,
1381
+ runningCount > 0 ? /* @__PURE__ */ jsxs4("span", { children: [
1382
+ "\u8FD0\u884C\u4E2D ",
1383
+ runningCount
1384
+ ] }) : null
1385
+ ]
1386
+ }
1387
+ ),
1388
+ open ? /* @__PURE__ */ jsx5("div", { className: "absolute bottom-full left-0 z-40 mb-2 w-[min(24rem,calc(100vw-2rem))] rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-2 text-xs text-[hsl(var(--popover-foreground))] shadow-xl", children: /* @__PURE__ */ jsx5("div", { className: "max-h-72 space-y-2 overflow-y-auto", children: tasks.map((task) => /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-[hsl(var(--border))] p-2", children: [
1389
+ /* @__PURE__ */ jsx5("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
1390
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1391
+ /* @__PURE__ */ jsx5("span", { className: "font-mono font-semibold", children: task.id }),
1392
+ /* @__PURE__ */ jsx5("span", { className: cn("rounded-full border px-1.5 py-0.5 text-[10px]", statusClass(task.status)), children: statusLabel(task.status) })
1393
+ ] }),
1394
+ /* @__PURE__ */ jsx5("div", { className: "mt-1 break-words text-[hsl(var(--foreground))]", children: task.description || task.command }),
1395
+ /* @__PURE__ */ jsx5("div", { className: "mt-1 text-[11px] text-[hsl(var(--muted-foreground))]", children: formatStartedAt(task.started_at) })
1396
+ ] }) }),
1397
+ /* @__PURE__ */ jsxs4("div", { className: "mt-2 flex items-center gap-1.5", children: [
1398
+ /* @__PURE__ */ jsxs4(
1399
+ "button",
1400
+ {
1401
+ type: "button",
1402
+ onClick: () => void openTaskLog(task),
1403
+ className: "inline-flex h-6 items-center gap-1 rounded-md border border-[hsl(var(--border))] px-2 text-[11px] hover:bg-[hsl(var(--accent))]",
1404
+ children: [
1405
+ /* @__PURE__ */ jsx5(FileText, { size: 11 }),
1406
+ "\u65E5\u5FD7"
1407
+ ]
1408
+ }
1409
+ ),
1410
+ task.status === "running" ? /* @__PURE__ */ jsxs4(
1411
+ "button",
1412
+ {
1413
+ type: "button",
1414
+ onClick: () => requestStopTask(task),
1415
+ className: "inline-flex h-6 items-center gap-1 rounded-md border border-rose-500/35 px-2 text-[11px] text-rose-500 hover:bg-rose-500/10",
1416
+ children: [
1417
+ /* @__PURE__ */ jsx5(Square, { size: 10 }),
1418
+ "\u505C\u6B62"
1419
+ ]
1420
+ }
1421
+ ) : null
1422
+ ] })
1423
+ ] }, task.id)) }) }) : null
1424
+ ] })
1425
+ ] });
1426
+ }
1427
+
1261
1428
  // src/react/components/chat/FileSizeLimitDialog.tsx
1262
1429
  import { X } from "lucide-react";
1263
1430
  import { useEffect as useEffect6 } from "react";
1264
1431
  import { createPortal } from "react-dom";
1265
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1432
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1266
1433
  function FileSizeLimitDialog({
1267
1434
  open,
1268
1435
  onOpenChange,
@@ -1284,7 +1451,7 @@ function FileSizeLimitDialog({
1284
1451
  }
1285
1452
  const limitText = formatFileSize(limitBytes);
1286
1453
  return createPortal(
1287
- /* @__PURE__ */ jsx5(
1454
+ /* @__PURE__ */ jsx6(
1288
1455
  "div",
1289
1456
  {
1290
1457
  className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",
@@ -1297,45 +1464,45 @@ function FileSizeLimitDialog({
1297
1464
  role: "dialog",
1298
1465
  "aria-modal": "true",
1299
1466
  "aria-labelledby": "file-size-limit-dialog-title",
1300
- children: /* @__PURE__ */ jsxs4(
1467
+ children: /* @__PURE__ */ jsxs5(
1301
1468
  "div",
1302
1469
  {
1303
1470
  className: "w-full max-w-lg overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--background))] shadow-2xl",
1304
1471
  onClick: (event) => event.stopPropagation(),
1305
1472
  onKeyDown: (event) => event.stopPropagation(),
1306
1473
  children: [
1307
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
1308
- /* @__PURE__ */ jsxs4("div", { children: [
1309
- /* @__PURE__ */ jsx5("h3", { id: "file-size-limit-dialog-title", className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u9644\u4EF6\u8D85\u8FC7\u5927\u5C0F\u9650\u5236" }),
1310
- /* @__PURE__ */ jsxs4("p", { className: "mt-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
1474
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
1475
+ /* @__PURE__ */ jsxs5("div", { children: [
1476
+ /* @__PURE__ */ jsx6("h3", { id: "file-size-limit-dialog-title", className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u9644\u4EF6\u8D85\u8FC7\u5927\u5C0F\u9650\u5236" }),
1477
+ /* @__PURE__ */ jsxs5("p", { className: "mt-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
1311
1478
  "\u5355\u4E2A\u9644\u4EF6\u6700\u5927\u652F\u6301 ",
1312
1479
  limitText,
1313
1480
  "\u3002\u4EE5\u4E0B\u6587\u4EF6\u672A\u52A0\u5165\u9644\u4EF6\u5217\u8868\u3002"
1314
1481
  ] })
1315
1482
  ] }),
1316
- /* @__PURE__ */ jsx5(
1483
+ /* @__PURE__ */ jsx6(
1317
1484
  "button",
1318
1485
  {
1319
1486
  type: "button",
1320
1487
  onClick: () => onOpenChange(false),
1321
1488
  title: "\u5173\u95ED",
1322
1489
  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))]",
1323
- children: /* @__PURE__ */ jsx5(X, { size: 14 })
1490
+ children: /* @__PURE__ */ jsx6(X, { size: 14 })
1324
1491
  }
1325
1492
  )
1326
1493
  ] }),
1327
- /* @__PURE__ */ jsx5("div", { className: "max-h-[min(50vh,24rem)] overflow-auto px-4 py-3", children: /* @__PURE__ */ jsx5("div", { className: "flex flex-col gap-2", children: files.map((file) => /* @__PURE__ */ jsxs4(
1494
+ /* @__PURE__ */ jsx6("div", { className: "max-h-[min(50vh,24rem)] overflow-auto px-4 py-3", children: /* @__PURE__ */ jsx6("div", { className: "flex flex-col gap-2", children: files.map((file) => /* @__PURE__ */ jsxs5(
1328
1495
  "div",
1329
1496
  {
1330
1497
  className: "flex items-center justify-between gap-3 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-3 py-2",
1331
1498
  children: [
1332
- /* @__PURE__ */ jsx5("span", { className: "min-w-0 truncate text-sm text-[hsl(var(--foreground))]", children: file.name }),
1333
- /* @__PURE__ */ jsx5("span", { className: "shrink-0 text-xs text-[hsl(var(--muted-foreground))]", children: formatFileSize(file.size) })
1499
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 truncate text-sm text-[hsl(var(--foreground))]", children: file.name }),
1500
+ /* @__PURE__ */ jsx6("span", { className: "shrink-0 text-xs text-[hsl(var(--muted-foreground))]", children: formatFileSize(file.size) })
1334
1501
  ]
1335
1502
  },
1336
1503
  `${file.name}:${file.size}`
1337
1504
  )) }) }),
1338
- /* @__PURE__ */ jsx5("div", { className: "flex justify-end border-t border-[hsl(var(--border))] px-4 py-3", children: /* @__PURE__ */ jsx5(
1505
+ /* @__PURE__ */ jsx6("div", { className: "flex justify-end border-t border-[hsl(var(--border))] px-4 py-3", children: /* @__PURE__ */ jsx6(
1339
1506
  "button",
1340
1507
  {
1341
1508
  type: "button",
@@ -1358,28 +1525,6 @@ import { useQuery as useQuery5 } from "@tanstack/react-query";
1358
1525
  import { RefreshCw } from "lucide-react";
1359
1526
  import { useMemo as useMemo6 } from "react";
1360
1527
 
1361
- // src/react/hooks/use-background-tasks.ts
1362
- import { useQuery as useQuery2 } from "@tanstack/react-query";
1363
- var EMPTY_TASKS = [];
1364
- function useBackgroundTasks(sessionId) {
1365
- const setTasks = useBackgroundStore((state) => state.setTasks);
1366
- const tasks = useBackgroundStore((state) => sessionId ? state.tasks[sessionId] : void 0);
1367
- const query = useQuery2({
1368
- queryKey: ["background-tasks", sessionId],
1369
- queryFn: ({ signal }) => listBackgroundTasks(sessionId, { signal }).then((items) => {
1370
- setTasks(sessionId, items);
1371
- return items;
1372
- }),
1373
- enabled: Boolean(sessionId)
1374
- });
1375
- return {
1376
- data: tasks ?? query.data ?? EMPTY_TASKS,
1377
- loading: query.isLoading,
1378
- error: query.error,
1379
- refetch: query.refetch
1380
- };
1381
- }
1382
-
1383
1528
  // src/react/hooks/use-context-stats.ts
1384
1529
  import { useQuery as useQuery3 } from "@tanstack/react-query";
1385
1530
  var EMPTY_CONTEXT_STATS = {
@@ -1455,7 +1600,7 @@ function useTokenPressure(sessionId) {
1455
1600
  }
1456
1601
 
1457
1602
  // src/react/components/chat/ProgressCircle.tsx
1458
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1603
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1459
1604
  var LEVEL_STYLES = {
1460
1605
  normal: {
1461
1606
  strokeClass: "stroke-slate-400",
@@ -1486,15 +1631,15 @@ function ProgressCircle({
1486
1631
  const circumference = 2 * Math.PI * radius;
1487
1632
  const dashOffset = circumference * (1 - clamped / 100);
1488
1633
  const styles = LEVEL_STYLES[level];
1489
- return /* @__PURE__ */ jsxs5("div", { className: cn("group relative inline-flex", className), children: [
1490
- /* @__PURE__ */ jsx6(
1634
+ return /* @__PURE__ */ jsxs6("div", { className: cn("group relative inline-flex", className), children: [
1635
+ /* @__PURE__ */ jsx7(
1491
1636
  "button",
1492
1637
  {
1493
1638
  type: "button",
1494
1639
  "aria-label": `\u4E0A\u4E0B\u6587\u5DF2\u4F7F\u7528 ${Math.round(clamped)}%`,
1495
1640
  className: "relative inline-flex cursor-help items-center justify-center rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-2 focus-visible:ring-offset-[hsl(var(--background))]",
1496
- children: /* @__PURE__ */ jsxs5("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, "aria-hidden": "true", children: [
1497
- /* @__PURE__ */ jsx6(
1641
+ children: /* @__PURE__ */ jsxs6("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, "aria-hidden": "true", children: [
1642
+ /* @__PURE__ */ jsx7(
1498
1643
  "circle",
1499
1644
  {
1500
1645
  cx: size / 2,
@@ -1505,7 +1650,7 @@ function ProgressCircle({
1505
1650
  className: styles.trackClass
1506
1651
  }
1507
1652
  ),
1508
- /* @__PURE__ */ jsx6(
1653
+ /* @__PURE__ */ jsx7(
1509
1654
  "circle",
1510
1655
  {
1511
1656
  cx: size / 2,
@@ -1523,12 +1668,12 @@ function ProgressCircle({
1523
1668
  ] })
1524
1669
  }
1525
1670
  ),
1526
- detail ? /* @__PURE__ */ jsx6("div", { className: "pointer-events-none absolute bottom-full left-1/2 z-20 mb-2 hidden w-64 max-w-[min(20rem,calc(100vw-2rem))] -translate-x-1/2 rounded-xl border border-slate-700 bg-slate-950 px-3 py-2 text-[11px] text-slate-100 shadow-xl group-hover:block group-focus-within:block", children: detail }) : null
1671
+ detail ? /* @__PURE__ */ jsx7("div", { className: "pointer-events-none absolute bottom-full left-1/2 z-20 mb-2 hidden w-64 max-w-[min(20rem,calc(100vw-2rem))] -translate-x-1/2 rounded-xl border border-slate-700 bg-slate-950 px-3 py-2 text-[11px] text-slate-100 shadow-xl group-hover:block group-focus-within:block", children: detail }) : null
1527
1672
  ] });
1528
1673
  }
1529
1674
 
1530
1675
  // src/react/components/chat/SkillStatusBar.tsx
1531
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1676
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1532
1677
  var COMPACT_NUMBER_FORMATTER = new Intl.NumberFormat("zh-CN", {
1533
1678
  notation: "compact",
1534
1679
  maximumFractionDigits: 1
@@ -1572,8 +1717,8 @@ function HoverPanel({
1572
1717
  title,
1573
1718
  children
1574
1719
  }) {
1575
- return /* @__PURE__ */ jsxs6("div", { className: "pointer-events-none absolute bottom-full left-1/2 z-20 mb-2 hidden w-64 max-w-[min(20rem,calc(100vw-2rem))] -translate-x-1/2 rounded-xl border border-slate-700 bg-slate-950 px-3 py-2 text-[11px] text-slate-100 shadow-xl group-hover:block", children: [
1576
- /* @__PURE__ */ jsx7("div", { className: "mb-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-slate-400", children: title }),
1720
+ return /* @__PURE__ */ jsxs7("div", { className: "absolute bottom-full left-1/2 z-20 mb-2 hidden w-80 max-w-[min(22rem,calc(100vw-2rem))] -translate-x-1/2 rounded-xl border border-slate-700 bg-slate-950 px-3 py-2 text-[11px] text-slate-100 shadow-xl group-hover:block", children: [
1721
+ /* @__PURE__ */ jsx8("div", { className: "mb-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-slate-400", children: title }),
1577
1722
  children
1578
1723
  ] });
1579
1724
  }
@@ -1592,13 +1737,10 @@ function SkillStatusBar({
1592
1737
  enabled: Boolean(sessionId)
1593
1738
  });
1594
1739
  const { data: contextStats } = useContextStats(sessionId);
1595
- const { data: tasks } = useBackgroundTasks(sessionId);
1596
1740
  const tokenPressure = useTokenPressure(sessionId);
1597
1741
  const connectionStatus = useConnectionStore((state) => state.status);
1598
1742
  const reconnectAttempt = useConnectionStore((state) => state.reconnectAttempt);
1599
1743
  const hasEverConnected = useConnectionStore((state) => state.hasEverConnected);
1600
- const runningTaskItems = tasks.filter((task) => task.status === "running");
1601
- const runningTasks = runningTaskItems.length;
1602
1744
  const statsReady = !loading && !error;
1603
1745
  const skillStoreConnected = statsReady && skillStats.remote_connected;
1604
1746
  const connectionMeta = useMemo6(
@@ -1610,11 +1752,6 @@ function SkillStatusBar({
1610
1752
  [connectionStatus, reconnectAttempt, hasEverConnected]
1611
1753
  );
1612
1754
  const items = [
1613
- {
1614
- key: "bg",
1615
- dotClass: runningTasks > 0 ? "bg-amber-400" : "bg-[hsl(var(--muted-foreground))]",
1616
- text: `\u540E\u53F0\u4EFB\u52A1 ${runningTasks}`
1617
- },
1618
1755
  {
1619
1756
  key: "loaded",
1620
1757
  dotClass: statsReady ? "bg-emerald-500" : "bg-[hsl(var(--muted-foreground))]",
@@ -1628,18 +1765,18 @@ function SkillStatusBar({
1628
1765
  ].filter((item) => item.key !== "total" || skillStats.remote_configured);
1629
1766
  const tokenSummary = useMemo6(() => {
1630
1767
  return {
1631
- detail: /* @__PURE__ */ jsxs6("div", { className: "space-y-1", children: [
1632
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-3 border-t border-slate-800 pt-1", children: [
1633
- /* @__PURE__ */ jsx7("span", { className: "text-slate-400", children: "\u5DF2\u7528" }),
1634
- /* @__PURE__ */ jsx7("span", { className: "font-mono", children: formatTokenNumber(contextStats.tokens_used) })
1768
+ detail: /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
1769
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3 border-t border-slate-800 pt-1", children: [
1770
+ /* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "\u5DF2\u7528" }),
1771
+ /* @__PURE__ */ jsx8("span", { className: "font-mono", children: formatTokenNumber(contextStats.tokens_used) })
1635
1772
  ] }),
1636
- contextStats.context_window > 0 ? /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-3", children: [
1637
- /* @__PURE__ */ jsx7("span", { className: "text-slate-400", children: "\u4E0A\u4E0B\u6587\u7A97\u53E3" }),
1638
- /* @__PURE__ */ jsx7("span", { className: "font-mono", children: formatCompactNumber(contextStats.context_window) })
1639
- ] }) : /* @__PURE__ */ jsx7("div", { className: "pt-1 text-slate-500", children: "\u672A\u914D\u7F6E\u4E0A\u4E0B\u6587\u7A97\u53E3\u5927\u5C0F\uFF0C\u53EF\u901A\u8FC7 CONTEXT_WINDOW \u73AF\u5883\u53D8\u91CF\u8BBE\u7F6E" }),
1640
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-3", children: [
1641
- /* @__PURE__ */ jsx7("span", { className: "text-slate-400", children: "\u6574\u7406\u9608\u503C" }),
1642
- /* @__PURE__ */ jsx7("span", { className: "font-mono", children: contextStats.compaction_ratio > 0 ? `${Math.round(contextStats.compaction_ratio * 100)}%` : "\u5DF2\u7981\u7528" })
1773
+ contextStats.context_window > 0 ? /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3", children: [
1774
+ /* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "\u4E0A\u4E0B\u6587\u7A97\u53E3" }),
1775
+ /* @__PURE__ */ jsx8("span", { className: "font-mono", children: formatCompactNumber(contextStats.context_window) })
1776
+ ] }) : /* @__PURE__ */ jsx8("div", { className: "pt-1 text-slate-500", children: "\u672A\u914D\u7F6E\u4E0A\u4E0B\u6587\u7A97\u53E3\u5927\u5C0F\uFF0C\u53EF\u901A\u8FC7 CONTEXT_WINDOW \u73AF\u5883\u53D8\u91CF\u8BBE\u7F6E" }),
1777
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3", children: [
1778
+ /* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "\u6574\u7406\u9608\u503C" }),
1779
+ /* @__PURE__ */ jsx8("span", { className: "font-mono", children: contextStats.compaction_ratio > 0 ? `${Math.round(contextStats.compaction_ratio * 100)}%` : "\u5DF2\u7981\u7528" })
1643
1780
  ] })
1644
1781
  ] }),
1645
1782
  label: contextStats.context_window > 0 ? `${formatTokensK(contextStats.tokens_used)} / ${formatTokensK(contextStats.context_window)} \u4E0A\u4E0B\u6587` : `${formatTokensK(contextStats.tokens_used)} \u4E0A\u4E0B\u6587`,
@@ -1649,9 +1786,9 @@ function SkillStatusBar({
1649
1786
  const containerClass = vertical ? "text-[11px] text-[hsl(var(--muted-foreground))]" : "bg-[hsl(var(--background))] px-5 pt-2";
1650
1787
  const innerClass = vertical ? "" : "mx-auto max-w-3xl";
1651
1788
  const listClass = vertical ? "flex flex-col items-stretch gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]" : "flex flex-wrap items-center gap-2 text-[10px] text-[hsl(var(--muted-foreground))]";
1652
- return /* @__PURE__ */ jsx7("div", { className: cn(containerClass, className), children: /* @__PURE__ */ jsx7("div", { className: cn(innerClass, innerClassName), children: /* @__PURE__ */ jsxs6("div", { className: listClass, children: [
1653
- tokenSummary ? /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2.5 py-1", children: [
1654
- /* @__PURE__ */ jsx7(
1789
+ return /* @__PURE__ */ jsx8("div", { className: cn(containerClass, className), children: /* @__PURE__ */ jsx8("div", { className: cn(innerClass, innerClassName), children: /* @__PURE__ */ jsxs7("div", { className: listClass, children: [
1790
+ tokenSummary ? /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2.5 py-1", children: [
1791
+ /* @__PURE__ */ jsx8(
1655
1792
  ProgressCircle,
1656
1793
  {
1657
1794
  percentage: tokenPressure.ratio * 100,
@@ -1659,10 +1796,10 @@ function SkillStatusBar({
1659
1796
  detail: tokenSummary.detail
1660
1797
  }
1661
1798
  ),
1662
- /* @__PURE__ */ jsx7("span", { className: "font-mono", children: tokenSummary.label }),
1663
- tokenSummary.warn ? /* @__PURE__ */ jsx7("span", { className: "rounded-full border border-rose-500/25 bg-rose-500/10 px-1.5 py-0.5 text-[10px] font-medium text-rose-200", children: "\u5EFA\u8BAE\u6574\u7406\u5BF9\u8BDD" }) : null
1799
+ /* @__PURE__ */ jsx8("span", { className: "font-mono", children: tokenSummary.label }),
1800
+ tokenSummary.warn ? /* @__PURE__ */ jsx8("span", { className: "rounded-full border border-rose-500/25 bg-rose-500/10 px-1.5 py-0.5 text-[10px] font-medium text-rose-200", children: "\u5EFA\u8BAE\u6574\u7406\u5BF9\u8BDD" }) : null
1664
1801
  ] }) : null,
1665
- connectionStatus !== "connected" ? /* @__PURE__ */ jsxs6(
1802
+ connectionStatus !== "connected" ? /* @__PURE__ */ jsxs7(
1666
1803
  "div",
1667
1804
  {
1668
1805
  className: cn(
@@ -1670,30 +1807,21 @@ function SkillStatusBar({
1670
1807
  connectionMeta.toneClass
1671
1808
  ),
1672
1809
  children: [
1673
- /* @__PURE__ */ jsx7("span", { className: cn("inline-block h-1.5 w-1.5 rounded-full", connectionMeta.dotClass) }),
1674
- /* @__PURE__ */ jsx7("span", { children: connectionMeta.label })
1810
+ /* @__PURE__ */ jsx8("span", { className: cn("inline-block h-1.5 w-1.5 rounded-full", connectionMeta.dotClass) }),
1811
+ /* @__PURE__ */ jsx8("span", { children: connectionMeta.label })
1675
1812
  ]
1676
1813
  }
1677
1814
  ) : null,
1678
- items.map((item, index) => /* @__PURE__ */ jsxs6(
1815
+ items.map((item, index) => /* @__PURE__ */ jsxs7(
1679
1816
  "div",
1680
1817
  {
1681
1818
  className: "flex items-center gap-2 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2.5 py-1",
1682
1819
  children: [
1683
- index > 0 && !tokenPressure && /* @__PURE__ */ jsx7("span", { className: "hidden text-[hsl(var(--border))]", children: "\xB7" }),
1684
- /* @__PURE__ */ jsx7("span", { className: `inline-block h-1.5 w-1.5 rounded-full ${item.dotClass}` }),
1685
- item.key === "bg" ? /* @__PURE__ */ jsxs6("div", { className: "group relative", children: [
1686
- /* @__PURE__ */ jsx7("span", { className: "cursor-help font-mono", children: item.text }),
1687
- runningTaskItems.length > 0 ? /* @__PURE__ */ jsx7(HoverPanel, { title: "\u8FD0\u884C\u4E2D\u4EFB\u52A1", children: /* @__PURE__ */ jsx7("div", { className: "max-h-40 overflow-y-auto", children: runningTaskItems.map((task) => /* @__PURE__ */ jsxs6("div", { className: "flex items-start gap-2 py-1 leading-relaxed", children: [
1688
- /* @__PURE__ */ jsx7("span", { className: "mt-1.5 inline-block h-2 w-2 shrink-0 rounded-full border border-amber-300 bg-transparent" }),
1689
- /* @__PURE__ */ jsxs6("div", { className: "min-w-0", children: [
1690
- /* @__PURE__ */ jsx7("div", { className: "font-medium", children: task.id }),
1691
- /* @__PURE__ */ jsx7("div", { className: "break-words text-slate-300/85", children: task.description || task.command })
1692
- ] })
1693
- ] }, task.id)) }) }) : null
1694
- ] }) : item.key === "loaded" ? /* @__PURE__ */ jsxs6("div", { className: "group relative flex items-center gap-1.5", children: [
1695
- /* @__PURE__ */ jsx7("span", { className: "cursor-help font-mono", children: item.text }),
1696
- onResync ? /* @__PURE__ */ jsx7(
1820
+ index > 0 && !tokenPressure && /* @__PURE__ */ jsx8("span", { className: "hidden text-[hsl(var(--border))]", children: "\xB7" }),
1821
+ /* @__PURE__ */ jsx8("span", { className: `inline-block h-1.5 w-1.5 rounded-full ${item.dotClass}` }),
1822
+ item.key === "loaded" ? /* @__PURE__ */ jsxs7("div", { className: "group relative flex items-center gap-1.5", children: [
1823
+ /* @__PURE__ */ jsx8("span", { className: "cursor-help font-mono", children: item.text }),
1824
+ onResync ? /* @__PURE__ */ jsx8(
1697
1825
  "button",
1698
1826
  {
1699
1827
  type: "button",
@@ -1701,21 +1829,21 @@ function SkillStatusBar({
1701
1829
  disabled: isResyncing,
1702
1830
  "aria-label": "\u540C\u6B65\u6280\u80FD",
1703
1831
  className: "inline-flex h-5 w-5 items-center justify-center rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--background))] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50",
1704
- children: /* @__PURE__ */ jsx7(RefreshCw, { size: 11, className: isResyncing ? "animate-spin" : "" })
1832
+ children: /* @__PURE__ */ jsx8(RefreshCw, { size: 11, className: isResyncing ? "animate-spin" : "" })
1705
1833
  }
1706
1834
  ) : null,
1707
- statsReady && sessionSkills.length > 0 ? /* @__PURE__ */ jsx7(HoverPanel, { title: "\u5DF2\u52A0\u8F7D\u6280\u80FD", children: /* @__PURE__ */ jsx7("div", { className: "max-h-40 overflow-y-auto", children: sessionSkills.map((skill) => /* @__PURE__ */ jsxs6(
1835
+ statsReady && sessionSkills.length > 0 ? /* @__PURE__ */ jsx8(HoverPanel, { title: "\u5DF2\u52A0\u8F7D\u6280\u80FD", children: /* @__PURE__ */ jsx8("div", { className: "max-h-40 overflow-y-auto", children: sessionSkills.map((skill) => /* @__PURE__ */ jsxs7(
1708
1836
  "div",
1709
1837
  {
1710
1838
  className: "flex items-start gap-2 py-1 leading-relaxed",
1711
1839
  children: [
1712
- /* @__PURE__ */ jsx7("span", { className: "mt-1.5 inline-block h-2 w-2 shrink-0 rounded-full border border-emerald-300 bg-transparent" }),
1713
- /* @__PURE__ */ jsx7("span", { className: "break-words", children: skillDisplayName(skill) })
1840
+ /* @__PURE__ */ jsx8("span", { className: "mt-1.5 inline-block h-2 w-2 shrink-0 rounded-full border border-emerald-300 bg-transparent" }),
1841
+ /* @__PURE__ */ jsx8("span", { className: "break-words", children: skillDisplayName(skill) })
1714
1842
  ]
1715
1843
  },
1716
1844
  skill.skill_id
1717
1845
  )) }) }) : null
1718
- ] }) : /* @__PURE__ */ jsx7("span", { className: "font-mono", children: item.text })
1846
+ ] }) : /* @__PURE__ */ jsx8("span", { className: "font-mono", children: item.text })
1719
1847
  ]
1720
1848
  },
1721
1849
  item.key
@@ -1850,7 +1978,7 @@ var SkillMention = Mention2.extend({
1850
1978
  });
1851
1979
 
1852
1980
  // src/react/components/chat/ChatInput.tsx
1853
- import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1981
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1854
1982
  function getEditorText(editor) {
1855
1983
  return editor?.getText({ blockSeparator: "\n" }) ?? "";
1856
1984
  }
@@ -1890,7 +2018,7 @@ function getFileCardIcon(attachment) {
1890
2018
  return FileCode2;
1891
2019
  }
1892
2020
  if (attachment.mimeType.startsWith("text/") || /\.(txt|pdf|doc|docx|rtf|odt)$/.test(lowerName)) {
1893
- return FileText;
2021
+ return FileText2;
1894
2022
  }
1895
2023
  return File2;
1896
2024
  }
@@ -1966,21 +2094,21 @@ function ComposerFilePill({
1966
2094
  const isFile = attachment.kind === "file";
1967
2095
  const isFailed = isFile && attachment.status === "failed";
1968
2096
  const isUploading = isFile && attachment.status === "uploading";
1969
- return /* @__PURE__ */ jsxs7(
2097
+ return /* @__PURE__ */ jsxs8(
1970
2098
  "div",
1971
2099
  {
1972
2100
  className: `flex shrink-0 items-center gap-1.5 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))]"}`,
1973
2101
  children: [
1974
- isUploading ? /* @__PURE__ */ jsx8(Loader22, { size: 12, className: "shrink-0 animate-spin text-[hsl(var(--muted-foreground))]" }) : /* @__PURE__ */ jsx8(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
1975
- /* @__PURE__ */ jsx8("span", { className: "max-w-32 truncate", children: attachment.name }),
1976
- /* @__PURE__ */ jsx8(
2102
+ isUploading ? /* @__PURE__ */ jsx9(Loader22, { size: 12, className: "shrink-0 animate-spin text-[hsl(var(--muted-foreground))]" }) : /* @__PURE__ */ jsx9(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
2103
+ /* @__PURE__ */ jsx9("span", { className: "max-w-32 truncate", children: attachment.name }),
2104
+ /* @__PURE__ */ jsx9(
1977
2105
  "button",
1978
2106
  {
1979
2107
  type: "button",
1980
2108
  onClick: () => onRemove(attachment.id),
1981
2109
  "aria-label": `\u79FB\u9664 ${attachment.name}`,
1982
2110
  className: "ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-rose-400",
1983
- children: /* @__PURE__ */ jsx8(X2, { size: 10 })
2111
+ children: /* @__PURE__ */ jsx9(X2, { size: 10 })
1984
2112
  }
1985
2113
  )
1986
2114
  ]
@@ -1993,13 +2121,13 @@ function AddContextDialog({
1993
2121
  onAdd
1994
2122
  }) {
1995
2123
  const CONTEXT_INLINE_THRESHOLD = 200;
1996
- const [label, setLabel] = useState6("");
1997
- const [content, setContent] = useState6("");
1998
- const [showSessionPicker, setShowSessionPicker] = useState6(false);
1999
- const [sessions, setSessions] = useState6([]);
2000
- const [loadingSessions, setLoadingSessions] = useState6(false);
2001
- const [importingId, setImportingId] = useState6(null);
2002
- const [isImportProcessing, setIsImportProcessing] = useState6(false);
2124
+ const [label, setLabel] = useState7("");
2125
+ const [content, setContent] = useState7("");
2126
+ const [showSessionPicker, setShowSessionPicker] = useState7(false);
2127
+ const [sessions, setSessions] = useState7([]);
2128
+ const [loadingSessions, setLoadingSessions] = useState7(false);
2129
+ const [importingId, setImportingId] = useState7(null);
2130
+ const [isImportProcessing, setIsImportProcessing] = useState7(false);
2003
2131
  const sanitizeContextFolderName = (raw) => {
2004
2132
  const normalized = raw.trim().toLowerCase();
2005
2133
  const safe = normalized.replace(/[^\w\-.\u4e00-\u9fa5]+/g, "_").replace(/^_+|_+$/g, "");
@@ -2099,7 +2227,7 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2099
2227
  setImportingId(null);
2100
2228
  }
2101
2229
  };
2102
- return /* @__PURE__ */ jsx8(
2230
+ return /* @__PURE__ */ jsx9(
2103
2231
  "div",
2104
2232
  {
2105
2233
  className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-4",
@@ -2107,44 +2235,44 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2107
2235
  onKeyDown: (e) => {
2108
2236
  if (e.key === "Escape") onClose();
2109
2237
  },
2110
- children: /* @__PURE__ */ jsxs7(
2238
+ children: /* @__PURE__ */ jsxs8(
2111
2239
  "div",
2112
2240
  {
2113
2241
  className: "w-full max-w-lg flex flex-col rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-2xl",
2114
2242
  onClick: (e) => e.stopPropagation(),
2115
2243
  onKeyDown: (e) => e.stopPropagation(),
2116
2244
  children: [
2117
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-5 py-3", children: [
2118
- /* @__PURE__ */ jsx8("h4", { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u6DFB\u52A0\u4E0A\u4E0B\u6587" }),
2119
- /* @__PURE__ */ jsx8(
2245
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-5 py-3", children: [
2246
+ /* @__PURE__ */ jsx9("h4", { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u6DFB\u52A0\u4E0A\u4E0B\u6587" }),
2247
+ /* @__PURE__ */ jsx9(
2120
2248
  "button",
2121
2249
  {
2122
2250
  type: "button",
2123
2251
  onClick: onClose,
2124
2252
  className: "rounded-md p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
2125
- children: /* @__PURE__ */ jsx8(X2, { size: 14 })
2253
+ children: /* @__PURE__ */ jsx9(X2, { size: 14 })
2126
2254
  }
2127
2255
  )
2128
2256
  ] }),
2129
- /* @__PURE__ */ jsxs7("div", { className: "px-5 py-4 space-y-3", children: [
2130
- /* @__PURE__ */ jsxs7("div", { className: "relative", children: [
2131
- /* @__PURE__ */ jsxs7(
2257
+ /* @__PURE__ */ jsxs8("div", { className: "px-5 py-4 space-y-3", children: [
2258
+ /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
2259
+ /* @__PURE__ */ jsxs8(
2132
2260
  "button",
2133
2261
  {
2134
2262
  type: "button",
2135
2263
  onClick: handleLoadSessions,
2136
2264
  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))]",
2137
2265
  children: [
2138
- /* @__PURE__ */ jsx8(Import, { size: 12 }),
2266
+ /* @__PURE__ */ jsx9(Import, { size: 12 }),
2139
2267
  "\u4ECE\u5176\u4ED6\u4F1A\u8BDD\u5BFC\u5165",
2140
- /* @__PURE__ */ jsx8(ChevronDown, { size: 10, className: `transition-transform ${showSessionPicker ? "rotate-180" : ""}` })
2268
+ /* @__PURE__ */ jsx9(ChevronDown, { size: 10, className: `transition-transform ${showSessionPicker ? "rotate-180" : ""}` })
2141
2269
  ]
2142
2270
  }
2143
2271
  ),
2144
- showSessionPicker && /* @__PURE__ */ jsx8("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__ */ jsxs7("div", { className: "flex items-center gap-2 px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
2145
- /* @__PURE__ */ jsx8(Loader22, { size: 12, className: "animate-spin" }),
2272
+ showSessionPicker && /* @__PURE__ */ jsx9("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__ */ jsxs8("div", { className: "flex items-center gap-2 px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
2273
+ /* @__PURE__ */ jsx9(Loader22, { size: 12, className: "animate-spin" }),
2146
2274
  "\u52A0\u8F7D\u4F1A\u8BDD\u5217\u8868\u2026"
2147
- ] }) : sessions.length === 0 ? /* @__PURE__ */ jsx8("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__ */ jsxs7(
2275
+ ] }) : sessions.length === 0 ? /* @__PURE__ */ jsx9("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__ */ jsxs8(
2148
2276
  "button",
2149
2277
  {
2150
2278
  type: "button",
@@ -2152,16 +2280,16 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2152
2280
  onClick: () => handleImportSession(s.id),
2153
2281
  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",
2154
2282
  children: [
2155
- importingId === s.id && /* @__PURE__ */ jsx8(Loader22, { size: 10, className: "shrink-0 animate-spin" }),
2156
- /* @__PURE__ */ jsx8("span", { className: "truncate", children: s.intent })
2283
+ importingId === s.id && /* @__PURE__ */ jsx9(Loader22, { size: 10, className: "shrink-0 animate-spin" }),
2284
+ /* @__PURE__ */ jsx9("span", { className: "truncate", children: s.intent })
2157
2285
  ]
2158
2286
  },
2159
2287
  s.id
2160
2288
  )) })
2161
2289
  ] }),
2162
- /* @__PURE__ */ jsxs7("div", { children: [
2163
- /* @__PURE__ */ jsx8("label", { htmlFor: "ctx-label", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u6807\u7B7E" }),
2164
- /* @__PURE__ */ jsx8(
2290
+ /* @__PURE__ */ jsxs8("div", { children: [
2291
+ /* @__PURE__ */ jsx9("label", { htmlFor: "ctx-label", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u6807\u7B7E" }),
2292
+ /* @__PURE__ */ jsx9(
2165
2293
  "input",
2166
2294
  {
2167
2295
  id: "ctx-label",
@@ -2172,13 +2300,13 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2172
2300
  }
2173
2301
  )
2174
2302
  ] }),
2175
- /* @__PURE__ */ jsxs7("div", { children: [
2176
- /* @__PURE__ */ jsx8("label", { htmlFor: "ctx-content", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u5185\u5BB9" }),
2177
- isImportProcessing && /* @__PURE__ */ jsxs7("div", { className: "mb-1.5 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
2178
- /* @__PURE__ */ jsx8(Loader22, { size: 11, className: "animate-spin" }),
2303
+ /* @__PURE__ */ jsxs8("div", { children: [
2304
+ /* @__PURE__ */ jsx9("label", { htmlFor: "ctx-content", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u5185\u5BB9" }),
2305
+ isImportProcessing && /* @__PURE__ */ jsxs8("div", { className: "mb-1.5 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
2306
+ /* @__PURE__ */ jsx9(Loader22, { size: 11, className: "animate-spin" }),
2179
2307
  "\u6B63\u5728\u5904\u7406\u5BFC\u5165\u5185\u5BB9\u5E76\u5199\u5165 workspace/context\uFF0C\u5B8C\u6210\u540E\u53EF\u70B9\u51FB\u201C\u786E\u5B9A\u201D"
2180
2308
  ] }),
2181
- /* @__PURE__ */ jsx8(
2309
+ /* @__PURE__ */ jsx9(
2182
2310
  "textarea",
2183
2311
  {
2184
2312
  id: "ctx-content",
@@ -2191,8 +2319,8 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2191
2319
  )
2192
2320
  ] })
2193
2321
  ] }),
2194
- /* @__PURE__ */ jsxs7("div", { className: "flex justify-end gap-2 border-t border-[hsl(var(--border))] px-5 py-3", children: [
2195
- /* @__PURE__ */ jsx8(
2322
+ /* @__PURE__ */ jsxs8("div", { className: "flex justify-end gap-2 border-t border-[hsl(var(--border))] px-5 py-3", children: [
2323
+ /* @__PURE__ */ jsx9(
2196
2324
  "button",
2197
2325
  {
2198
2326
  type: "button",
@@ -2201,7 +2329,7 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
2201
2329
  children: "\u53D6\u6D88"
2202
2330
  }
2203
2331
  ),
2204
- /* @__PURE__ */ jsx8(
2332
+ /* @__PURE__ */ jsx9(
2205
2333
  "button",
2206
2334
  {
2207
2335
  type: "button",
@@ -2229,11 +2357,11 @@ function ComposerContextPill({
2229
2357
  content,
2230
2358
  onRemove
2231
2359
  }) {
2232
- const [showDetail, setShowDetail] = useState6(false);
2360
+ const [showDetail, setShowDetail] = useState7(false);
2233
2361
  const tokenK = formatTokenK(content);
2234
- return /* @__PURE__ */ jsxs7(Fragment, { children: [
2235
- /* @__PURE__ */ jsxs7("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: [
2236
- /* @__PURE__ */ jsx8(
2362
+ return /* @__PURE__ */ jsxs8(Fragment2, { children: [
2363
+ /* @__PURE__ */ jsxs8("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: [
2364
+ /* @__PURE__ */ jsx9(
2237
2365
  "button",
2238
2366
  {
2239
2367
  type: "button",
@@ -2243,7 +2371,7 @@ function ComposerContextPill({
2243
2371
  children: label
2244
2372
  }
2245
2373
  ),
2246
- /* @__PURE__ */ jsx8(
2374
+ /* @__PURE__ */ jsx9(
2247
2375
  "span",
2248
2376
  {
2249
2377
  className: "shrink-0 rounded bg-[hsl(var(--background))] px-1.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]",
@@ -2251,18 +2379,18 @@ function ComposerContextPill({
2251
2379
  children: tokenK
2252
2380
  }
2253
2381
  ),
2254
- /* @__PURE__ */ jsx8(
2382
+ /* @__PURE__ */ jsx9(
2255
2383
  "button",
2256
2384
  {
2257
2385
  type: "button",
2258
2386
  onClick: () => onRemove(id),
2259
2387
  "aria-label": `\u79FB\u9664\u4E0A\u4E0B\u6587 ${label}`,
2260
2388
  className: "ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-rose-400",
2261
- children: /* @__PURE__ */ jsx8(X2, { size: 10 })
2389
+ children: /* @__PURE__ */ jsx9(X2, { size: 10 })
2262
2390
  }
2263
2391
  )
2264
2392
  ] }),
2265
- showDetail && /* @__PURE__ */ jsx8(
2393
+ showDetail && /* @__PURE__ */ jsx9(
2266
2394
  "div",
2267
2395
  {
2268
2396
  className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-6",
@@ -2270,26 +2398,26 @@ function ComposerContextPill({
2270
2398
  onKeyDown: (e) => {
2271
2399
  if (e.key === "Escape") setShowDetail(false);
2272
2400
  },
2273
- children: /* @__PURE__ */ jsxs7(
2401
+ children: /* @__PURE__ */ jsxs8(
2274
2402
  "div",
2275
2403
  {
2276
2404
  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",
2277
2405
  onClick: (e) => e.stopPropagation(),
2278
2406
  onKeyDown: (e) => e.stopPropagation(),
2279
2407
  children: [
2280
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [
2281
- /* @__PURE__ */ jsx8("h4", { className: "text-xs font-semibold text-[hsl(var(--foreground))]", children: label }),
2282
- /* @__PURE__ */ jsx8(
2408
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [
2409
+ /* @__PURE__ */ jsx9("h4", { className: "text-xs font-semibold text-[hsl(var(--foreground))]", children: label }),
2410
+ /* @__PURE__ */ jsx9(
2283
2411
  "button",
2284
2412
  {
2285
2413
  type: "button",
2286
2414
  onClick: () => setShowDetail(false),
2287
2415
  className: "rounded-md p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
2288
- children: /* @__PURE__ */ jsx8(X2, { size: 14 })
2416
+ children: /* @__PURE__ */ jsx9(X2, { size: 14 })
2289
2417
  }
2290
2418
  )
2291
2419
  ] }),
2292
- /* @__PURE__ */ jsx8("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: /* @__PURE__ */ jsx8("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground)/0.85)]", children: content }) })
2420
+ /* @__PURE__ */ jsx9("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: /* @__PURE__ */ jsx9("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground)/0.85)]", children: content }) })
2293
2421
  ]
2294
2422
  }
2295
2423
  )
@@ -2443,7 +2571,7 @@ function ChatInput({
2443
2571
  onResyncSkills,
2444
2572
  isResyncingSkills = false
2445
2573
  }) {
2446
- const [input, setInputInternal] = useState6(externalDraft?.value ?? "");
2574
+ const [input, setInputInternal] = useState7(externalDraft?.value ?? "");
2447
2575
  const setInput = useEffectEvent2((value) => {
2448
2576
  setInputInternal(value);
2449
2577
  externalDraft?.setValue(value);
@@ -2459,7 +2587,7 @@ function ChatInput({
2459
2587
  }
2460
2588
  setInputInternal(externalDraftValue);
2461
2589
  }, [externalDraftValue]);
2462
- const [composerAttachments, setComposerAttachmentsInternal] = useState6(
2590
+ const [composerAttachments, setComposerAttachmentsInternal] = useState7(
2463
2591
  externalAttachments?.value ?? []
2464
2592
  );
2465
2593
  const setComposerAttachments = useEffectEvent2(
@@ -2479,10 +2607,10 @@ function ChatInput({
2479
2607
  if (composerAttachmentsRef.current === externalAttachmentsValue) return;
2480
2608
  setComposerAttachmentsInternal(externalAttachmentsValue);
2481
2609
  }, [externalAttachmentsValue]);
2482
- const [dragging, setDragging] = useState6(false);
2483
- const [isEditorFocused, setIsEditorFocused] = useState6(false);
2484
- const [oversizedFiles, setOversizedFiles] = useState6([]);
2485
- const [selectedModel, setSelectedModel] = useState6("");
2610
+ const [dragging, setDragging] = useState7(false);
2611
+ const [isEditorFocused, setIsEditorFocused] = useState7(false);
2612
+ const [oversizedFiles, setOversizedFiles] = useState7([]);
2613
+ const [selectedModel, setSelectedModel] = useState7("");
2486
2614
  const { setPreferredModel } = usePreferredModel();
2487
2615
  const queryClient = useQueryClient2();
2488
2616
  const actionMenuRef = useRef4(null);
@@ -2522,7 +2650,7 @@ function ChatInput({
2522
2650
  const inputHistory = useInputHistory(activeSessionId);
2523
2651
  const getSessionId = useEffectEvent2(() => activeSessionId);
2524
2652
  const handleSlashCommand = useEffectEvent2((commandId) => onCommand?.(commandId));
2525
- const [localImageUrls, setLocalImageUrls] = useState6({});
2653
+ const [localImageUrls, setLocalImageUrls] = useState7({});
2526
2654
  useEffect7(() => {
2527
2655
  const closeActionMenu = (event) => {
2528
2656
  const menu = actionMenuRef.current;
@@ -2650,7 +2778,7 @@ function ChatInput({
2650
2778
  if (!container || !root) return;
2651
2779
  updateSuggestionPosition(container, props.clientRect);
2652
2780
  root.render(
2653
- /* @__PURE__ */ jsx8(
2781
+ /* @__PURE__ */ jsx9(
2654
2782
  FileCompletionMenu,
2655
2783
  {
2656
2784
  ref: (instance) => {
@@ -2727,7 +2855,7 @@ function ChatInput({
2727
2855
  if (!container || !root) return;
2728
2856
  updateSuggestionPosition(container, props.clientRect);
2729
2857
  root.render(
2730
- /* @__PURE__ */ jsx8(
2858
+ /* @__PURE__ */ jsx9(
2731
2859
  SkillCompletionMenu,
2732
2860
  {
2733
2861
  ref: (instance) => {
@@ -3055,7 +3183,7 @@ function ChatInput({
3055
3183
  const removeAttachment = (id) => {
3056
3184
  setComposerAttachments((prev) => prev.filter((attachment) => attachment.id !== id));
3057
3185
  };
3058
- const [showAddContext, setShowAddContext] = useState6(false);
3186
+ const [showAddContext, setShowAddContext] = useState7(false);
3059
3187
  const isPlanning = mode === "planning";
3060
3188
  const placeholder = isPlanning ? "\u89C4\u5212\u8FDB\u884C\u4E2D\u2026 \u53EF\u8F93\u5165\u8865\u5145\u9700\u6C42\u6216\u7B49\u5F85\u5B8C\u6210" : "\u8F93\u5165\u6D88\u606F\u2026";
3061
3189
  const attachments = renderAttachments?.() ?? null;
@@ -3074,384 +3202,388 @@ function ChatInput({
3074
3202
  );
3075
3203
  const hasValidAttachments = composerAttachments.some((attachment) => attachment.status !== "failed");
3076
3204
  const isSendDisabled = connectionStatus !== "connected" || hasUploadingFiles || !input.trim() && !hasValidAttachments && !hasRenderedAttachments && !hasPendingContexts;
3077
- return /* @__PURE__ */ jsxs7(Fragment, { children: [
3078
- /* @__PURE__ */ jsx8("div", { className: `bg-[hsl(var(--background))] px-5 py-3 ${className ?? ""}`, children: /* @__PURE__ */ jsx8("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: /* @__PURE__ */ jsx8(
3079
- "div",
3080
- {
3081
- className: "relative",
3082
- onDragOver: (event) => {
3083
- event.preventDefault();
3084
- setDragging(true);
3085
- },
3086
- onDragLeave: () => setDragging(false),
3087
- onDrop: (event) => {
3088
- event.preventDefault();
3089
- setDragging(false);
3090
- const fileRef = event.dataTransfer.getData("application/blade-file-ref");
3091
- if (fileRef) {
3092
- try {
3093
- const { path, name } = JSON.parse(fileRef);
3094
- const sandboxPath = `/workspace/${path}`;
3095
- const editor2 = editorRef.current;
3096
- if (editor2) {
3097
- editor2.commands.focus("end");
3098
- editor2.commands.insertContent([
3099
- { type: "fileMention", attrs: { path: sandboxPath, name } },
3100
- { type: "text", text: " " }
3101
- ]);
3205
+ return /* @__PURE__ */ jsxs8(Fragment2, { children: [
3206
+ /* @__PURE__ */ jsx9("div", { className: `bg-[hsl(var(--background))] px-5 py-3 ${className ?? ""}`, children: /* @__PURE__ */ jsxs8("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: [
3207
+ activeSessionId ? /* @__PURE__ */ jsx9(BackgroundTasksPill, { sessionId: activeSessionId }) : null,
3208
+ /* @__PURE__ */ jsx9(
3209
+ "div",
3210
+ {
3211
+ className: "relative",
3212
+ onDragOver: (event) => {
3213
+ event.preventDefault();
3214
+ setDragging(true);
3215
+ },
3216
+ onDragLeave: () => setDragging(false),
3217
+ onDrop: (event) => {
3218
+ event.preventDefault();
3219
+ setDragging(false);
3220
+ const fileRef = event.dataTransfer.getData("application/blade-file-ref");
3221
+ if (fileRef) {
3222
+ try {
3223
+ const { path, name } = JSON.parse(fileRef);
3224
+ const normalizedPath = path.replace(/^\.?\//, "");
3225
+ const sandboxPath = path.startsWith("/") ? path : activeSessionId ? `/root/\u667A\u80FD\u52A9\u624B\u5DE5\u4F5C\u7A7A\u95F4/${activeSessionId}/${normalizedPath}` : normalizedPath;
3226
+ const editor2 = editorRef.current;
3227
+ if (editor2) {
3228
+ editor2.commands.focus("end");
3229
+ editor2.commands.insertContent([
3230
+ { type: "fileMention", attrs: { path: sandboxPath, name } },
3231
+ { type: "text", text: " " }
3232
+ ]);
3233
+ }
3234
+ } catch {
3102
3235
  }
3103
- } catch {
3236
+ return;
3104
3237
  }
3105
- return;
3106
- }
3107
- void stableAppendFiles(event.dataTransfer.files);
3108
- },
3109
- children: /* @__PURE__ */ jsxs7(
3110
- "div",
3111
- {
3112
- 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))]"}`,
3113
- children: [
3114
- dragging && /* @__PURE__ */ jsx8("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__ */ jsx8("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" }) }),
3115
- composerAttachments.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "flex max-h-40 flex-col gap-2 overflow-y-auto border-b border-[hsl(var(--border))] px-3 py-2", children: [
3116
- imageAttachments.length > 0 && /* @__PURE__ */ jsx8("div", { className: "grid grid-cols-3 gap-2", children: imageAttachments.map((attachment) => /* @__PURE__ */ jsxs7(
3117
- "div",
3118
- {
3119
- className: "relative overflow-hidden rounded-xl border border-[hsl(var(--border))]",
3120
- children: [
3121
- /* @__PURE__ */ jsx8(
3122
- "img",
3123
- {
3124
- src: getImagePreviewUrl(attachment, activeSessionId, localImageUrls),
3125
- alt: attachment.name || "\u56FE\u7247\u9884\u89C8",
3126
- className: "h-24 w-full object-cover"
3127
- }
3128
- ),
3129
- /* @__PURE__ */ jsx8(
3130
- "button",
3131
- {
3132
- type: "button",
3133
- onClick: () => removeAttachment(attachment.id),
3134
- "aria-label": `\u79FB\u9664 ${attachment.name || "\u56FE\u7247"}`,
3135
- 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))]",
3136
- children: /* @__PURE__ */ jsx8(X2, { size: 12 })
3238
+ void stableAppendFiles(event.dataTransfer.files);
3239
+ },
3240
+ children: /* @__PURE__ */ jsxs8(
3241
+ "div",
3242
+ {
3243
+ 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))]"}`,
3244
+ children: [
3245
+ dragging && /* @__PURE__ */ jsx9("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__ */ jsx9("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" }) }),
3246
+ composerAttachments.length > 0 && /* @__PURE__ */ jsxs8("div", { className: "flex max-h-40 flex-col gap-2 overflow-y-auto border-b border-[hsl(var(--border))] px-3 py-2", children: [
3247
+ imageAttachments.length > 0 && /* @__PURE__ */ jsx9("div", { className: "grid grid-cols-3 gap-2", children: imageAttachments.map((attachment) => /* @__PURE__ */ jsxs8(
3248
+ "div",
3249
+ {
3250
+ className: "relative overflow-hidden rounded-xl border border-[hsl(var(--border))]",
3251
+ children: [
3252
+ /* @__PURE__ */ jsx9(
3253
+ "img",
3254
+ {
3255
+ src: getImagePreviewUrl(attachment, activeSessionId, localImageUrls),
3256
+ alt: attachment.name || "\u56FE\u7247\u9884\u89C8",
3257
+ className: "h-24 w-full object-cover"
3258
+ }
3259
+ ),
3260
+ /* @__PURE__ */ jsx9(
3261
+ "button",
3262
+ {
3263
+ type: "button",
3264
+ onClick: () => removeAttachment(attachment.id),
3265
+ "aria-label": `\u79FB\u9664 ${attachment.name || "\u56FE\u7247"}`,
3266
+ 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))]",
3267
+ children: /* @__PURE__ */ jsx9(X2, { size: 12 })
3268
+ }
3269
+ )
3270
+ ]
3271
+ },
3272
+ attachment.id
3273
+ )) }),
3274
+ fileAttachments.length > 0 && /* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => /* @__PURE__ */ jsx9(
3275
+ ComposerFilePill,
3276
+ {
3277
+ attachment,
3278
+ onRemove: removeAttachment
3279
+ },
3280
+ attachment.id
3281
+ )) })
3282
+ ] }),
3283
+ hasPendingContexts || isSkillEditor ? /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-1.5 border-b border-[hsl(var(--border))] px-3 py-2", children: [
3284
+ pendingContexts?.map((context) => /* @__PURE__ */ jsx9(
3285
+ ComposerContextPill,
3286
+ {
3287
+ id: context.id,
3288
+ label: context.label,
3289
+ content: context.content,
3290
+ onRemove: (contextId) => {
3291
+ if (!activeSessionId) {
3292
+ return;
3137
3293
  }
3138
- )
3139
- ]
3140
- },
3141
- attachment.id
3142
- )) }),
3143
- fileAttachments.length > 0 && /* @__PURE__ */ jsx8("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => /* @__PURE__ */ jsx8(
3144
- ComposerFilePill,
3145
- {
3146
- attachment,
3147
- onRemove: removeAttachment
3148
- },
3149
- attachment.id
3150
- )) })
3151
- ] }),
3152
- hasPendingContexts || isSkillEditor ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-1.5 border-b border-[hsl(var(--border))] px-3 py-2", children: [
3153
- pendingContexts?.map((context) => /* @__PURE__ */ jsx8(
3154
- ComposerContextPill,
3155
- {
3156
- id: context.id,
3157
- label: context.label,
3158
- content: context.content,
3159
- onRemove: (contextId) => {
3160
- if (!activeSessionId) {
3161
- return;
3294
+ removePendingContext(activeSessionId, contextId);
3162
3295
  }
3163
- removePendingContext(activeSessionId, contextId);
3296
+ },
3297
+ context.id
3298
+ )),
3299
+ isSkillEditor && /* @__PURE__ */ jsx9(
3300
+ "button",
3301
+ {
3302
+ type: "button",
3303
+ onClick: () => setShowAddContext(true),
3304
+ title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
3305
+ 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))]",
3306
+ children: /* @__PURE__ */ jsx9(Plus, { size: 12 })
3164
3307
  }
3165
- },
3166
- context.id
3167
- )),
3168
- isSkillEditor && /* @__PURE__ */ jsx8(
3169
- "button",
3308
+ )
3309
+ ] }) : null,
3310
+ showAddContext && activeSessionId && /* @__PURE__ */ jsx9(
3311
+ AddContextDialog,
3170
3312
  {
3171
- type: "button",
3172
- onClick: () => setShowAddContext(true),
3173
- title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
3174
- 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))]",
3175
- children: /* @__PURE__ */ jsx8(Plus, { size: 12 })
3176
- }
3177
- )
3178
- ] }) : null,
3179
- showAddContext && activeSessionId && /* @__PURE__ */ jsx8(
3180
- AddContextDialog,
3181
- {
3182
- sessionId: activeSessionId,
3183
- onClose: () => setShowAddContext(false),
3184
- onAdd: (label, content) => {
3185
- if (activeSessionId) {
3186
- useUiBridgeStore.getState().addPendingContext(activeSessionId, { label, content });
3313
+ sessionId: activeSessionId,
3314
+ onClose: () => setShowAddContext(false),
3315
+ onAdd: (label, content) => {
3316
+ if (activeSessionId) {
3317
+ useUiBridgeStore.getState().addPendingContext(activeSessionId, { label, content });
3318
+ }
3187
3319
  }
3188
3320
  }
3189
- }
3190
- ),
3191
- attachments ? /* @__PURE__ */ jsx8("div", { className: "border-b border-[hsl(var(--border))] px-3 py-3", children: attachments }) : null,
3192
- slotAboveTextarea ? /* @__PURE__ */ jsx8("div", { className: "border-b border-[hsl(var(--border))] px-3 py-2", children: slotAboveTextarea }) : null,
3193
- /* @__PURE__ */ jsxs7("div", { className: "relative", children: [
3194
- input.length === 0 && /* @__PURE__ */ jsx8("div", { className: "pointer-events-none absolute left-4 top-3 text-sm leading-relaxed text-[hsl(var(--muted-foreground))]", children: placeholder }),
3195
- /* @__PURE__ */ jsx8(EditorContent, { editor })
3196
- ] }),
3197
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between border-t border-[hsl(var(--border))] px-3 py-1.5", children: [
3198
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
3199
- /* @__PURE__ */ jsx8(
3200
- "input",
3201
- {
3202
- ref: fileInputRef,
3203
- type: "file",
3204
- accept: "*/*",
3205
- multiple: true,
3206
- onChange: (event) => {
3207
- if (event.target.files) {
3208
- void appendFiles(event.target.files);
3209
- event.target.value = "";
3210
- }
3211
- },
3212
- className: "hidden"
3213
- }
3214
- ),
3215
- /* @__PURE__ */ jsx8(
3216
- "input",
3217
- {
3218
- ref: folderInputRef,
3219
- type: "file",
3220
- multiple: true,
3221
- onChange: (event) => {
3222
- if (event.target.files) {
3223
- void appendFiles(event.target.files);
3224
- event.target.value = "";
3225
- }
3226
- },
3227
- className: "hidden",
3228
- ...{ webkitdirectory: "" }
3229
- }
3230
- ),
3231
- /* @__PURE__ */ jsxs7("details", { ref: actionMenuRef, className: "group relative", children: [
3232
- /* @__PURE__ */ jsx8(
3233
- "summary",
3321
+ ),
3322
+ attachments ? /* @__PURE__ */ jsx9("div", { className: "border-b border-[hsl(var(--border))] px-3 py-3", children: attachments }) : null,
3323
+ slotAboveTextarea ? /* @__PURE__ */ jsx9("div", { className: "border-b border-[hsl(var(--border))] px-3 py-2", children: slotAboveTextarea }) : null,
3324
+ /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
3325
+ input.length === 0 && /* @__PURE__ */ jsx9("div", { className: "pointer-events-none absolute left-4 top-3 text-sm leading-relaxed text-[hsl(var(--muted-foreground))]", children: placeholder }),
3326
+ /* @__PURE__ */ jsx9(EditorContent, { editor })
3327
+ ] }),
3328
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between border-t border-[hsl(var(--border))] px-3 py-1.5", children: [
3329
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
3330
+ /* @__PURE__ */ jsx9(
3331
+ "input",
3234
3332
  {
3235
- "aria-label": "\u6DFB\u52A0\u5185\u5BB9",
3236
- title: "\u6DFB\u52A0\u5185\u5BB9",
3237
- 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",
3238
- children: /* @__PURE__ */ jsx8(Plus, { size: 14 })
3333
+ ref: fileInputRef,
3334
+ type: "file",
3335
+ accept: "*/*",
3336
+ multiple: true,
3337
+ onChange: (event) => {
3338
+ if (event.target.files) {
3339
+ void appendFiles(event.target.files);
3340
+ event.target.value = "";
3341
+ }
3342
+ },
3343
+ className: "hidden"
3239
3344
  }
3240
3345
  ),
3241
- /* @__PURE__ */ jsxs7("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: [
3242
- /* @__PURE__ */ jsxs7(
3243
- "button",
3244
- {
3245
- type: "button",
3246
- onClick: () => {
3247
- actionMenuRef.current?.removeAttribute("open");
3248
- fileInputRef.current?.click();
3249
- },
3250
- className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3251
- children: [
3252
- /* @__PURE__ */ jsx8(Paperclip, { size: 13 }),
3253
- "\u4E0A\u4F20\u6587\u4EF6"
3254
- ]
3255
- }
3256
- ),
3257
- /* @__PURE__ */ jsxs7(
3258
- "button",
3346
+ /* @__PURE__ */ jsx9(
3347
+ "input",
3348
+ {
3349
+ ref: folderInputRef,
3350
+ type: "file",
3351
+ multiple: true,
3352
+ onChange: (event) => {
3353
+ if (event.target.files) {
3354
+ void appendFiles(event.target.files);
3355
+ event.target.value = "";
3356
+ }
3357
+ },
3358
+ className: "hidden",
3359
+ ...{ webkitdirectory: "" }
3360
+ }
3361
+ ),
3362
+ /* @__PURE__ */ jsxs8("details", { ref: actionMenuRef, className: "group relative", children: [
3363
+ /* @__PURE__ */ jsx9(
3364
+ "summary",
3259
3365
  {
3260
- type: "button",
3261
- onClick: () => {
3262
- actionMenuRef.current?.removeAttribute("open");
3263
- folderInputRef.current?.click();
3264
- },
3265
- className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3266
- children: [
3267
- /* @__PURE__ */ jsx8(FolderUp, { size: 13 }),
3268
- "\u4E0A\u4F20\u6587\u4EF6\u5939"
3269
- ]
3366
+ "aria-label": "\u6DFB\u52A0\u5185\u5BB9",
3367
+ title: "\u6DFB\u52A0\u5185\u5BB9",
3368
+ 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",
3369
+ children: /* @__PURE__ */ jsx9(Plus, { size: 14 })
3270
3370
  }
3271
3371
  ),
3272
- onCommand ? /* @__PURE__ */ jsxs7(Fragment, { children: [
3273
- /* @__PURE__ */ jsxs7(
3274
- "button",
3275
- {
3276
- type: "button",
3277
- onClick: () => {
3278
- actionMenuRef.current?.removeAttribute("open");
3279
- void onCommand("compact");
3280
- },
3281
- disabled: isStreaming,
3282
- 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",
3283
- children: [
3284
- isStreaming ? /* @__PURE__ */ jsx8(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx8(Scissors, { size: 13 }),
3285
- "\u6574\u7406\u5BF9\u8BDD"
3286
- ]
3287
- }
3288
- ),
3289
- /* @__PURE__ */ jsxs7(
3372
+ /* @__PURE__ */ jsxs8("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: [
3373
+ /* @__PURE__ */ jsxs8(
3290
3374
  "button",
3291
3375
  {
3292
3376
  type: "button",
3293
3377
  onClick: () => {
3294
3378
  actionMenuRef.current?.removeAttribute("open");
3295
- void onCommand("download_session");
3379
+ fileInputRef.current?.click();
3296
3380
  },
3297
3381
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3298
3382
  children: [
3299
- /* @__PURE__ */ jsx8(Download, { size: 13 }),
3300
- "\u5BFC\u51FA\u4F1A\u8BDD"
3383
+ /* @__PURE__ */ jsx9(Paperclip, { size: 13 }),
3384
+ "\u4E0A\u4F20\u6587\u4EF6"
3301
3385
  ]
3302
3386
  }
3303
3387
  ),
3304
- canShareSession ? /* @__PURE__ */ jsxs7(
3305
- "button",
3306
- {
3307
- type: "button",
3308
- onClick: () => {
3309
- actionMenuRef.current?.removeAttribute("open");
3310
- void onCommand("share_session");
3311
- },
3312
- className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3313
- children: [
3314
- /* @__PURE__ */ jsx8(Share2, { size: 13 }),
3315
- "\u5206\u4EAB\u4F1A\u8BDD"
3316
- ]
3317
- }
3318
- ) : null,
3319
- /* @__PURE__ */ jsxs7(
3388
+ /* @__PURE__ */ jsxs8(
3320
3389
  "button",
3321
3390
  {
3322
3391
  type: "button",
3323
3392
  onClick: () => {
3324
3393
  actionMenuRef.current?.removeAttribute("open");
3325
- void onCommand("extract_skill");
3394
+ folderInputRef.current?.click();
3326
3395
  },
3327
3396
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3328
3397
  children: [
3329
- /* @__PURE__ */ jsx8(FlaskConical, { size: 13 }),
3330
- "\u63D0\u53D6\u6280\u80FD"
3398
+ /* @__PURE__ */ jsx9(FolderUp, { size: 13 }),
3399
+ "\u4E0A\u4F20\u6587\u4EF6\u5939"
3331
3400
  ]
3332
3401
  }
3333
3402
  ),
3334
- /* @__PURE__ */ jsxs7(
3335
- "button",
3336
- {
3337
- type: "button",
3338
- onClick: () => {
3339
- actionMenuRef.current?.removeAttribute("open");
3340
- void onCommand("generate_app");
3341
- },
3342
- className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3343
- children: [
3344
- /* @__PURE__ */ jsx8(Rocket, { size: 13 }),
3345
- "\u751F\u6210\u5E94\u7528"
3346
- ]
3347
- }
3348
- )
3349
- ] }) : null,
3350
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 px-3 py-2", children: [
3351
- /* @__PURE__ */ jsx8(Sparkles2, { size: 13 }),
3352
- /* @__PURE__ */ jsx8("span", { className: "shrink-0", children: "\u6A21\u578B" }),
3353
- /* @__PURE__ */ jsx8(
3354
- ModelSelector,
3355
- {
3356
- value: selectedModel,
3357
- onValueChange: (model) => {
3358
- setSelectedModel(model);
3359
- if (activeSessionId) {
3360
- patchSession(activeSessionId, { model });
3361
- }
3362
- setPreferredModel(model);
3363
- },
3364
- compact: true,
3365
- placement: "top"
3366
- }
3367
- )
3403
+ onCommand ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
3404
+ /* @__PURE__ */ jsxs8(
3405
+ "button",
3406
+ {
3407
+ type: "button",
3408
+ onClick: () => {
3409
+ actionMenuRef.current?.removeAttribute("open");
3410
+ void onCommand("compact");
3411
+ },
3412
+ disabled: isStreaming,
3413
+ 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",
3414
+ children: [
3415
+ isStreaming ? /* @__PURE__ */ jsx9(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx9(Scissors, { size: 13 }),
3416
+ "\u6574\u7406\u5BF9\u8BDD"
3417
+ ]
3418
+ }
3419
+ ),
3420
+ /* @__PURE__ */ jsxs8(
3421
+ "button",
3422
+ {
3423
+ type: "button",
3424
+ onClick: () => {
3425
+ actionMenuRef.current?.removeAttribute("open");
3426
+ void onCommand("download_session");
3427
+ },
3428
+ className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3429
+ children: [
3430
+ /* @__PURE__ */ jsx9(Download, { size: 13 }),
3431
+ "\u5BFC\u51FA\u4F1A\u8BDD"
3432
+ ]
3433
+ }
3434
+ ),
3435
+ canShareSession ? /* @__PURE__ */ jsxs8(
3436
+ "button",
3437
+ {
3438
+ type: "button",
3439
+ onClick: () => {
3440
+ actionMenuRef.current?.removeAttribute("open");
3441
+ void onCommand("share_session");
3442
+ },
3443
+ className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3444
+ children: [
3445
+ /* @__PURE__ */ jsx9(Share2, { size: 13 }),
3446
+ "\u5206\u4EAB\u4F1A\u8BDD"
3447
+ ]
3448
+ }
3449
+ ) : null,
3450
+ /* @__PURE__ */ jsxs8(
3451
+ "button",
3452
+ {
3453
+ type: "button",
3454
+ onClick: () => {
3455
+ actionMenuRef.current?.removeAttribute("open");
3456
+ void onCommand("extract_skill");
3457
+ },
3458
+ className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3459
+ children: [
3460
+ /* @__PURE__ */ jsx9(FlaskConical, { size: 13 }),
3461
+ "\u63D0\u53D6\u6280\u80FD"
3462
+ ]
3463
+ }
3464
+ ),
3465
+ /* @__PURE__ */ jsxs8(
3466
+ "button",
3467
+ {
3468
+ type: "button",
3469
+ onClick: () => {
3470
+ actionMenuRef.current?.removeAttribute("open");
3471
+ void onCommand("generate_app");
3472
+ },
3473
+ className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3474
+ children: [
3475
+ /* @__PURE__ */ jsx9(Rocket, { size: 13 }),
3476
+ "\u751F\u6210\u5E94\u7528"
3477
+ ]
3478
+ }
3479
+ )
3480
+ ] }) : null,
3481
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 px-3 py-2", children: [
3482
+ /* @__PURE__ */ jsx9(Sparkles2, { size: 13 }),
3483
+ /* @__PURE__ */ jsx9("span", { className: "shrink-0", children: "\u6A21\u578B" }),
3484
+ /* @__PURE__ */ jsx9(
3485
+ ModelSelector,
3486
+ {
3487
+ value: selectedModel,
3488
+ onValueChange: (model) => {
3489
+ setSelectedModel(model);
3490
+ if (activeSessionId) {
3491
+ patchSession(activeSessionId, { model });
3492
+ }
3493
+ setPreferredModel(model);
3494
+ },
3495
+ compact: true,
3496
+ placement: "top"
3497
+ }
3498
+ )
3499
+ ] })
3368
3500
  ] })
3369
- ] })
3370
- ] }),
3371
- /* @__PURE__ */ jsx8(
3372
- "button",
3373
- {
3374
- type: "button",
3375
- onClick: onToggleMode,
3376
- disabled: isStreaming || !onToggleMode,
3377
- "aria-pressed": isPlanning,
3378
- "aria-label": isPlanning ? "\u5173\u95ED\u89C4\u5212\u6A21\u5F0F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
3379
- title: isPlanning ? "\u89C4\u5212\u6A21\u5F0F\u5DF2\u5F00\u542F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
3380
- 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`,
3381
- children: /* @__PURE__ */ jsx8(Lightbulb, { size: 13 })
3382
- }
3383
- )
3384
- ] }),
3385
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5", children: [
3386
- /* @__PURE__ */ jsxs7("div", { className: "group/help relative", children: [
3387
- /* @__PURE__ */ jsx8(
3501
+ ] }),
3502
+ /* @__PURE__ */ jsx9(
3388
3503
  "button",
3389
3504
  {
3390
3505
  type: "button",
3391
- "aria-label": "\u67E5\u770B\u8F93\u5165\u63D0\u793A",
3392
- 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))]",
3393
- children: /* @__PURE__ */ jsx8(CircleHelp, { size: 13 })
3506
+ onClick: onToggleMode,
3507
+ disabled: isStreaming || !onToggleMode,
3508
+ "aria-pressed": isPlanning,
3509
+ "aria-label": isPlanning ? "\u5173\u95ED\u89C4\u5212\u6A21\u5F0F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
3510
+ title: isPlanning ? "\u89C4\u5212\u6A21\u5F0F\u5DF2\u5F00\u542F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
3511
+ 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`,
3512
+ children: /* @__PURE__ */ jsx9(Lightbulb, { size: 13 })
3394
3513
  }
3395
- ),
3396
- /* @__PURE__ */ jsx8("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__ */ jsxs7("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: [
3397
- activeSessionId ? /* @__PURE__ */ jsx8("div", { className: "mb-2 border-b border-[hsl(var(--border))] pb-2", children: /* @__PURE__ */ jsx8(
3398
- SkillStatusBarComponent,
3514
+ )
3515
+ ] }),
3516
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1.5", children: [
3517
+ /* @__PURE__ */ jsxs8("div", { className: "group/help relative", children: [
3518
+ /* @__PURE__ */ jsx9(
3519
+ "button",
3399
3520
  {
3400
- sessionId: activeSessionId,
3401
- onResync: onResyncSkills,
3402
- isResyncing: isResyncingSkills,
3403
- vertical: true,
3404
- className: skillStatusBarClassName,
3405
- innerClassName: skillStatusBarInnerClassName
3521
+ type: "button",
3522
+ "aria-label": "\u67E5\u770B\u8F93\u5165\u63D0\u793A",
3523
+ 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))]",
3524
+ children: /* @__PURE__ */ jsx9(CircleHelp, { size: 13 })
3406
3525
  }
3407
- ) }) : null,
3408
- /* @__PURE__ */ jsxs7("div", { className: "space-y-0.5", children: [
3409
- /* @__PURE__ */ jsx8("div", { children: "Shift+Enter \u6362\u884C" }),
3410
- /* @__PURE__ */ jsx8("div", { children: "/ \u8C03\u7528\u6280\u80FD" }),
3411
- /* @__PURE__ */ jsx8("div", { children: "@ \u5F15\u7528\u6587\u4EF6" })
3412
- ] })
3413
- ] }) })
3414
- ] }),
3415
- /* @__PURE__ */ jsx8(
3416
- "button",
3417
- {
3418
- type: "button",
3419
- onClick: asrEnabled ? voice.toggle : handleMicDisabledClick,
3420
- disabled: isStreaming,
3421
- "aria-label": !asrEnabled ? "\u8BED\u97F3\u8F93\u5165\u672A\u5F00\u542F" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u5F00\u59CB\u8BED\u97F3\u8F93\u5165",
3422
- title: !asrEnabled ? "\u8BED\u97F3\u8F93\u5165\u672A\u5F00\u542F" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u8BED\u97F3\u8F93\u5165",
3423
- 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))]"}`,
3424
- children: !asrEnabled ? /* @__PURE__ */ jsx8(MicOff, { size: 13 }) : isRecording ? /* @__PURE__ */ jsx8(VoiceWaveform, { level: voiceLevel, size: 18 }) : /* @__PURE__ */ jsx8(Mic, { size: 13 })
3425
- }
3426
- ),
3427
- isStreaming ? /* @__PURE__ */ jsx8(
3428
- "button",
3429
- {
3430
- type: "button",
3431
- onClick: onStop,
3432
- "aria-label": "\u505C\u6B62\u751F\u6210",
3433
- 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",
3434
- children: /* @__PURE__ */ jsx8(Square, { size: 13 })
3435
- }
3436
- ) : /* @__PURE__ */ jsx8(
3437
- "button",
3438
- {
3439
- type: "button",
3440
- onClick: handleSubmit,
3441
- disabled: isSendDisabled || isRecording,
3442
- "aria-label": "\u53D1\u9001\u6D88\u606F",
3443
- 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",
3444
- children: /* @__PURE__ */ jsx8(Send, { size: 13 })
3445
- }
3446
- )
3526
+ ),
3527
+ /* @__PURE__ */ jsx9("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__ */ jsxs8("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: [
3528
+ activeSessionId ? /* @__PURE__ */ jsx9("div", { className: "mb-2 border-b border-[hsl(var(--border))] pb-2", children: /* @__PURE__ */ jsx9(
3529
+ SkillStatusBarComponent,
3530
+ {
3531
+ sessionId: activeSessionId,
3532
+ onResync: onResyncSkills,
3533
+ isResyncing: isResyncingSkills,
3534
+ vertical: true,
3535
+ className: skillStatusBarClassName,
3536
+ innerClassName: skillStatusBarInnerClassName
3537
+ }
3538
+ ) }) : null,
3539
+ /* @__PURE__ */ jsxs8("div", { className: "space-y-0.5", children: [
3540
+ /* @__PURE__ */ jsx9("div", { children: "Shift+Enter \u6362\u884C" }),
3541
+ /* @__PURE__ */ jsx9("div", { children: "/ \u8C03\u7528\u6280\u80FD" }),
3542
+ /* @__PURE__ */ jsx9("div", { children: "@ \u5F15\u7528\u6587\u4EF6" })
3543
+ ] })
3544
+ ] }) })
3545
+ ] }),
3546
+ /* @__PURE__ */ jsx9(
3547
+ "button",
3548
+ {
3549
+ type: "button",
3550
+ onClick: asrEnabled ? voice.toggle : handleMicDisabledClick,
3551
+ disabled: isStreaming,
3552
+ "aria-label": !asrEnabled ? "\u8BED\u97F3\u8F93\u5165\u672A\u5F00\u542F" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u5F00\u59CB\u8BED\u97F3\u8F93\u5165",
3553
+ title: !asrEnabled ? "\u8BED\u97F3\u8F93\u5165\u672A\u5F00\u542F" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u8BED\u97F3\u8F93\u5165",
3554
+ 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))]"}`,
3555
+ children: !asrEnabled ? /* @__PURE__ */ jsx9(MicOff, { size: 13 }) : isRecording ? /* @__PURE__ */ jsx9(VoiceWaveform, { level: voiceLevel, size: 18 }) : /* @__PURE__ */ jsx9(Mic, { size: 13 })
3556
+ }
3557
+ ),
3558
+ isStreaming ? /* @__PURE__ */ jsx9(
3559
+ "button",
3560
+ {
3561
+ type: "button",
3562
+ onClick: onStop,
3563
+ "aria-label": "\u505C\u6B62\u751F\u6210",
3564
+ 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",
3565
+ children: /* @__PURE__ */ jsx9(Square2, { size: 13 })
3566
+ }
3567
+ ) : /* @__PURE__ */ jsx9(
3568
+ "button",
3569
+ {
3570
+ type: "button",
3571
+ onClick: handleSubmit,
3572
+ disabled: isSendDisabled || isRecording,
3573
+ "aria-label": "\u53D1\u9001\u6D88\u606F",
3574
+ 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",
3575
+ children: /* @__PURE__ */ jsx9(Send, { size: 13 })
3576
+ }
3577
+ )
3578
+ ] })
3447
3579
  ] })
3448
- ] })
3449
- ]
3450
- }
3451
- )
3452
- }
3453
- ) }) }),
3454
- /* @__PURE__ */ jsx8(
3580
+ ]
3581
+ }
3582
+ )
3583
+ }
3584
+ )
3585
+ ] }) }),
3586
+ /* @__PURE__ */ jsx9(
3455
3587
  FileSizeLimitDialog,
3456
3588
  {
3457
3589
  open: oversizedFiles.length > 0,
@@ -3469,18 +3601,18 @@ function ChatInput({
3469
3601
 
3470
3602
  // src/react/components/chat/ConnectionBanner.tsx
3471
3603
  import { AlertTriangle, LoaderCircle } from "lucide-react";
3472
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
3604
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
3473
3605
  function getBannerCopy(status, reconnectAttempt, hasEverConnected) {
3474
3606
  if (status === "connecting") {
3475
3607
  return {
3476
- icon: /* @__PURE__ */ jsx9(LoaderCircle, { size: 14, className: "animate-spin" }),
3608
+ icon: /* @__PURE__ */ jsx10(LoaderCircle, { size: 14, className: "animate-spin" }),
3477
3609
  toneClass: "border-amber-500/25 bg-amber-500/10 text-amber-100",
3478
3610
  title: "\u8FDE\u63A5\u5DF2\u65AD\u5F00\uFF0C\u6B63\u5728\u91CD\u8FDE\u2026",
3479
3611
  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"
3480
3612
  };
3481
3613
  }
3482
3614
  return {
3483
- icon: /* @__PURE__ */ jsx9(AlertTriangle, { size: 14 }),
3615
+ icon: /* @__PURE__ */ jsx10(AlertTriangle, { size: 14 }),
3484
3616
  toneClass: "border-rose-500/25 bg-rose-500/10 text-rose-100",
3485
3617
  title: hasEverConnected ? "\u8FDE\u63A5\u5DF2\u65AD\u5F00\uFF0C\u6B63\u5728\u7B49\u5F85\u91CD\u8FDE\u2026" : "\u6682\u65F6\u65E0\u6CD5\u5EFA\u7ACB\u8FDE\u63A5",
3486
3618
  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"
@@ -3495,7 +3627,7 @@ function ConnectionBanner() {
3495
3627
  return null;
3496
3628
  }
3497
3629
  const copy = getBannerCopy(status, reconnectAttempt, hasEverConnected);
3498
- return /* @__PURE__ */ jsx9("div", { className: "bg-[hsl(var(--background))] px-5 pt-3", children: /* @__PURE__ */ jsxs8(
3630
+ return /* @__PURE__ */ jsx10("div", { className: "bg-[hsl(var(--background))] px-5 pt-3", children: /* @__PURE__ */ jsxs9(
3499
3631
  "div",
3500
3632
  {
3501
3633
  className: cn(
@@ -3503,10 +3635,10 @@ function ConnectionBanner() {
3503
3635
  copy.toneClass
3504
3636
  ),
3505
3637
  children: [
3506
- /* @__PURE__ */ jsx9("span", { className: "mt-0.5 shrink-0", children: copy.icon }),
3507
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
3508
- /* @__PURE__ */ jsx9("div", { className: "text-sm font-medium", children: copy.title }),
3509
- /* @__PURE__ */ jsx9("div", { className: "text-xs opacity-80", children: copy.detail })
3638
+ /* @__PURE__ */ jsx10("span", { className: "mt-0.5 shrink-0", children: copy.icon }),
3639
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
3640
+ /* @__PURE__ */ jsx10("div", { className: "text-sm font-medium", children: copy.title }),
3641
+ /* @__PURE__ */ jsx10("div", { className: "text-xs opacity-80", children: copy.detail })
3510
3642
  ] })
3511
3643
  ]
3512
3644
  }
@@ -3521,11 +3653,11 @@ import {
3521
3653
  useEffectEvent as useEffectEvent4,
3522
3654
  useMemo as useMemo17,
3523
3655
  useRef as useRef11,
3524
- useState as useState19
3656
+ useState as useState20
3525
3657
  } from "react";
3526
3658
 
3527
3659
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
3528
- import { useCallback as useCallback7, useMemo as useMemo8, useRef as useRef5, useState as useState7 } from "react";
3660
+ import { useCallback as useCallback7, useMemo as useMemo8, useRef as useRef5, useState as useState8 } from "react";
3529
3661
  var DEFAULT_SPRING_ANIMATION = {
3530
3662
  /**
3531
3663
  * A value from 0 to 1, on how much to damp the animation.
@@ -3562,9 +3694,9 @@ globalThis.document?.addEventListener("click", () => {
3562
3694
  mouseDown = false;
3563
3695
  });
3564
3696
  var useStickToBottom = (options = {}) => {
3565
- const [escapedFromLock, updateEscapedFromLock] = useState7(false);
3566
- const [isAtBottom, updateIsAtBottom] = useState7(options.initial !== false);
3567
- const [isNearBottom, setIsNearBottom] = useState7(false);
3697
+ const [escapedFromLock, updateEscapedFromLock] = useState8(false);
3698
+ const [isAtBottom, updateIsAtBottom] = useState8(options.initial !== false);
3699
+ const [isNearBottom, setIsNearBottom] = useState8(false);
3568
3700
  const optionsRef = useRef5(null);
3569
3701
  optionsRef.current = options;
3570
3702
  const isSelecting = useCallback7(() => {
@@ -3950,7 +4082,7 @@ function useStickToBottomContext() {
3950
4082
 
3951
4083
  // src/react/components/chat/AssistantTurnBlock.tsx
3952
4084
  import { AlertCircle, BookOpen, Check as Check4, ChevronRight as ChevronRight5 } from "lucide-react";
3953
- import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo15, useRef as useRef10, useState as useState16 } from "react";
4085
+ import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo15, useRef as useRef10, useState as useState17 } from "react";
3954
4086
 
3955
4087
  // src/react/routes.ts
3956
4088
  var MEMORIES_ROUTE = "/memories";
@@ -3969,7 +4101,7 @@ import {
3969
4101
  useEffect as useEffect9,
3970
4102
  useMemo as useMemo11,
3971
4103
  useRef as useRef7,
3972
- useState as useState8
4104
+ useState as useState9
3973
4105
  } from "react";
3974
4106
  import { createPortal as createPortal2 } from "react-dom";
3975
4107
  import { Streamdown } from "streamdown";
@@ -3977,7 +4109,7 @@ import { Streamdown } from "streamdown";
3977
4109
  // src/react/components/ai-elements/shimmer.tsx
3978
4110
  import { motion } from "motion/react";
3979
4111
  import { memo, useMemo as useMemo10 } from "react";
3980
- import { jsx as jsx10 } from "react/jsx-runtime";
4112
+ import { jsx as jsx11 } from "react/jsx-runtime";
3981
4113
  var motionComponentCache = /* @__PURE__ */ new Map();
3982
4114
  var getMotionComponent = (element) => {
3983
4115
  let component = motionComponentCache.get(element);
@@ -4001,7 +4133,7 @@ var ShimmerComponent = ({
4001
4133
  () => (children?.length ?? 0) * spread,
4002
4134
  [children, spread]
4003
4135
  );
4004
- return /* @__PURE__ */ jsx10(
4136
+ return /* @__PURE__ */ jsx11(
4005
4137
  MotionComponent,
4006
4138
  {
4007
4139
  animate: { backgroundPosition: "0% center" },
@@ -4027,7 +4159,7 @@ var ShimmerComponent = ({
4027
4159
  var Shimmer = memo(ShimmerComponent);
4028
4160
 
4029
4161
  // src/react/components/ai-elements/reasoning.tsx
4030
- import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
4162
+ import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
4031
4163
  var ReasoningContext = createContext2(null);
4032
4164
  var useReasoning = () => {
4033
4165
  const context = useContext2(ReasoningContext);
@@ -4061,7 +4193,7 @@ var Reasoning = memo2(
4061
4193
  prop: durationProp
4062
4194
  });
4063
4195
  const hasEverStreamedRef = useRef7(isStreaming);
4064
- const [hasAutoClosed, setHasAutoClosed] = useState8(false);
4196
+ const [hasAutoClosed, setHasAutoClosed] = useState9(false);
4065
4197
  const startTimeRef = useRef7(null);
4066
4198
  useEffect9(() => {
4067
4199
  if (isStreaming) {
@@ -4098,7 +4230,7 @@ var Reasoning = memo2(
4098
4230
  () => ({ duration, isOpen, isStreaming, setIsOpen }),
4099
4231
  [duration, isOpen, isStreaming, setIsOpen]
4100
4232
  );
4101
- return /* @__PURE__ */ jsx11(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx11(
4233
+ return /* @__PURE__ */ jsx12(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx12(
4102
4234
  Collapsible,
4103
4235
  {
4104
4236
  className: cn("not-prose mb-4", className),
@@ -4112,12 +4244,12 @@ var Reasoning = memo2(
4112
4244
  );
4113
4245
  var defaultGetThinkingMessage = (isStreaming, duration) => {
4114
4246
  if (isStreaming || duration === 0) {
4115
- return /* @__PURE__ */ jsx11(Shimmer, { duration: 1, children: "\u6DF1\u5EA6\u601D\u8003\u4E2D..." });
4247
+ return /* @__PURE__ */ jsx12(Shimmer, { duration: 1, children: "\u6DF1\u5EA6\u601D\u8003\u4E2D..." });
4116
4248
  }
4117
4249
  if (duration === void 0) {
4118
- return /* @__PURE__ */ jsx11("p", { children: "\u5DF2\u6DF1\u5EA6\u601D\u8003" });
4250
+ return /* @__PURE__ */ jsx12("p", { children: "\u5DF2\u6DF1\u5EA6\u601D\u8003" });
4119
4251
  }
4120
- return /* @__PURE__ */ jsxs9("p", { children: [
4252
+ return /* @__PURE__ */ jsxs10("p", { children: [
4121
4253
  "\u5DF2\u6DF1\u5EA6\u601D\u8003 ",
4122
4254
  duration,
4123
4255
  " \u79D2"
@@ -4131,7 +4263,7 @@ var ReasoningTrigger = memo2(
4131
4263
  ...props
4132
4264
  }) => {
4133
4265
  const { isStreaming, isOpen, duration } = useReasoning();
4134
- return /* @__PURE__ */ jsx11(
4266
+ return /* @__PURE__ */ jsx12(
4135
4267
  CollapsibleTrigger,
4136
4268
  {
4137
4269
  className: cn(
@@ -4139,10 +4271,10 @@ var ReasoningTrigger = memo2(
4139
4271
  className
4140
4272
  ),
4141
4273
  ...props,
4142
- children: children ?? /* @__PURE__ */ jsxs9(Fragment2, { children: [
4143
- /* @__PURE__ */ jsx11(BrainIcon, { className: "size-4" }),
4274
+ children: children ?? /* @__PURE__ */ jsxs10(Fragment3, { children: [
4275
+ /* @__PURE__ */ jsx12(BrainIcon, { className: "size-4" }),
4144
4276
  getThinkingMessage(isStreaming, duration),
4145
- /* @__PURE__ */ jsx11(
4277
+ /* @__PURE__ */ jsx12(
4146
4278
  ChevronDownIcon,
4147
4279
  {
4148
4280
  className: cn(
@@ -4159,7 +4291,7 @@ var ReasoningTrigger = memo2(
4159
4291
  var streamdownPlugins = { cjk, math, mermaid };
4160
4292
  var streamdownComponents = { code: CardCodeBlock };
4161
4293
  var ReasoningContent = memo2(
4162
- ({ className, children, ...props }) => /* @__PURE__ */ jsx11(
4294
+ ({ className, children, ...props }) => /* @__PURE__ */ jsx12(
4163
4295
  CollapsibleContent,
4164
4296
  {
4165
4297
  className: cn(
@@ -4168,7 +4300,7 @@ var ReasoningContent = memo2(
4168
4300
  className
4169
4301
  ),
4170
4302
  ...props,
4171
- children: /* @__PURE__ */ jsx11(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children })
4303
+ children: /* @__PURE__ */ jsx12(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children })
4172
4304
  }
4173
4305
  )
4174
4306
  );
@@ -4177,8 +4309,8 @@ function compactReasoningText(text) {
4177
4309
  }
4178
4310
  function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
4179
4311
  const compactReasoning = compactReasoningText(reasoning);
4180
- const [open, setOpen] = useState8(false);
4181
- return /* @__PURE__ */ jsxs9(
4312
+ const [open, setOpen] = useState9(false);
4313
+ return /* @__PURE__ */ jsxs10(
4182
4314
  "span",
4183
4315
  {
4184
4316
  className: cn(
@@ -4186,7 +4318,7 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
4186
4318
  variant === "inline" ? "ml-1" : "ml-1 shrink-0"
4187
4319
  ),
4188
4320
  children: [
4189
- /* @__PURE__ */ jsx11(
4321
+ /* @__PURE__ */ jsx12(
4190
4322
  "button",
4191
4323
  {
4192
4324
  type: "button",
@@ -4201,7 +4333,7 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
4201
4333
  }
4202
4334
  ),
4203
4335
  open ? createPortal2(
4204
- /* @__PURE__ */ jsx11(
4336
+ /* @__PURE__ */ jsx12(
4205
4337
  "div",
4206
4338
  {
4207
4339
  className: "fixed inset-0 z-[70] flex items-center justify-center bg-black/10 p-6",
@@ -4217,26 +4349,26 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
4217
4349
  setOpen(false);
4218
4350
  }
4219
4351
  },
4220
- children: /* @__PURE__ */ jsxs9(
4352
+ children: /* @__PURE__ */ jsxs10(
4221
4353
  "div",
4222
4354
  {
4223
4355
  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",
4224
4356
  "aria-label": "\u601D\u8003\u8BE6\u60C5",
4225
4357
  children: [
4226
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-2", children: [
4227
- /* @__PURE__ */ jsx11("span", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u601D\u8003\u8BE6\u60C5" }),
4228
- /* @__PURE__ */ jsx11(
4358
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-2", children: [
4359
+ /* @__PURE__ */ jsx12("span", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u601D\u8003\u8BE6\u60C5" }),
4360
+ /* @__PURE__ */ jsx12(
4229
4361
  "button",
4230
4362
  {
4231
4363
  type: "button",
4232
4364
  onClick: () => setOpen(false),
4233
4365
  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",
4234
4366
  "aria-label": "\u5173\u95ED\u601D\u8003\u8BE6\u60C5",
4235
- children: /* @__PURE__ */ jsx11(XIcon, { size: 14, "aria-hidden": "true" })
4367
+ children: /* @__PURE__ */ jsx12(XIcon, { size: 14, "aria-hidden": "true" })
4236
4368
  }
4237
4369
  )
4238
4370
  ] }),
4239
- /* @__PURE__ */ jsx11("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__ */ jsx11(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children: compactReasoning }) })
4371
+ /* @__PURE__ */ jsx12("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__ */ jsx12(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children: compactReasoning }) })
4240
4372
  ]
4241
4373
  }
4242
4374
  )
@@ -4253,12 +4385,12 @@ ReasoningTrigger.displayName = "ReasoningTrigger";
4253
4385
  ReasoningContent.displayName = "ReasoningContent";
4254
4386
 
4255
4387
  // src/react/components/chat/AgentLoopBlock.tsx
4256
- import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText5, Loader2 as Loader24, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
4257
- import { useEffect as useEffect13, useMemo as useMemo14, useState as useState15 } from "react";
4388
+ import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText6, Loader2 as Loader24, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
4389
+ import { useEffect as useEffect13, useMemo as useMemo14, useState as useState16 } from "react";
4258
4390
 
4259
4391
  // src/react/components/chat/ResourceIframe.tsx
4260
- import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef8, useState as useState9 } from "react";
4261
- import { jsx as jsx12 } from "react/jsx-runtime";
4392
+ import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef8, useState as useState10 } from "react";
4393
+ import { jsx as jsx13 } from "react/jsx-runtime";
4262
4394
  function isResourceBridgeMessage(value) {
4263
4395
  return typeof value === "object" && value !== null && value.__resourceBridge === true && typeof value.action === "string";
4264
4396
  }
@@ -4275,7 +4407,7 @@ function ResourceIframe({ ui, sessionId }) {
4275
4407
  const theme = useUiStore((state) => state.theme);
4276
4408
  const resourceUri = ui.resourceUri ?? ui.resourceURI;
4277
4409
  const iframeLabel = ui.title ?? resourceUri ?? "\u5DE5\u5177\u754C\u9762";
4278
- const [autoHeight, setAutoHeight] = useState9(null);
4410
+ const [autoHeight, setAutoHeight] = useState10(null);
4279
4411
  useEffect10(() => {
4280
4412
  setAutoHeight(null);
4281
4413
  }, [ui.resourceHTML, resourceUri]);
@@ -4364,7 +4496,7 @@ function ResourceIframe({ ui, sessionId }) {
4364
4496
  }
4365
4497
  const inlineHeight = autoHeight ?? ui.height;
4366
4498
  const sandbox = resourceUri ? "allow-scripts allow-same-origin" : "allow-scripts";
4367
- return /* @__PURE__ */ jsx12(
4499
+ return /* @__PURE__ */ jsx13(
4368
4500
  "iframe",
4369
4501
  {
4370
4502
  ref: iframeRef,
@@ -4386,10 +4518,10 @@ function ResourceIframe({ ui, sessionId }) {
4386
4518
 
4387
4519
  // src/react/components/chat/ToolCallBlock.tsx
4388
4520
  import { Check, ChevronRight as ChevronRight3, Loader2 as Loader23, MessageSquareMore, PanelRightOpen, X as X4 } from "lucide-react";
4389
- import { useMemo as useMemo12, useState as useState12 } from "react";
4521
+ import { useMemo as useMemo12, useState as useState13 } from "react";
4390
4522
 
4391
4523
  // src/react/components/chat/tool-renderers/shared.tsx
4392
- import { jsx as jsx13 } from "react/jsx-runtime";
4524
+ import { jsx as jsx14 } from "react/jsx-runtime";
4393
4525
  function getResultText(result) {
4394
4526
  if (typeof result === "string") return result;
4395
4527
  if (Array.isArray(result)) {
@@ -4456,7 +4588,7 @@ function CodePreview({
4456
4588
  }) {
4457
4589
  const { highlightedHtml } = useHighlightedCodeHtml(content, getCodeLanguage(filePath));
4458
4590
  if (!content.trim()) {
4459
- return /* @__PURE__ */ jsx13(
4591
+ return /* @__PURE__ */ jsx14(
4460
4592
  "pre",
4461
4593
  {
4462
4594
  className: cn(
@@ -4464,11 +4596,11 @@ function CodePreview({
4464
4596
  "bg-[hsl(var(--muted))]/35 p-3 font-mono text-[11px] text-[hsl(var(--muted-foreground))]",
4465
4597
  className
4466
4598
  ),
4467
- children: /* @__PURE__ */ jsx13("code", { children: emptyLabel })
4599
+ children: /* @__PURE__ */ jsx14("code", { children: emptyLabel })
4468
4600
  }
4469
4601
  );
4470
4602
  }
4471
- return /* @__PURE__ */ jsx13(
4603
+ return /* @__PURE__ */ jsx14(
4472
4604
  "pre",
4473
4605
  {
4474
4606
  className: cn(
@@ -4476,19 +4608,19 @@ function CodePreview({
4476
4608
  "bg-[hsl(var(--muted))]/35 p-3 text-[11px]",
4477
4609
  className
4478
4610
  ),
4479
- children: highlightedHtml ? /* @__PURE__ */ jsx13(
4611
+ children: highlightedHtml ? /* @__PURE__ */ jsx14(
4480
4612
  "code",
4481
4613
  {
4482
4614
  className: "font-mono",
4483
4615
  dangerouslySetInnerHTML: { __html: highlightedHtml }
4484
4616
  }
4485
- ) : /* @__PURE__ */ jsx13("code", { className: "whitespace-pre-wrap break-words font-mono text-[hsl(var(--foreground))]", children: content })
4617
+ ) : /* @__PURE__ */ jsx14("code", { className: "whitespace-pre-wrap break-words font-mono text-[hsl(var(--foreground))]", children: content })
4486
4618
  }
4487
4619
  );
4488
4620
  }
4489
4621
 
4490
4622
  // src/react/components/chat/tool-renderers/BashRenderer.tsx
4491
- import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
4623
+ import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
4492
4624
  function pickOutputField(data) {
4493
4625
  if (!data) return null;
4494
4626
  for (const key of ["output", "stdout", "stderr"]) {
@@ -4498,7 +4630,7 @@ function pickOutputField(data) {
4498
4630
  return null;
4499
4631
  }
4500
4632
  function MetaPill({ label }) {
4501
- return /* @__PURE__ */ jsx14("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-[10px] text-secondary-foreground", children: label });
4633
+ return /* @__PURE__ */ jsx15("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-[10px] text-secondary-foreground", children: label });
4502
4634
  }
4503
4635
  function BashRenderer({ toolCall }) {
4504
4636
  const argsValue = parseJsonValue(toolCall.arguments);
@@ -4521,16 +4653,16 @@ function BashRenderer({ toolCall }) {
4521
4653
  const rawFallbackOutput = result === null && typeof resultStr === "string" && resultStr.trim().length > 0 ? resultStr : null;
4522
4654
  const output = structuredOutput !== null ? structuredOutput : errorMessage ?? rawFallbackOutput ?? (normalizedName === "BgBash" ? "" : null);
4523
4655
  const hasFailure = toolCall.status === "error" || timedOut || exitCode !== null && exitCode !== 0;
4524
- return /* @__PURE__ */ jsxs10("div", { className: "space-y-3", children: [
4525
- (description || cwd) && /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
4526
- description ? /* @__PURE__ */ jsx14("span", { children: description }) : null,
4527
- cwd ? /* @__PURE__ */ jsx14("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: cwd }) : null
4656
+ return /* @__PURE__ */ jsxs11("div", { className: "space-y-3", children: [
4657
+ (description || cwd) && /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
4658
+ description ? /* @__PURE__ */ jsx15("span", { children: description }) : null,
4659
+ cwd ? /* @__PURE__ */ jsx15("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: cwd }) : null
4528
4660
  ] }),
4529
- /* @__PURE__ */ jsxs10("div", { className: "overflow-hidden rounded-lg border border-border bg-card", children: [
4530
- /* @__PURE__ */ jsx14("div", { className: "border-b border-border px-3 py-2 text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u547D\u4EE4" }),
4531
- /* @__PURE__ */ jsx14("pre", { className: "overflow-x-auto px-3 py-3 font-mono text-[11px] leading-5 text-foreground", children: /* @__PURE__ */ jsx14("code", { children: `$ ${command || "\uFF08\u672A\u63D0\u4F9B\u547D\u4EE4\uFF09"}` }) })
4661
+ /* @__PURE__ */ jsxs11("div", { className: "overflow-hidden rounded-lg border border-border bg-card", children: [
4662
+ /* @__PURE__ */ jsx15("div", { className: "border-b border-border px-3 py-2 text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u547D\u4EE4" }),
4663
+ /* @__PURE__ */ jsx15("pre", { className: "overflow-x-auto px-3 py-3 font-mono text-[11px] leading-5 text-foreground", children: /* @__PURE__ */ jsx15("code", { children: `$ ${command || "\uFF08\u672A\u63D0\u4F9B\u547D\u4EE4\uFF09"}` }) })
4532
4664
  ] }),
4533
- /* @__PURE__ */ jsxs10(
4665
+ /* @__PURE__ */ jsxs11(
4534
4666
  "div",
4535
4667
  {
4536
4668
  className: cn(
@@ -4538,26 +4670,26 @@ function BashRenderer({ toolCall }) {
4538
4670
  hasFailure ? "border-red-500/50" : "border-border"
4539
4671
  ),
4540
4672
  children: [
4541
- /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center justify-between gap-2 border-b border-border px-3 py-2", children: [
4542
- /* @__PURE__ */ jsx14("div", { className: "text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u8F93\u51FA" }),
4543
- /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-1.5", children: [
4544
- taskId ? /* @__PURE__ */ jsx14(MetaPill, { label: `\u4EFB\u52A1 ${taskId}` }) : null,
4545
- exitCode !== null ? /* @__PURE__ */ jsx14(MetaPill, { label: `\u9000\u51FA\u7801 ${exitCode}` }) : null,
4546
- timedOut ? /* @__PURE__ */ jsx14(MetaPill, { label: "\u5DF2\u8D85\u65F6" }) : null,
4547
- truncated ? /* @__PURE__ */ jsx14(MetaPill, { label: "\u8F93\u51FA\u5DF2\u622A\u65AD" }) : null,
4548
- normalizedName === "BgBash" && !taskId ? /* @__PURE__ */ jsx14(MetaPill, { label: "\u540E\u53F0\u4EFB\u52A1" }) : null
4673
+ /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center justify-between gap-2 border-b border-border px-3 py-2", children: [
4674
+ /* @__PURE__ */ jsx15("div", { className: "text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u8F93\u51FA" }),
4675
+ /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-1.5", children: [
4676
+ taskId ? /* @__PURE__ */ jsx15(MetaPill, { label: `\u4EFB\u52A1 ${taskId}` }) : null,
4677
+ exitCode !== null ? /* @__PURE__ */ jsx15(MetaPill, { label: `\u9000\u51FA\u7801 ${exitCode}` }) : null,
4678
+ timedOut ? /* @__PURE__ */ jsx15(MetaPill, { label: "\u5DF2\u8D85\u65F6" }) : null,
4679
+ truncated ? /* @__PURE__ */ jsx15(MetaPill, { label: "\u8F93\u51FA\u5DF2\u622A\u65AD" }) : null,
4680
+ normalizedName === "BgBash" && !taskId ? /* @__PURE__ */ jsx15(MetaPill, { label: "\u540E\u53F0\u4EFB\u52A1" }) : null
4549
4681
  ] })
4550
4682
  ] }),
4551
- /* @__PURE__ */ jsx14("pre", { className: "max-h-[280px] overflow-auto px-3 py-3 font-mono text-[11px] leading-5 text-foreground", children: /* @__PURE__ */ jsx14("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" }) })
4683
+ /* @__PURE__ */ jsx15("pre", { className: "max-h-[280px] overflow-auto px-3 py-3 font-mono text-[11px] leading-5 text-foreground", children: /* @__PURE__ */ jsx15("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" }) })
4552
4684
  ]
4553
4685
  }
4554
4686
  ),
4555
- cwdResetNote ? /* @__PURE__ */ jsx14("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
4687
+ cwdResetNote ? /* @__PURE__ */ jsx15("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
4556
4688
  ] });
4557
4689
  }
4558
4690
 
4559
4691
  // src/react/components/chat/tool-renderers/FileEditRenderer.tsx
4560
- import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
4692
+ import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
4561
4693
  var MAX_DIFF_LINES = 200;
4562
4694
  function computeDiff(oldText, newText) {
4563
4695
  const oldLines = oldText.split("\n");
@@ -4634,6 +4766,26 @@ function buildWritePreview(content) {
4634
4766
  newLine: index + 1
4635
4767
  }));
4636
4768
  }
4769
+ function buildEditPreview(args) {
4770
+ const edits = Array.isArray(args?.edits) ? args.edits : null;
4771
+ if (edits) {
4772
+ return edits.flatMap((rawEdit, index) => {
4773
+ if (!isPlainObject(rawEdit)) {
4774
+ return [];
4775
+ }
4776
+ const oldText = getStringValue(rawEdit, "old_text") ?? "";
4777
+ const newText = getStringValue(rawEdit, "new_text") ?? "";
4778
+ const lines = computeDiff(oldText, newText);
4779
+ return index === 0 ? lines : [
4780
+ { type: "unchanged", value: "", oldLine: null, newLine: null },
4781
+ ...lines
4782
+ ];
4783
+ });
4784
+ }
4785
+ const oldString = getStringValue(args, "old_string") ?? "";
4786
+ const newString = getStringValue(args, "new_string") ?? "";
4787
+ return computeDiff(oldString, newString);
4788
+ }
4637
4789
  function extractChecksum(result) {
4638
4790
  const text = typeof result === "string" ? result : null;
4639
4791
  const match = text?.match(/\[checksum:\s*([^\]]+)\]/);
@@ -4647,26 +4799,26 @@ function FileEditRenderer({ toolCall }) {
4647
4799
  const fileName = getFileName(filePath);
4648
4800
  const errorMessage = extractErrorMessage(toolCall.result);
4649
4801
  const checksum = extractChecksum(toolCall.result);
4802
+ const description = getStringValue(args, "description");
4650
4803
  const writeContent = getStringValue(args, "content") ?? "";
4651
- const oldString = getStringValue(args, "old_string") ?? "";
4652
- const newString = getStringValue(args, "new_string") ?? "";
4653
- const diffLines = normalizedName === "Write" ? buildWritePreview(writeContent) : computeDiff(oldString, newString);
4804
+ const diffLines = normalizedName === "Write" ? buildWritePreview(writeContent) : buildEditPreview(args);
4654
4805
  const resultStr = typeof toolCall.result === "string" ? toolCall.result : null;
4655
4806
  const summaryText = resultStr?.trim() && !errorMessage ? resultStr.trim() : null;
4656
- return /* @__PURE__ */ jsxs11("div", { className: "space-y-3", children: [
4657
- /* @__PURE__ */ jsxs11("div", { className: "flex items-start justify-between gap-3", children: [
4658
- /* @__PURE__ */ jsxs11("div", { className: "min-w-0", children: [
4659
- /* @__PURE__ */ jsx15("div", { className: "text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: normalizedName === "Write" ? "\u5199\u5165\u6587\u4EF6" : "\u7F16\u8F91\u6587\u4EF6" }),
4660
- /* @__PURE__ */ jsx15("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: filePath ?? fileName })
4807
+ return /* @__PURE__ */ jsxs12("div", { className: "space-y-3", children: [
4808
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-start justify-between gap-3", children: [
4809
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
4810
+ /* @__PURE__ */ jsx16("div", { className: "text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: normalizedName === "Write" ? "\u5199\u5165\u6587\u4EF6" : "\u7F16\u8F91\u6587\u4EF6" }),
4811
+ /* @__PURE__ */ jsx16("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: filePath ?? fileName })
4661
4812
  ] }),
4662
- checksum ? /* @__PURE__ */ jsx15("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
4813
+ checksum ? /* @__PURE__ */ jsx16("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
4663
4814
  ] }),
4664
- errorMessage ? /* @__PURE__ */ jsx15("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,
4665
- /* @__PURE__ */ jsxs11("div", { className: "overflow-hidden rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20", children: [
4666
- /* @__PURE__ */ jsx15("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" }),
4667
- /* @__PURE__ */ jsx15("pre", { className: "max-h-[320px] overflow-auto p-0 font-mono text-[11px] leading-5", children: diffLines.length > 0 ? diffLines.map((line, index) => {
4815
+ description ? /* @__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: description }) : null,
4816
+ errorMessage ? /* @__PURE__ */ jsx16("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,
4817
+ /* @__PURE__ */ jsxs12("div", { className: "overflow-hidden rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20", children: [
4818
+ /* @__PURE__ */ jsx16("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" }),
4819
+ /* @__PURE__ */ jsx16("pre", { className: "max-h-[320px] overflow-auto p-0 font-mono text-[11px] leading-5", children: diffLines.length > 0 ? diffLines.map((line, index) => {
4668
4820
  const prefix = line.type === "added" ? "+ " : line.type === "removed" ? "- " : " ";
4669
- return /* @__PURE__ */ jsxs11(
4821
+ return /* @__PURE__ */ jsxs12(
4670
4822
  "div",
4671
4823
  {
4672
4824
  className: cn(
@@ -4676,9 +4828,9 @@ function FileEditRenderer({ toolCall }) {
4676
4828
  line.type === "unchanged" && "text-[hsl(var(--foreground))]"
4677
4829
  ),
4678
4830
  children: [
4679
- /* @__PURE__ */ jsx15("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.oldLine ?? "" }),
4680
- /* @__PURE__ */ jsx15("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.newLine ?? "" }),
4681
- /* @__PURE__ */ jsxs11("span", { className: "min-w-0 whitespace-pre-wrap break-words py-0.5", children: [
4831
+ /* @__PURE__ */ jsx16("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.oldLine ?? "" }),
4832
+ /* @__PURE__ */ jsx16("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.newLine ?? "" }),
4833
+ /* @__PURE__ */ jsxs12("span", { className: "min-w-0 whitespace-pre-wrap break-words py-0.5", children: [
4682
4834
  prefix,
4683
4835
  line.value
4684
4836
  ] })
@@ -4686,24 +4838,24 @@ function FileEditRenderer({ toolCall }) {
4686
4838
  },
4687
4839
  `${line.type}-${line.oldLine}-${line.newLine}-${index}`
4688
4840
  );
4689
- }) : /* @__PURE__ */ jsx15("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" }) })
4841
+ }) : /* @__PURE__ */ jsx16("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" }) })
4690
4842
  ] }),
4691
- summaryText ? /* @__PURE__ */ jsx15("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
4843
+ summaryText ? /* @__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: summaryText }) : null
4692
4844
  ] });
4693
4845
  }
4694
4846
 
4695
4847
  // src/react/components/chat/tool-renderers/FileReadRenderer.tsx
4696
- import { useState as useState11 } from "react";
4848
+ import { useState as useState12 } from "react";
4697
4849
 
4698
4850
  // src/react/components/chat/ImageLightbox.tsx
4699
4851
  import { ChevronLeft, ChevronRight as ChevronRight2, Download as Download2, ExternalLink, Minus, Plus as Plus2, RotateCcw, X as X3 } from "lucide-react";
4700
- import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef9, useState as useState10 } from "react";
4852
+ import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
4701
4853
  import { createPortal as createPortal3 } from "react-dom";
4702
- import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
4854
+ import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
4703
4855
  function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
4704
- const [currentIndex, setCurrentIndex] = useState10(initialIndex);
4705
- const [scale, setScale] = useState10(1);
4706
- const [translate, setTranslate] = useState10({ x: 0, y: 0 });
4856
+ const [currentIndex, setCurrentIndex] = useState11(initialIndex);
4857
+ const [scale, setScale] = useState11(1);
4858
+ const [translate, setTranslate] = useState11({ x: 0, y: 0 });
4707
4859
  const dragging = useRef9(false);
4708
4860
  const dragStart = useRef9({ x: 0, y: 0 });
4709
4861
  const translateStart = useRef9({ x: 0, y: 0 });
@@ -4809,22 +4961,22 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
4809
4961
  if (images.length === 0) {
4810
4962
  return createPortal3(
4811
4963
  // biome-ignore lint/a11y/useKeyWithClickEvents: ESC handler is registered via useEffect
4812
- /* @__PURE__ */ jsxs12(
4964
+ /* @__PURE__ */ jsxs13(
4813
4965
  "div",
4814
4966
  {
4815
4967
  className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80",
4816
4968
  onClick: close,
4817
4969
  children: [
4818
- /* @__PURE__ */ jsx16(
4970
+ /* @__PURE__ */ jsx17(
4819
4971
  "button",
4820
4972
  {
4821
4973
  type: "button",
4822
4974
  onClick: close,
4823
4975
  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",
4824
- children: /* @__PURE__ */ jsx16(X3, { size: 20 })
4976
+ children: /* @__PURE__ */ jsx17(X3, { size: 20 })
4825
4977
  }
4826
4978
  ),
4827
- /* @__PURE__ */ jsx16("span", { className: "text-sm text-white/60", children: "\u52A0\u8F7D\u4E2D..." })
4979
+ /* @__PURE__ */ jsx17("span", { className: "text-sm text-white/60", children: "\u52A0\u8F7D\u4E2D..." })
4828
4980
  ]
4829
4981
  }
4830
4982
  ),
@@ -4835,46 +4987,46 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
4835
4987
  const showNav = images.length > 1;
4836
4988
  return createPortal3(
4837
4989
  // biome-ignore lint/a11y/useKeyWithClickEvents: ESC handler is registered via useEffect
4838
- /* @__PURE__ */ jsxs12("div", { className: "fixed inset-0 z-50 bg-black/80", onClick: handleAreaClick, children: [
4839
- /* @__PURE__ */ jsxs12(
4990
+ /* @__PURE__ */ jsxs13("div", { className: "fixed inset-0 z-50 bg-black/80", onClick: handleAreaClick, children: [
4991
+ /* @__PURE__ */ jsxs13(
4840
4992
  "div",
4841
4993
  {
4842
4994
  className: "absolute right-4 top-4 z-10 flex items-center gap-1.5",
4843
4995
  onClick: (e) => e.stopPropagation(),
4844
4996
  children: [
4845
- /* @__PURE__ */ jsx16(
4997
+ /* @__PURE__ */ jsx17(
4846
4998
  "button",
4847
4999
  {
4848
5000
  type: "button",
4849
5001
  onClick: handleDownload,
4850
5002
  title: "\u4E0B\u8F7D\u56FE\u7247",
4851
5003
  className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
4852
- children: /* @__PURE__ */ jsx16(Download2, { size: 18 })
5004
+ children: /* @__PURE__ */ jsx17(Download2, { size: 18 })
4853
5005
  }
4854
5006
  ),
4855
- /* @__PURE__ */ jsx16(
5007
+ /* @__PURE__ */ jsx17(
4856
5008
  "button",
4857
5009
  {
4858
5010
  type: "button",
4859
5011
  onClick: handleOpenInNewTab,
4860
5012
  title: "\u65B0\u6807\u7B7E\u9875\u6253\u5F00",
4861
5013
  className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
4862
- children: /* @__PURE__ */ jsx16(ExternalLink, { size: 18 })
5014
+ children: /* @__PURE__ */ jsx17(ExternalLink, { size: 18 })
4863
5015
  }
4864
5016
  ),
4865
- /* @__PURE__ */ jsx16(
5017
+ /* @__PURE__ */ jsx17(
4866
5018
  "button",
4867
5019
  {
4868
5020
  type: "button",
4869
5021
  onClick: close,
4870
5022
  className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
4871
- children: /* @__PURE__ */ jsx16(X3, { size: 20 })
5023
+ children: /* @__PURE__ */ jsx17(X3, { size: 20 })
4872
5024
  }
4873
5025
  )
4874
5026
  ]
4875
5027
  }
4876
5028
  ),
4877
- showNav && currentIndex > 0 && /* @__PURE__ */ jsx16(
5029
+ showNav && currentIndex > 0 && /* @__PURE__ */ jsx17(
4878
5030
  "button",
4879
5031
  {
4880
5032
  type: "button",
@@ -4883,10 +5035,10 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
4883
5035
  goPrev();
4884
5036
  },
4885
5037
  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",
4886
- children: /* @__PURE__ */ jsx16(ChevronLeft, { size: 24 })
5038
+ children: /* @__PURE__ */ jsx17(ChevronLeft, { size: 24 })
4887
5039
  }
4888
5040
  ),
4889
- showNav && currentIndex < images.length - 1 && /* @__PURE__ */ jsx16(
5041
+ showNav && currentIndex < images.length - 1 && /* @__PURE__ */ jsx17(
4890
5042
  "button",
4891
5043
  {
4892
5044
  type: "button",
@@ -4895,51 +5047,51 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
4895
5047
  goNext();
4896
5048
  },
4897
5049
  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",
4898
- children: /* @__PURE__ */ jsx16(ChevronRight2, { size: 24 })
5050
+ children: /* @__PURE__ */ jsx17(ChevronRight2, { size: 24 })
4899
5051
  }
4900
5052
  ),
4901
- /* @__PURE__ */ jsxs12("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: [
4902
- /* @__PURE__ */ jsx16(
5053
+ /* @__PURE__ */ jsxs13("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: [
5054
+ /* @__PURE__ */ jsx17(
4903
5055
  "button",
4904
5056
  {
4905
5057
  type: "button",
4906
5058
  onClick: zoomOut,
4907
5059
  className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
4908
- children: /* @__PURE__ */ jsx16(Minus, { size: 16 })
5060
+ children: /* @__PURE__ */ jsx17(Minus, { size: 16 })
4909
5061
  }
4910
5062
  ),
4911
- /* @__PURE__ */ jsxs12("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
5063
+ /* @__PURE__ */ jsxs13("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
4912
5064
  Math.round(scale * 100),
4913
5065
  "%"
4914
5066
  ] }),
4915
- /* @__PURE__ */ jsx16(
5067
+ /* @__PURE__ */ jsx17(
4916
5068
  "button",
4917
5069
  {
4918
5070
  type: "button",
4919
5071
  onClick: zoomIn,
4920
5072
  className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
4921
- children: /* @__PURE__ */ jsx16(Plus2, { size: 16 })
5073
+ children: /* @__PURE__ */ jsx17(Plus2, { size: 16 })
4922
5074
  }
4923
5075
  ),
4924
- /* @__PURE__ */ jsx16(
5076
+ /* @__PURE__ */ jsx17(
4925
5077
  "button",
4926
5078
  {
4927
5079
  type: "button",
4928
5080
  onClick: reset,
4929
5081
  className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
4930
- children: /* @__PURE__ */ jsx16(RotateCcw, { size: 16 })
5082
+ children: /* @__PURE__ */ jsx17(RotateCcw, { size: 16 })
4931
5083
  }
4932
5084
  ),
4933
- showNav && /* @__PURE__ */ jsxs12(Fragment3, { children: [
4934
- /* @__PURE__ */ jsx16("div", { className: "mx-1 h-4 w-px bg-white/20" }),
4935
- /* @__PURE__ */ jsxs12("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
5085
+ showNav && /* @__PURE__ */ jsxs13(Fragment4, { children: [
5086
+ /* @__PURE__ */ jsx17("div", { className: "mx-1 h-4 w-px bg-white/20" }),
5087
+ /* @__PURE__ */ jsxs13("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
4936
5088
  currentIndex + 1,
4937
5089
  " / ",
4938
5090
  images.length
4939
5091
  ] })
4940
5092
  ] })
4941
5093
  ] }),
4942
- /* @__PURE__ */ jsx16(
5094
+ /* @__PURE__ */ jsx17(
4943
5095
  "div",
4944
5096
  {
4945
5097
  className: "flex h-full w-full items-center justify-center overflow-hidden p-12",
@@ -4950,7 +5102,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
4950
5102
  onMouseUp: handleMouseUp,
4951
5103
  onMouseLeave: handleMouseUp,
4952
5104
  onDoubleClick: handleDoubleClick,
4953
- children: /* @__PURE__ */ jsx16(
5105
+ children: /* @__PURE__ */ jsx17(
4954
5106
  "img",
4955
5107
  {
4956
5108
  ref: imgRef,
@@ -4972,7 +5124,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
4972
5124
  }
4973
5125
 
4974
5126
  // src/react/components/chat/tool-renderers/FileReadRenderer.tsx
4975
- import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
5127
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
4976
5128
  var NUMBERED_LINE_RE = /^(\s*\d+)\t([\s\S]*)$/;
4977
5129
  function parseReadResult(result) {
4978
5130
  if (!result) {
@@ -5016,11 +5168,12 @@ function formatLineRange(startLine, endLine) {
5016
5168
  return startLine === endLine ? `\u7B2C ${startLine} \u884C` : `\u7B2C ${startLine}-${endLine} \u884C`;
5017
5169
  }
5018
5170
  function FileReadRenderer({ toolCall }) {
5019
- const [lightboxIndex, setLightboxIndex] = useState11(null);
5171
+ const [lightboxIndex, setLightboxIndex] = useState12(null);
5020
5172
  const argsValue = parseJsonValue(toolCall.arguments);
5021
5173
  const args = isPlainObject(argsValue) ? argsValue : null;
5022
5174
  const filePath = extractToolFilePath(toolCall);
5023
5175
  const fileName = getFileName(filePath);
5176
+ const description = getStringValue(args, "description");
5024
5177
  const resultText = getResultText(toolCall.result);
5025
5178
  const imageUrls = getResultImageUrls(toolCall.result);
5026
5179
  const isImageResult = imageUrls.length > 0;
@@ -5031,27 +5184,28 @@ function FileReadRenderer({ toolCall }) {
5031
5184
  const resolvedStartLine = startLine ?? (lineCount > 0 ? fallbackStart : null);
5032
5185
  const resolvedEndLine = endLine ?? (resolvedStartLine !== null && lineCount > 0 ? resolvedStartLine + lineCount - 1 : null);
5033
5186
  const lineRange = formatLineRange(resolvedStartLine, resolvedEndLine);
5034
- return /* @__PURE__ */ jsxs13("div", { className: "space-y-3", children: [
5035
- /* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-3", children: [
5036
- /* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
5037
- /* @__PURE__ */ jsx17("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: fileName }),
5038
- filePath ? /* @__PURE__ */ jsx17("div", { className: "truncate text-[10px] text-[hsl(var(--muted-foreground))]", children: filePath }) : null
5187
+ return /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
5188
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-start justify-between gap-3", children: [
5189
+ /* @__PURE__ */ jsxs14("div", { className: "min-w-0", children: [
5190
+ /* @__PURE__ */ jsx18("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: fileName }),
5191
+ filePath ? /* @__PURE__ */ jsx18("div", { className: "truncate text-[10px] text-[hsl(var(--muted-foreground))]", children: filePath }) : null
5039
5192
  ] }),
5040
- /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center justify-end gap-1.5", children: [
5041
- lineRange ? /* @__PURE__ */ jsx17("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,
5042
- 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
5193
+ /* @__PURE__ */ jsxs14("div", { className: "flex flex-wrap items-center justify-end gap-1.5", children: [
5194
+ lineRange ? /* @__PURE__ */ jsx18("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,
5195
+ 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
5043
5196
  ] })
5044
5197
  ] }),
5045
- 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,
5046
- isImageResult ? /* @__PURE__ */ jsxs13("div", { className: "grid gap-2", children: [
5047
- imageUrls.map((url, idx) => /* @__PURE__ */ jsx17(
5198
+ 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,
5199
+ 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,
5200
+ isImageResult ? /* @__PURE__ */ jsxs14("div", { className: "grid gap-2", children: [
5201
+ imageUrls.map((url, idx) => /* @__PURE__ */ jsx18(
5048
5202
  "button",
5049
5203
  {
5050
5204
  type: "button",
5051
5205
  onClick: () => setLightboxIndex(idx),
5052
5206
  className: "cursor-zoom-in",
5053
5207
  title: "\u67E5\u770B\u5927\u56FE",
5054
- children: /* @__PURE__ */ jsx17(
5208
+ children: /* @__PURE__ */ jsx18(
5055
5209
  "img",
5056
5210
  {
5057
5211
  src: url,
@@ -5062,7 +5216,7 @@ function FileReadRenderer({ toolCall }) {
5062
5216
  },
5063
5217
  url.slice(0, 64)
5064
5218
  )),
5065
- /* @__PURE__ */ jsx17(
5219
+ /* @__PURE__ */ jsx18(
5066
5220
  ImageLightbox,
5067
5221
  {
5068
5222
  open: lightboxIndex != null,
@@ -5073,15 +5227,15 @@ function FileReadRenderer({ toolCall }) {
5073
5227
  initialIndex: lightboxIndex ?? 0
5074
5228
  }
5075
5229
  ),
5076
- content ? /* @__PURE__ */ jsx17("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: content }) : null
5077
- ] }) : !errorMessage ? /* @__PURE__ */ jsx17(CodePreview, { content, filePath, className: "max-h-[360px]" }) : null,
5078
- note ? /* @__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: note }) : null
5230
+ content ? /* @__PURE__ */ jsx18("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: content }) : null
5231
+ ] }) : !errorMessage ? /* @__PURE__ */ jsx18(CodePreview, { content, filePath, className: "max-h-[360px]" }) : null,
5232
+ note ? /* @__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: note }) : null
5079
5233
  ] });
5080
5234
  }
5081
5235
 
5082
5236
  // src/react/components/chat/tool-renderers/SearchRenderer.tsx
5083
- import { ExternalLink as ExternalLink2, FileText as FileText2, Folder as Folder2, Globe2 } from "lucide-react";
5084
- import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
5237
+ import { ExternalLink as ExternalLink2, FileText as FileText3, Folder as Folder2, Globe2 } from "lucide-react";
5238
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
5085
5239
  function toRecordArray(value) {
5086
5240
  return Array.isArray(value) ? value.filter(isPlainObject) : [];
5087
5241
  }
@@ -5143,7 +5297,7 @@ function parseWebFetchResult(result) {
5143
5297
  };
5144
5298
  }
5145
5299
  function renderEmptyState(label) {
5146
- return /* @__PURE__ */ jsx18("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 });
5300
+ return /* @__PURE__ */ jsx19("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 });
5147
5301
  }
5148
5302
  function SearchRenderer({ toolCall }) {
5149
5303
  const normalizedName = formatToolName(toolCall.name);
@@ -5152,26 +5306,26 @@ function SearchRenderer({ toolCall }) {
5152
5306
  const resultStr = getResultText(toolCall.result);
5153
5307
  const errorMessage = extractErrorMessage(resultStr);
5154
5308
  if (errorMessage) {
5155
- return /* @__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 });
5309
+ return /* @__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 });
5156
5310
  }
5157
5311
  if (normalizedName === "Ls" || normalizedName === "Glob") {
5158
5312
  const items = parseDirectoryItems(resultStr);
5159
5313
  const path = getStringValue(args, "path");
5160
- return /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
5161
- path ? /* @__PURE__ */ jsxs14("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5314
+ return /* @__PURE__ */ jsxs15("div", { className: "space-y-3", children: [
5315
+ path ? /* @__PURE__ */ jsxs15("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5162
5316
  "\u76EE\u5F55\uFF1A",
5163
5317
  path
5164
5318
  ] }) : null,
5165
- items.length > 0 ? /* @__PURE__ */ jsx18("div", { className: "grid gap-2", children: items.map((item) => /* @__PURE__ */ jsxs14(
5319
+ items.length > 0 ? /* @__PURE__ */ jsx19("div", { className: "grid gap-2", children: items.map((item) => /* @__PURE__ */ jsxs15(
5166
5320
  "div",
5167
5321
  {
5168
5322
  className: "flex items-center justify-between gap-3 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-2",
5169
5323
  children: [
5170
- /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 items-center gap-2", children: [
5171
- item.isDir ? /* @__PURE__ */ jsx18(Folder2, { size: 14, className: "shrink-0 text-blue-300" }) : /* @__PURE__ */ jsx18(FileText2, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
5172
- /* @__PURE__ */ jsx18("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: item.name })
5324
+ /* @__PURE__ */ jsxs15("div", { className: "flex min-w-0 items-center gap-2", children: [
5325
+ item.isDir ? /* @__PURE__ */ jsx19(Folder2, { size: 14, className: "shrink-0 text-blue-300" }) : /* @__PURE__ */ jsx19(FileText3, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
5326
+ /* @__PURE__ */ jsx19("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: item.name })
5173
5327
  ] }),
5174
- /* @__PURE__ */ jsx18("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: item.isDir ? "\u76EE\u5F55" : formatBytes(item.size) ?? "\u6587\u4EF6" })
5328
+ /* @__PURE__ */ jsx19("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: item.isDir ? "\u76EE\u5F55" : formatBytes(item.size) ?? "\u6587\u4EF6" })
5175
5329
  ]
5176
5330
  },
5177
5331
  `${item.name}-${item.size}-${item.isDir}`
@@ -5181,28 +5335,28 @@ function SearchRenderer({ toolCall }) {
5181
5335
  if (normalizedName === "Grep") {
5182
5336
  const { matches, searchPath } = parseGrepResult(resultStr);
5183
5337
  const pattern = getStringValue(args, "pattern");
5184
- return /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
5185
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5186
- pattern ? /* @__PURE__ */ jsx18("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: pattern }) : null,
5187
- searchPath ? /* @__PURE__ */ jsxs14("span", { children: [
5338
+ return /* @__PURE__ */ jsxs15("div", { className: "space-y-3", children: [
5339
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5340
+ pattern ? /* @__PURE__ */ jsx19("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: pattern }) : null,
5341
+ searchPath ? /* @__PURE__ */ jsxs15("span", { children: [
5188
5342
  "\u8303\u56F4\uFF1A",
5189
5343
  searchPath
5190
5344
  ] }) : null
5191
5345
  ] }),
5192
- matches.length > 0 ? /* @__PURE__ */ jsx18("div", { className: "grid gap-2", children: matches.map((match) => /* @__PURE__ */ jsxs14(
5346
+ matches.length > 0 ? /* @__PURE__ */ jsx19("div", { className: "grid gap-2", children: matches.map((match) => /* @__PURE__ */ jsxs15(
5193
5347
  "div",
5194
5348
  {
5195
5349
  className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-2",
5196
5350
  children: [
5197
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-between gap-3", children: [
5198
- /* @__PURE__ */ jsx18("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: match.path }),
5199
- match.lineNumber !== null ? /* @__PURE__ */ jsxs14("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
5351
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between gap-3", children: [
5352
+ /* @__PURE__ */ jsx19("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: match.path }),
5353
+ match.lineNumber !== null ? /* @__PURE__ */ jsxs15("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
5200
5354
  "\u7B2C ",
5201
5355
  match.lineNumber,
5202
5356
  " \u884C"
5203
5357
  ] }) : null
5204
5358
  ] }),
5205
- /* @__PURE__ */ jsx18("pre", { className: "mt-2 overflow-x-auto whitespace-pre-wrap font-mono text-[11px] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx18("code", { children: match.line }) })
5359
+ /* @__PURE__ */ jsx19("pre", { className: "mt-2 overflow-x-auto whitespace-pre-wrap font-mono text-[11px] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx19("code", { children: match.line }) })
5206
5360
  ]
5207
5361
  },
5208
5362
  `${match.path}-${match.lineNumber}-${match.line}`
@@ -5211,16 +5365,16 @@ function SearchRenderer({ toolCall }) {
5211
5365
  }
5212
5366
  const { results, summary } = normalizedName === "WebFetch" ? parseWebFetchResult(resultStr) : { results: parseWebResults(resultStr), summary: null };
5213
5367
  const query = getStringValue(args, "query");
5214
- return /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
5215
- query ? /* @__PURE__ */ jsxs14("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5368
+ return /* @__PURE__ */ jsxs15("div", { className: "space-y-3", children: [
5369
+ query ? /* @__PURE__ */ jsxs15("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
5216
5370
  "\u67E5\u8BE2\uFF1A",
5217
5371
  query
5218
5372
  ] }) : null,
5219
- summary ? /* @__PURE__ */ jsxs14("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-3", children: [
5220
- /* @__PURE__ */ jsx18("div", { className: "mb-2 text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: "\u6458\u8981" }),
5221
- /* @__PURE__ */ jsx18("p", { className: "whitespace-pre-wrap text-[11px] leading-5 text-[hsl(var(--foreground))]", children: summary })
5373
+ summary ? /* @__PURE__ */ jsxs15("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-3", children: [
5374
+ /* @__PURE__ */ jsx19("div", { className: "mb-2 text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: "\u6458\u8981" }),
5375
+ /* @__PURE__ */ jsx19("p", { className: "whitespace-pre-wrap text-[11px] leading-5 text-[hsl(var(--foreground))]", children: summary })
5222
5376
  ] }) : null,
5223
- results.length > 0 ? /* @__PURE__ */ jsx18("div", { className: "grid gap-2", children: results.map((item, index) => /* @__PURE__ */ jsx18(
5377
+ results.length > 0 ? /* @__PURE__ */ jsx19("div", { className: "grid gap-2", children: results.map((item, index) => /* @__PURE__ */ jsx19(
5224
5378
  "a",
5225
5379
  {
5226
5380
  href: item.url ?? void 0,
@@ -5230,12 +5384,12 @@ function SearchRenderer({ toolCall }) {
5230
5384
  "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-3 transition-colors",
5231
5385
  item.url && "hover:border-[hsl(var(--ring))] hover:bg-[hsl(var(--muted))]/35"
5232
5386
  ),
5233
- children: /* @__PURE__ */ jsxs14("div", { className: "flex items-start gap-3", children: [
5234
- /* @__PURE__ */ jsx18(Globe2, { size: 15, className: "mt-0.5 shrink-0 text-blue-300" }),
5235
- /* @__PURE__ */ jsxs14("div", { className: "min-w-0 flex-1", children: [
5236
- /* @__PURE__ */ jsxs14("div", { className: "flex items-start justify-between gap-3", children: [
5237
- /* @__PURE__ */ jsx18("span", { className: "line-clamp-2 text-[11px] font-medium text-[hsl(var(--foreground))]", children: item.title ?? item.url ?? "\u672A\u547D\u540D\u7ED3\u679C" }),
5238
- item.url ? /* @__PURE__ */ jsx18(
5387
+ children: /* @__PURE__ */ jsxs15("div", { className: "flex items-start gap-3", children: [
5388
+ /* @__PURE__ */ jsx19(Globe2, { size: 15, className: "mt-0.5 shrink-0 text-blue-300" }),
5389
+ /* @__PURE__ */ jsxs15("div", { className: "min-w-0 flex-1", children: [
5390
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-3", children: [
5391
+ /* @__PURE__ */ jsx19("span", { className: "line-clamp-2 text-[11px] font-medium text-[hsl(var(--foreground))]", children: item.title ?? item.url ?? "\u672A\u547D\u540D\u7ED3\u679C" }),
5392
+ item.url ? /* @__PURE__ */ jsx19(
5239
5393
  ExternalLink2,
5240
5394
  {
5241
5395
  size: 12,
@@ -5243,8 +5397,8 @@ function SearchRenderer({ toolCall }) {
5243
5397
  }
5244
5398
  ) : null
5245
5399
  ] }),
5246
- item.url ? /* @__PURE__ */ jsx18("div", { className: "mt-1 truncate font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.url }) : null,
5247
- item.description ? /* @__PURE__ */ jsx18("p", { className: "mt-2 line-clamp-3 text-[11px] leading-5 text-[hsl(var(--muted-foreground))]", children: item.description }) : null
5400
+ item.url ? /* @__PURE__ */ jsx19("div", { className: "mt-1 truncate font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.url }) : null,
5401
+ item.description ? /* @__PURE__ */ jsx19("p", { className: "mt-2 line-clamp-3 text-[11px] leading-5 text-[hsl(var(--muted-foreground))]", children: item.description }) : null
5248
5402
  ] })
5249
5403
  ] })
5250
5404
  },
@@ -5271,7 +5425,7 @@ function getRenderer(toolName) {
5271
5425
  }
5272
5426
 
5273
5427
  // src/react/components/chat/ToolCallBlock.tsx
5274
- import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
5428
+ import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
5275
5429
  function FilePathLink({ filePath, sessionId }) {
5276
5430
  const activeSessionId = useSessionStore((s) => s.activeSessionId);
5277
5431
  const pushArtifact = useUiStore((s) => s.pushArtifact);
@@ -5289,14 +5443,14 @@ function FilePathLink({ filePath, sessionId }) {
5289
5443
  } catch {
5290
5444
  }
5291
5445
  };
5292
- return /* @__PURE__ */ jsx19(
5446
+ return /* @__PURE__ */ jsx20(
5293
5447
  "button",
5294
5448
  {
5295
5449
  type: "button",
5296
5450
  onClick: handleClick,
5297
5451
  className: "flex min-w-0 items-center gap-1 text-blue-400 hover:text-blue-300 hover:underline cursor-pointer font-mono",
5298
5452
  title: `\u9884\u89C8 ${filePath}`,
5299
- children: /* @__PURE__ */ jsx19("span", { className: "truncate", children: fileName })
5453
+ children: /* @__PURE__ */ jsx20("span", { className: "truncate", children: fileName })
5300
5454
  }
5301
5455
  );
5302
5456
  }
@@ -5312,7 +5466,7 @@ function ToolCallBlock({
5312
5466
  reasoning,
5313
5467
  customization
5314
5468
  }) {
5315
- const [expanded, setExpanded] = useState12(false);
5469
+ const [expanded, setExpanded] = useState13(false);
5316
5470
  const activeSessionId = useSessionStore((s) => s.activeSessionId);
5317
5471
  const sessions = useSessionStore((s) => s.sessions);
5318
5472
  const pushArtifact = useUiStore((s) => s.pushArtifact);
@@ -5339,7 +5493,7 @@ function ToolCallBlock({
5339
5493
  const canAnswer = toolCall.status === "awaiting_answer" && Boolean(resolvedOnAnswer) && Boolean(resolvedSessionStatus);
5340
5494
  const shouldRenderQuestion = Boolean(askData) && (canAnswer || resolvedAnswered || toolCall.status === "done");
5341
5495
  if (askData && shouldRenderQuestion) {
5342
- const questionBlock = /* @__PURE__ */ jsx19(
5496
+ const questionBlock = /* @__PURE__ */ jsx20(
5343
5497
  AskUserQuestionBlock,
5344
5498
  {
5345
5499
  data: askData,
@@ -5353,9 +5507,9 @@ function ToolCallBlock({
5353
5507
  if (!reasoning) {
5354
5508
  return questionBlock;
5355
5509
  }
5356
- return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
5510
+ return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
5357
5511
  questionBlock,
5358
- /* @__PURE__ */ jsx19("div", { className: "ml-4", children: /* @__PURE__ */ jsx19(ThinkingBadge, { reasoning, variant: "block" }) })
5512
+ /* @__PURE__ */ jsx20("div", { className: "ml-4", children: /* @__PURE__ */ jsx20(ThinkingBadge, { reasoning, variant: "block" }) })
5359
5513
  ] });
5360
5514
  }
5361
5515
  }
@@ -5367,11 +5521,11 @@ function ToolCallBlock({
5367
5521
  const borderWidthClass = level === 2 ? "border-l-[2px]" : "border-l-[3px]";
5368
5522
  const indentClass = level === 2 ? "ml-3" : "ml-4";
5369
5523
  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))]";
5370
- const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx19(Loader23, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx19(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx19(X4, { size: 11 }) : /* @__PURE__ */ jsx19(Check, { size: 11 });
5524
+ const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx20(Loader23, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx20(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx20(X4, { size: 11 }) : /* @__PURE__ */ jsx20(Check, { size: 11 });
5371
5525
  const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
5372
- return /* @__PURE__ */ jsxs15("div", { className: cn(indentClass, "text-xs", customization?.classNames?.toolCall), children: [
5373
- /* @__PURE__ */ jsxs15("div", { className: cn(borderWidthClass, toneClass, "flex items-center gap-2 px-3 py-2"), children: [
5374
- /* @__PURE__ */ jsxs15(
5526
+ return /* @__PURE__ */ jsxs16("div", { className: cn(indentClass, "text-xs", customization?.classNames?.toolCall), children: [
5527
+ /* @__PURE__ */ jsxs16("div", { className: cn(borderWidthClass, toneClass, "flex items-center gap-2 px-3 py-2"), children: [
5528
+ /* @__PURE__ */ jsxs16(
5375
5529
  "button",
5376
5530
  {
5377
5531
  type: "button",
@@ -5379,7 +5533,7 @@ function ToolCallBlock({
5379
5533
  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",
5380
5534
  "aria-expanded": expanded,
5381
5535
  children: [
5382
- /* @__PURE__ */ jsx19(
5536
+ /* @__PURE__ */ jsx20(
5383
5537
  ChevronRight3,
5384
5538
  {
5385
5539
  size: 11,
@@ -5389,19 +5543,19 @@ function ToolCallBlock({
5389
5543
  )
5390
5544
  }
5391
5545
  ),
5392
- /* @__PURE__ */ jsxs15("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
5546
+ /* @__PURE__ */ jsxs16("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
5393
5547
  statusIcon,
5394
- /* @__PURE__ */ jsx19("span", { children: getToolStatusLabel(toolCall.status) })
5548
+ /* @__PURE__ */ jsx20("span", { children: getToolStatusLabel(toolCall.status) })
5395
5549
  ] }),
5396
- /* @__PURE__ */ jsxs15("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: [
5550
+ /* @__PURE__ */ jsxs16("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: [
5397
5551
  displayName,
5398
5552
  toolCall.status === "error" ? "\uFF08\u5F85\u91CD\u8BD5\uFF09" : ""
5399
5553
  ] })
5400
5554
  ]
5401
5555
  }
5402
5556
  ),
5403
- filePath && /* @__PURE__ */ jsx19("span", { className: "flex min-w-0 max-w-[50%] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx19(FilePathLink, { filePath, sessionId: resolvedSessionId }) }),
5404
- loadedSkillName ? /* @__PURE__ */ jsx19(
5557
+ filePath && /* @__PURE__ */ jsx20("span", { className: "flex min-w-0 max-w-[50%] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx20(FilePathLink, { filePath, sessionId: resolvedSessionId }) }),
5558
+ loadedSkillName ? /* @__PURE__ */ jsx20(
5405
5559
  "span",
5406
5560
  {
5407
5561
  className: "min-w-0 max-w-[50%] shrink truncate text-[hsl(var(--foreground))]",
@@ -5409,9 +5563,9 @@ function ToolCallBlock({
5409
5563
  children: loadedSkillName
5410
5564
  }
5411
5565
  ) : null,
5412
- reasoning ? /* @__PURE__ */ jsx19(ThinkingBadge, { reasoning, variant: "block" }) : null,
5413
- typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx19("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) }),
5414
- uiMeta?.target === "preview" && resolvedSessionId && !isInternalStatusPreview(uiMeta) ? /* @__PURE__ */ jsxs15(
5566
+ reasoning ? /* @__PURE__ */ jsx20(ThinkingBadge, { reasoning, variant: "block" }) : null,
5567
+ typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx20("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) }),
5568
+ uiMeta?.target === "preview" && resolvedSessionId && !isInternalStatusPreview(uiMeta) ? /* @__PURE__ */ jsxs16(
5415
5569
  "button",
5416
5570
  {
5417
5571
  type: "button",
@@ -5429,18 +5583,18 @@ function ToolCallBlock({
5429
5583
  className: "inline-flex shrink-0 items-center gap-1 text-blue-400 hover:text-blue-300 hover:underline cursor-pointer",
5430
5584
  title: `\u6253\u5F00 ${uiMeta.title ?? displayName}`,
5431
5585
  children: [
5432
- /* @__PURE__ */ jsx19(PanelRightOpen, { size: 11 }),
5433
- /* @__PURE__ */ jsx19("span", { children: uiMeta.title ?? displayName })
5586
+ /* @__PURE__ */ jsx20(PanelRightOpen, { size: 11 }),
5587
+ /* @__PURE__ */ jsx20("span", { children: uiMeta.title ?? displayName })
5434
5588
  ]
5435
5589
  }
5436
5590
  ) : null
5437
5591
  ] }),
5438
- expanded && /* @__PURE__ */ jsx19("div", { className: "ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3", children: Renderer ? /* @__PURE__ */ jsx19(Renderer, { toolCall, sessionId: resolvedSessionId }) : /* @__PURE__ */ jsxs15(Fragment4, { children: [
5439
- /* @__PURE__ */ jsx19("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
5440
- /* @__PURE__ */ jsx19("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) }),
5441
- toolCall.result != null && /* @__PURE__ */ jsxs15(Fragment4, { children: [
5442
- /* @__PURE__ */ jsx19("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
5443
- /* @__PURE__ */ jsx19(
5592
+ expanded && /* @__PURE__ */ jsx20("div", { className: "ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3", children: Renderer ? /* @__PURE__ */ jsx20(Renderer, { toolCall, sessionId: resolvedSessionId }) : /* @__PURE__ */ jsxs16(Fragment5, { children: [
5593
+ /* @__PURE__ */ jsx20("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
5594
+ /* @__PURE__ */ jsx20("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) }),
5595
+ toolCall.result != null && /* @__PURE__ */ jsxs16(Fragment5, { children: [
5596
+ /* @__PURE__ */ jsx20("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
5597
+ /* @__PURE__ */ jsx20(
5444
5598
  "pre",
5445
5599
  {
5446
5600
  className: cn(
@@ -5516,7 +5670,7 @@ function buildAskUserPayload(argumentsJson) {
5516
5670
  }
5517
5671
 
5518
5672
  // src/react/components/chat/UserMessageBubble.tsx
5519
- import { useState as useState14 } from "react";
5673
+ import { useState as useState15 } from "react";
5520
5674
 
5521
5675
  // src/react/lib/preview-dispatch.ts
5522
5676
  var IMAGE_EXTS = [
@@ -5661,7 +5815,7 @@ import { Download as Download3, X as X5 } from "lucide-react";
5661
5815
  import { useEffect as useEffect12 } from "react";
5662
5816
  import { createPortal as createPortal4 } from "react-dom";
5663
5817
  import { useQuery as useQuery6 } from "@tanstack/react-query";
5664
- import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
5818
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
5665
5819
  function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
5666
5820
  useEffect12(() => {
5667
5821
  if (!open) return;
@@ -5689,7 +5843,7 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
5689
5843
  staleTime: 6e4
5690
5844
  });
5691
5845
  if (!open) return null;
5692
- const body = /* @__PURE__ */ jsx20(
5846
+ const body = /* @__PURE__ */ jsx21(
5693
5847
  "div",
5694
5848
  {
5695
5849
  className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",
@@ -5700,17 +5854,17 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
5700
5854
  role: "dialog",
5701
5855
  "aria-modal": "true",
5702
5856
  "aria-labelledby": "attachment-preview-title",
5703
- children: /* @__PURE__ */ jsxs16(
5857
+ children: /* @__PURE__ */ jsxs17(
5704
5858
  "div",
5705
5859
  {
5706
5860
  className: "max-h-[90vh] w-full max-w-3xl overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--background))] shadow-2xl",
5707
5861
  onClick: (e) => e.stopPropagation(),
5708
5862
  onKeyDown: (e) => e.stopPropagation(),
5709
5863
  children: [
5710
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
5711
- /* @__PURE__ */ jsx20("h3", { id: "attachment-preview-title", className: "truncate text-sm font-semibold text-[hsl(var(--foreground))]", children: filename }),
5712
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
5713
- url && /* @__PURE__ */ jsx20(
5864
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
5865
+ /* @__PURE__ */ jsx21("h3", { id: "attachment-preview-title", className: "truncate text-sm font-semibold text-[hsl(var(--foreground))]", children: filename }),
5866
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1", children: [
5867
+ url && /* @__PURE__ */ jsx21(
5714
5868
  "a",
5715
5869
  {
5716
5870
  href: url,
@@ -5719,22 +5873,22 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
5719
5873
  rel: "noopener noreferrer",
5720
5874
  title: "\u4E0B\u8F7D",
5721
5875
  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))]",
5722
- children: /* @__PURE__ */ jsx20(Download3, { size: 14 })
5876
+ children: /* @__PURE__ */ jsx21(Download3, { size: 14 })
5723
5877
  }
5724
5878
  ),
5725
- /* @__PURE__ */ jsx20(
5879
+ /* @__PURE__ */ jsx21(
5726
5880
  "button",
5727
5881
  {
5728
5882
  type: "button",
5729
5883
  onClick: () => onOpenChange(false),
5730
5884
  title: "\u5173\u95ED",
5731
5885
  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))]",
5732
- children: /* @__PURE__ */ jsx20(X5, { size: 14 })
5886
+ children: /* @__PURE__ */ jsx21(X5, { size: 14 })
5733
5887
  }
5734
5888
  )
5735
5889
  ] })
5736
5890
  ] }),
5737
- /* @__PURE__ */ jsx20("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 }) })
5891
+ /* @__PURE__ */ jsx21("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 }) })
5738
5892
  ]
5739
5893
  }
5740
5894
  )
@@ -5749,43 +5903,43 @@ function renderContent({
5749
5903
  error
5750
5904
  }) {
5751
5905
  if (!url) {
5752
- return /* @__PURE__ */ jsx20("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u6B64\u9644\u4EF6\u6682\u65E0\u53EF\u7528\u9884\u89C8\u5730\u5740\u3002" });
5906
+ return /* @__PURE__ */ jsx21("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u6B64\u9644\u4EF6\u6682\u65E0\u53EF\u7528\u9884\u89C8\u5730\u5740\u3002" });
5753
5907
  }
5754
5908
  if (mode === "default") {
5755
- return /* @__PURE__ */ jsxs16("p", { className: "text-[hsl(var(--muted-foreground))]", children: [
5909
+ return /* @__PURE__ */ jsxs17("p", { className: "text-[hsl(var(--muted-foreground))]", children: [
5756
5910
  "\u6B64\u7C7B\u578B\u6682\u4E0D\u652F\u6301\u5185\u5D4C\u9884\u89C8\u3002\u8BF7\u70B9\u51FB\u53F3\u4E0A\u89D2",
5757
- /* @__PURE__ */ jsx20("span", { className: "mx-1 font-medium text-[hsl(var(--foreground))]", children: "\u4E0B\u8F7D" }),
5911
+ /* @__PURE__ */ jsx21("span", { className: "mx-1 font-medium text-[hsl(var(--foreground))]", children: "\u4E0B\u8F7D" }),
5758
5912
  "\u6309\u94AE\u67E5\u770B\u3002"
5759
5913
  ] });
5760
5914
  }
5761
5915
  if (error) {
5762
- return /* @__PURE__ */ jsxs16("p", { className: "text-[hsl(var(--destructive))]", children: [
5916
+ return /* @__PURE__ */ jsxs17("p", { className: "text-[hsl(var(--destructive))]", children: [
5763
5917
  "\u52A0\u8F7D\u5931\u8D25\uFF1A",
5764
5918
  String(error?.message ?? error)
5765
5919
  ] });
5766
5920
  }
5767
5921
  if (content == null) {
5768
- return /* @__PURE__ */ jsx20("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u52A0\u8F7D\u4E2D\u2026" });
5922
+ return /* @__PURE__ */ jsx21("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u52A0\u8F7D\u4E2D\u2026" });
5769
5923
  }
5770
5924
  if (mode === "markdown") {
5771
- return /* @__PURE__ */ jsx20(MarkdownContent, { className: "prose prose-sm prose-invert max-w-none", children: content });
5925
+ return /* @__PURE__ */ jsx21(MarkdownContent, { className: "prose prose-sm prose-invert max-w-none", children: content });
5772
5926
  }
5773
- return /* @__PURE__ */ jsx20("pre", { className: "whitespace-pre-wrap font-mono text-xs leading-relaxed", children: content });
5927
+ return /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap font-mono text-xs leading-relaxed", children: content });
5774
5928
  }
5775
5929
 
5776
5930
  // src/react/components/chat/MessageContextPills.tsx
5777
5931
  import { Bookmark } from "lucide-react";
5778
- import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
5932
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
5779
5933
  function MessageContextPills({ contexts }) {
5780
5934
  if (contexts.length === 0) return null;
5781
- return /* @__PURE__ */ jsx21("div", { className: "flex flex-wrap gap-1.5", children: contexts.map((ctx, index) => /* @__PURE__ */ jsxs17(
5935
+ return /* @__PURE__ */ jsx22("div", { className: "flex flex-wrap gap-1.5", children: contexts.map((ctx, index) => /* @__PURE__ */ jsxs18(
5782
5936
  "div",
5783
5937
  {
5784
5938
  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)]",
5785
5939
  title: ctx.content,
5786
5940
  children: [
5787
- /* @__PURE__ */ jsx21(Bookmark, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.65)]" }),
5788
- /* @__PURE__ */ jsx21("span", { className: "max-w-56 truncate", children: ctx.label })
5941
+ /* @__PURE__ */ jsx22(Bookmark, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.65)]" }),
5942
+ /* @__PURE__ */ jsx22("span", { className: "max-w-56 truncate", children: ctx.label })
5789
5943
  ]
5790
5944
  },
5791
5945
  `${ctx.label}:${index}`
@@ -5793,8 +5947,8 @@ function MessageContextPills({ contexts }) {
5793
5947
  }
5794
5948
 
5795
5949
  // src/react/components/chat/MessageFileAttachmentList.tsx
5796
- import { Archive as Archive2, File as File3, FileCode2 as FileCode22, FileText as FileText3, Film as Film2, Music as Music2 } from "lucide-react";
5797
- import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
5950
+ import { Archive as Archive2, File as File3, FileCode2 as FileCode22, FileText as FileText4, Film as Film2, Music as Music2 } from "lucide-react";
5951
+ import { Fragment as Fragment6, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
5798
5952
  function getFileIcon(fileName) {
5799
5953
  const lowerName = fileName.toLowerCase();
5800
5954
  if (/\.(zip|rar|7z|tar|gz|bz2|xz)$/.test(lowerName)) {
@@ -5810,7 +5964,7 @@ function getFileIcon(fileName) {
5810
5964
  return Film2;
5811
5965
  }
5812
5966
  if (/\.(txt|pdf|doc|docx|rtf|odt)$/.test(lowerName)) {
5813
- return FileText3;
5967
+ return FileText4;
5814
5968
  }
5815
5969
  return File3;
5816
5970
  }
@@ -5823,15 +5977,15 @@ function MessageFileAttachmentList({
5823
5977
  return null;
5824
5978
  }
5825
5979
  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))]";
5826
- return /* @__PURE__ */ jsx22("div", { className: cn("flex flex-wrap gap-1.5", className), children: files.map((file) => {
5980
+ return /* @__PURE__ */ jsx23("div", { className: cn("flex flex-wrap gap-1.5", className), children: files.map((file) => {
5827
5981
  const Icon = getFileIcon(file.name);
5828
5982
  const key = `${file.name}-${file.data.slice(0, 32)}`;
5829
- const content = /* @__PURE__ */ jsxs18(Fragment5, { children: [
5830
- /* @__PURE__ */ jsx22(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
5831
- /* @__PURE__ */ jsx22("span", { className: "max-w-32 truncate", children: file.name })
5983
+ const content = /* @__PURE__ */ jsxs19(Fragment6, { children: [
5984
+ /* @__PURE__ */ jsx23(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
5985
+ /* @__PURE__ */ jsx23("span", { className: "max-w-32 truncate", children: file.name })
5832
5986
  ] });
5833
5987
  if (onPreview) {
5834
- return /* @__PURE__ */ jsx22(
5988
+ return /* @__PURE__ */ jsx23(
5835
5989
  "button",
5836
5990
  {
5837
5991
  type: "button",
@@ -5843,16 +5997,16 @@ function MessageFileAttachmentList({
5843
5997
  key
5844
5998
  );
5845
5999
  }
5846
- return /* @__PURE__ */ jsx22("div", { className: pillClass, title: file.name, children: content }, key);
6000
+ return /* @__PURE__ */ jsx23("div", { className: pillClass, title: file.name, children: content }, key);
5847
6001
  }) });
5848
6002
  }
5849
6003
 
5850
6004
  // src/react/components/chat/MessageActions.tsx
5851
6005
  import { Check as Check2, Copy } from "lucide-react";
5852
- import { useState as useState13 } from "react";
5853
- import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
6006
+ import { useState as useState14 } from "react";
6007
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
5854
6008
  function MessageActions({ content, className }) {
5855
- const [copied, setCopied] = useState13(false);
6009
+ const [copied, setCopied] = useState14(false);
5856
6010
  const handleCopy = async () => {
5857
6011
  const ok = await copyToClipboard(content);
5858
6012
  if (ok) {
@@ -5860,7 +6014,7 @@ function MessageActions({ content, className }) {
5860
6014
  setTimeout(() => setCopied(false), 2e3);
5861
6015
  }
5862
6016
  };
5863
- return /* @__PURE__ */ jsx23("div", { className: cn("flex items-center gap-1 mt-1.5", className), children: /* @__PURE__ */ jsxs19(
6017
+ return /* @__PURE__ */ jsx24("div", { className: cn("flex items-center gap-1 mt-1.5", className), children: /* @__PURE__ */ jsxs20(
5864
6018
  "button",
5865
6019
  {
5866
6020
  type: "button",
@@ -5870,16 +6024,16 @@ function MessageActions({ content, className }) {
5870
6024
  copied ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--accent))]"
5871
6025
  ),
5872
6026
  children: [
5873
- copied ? /* @__PURE__ */ jsx23(Check2, { size: 12 }) : /* @__PURE__ */ jsx23(Copy, { size: 12 }),
5874
- /* @__PURE__ */ jsx23("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
6027
+ copied ? /* @__PURE__ */ jsx24(Check2, { size: 12 }) : /* @__PURE__ */ jsx24(Copy, { size: 12 }),
6028
+ /* @__PURE__ */ jsx24("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
5875
6029
  ]
5876
6030
  }
5877
6031
  ) });
5878
6032
  }
5879
6033
 
5880
6034
  // src/react/components/chat/TextAttachmentPills.tsx
5881
- import { Archive as Archive3, File as File4, FileCode2 as FileCode23, FileText as FileText4, Film as Film3, Music as Music3, FileSpreadsheet, Image } from "lucide-react";
5882
- import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
6035
+ import { Archive as Archive3, File as File4, FileCode2 as FileCode23, FileText as FileText5, Film as Film3, Music as Music3, FileSpreadsheet, Image } from "lucide-react";
6036
+ import { Fragment as Fragment7, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
5883
6037
  function getFileIcon2(fileName) {
5884
6038
  const lower2 = fileName.toLowerCase();
5885
6039
  if (/\.(zip|rar|7z|tar|gz)$/.test(lower2)) return Archive3;
@@ -5888,21 +6042,21 @@ function getFileIcon2(fileName) {
5888
6042
  if (/\.(mp4|mov|mkv|avi|webm)$/.test(lower2)) return Film3;
5889
6043
  if (/\.(png|jpg|jpeg|gif|svg|webp|bmp)$/.test(lower2)) return Image;
5890
6044
  if (/\.(xlsx?|csv)$/.test(lower2)) return FileSpreadsheet;
5891
- if (/\.(txt|pdf|docx?|rtf|md)$/.test(lower2)) return FileText4;
6045
+ if (/\.(txt|pdf|docx?|rtf|md)$/.test(lower2)) return FileText5;
5892
6046
  return File4;
5893
6047
  }
5894
6048
  function TextAttachmentPills({ attachments, onPreview }) {
5895
6049
  if (attachments.length === 0) return null;
5896
6050
  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)]";
5897
- return /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-1.5", children: attachments.map((att, index) => {
6051
+ return /* @__PURE__ */ jsx25("div", { className: "flex flex-wrap gap-1.5", children: attachments.map((att, index) => {
5898
6052
  const Icon = getFileIcon2(att.name);
5899
6053
  const key = `${att.uploadedPath ?? att.name}:${att.name}:${index}`;
5900
- const content = /* @__PURE__ */ jsxs20(Fragment6, { children: [
5901
- /* @__PURE__ */ jsx24(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.6)]" }),
5902
- /* @__PURE__ */ jsx24("span", { className: "max-w-40 truncate", children: att.name })
6054
+ const content = /* @__PURE__ */ jsxs21(Fragment7, { children: [
6055
+ /* @__PURE__ */ jsx25(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.6)]" }),
6056
+ /* @__PURE__ */ jsx25("span", { className: "max-w-40 truncate", children: att.name })
5903
6057
  ] });
5904
6058
  if (onPreview) {
5905
- return /* @__PURE__ */ jsx24(
6059
+ return /* @__PURE__ */ jsx25(
5906
6060
  "button",
5907
6061
  {
5908
6062
  type: "button",
@@ -5914,7 +6068,7 @@ function TextAttachmentPills({ attachments, onPreview }) {
5914
6068
  key
5915
6069
  );
5916
6070
  }
5917
- return /* @__PURE__ */ jsx24("div", { className: pillClass, title: att.name, children: content }, key);
6071
+ return /* @__PURE__ */ jsx25("div", { className: pillClass, title: att.name, children: content }, key);
5918
6072
  }) });
5919
6073
  }
5920
6074
 
@@ -5923,34 +6077,34 @@ import { RefreshCcw } from "lucide-react";
5923
6077
 
5924
6078
  // src/react/components/chat/whatif-quote-context.tsx
5925
6079
  import { createContext as createContext3, useContext as useContext3, useMemo as useMemo13 } from "react";
5926
- import { jsx as jsx25 } from "react/jsx-runtime";
6080
+ import { jsx as jsx26 } from "react/jsx-runtime";
5927
6081
  var WhatIfQuoteContext = createContext3({});
5928
6082
  function WhatIfQuoteProvider({
5929
6083
  onJumpToStep,
5930
6084
  children
5931
6085
  }) {
5932
6086
  const value = useMemo13(() => ({ onJumpToStep }), [onJumpToStep]);
5933
- return /* @__PURE__ */ jsx25(WhatIfQuoteContext.Provider, { value, children });
6087
+ return /* @__PURE__ */ jsx26(WhatIfQuoteContext.Provider, { value, children });
5934
6088
  }
5935
6089
  function useWhatIfQuoteContext() {
5936
6090
  return useContext3(WhatIfQuoteContext);
5937
6091
  }
5938
6092
 
5939
6093
  // src/react/components/chat/WhatIfUserBubble.tsx
5940
- import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
6094
+ import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
5941
6095
  function WhatIfUserBubble({ parsed, onQuoteClick }) {
5942
6096
  const { onJumpToStep } = useWhatIfQuoteContext();
5943
6097
  const handleQuoteClick = onQuoteClick ?? onJumpToStep;
5944
6098
  const { fromStep, quotes, userText } = parsed;
5945
- return /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-end gap-2", children: [
5946
- /* @__PURE__ */ jsxs21("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: [
5947
- /* @__PURE__ */ jsx26(RefreshCcw, { size: 10 }),
5948
- /* @__PURE__ */ jsx26("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
6099
+ return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col items-end gap-2", children: [
6100
+ /* @__PURE__ */ jsxs22("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: [
6101
+ /* @__PURE__ */ jsx27(RefreshCcw, { size: 10 }),
6102
+ /* @__PURE__ */ jsx27("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
5949
6103
  ] }),
5950
- quotes.length > 0 && /* @__PURE__ */ jsx26("div", { className: "flex flex-wrap justify-end gap-1.5", children: quotes.map((q, i) => {
6104
+ quotes.length > 0 && /* @__PURE__ */ jsx27("div", { className: "flex flex-wrap justify-end gap-1.5", children: quotes.map((q, i) => {
5951
6105
  const clickable = q.stepNumber != null && !!handleQuoteClick;
5952
6106
  const label = q.stepNumber != null ? `\u6B65\u9AA4${q.stepNumber} \xB7 ${q.label}` : q.label;
5953
- return /* @__PURE__ */ jsxs21(
6107
+ return /* @__PURE__ */ jsxs22(
5954
6108
  "button",
5955
6109
  {
5956
6110
  type: "button",
@@ -5959,14 +6113,14 @@ function WhatIfUserBubble({ parsed, onQuoteClick }) {
5959
6113
  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))]",
5960
6114
  title: clickable ? "\u8DF3\u8F6C\u5230\u5BF9\u5E94\u6B65\u9AA4\u5361\u7247" : void 0,
5961
6115
  children: [
5962
- /* @__PURE__ */ jsx26("span", { children: "\u21B3" }),
5963
- /* @__PURE__ */ jsx26("span", { className: "max-w-[14rem] truncate", children: label })
6116
+ /* @__PURE__ */ jsx27("span", { children: "\u21B3" }),
6117
+ /* @__PURE__ */ jsx27("span", { className: "max-w-[14rem] truncate", children: label })
5964
6118
  ]
5965
6119
  },
5966
6120
  `${q.stepNumber ?? "x"}-${i}`
5967
6121
  );
5968
6122
  }) }),
5969
- userText && /* @__PURE__ */ jsx26("div", { className: "rounded-2xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-sm leading-relaxed text-[hsl(var(--user-msg-fg))] shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]", children: /* @__PURE__ */ jsx26(
6123
+ userText && /* @__PURE__ */ jsx27("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__ */ jsx27(
5970
6124
  MarkdownContent,
5971
6125
  {
5972
6126
  className: "prose prose-sm prose-invert max-w-none [&_li>p]:inline [&_p]:mb-3 [&_p:last-child]:mb-0",
@@ -5978,7 +6132,7 @@ function WhatIfUserBubble({ parsed, onQuoteClick }) {
5978
6132
  }
5979
6133
 
5980
6134
  // src/react/components/chat/UserMessageBubble.tsx
5981
- import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
6135
+ import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
5982
6136
  function isUserMessage(message) {
5983
6137
  return message.role === "user";
5984
6138
  }
@@ -6006,9 +6160,9 @@ function UserMessageBubble({ message, className }) {
6006
6160
  const trimmedClean = cleanText.trim();
6007
6161
  const whatifParsed = trimmedClean && imageParts.length === 0 && fileParts.length === 0 && textAttachments.length === 0 ? parseWhatIfPrompt(cleanText) : null;
6008
6162
  if (whatifParsed) {
6009
- return /* @__PURE__ */ jsx27("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs22("div", { className: "group flex max-w-[72%] flex-col items-end gap-2", children: [
6010
- /* @__PURE__ */ jsx27(WhatIfUserBubble, { parsed: whatifParsed }),
6011
- whatifParsed.userText && /* @__PURE__ */ jsx27(
6163
+ return /* @__PURE__ */ jsx28("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs23("div", { className: "group flex max-w-[72%] flex-col items-end gap-2", children: [
6164
+ /* @__PURE__ */ jsx28(WhatIfUserBubble, { parsed: whatifParsed }),
6165
+ whatifParsed.userText && /* @__PURE__ */ jsx28(
6012
6166
  MessageActions,
6013
6167
  {
6014
6168
  content: whatifParsed.userText,
@@ -6042,8 +6196,8 @@ function UserMessageBubble({ message, className }) {
6042
6196
  alt: attachment.name || "\u7528\u6237\u4E0A\u4F20\u7684\u56FE\u7247"
6043
6197
  }))
6044
6198
  ];
6045
- const [lightboxIndex, setLightboxIndex] = useState14(null);
6046
- const [preview, setPreview] = useState14(null);
6199
+ const [lightboxIndex, setLightboxIndex] = useState15(null);
6200
+ const [preview, setPreview] = useState15(null);
6047
6201
  const handleTextAttachmentPreview = (attachment) => {
6048
6202
  if (!activeSessionId) return;
6049
6203
  const pathForUrl = attachment.uploadedPath ?? attachment.name;
@@ -6062,16 +6216,16 @@ function UserMessageBubble({ message, className }) {
6062
6216
  const mode = kind === "text" ? lower2.endsWith(".md") ? "markdown" : "text" : "default";
6063
6217
  setPreview({ filename: attachment.name, url, mode });
6064
6218
  };
6065
- return /* @__PURE__ */ jsx27("div", { className: cn("flex justify-end", className), children: /* @__PURE__ */ jsxs22("div", { className: "group flex max-w-[72%] flex-col items-end gap-3", children: [
6066
- (imageParts.length > 0 || imageTextAttachments.length > 0) && /* @__PURE__ */ jsxs22("div", { className: "grid gap-2", children: [
6067
- imageParts.map((part, idx) => /* @__PURE__ */ jsx27(
6219
+ return /* @__PURE__ */ jsx28("div", { className: cn("flex justify-end", className), children: /* @__PURE__ */ jsxs23("div", { className: "group flex max-w-[72%] flex-col items-end gap-3", children: [
6220
+ (imageParts.length > 0 || imageTextAttachments.length > 0) && /* @__PURE__ */ jsxs23("div", { className: "grid gap-2", children: [
6221
+ imageParts.map((part, idx) => /* @__PURE__ */ jsx28(
6068
6222
  "button",
6069
6223
  {
6070
6224
  type: "button",
6071
6225
  onClick: () => setLightboxIndex(idx),
6072
6226
  className: "cursor-zoom-in",
6073
6227
  title: "\u67E5\u770B\u5927\u56FE",
6074
- children: /* @__PURE__ */ jsx27(
6228
+ children: /* @__PURE__ */ jsx28(
6075
6229
  "img",
6076
6230
  {
6077
6231
  src: part.image_url.url,
@@ -6082,14 +6236,14 @@ function UserMessageBubble({ message, className }) {
6082
6236
  },
6083
6237
  part.image_url.url
6084
6238
  )),
6085
- imageTextAttachments.map((attachment, idx) => /* @__PURE__ */ jsx27(
6239
+ imageTextAttachments.map((attachment, idx) => /* @__PURE__ */ jsx28(
6086
6240
  "button",
6087
6241
  {
6088
6242
  type: "button",
6089
6243
  onClick: () => setLightboxIndex(imageParts.length + idx),
6090
6244
  className: "cursor-zoom-in",
6091
6245
  title: "\u67E5\u770B\u5927\u56FE",
6092
- children: /* @__PURE__ */ jsx27(
6246
+ children: /* @__PURE__ */ jsx28(
6093
6247
  "img",
6094
6248
  {
6095
6249
  src: attachment.url,
@@ -6101,7 +6255,7 @@ function UserMessageBubble({ message, className }) {
6101
6255
  `${attachment.uploadedPath}:${attachment.name}`
6102
6256
  ))
6103
6257
  ] }),
6104
- lightboxImages.length > 0 && /* @__PURE__ */ jsx27(
6258
+ lightboxImages.length > 0 && /* @__PURE__ */ jsx28(
6105
6259
  ImageLightbox,
6106
6260
  {
6107
6261
  open: lightboxIndex != null,
@@ -6112,15 +6266,15 @@ function UserMessageBubble({ message, className }) {
6112
6266
  initialIndex: lightboxIndex ?? 0
6113
6267
  }
6114
6268
  ),
6115
- /* @__PURE__ */ jsx27(MessageFileAttachmentList, { files: fileParts }),
6116
- /* @__PURE__ */ jsx27(
6269
+ /* @__PURE__ */ jsx28(MessageFileAttachmentList, { files: fileParts }),
6270
+ /* @__PURE__ */ jsx28(
6117
6271
  TextAttachmentPills,
6118
6272
  {
6119
6273
  attachments: nonImageTextAttachments,
6120
6274
  onPreview: handleTextAttachmentPreview
6121
6275
  }
6122
6276
  ),
6123
- preview && /* @__PURE__ */ jsx27(
6277
+ preview && /* @__PURE__ */ jsx28(
6124
6278
  AttachmentPreviewDialog,
6125
6279
  {
6126
6280
  open: preview != null,
@@ -6132,8 +6286,8 @@ function UserMessageBubble({ message, className }) {
6132
6286
  mode: preview.mode
6133
6287
  }
6134
6288
  ),
6135
- /* @__PURE__ */ jsx27(MessageContextPills, { contexts: textContexts }),
6136
- trimmedClean && /* @__PURE__ */ jsx27("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__ */ jsx27(
6289
+ /* @__PURE__ */ jsx28(MessageContextPills, { contexts: textContexts }),
6290
+ trimmedClean && /* @__PURE__ */ jsx28("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__ */ jsx28(
6137
6291
  MarkdownContent,
6138
6292
  {
6139
6293
  className: "prose prose-sm prose-invert max-w-none [&_li>p]:inline [&_p]:mb-3 [&_p:last-child]:mb-0",
@@ -6141,7 +6295,7 @@ function UserMessageBubble({ message, className }) {
6141
6295
  children: cleanText
6142
6296
  }
6143
6297
  ) }),
6144
- trimmedClean && /* @__PURE__ */ jsx27(
6298
+ trimmedClean && /* @__PURE__ */ jsx28(
6145
6299
  MessageActions,
6146
6300
  {
6147
6301
  content: trimmedClean,
@@ -6156,14 +6310,14 @@ function ErrorMessageBlock({
6156
6310
  }) {
6157
6311
  const text = getTextContent(message.content);
6158
6312
  const looksLikeModelUnavailable = /no source matches this model|404/i.test(text);
6159
- return /* @__PURE__ */ jsx27("div", { className: cn("flex justify-center", className), children: /* @__PURE__ */ jsxs22("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: [
6313
+ return /* @__PURE__ */ jsx28("div", { className: cn("flex justify-center", className), children: /* @__PURE__ */ jsxs23("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: [
6160
6314
  text,
6161
- looksLikeModelUnavailable ? /* @__PURE__ */ jsx27("div", { className: "mt-1 opacity-80", children: "\u6A21\u578B\u53EF\u80FD\u672A\u542F\u52A8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" }) : null
6315
+ looksLikeModelUnavailable ? /* @__PURE__ */ jsx28("div", { className: "mt-1 opacity-80", children: "\u6A21\u578B\u53EF\u80FD\u672A\u542F\u52A8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" }) : null
6162
6316
  ] }) });
6163
6317
  }
6164
6318
 
6165
6319
  // src/react/components/chat/AgentLoopBlock.tsx
6166
- import { Fragment as Fragment7, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
6320
+ import { Fragment as Fragment8, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
6167
6321
  var EMPTY_MESSAGES2 = [];
6168
6322
  var EMPTY_AGENT_LOOPS = {};
6169
6323
  var COLLAPSED_SUMMARY_HIDDEN_TOOLS = /* @__PURE__ */ new Set([
@@ -6210,7 +6364,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6210
6364
  () => visibleLoopToolCalls.some((childToolCall) => childToolCall.status === "awaiting_answer"),
6211
6365
  [visibleLoopToolCalls]
6212
6366
  );
6213
- const [expanded, setExpanded] = useState15(hasAwaitingAnswer);
6367
+ const [expanded, setExpanded] = useState16(hasAwaitingAnswer);
6214
6368
  const completedToolLabels = useMemo14(
6215
6369
  () => visibleLoopToolCalls.flatMap((childToolCall) => {
6216
6370
  const isCompleted = childToolCall.status === "done" || childToolCall.status !== "pending" && childToolCall.status !== "awaiting_answer" && childToolCall.status !== "error" && childToolCall.status !== "cancelled";
@@ -6256,7 +6410,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6256
6410
  const description = safeParseDescription(toolCall.arguments);
6257
6411
  const status = hasAwaitingAnswer || toolCall.status === "awaiting_answer" ? "awaiting_answer" : toolCall.status === "pending" || loopEntry?.info.status === "running" ? "running" : "done";
6258
6412
  const cardStyles = getLoopCardStyles(status);
6259
- return /* @__PURE__ */ jsxs23(
6413
+ return /* @__PURE__ */ jsxs24(
6260
6414
  "div",
6261
6415
  {
6262
6416
  className: cn(
@@ -6264,8 +6418,8 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6264
6418
  cardStyles.borderClass
6265
6419
  ),
6266
6420
  children: [
6267
- status === "running" || status === "awaiting_answer" ? /* @__PURE__ */ jsxs23(Fragment7, { children: [
6268
- /* @__PURE__ */ jsxs23(
6421
+ status === "running" || status === "awaiting_answer" ? /* @__PURE__ */ jsxs24(Fragment8, { children: [
6422
+ /* @__PURE__ */ jsxs24(
6269
6423
  "div",
6270
6424
  {
6271
6425
  className: cn(
@@ -6273,24 +6427,24 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6273
6427
  cardStyles.headerClass
6274
6428
  ),
6275
6429
  children: [
6276
- /* @__PURE__ */ jsx28(
6430
+ /* @__PURE__ */ jsx29(
6277
6431
  "button",
6278
6432
  {
6279
6433
  type: "button",
6280
6434
  onClick: toggleExpanded,
6281
6435
  "aria-expanded": expanded,
6282
6436
  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",
6283
- children: /* @__PURE__ */ jsxs23("span", { className: "min-w-0 flex items-center gap-2", children: [
6284
- status === "awaiting_answer" ? /* @__PURE__ */ jsx28(MessageSquareMore2, { size: 14, className: "shrink-0 text-amber-500" }) : /* @__PURE__ */ jsx28(Bot, { size: 14, className: "shrink-0 text-blue-500" }),
6285
- /* @__PURE__ */ jsxs23("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: [
6437
+ children: /* @__PURE__ */ jsxs24("span", { className: "min-w-0 flex items-center gap-2", children: [
6438
+ status === "awaiting_answer" ? /* @__PURE__ */ jsx29(MessageSquareMore2, { size: 14, className: "shrink-0 text-amber-500" }) : /* @__PURE__ */ jsx29(Bot, { size: 14, className: "shrink-0 text-blue-500" }),
6439
+ /* @__PURE__ */ jsxs24("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: [
6286
6440
  description,
6287
6441
  status === "awaiting_answer" ? " \u2014 \u7B49\u5F85\u56DE\u7B54" : ""
6288
6442
  ] })
6289
6443
  ] })
6290
6444
  }
6291
6445
  ),
6292
- reasoning ? /* @__PURE__ */ jsx28(ThinkingBadge, { reasoning, variant: "block" }) : null,
6293
- /* @__PURE__ */ jsx28(
6446
+ reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning, variant: "block" }) : null,
6447
+ /* @__PURE__ */ jsx29(
6294
6448
  Bot,
6295
6449
  {
6296
6450
  size: 13,
@@ -6298,14 +6452,14 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6298
6452
  "aria-label": "\u5B50\u667A\u80FD\u4F53"
6299
6453
  }
6300
6454
  ),
6301
- /* @__PURE__ */ jsx28(
6455
+ /* @__PURE__ */ jsx29(
6302
6456
  "button",
6303
6457
  {
6304
6458
  type: "button",
6305
6459
  onClick: toggleExpanded,
6306
6460
  "aria-expanded": expanded,
6307
6461
  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",
6308
- children: /* @__PURE__ */ jsx28(
6462
+ children: /* @__PURE__ */ jsx29(
6309
6463
  ChevronRight4,
6310
6464
  {
6311
6465
  size: 14,
@@ -6320,7 +6474,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6320
6474
  ]
6321
6475
  }
6322
6476
  ),
6323
- !expanded ? /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-1 py-2", children: visibleLoopToolCalls.length > 0 ? visibleLoopToolCalls.map((childToolCall) => /* @__PURE__ */ jsx28(
6477
+ !expanded ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-1 py-2", children: visibleLoopToolCalls.length > 0 ? visibleLoopToolCalls.map((childToolCall) => /* @__PURE__ */ jsx29(
6324
6478
  ToolCallBlock,
6325
6479
  {
6326
6480
  toolCall: childToolCall,
@@ -6328,12 +6482,12 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6328
6482
  level: 2
6329
6483
  },
6330
6484
  childToolCall.id
6331
- )) : /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
6332
- /* @__PURE__ */ jsx28(Loader24, { size: 12, className: "shrink-0 animate-spin text-blue-500" }),
6333
- /* @__PURE__ */ jsx28("span", { children: "\u6B63\u5728\u542F\u52A8..." })
6334
- ] }) }) : status === "awaiting_answer" ? /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-1 py-2", children: /* @__PURE__ */ jsx28("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
6335
- ] }) : /* @__PURE__ */ jsxs23(Fragment7, { children: [
6336
- /* @__PURE__ */ jsxs23(
6485
+ )) : /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
6486
+ /* @__PURE__ */ jsx29(Loader24, { size: 12, className: "shrink-0 animate-spin text-blue-500" }),
6487
+ /* @__PURE__ */ jsx29("span", { children: "\u6B63\u5728\u542F\u52A8..." })
6488
+ ] }) }) : status === "awaiting_answer" ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-1 py-2", children: /* @__PURE__ */ jsx29("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
6489
+ ] }) : /* @__PURE__ */ jsxs24(Fragment8, { children: [
6490
+ /* @__PURE__ */ jsxs24(
6337
6491
  "div",
6338
6492
  {
6339
6493
  className: cn(
@@ -6341,21 +6495,21 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6341
6495
  cardStyles.headerClass
6342
6496
  ),
6343
6497
  children: [
6344
- /* @__PURE__ */ jsx28(
6498
+ /* @__PURE__ */ jsx29(
6345
6499
  "button",
6346
6500
  {
6347
6501
  type: "button",
6348
6502
  onClick: toggleExpanded,
6349
6503
  "aria-expanded": expanded,
6350
6504
  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",
6351
- children: /* @__PURE__ */ jsxs23("span", { className: "min-w-0 flex items-center gap-2", children: [
6352
- /* @__PURE__ */ jsx28(Check3, { size: 14, className: "shrink-0 text-emerald-500" }),
6353
- /* @__PURE__ */ jsx28("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: description })
6505
+ children: /* @__PURE__ */ jsxs24("span", { className: "min-w-0 flex items-center gap-2", children: [
6506
+ /* @__PURE__ */ jsx29(Check3, { size: 14, className: "shrink-0 text-emerald-500" }),
6507
+ /* @__PURE__ */ jsx29("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: description })
6354
6508
  ] })
6355
6509
  }
6356
6510
  ),
6357
- reasoning ? /* @__PURE__ */ jsx28(ThinkingBadge, { reasoning, variant: "block" }) : null,
6358
- /* @__PURE__ */ jsx28(
6511
+ reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning, variant: "block" }) : null,
6512
+ /* @__PURE__ */ jsx29(
6359
6513
  Bot,
6360
6514
  {
6361
6515
  size: 13,
@@ -6363,14 +6517,14 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6363
6517
  "aria-label": "\u5B50\u667A\u80FD\u4F53"
6364
6518
  }
6365
6519
  ),
6366
- /* @__PURE__ */ jsx28(
6520
+ /* @__PURE__ */ jsx29(
6367
6521
  "button",
6368
6522
  {
6369
6523
  type: "button",
6370
6524
  onClick: toggleExpanded,
6371
6525
  "aria-expanded": expanded,
6372
6526
  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",
6373
- children: /* @__PURE__ */ jsx28(
6527
+ children: /* @__PURE__ */ jsx29(
6374
6528
  ChevronRight4,
6375
6529
  {
6376
6530
  size: 14,
@@ -6385,9 +6539,9 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6385
6539
  ]
6386
6540
  }
6387
6541
  ),
6388
- !expanded ? /* @__PURE__ */ jsxs23(Fragment7, { children: [
6389
- /* @__PURE__ */ jsx28("div", { className: "flex flex-wrap gap-1.5 px-4 py-2", children: completedToolLabels.length > 0 ? completedToolLabels.map(
6390
- (item) => item.kind === "file" ? /* @__PURE__ */ jsxs23(
6542
+ !expanded ? /* @__PURE__ */ jsxs24(Fragment8, { children: [
6543
+ /* @__PURE__ */ jsx29("div", { className: "flex flex-wrap gap-1.5 px-4 py-2", children: completedToolLabels.length > 0 ? completedToolLabels.map(
6544
+ (item) => item.kind === "file" ? /* @__PURE__ */ jsxs24(
6391
6545
  "span",
6392
6546
  {
6393
6547
  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",
@@ -6398,12 +6552,12 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6398
6552
  },
6399
6553
  title: item.label,
6400
6554
  children: [
6401
- /* @__PURE__ */ jsx28(FileText5, { size: 12, className: "shrink-0", "aria-hidden": "true" }),
6402
- /* @__PURE__ */ jsx28("span", { className: "truncate", children: item.label })
6555
+ /* @__PURE__ */ jsx29(FileText6, { size: 12, className: "shrink-0", "aria-hidden": "true" }),
6556
+ /* @__PURE__ */ jsx29("span", { className: "truncate", children: item.label })
6403
6557
  ]
6404
6558
  },
6405
6559
  item.key
6406
- ) : /* @__PURE__ */ jsx28(
6560
+ ) : /* @__PURE__ */ jsx29(
6407
6561
  "span",
6408
6562
  {
6409
6563
  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",
@@ -6416,12 +6570,12 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6416
6570
  },
6417
6571
  item.key
6418
6572
  )
6419
- ) : /* @__PURE__ */ jsx28("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5DE5\u5177\u8C03\u7528" }) }),
6420
- inlineToolUiBlocks.length > 0 ? /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-2 px-4 pb-3", children: inlineToolUiBlocks.map((block) => /* @__PURE__ */ jsx28(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null
6573
+ ) : /* @__PURE__ */ jsx29("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5DE5\u5177\u8C03\u7528" }) }),
6574
+ inlineToolUiBlocks.length > 0 ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2 px-4 pb-3", children: inlineToolUiBlocks.map((block) => /* @__PURE__ */ jsx29(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null
6421
6575
  ] }) : null
6422
6576
  ] }),
6423
- expanded && /* @__PURE__ */ jsx28("div", { className: "border-t border-[hsl(var(--border))] py-2", children: childMessages.length > 0 ? /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-3 px-3", children: childMessages.map(
6424
- (message, index) => message.role === "assistant" ? /* @__PURE__ */ jsx28(
6577
+ expanded && /* @__PURE__ */ jsx29("div", { className: "border-t border-[hsl(var(--border))] py-2", children: childMessages.length > 0 ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-3 px-3", children: childMessages.map(
6578
+ (message, index) => message.role === "assistant" ? /* @__PURE__ */ jsx29(
6425
6579
  ExpandedChildAssistantMessage,
6426
6580
  {
6427
6581
  message,
@@ -6429,13 +6583,13 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6429
6583
  isStreaming: message.status === "streaming"
6430
6584
  },
6431
6585
  message.entry_id ?? `${message.timestamp ?? "child"}-${index}`
6432
- ) : message.role === "user" ? /* @__PURE__ */ jsx28(
6586
+ ) : message.role === "user" ? /* @__PURE__ */ jsx29(
6433
6587
  ExpandedChildUserMessage,
6434
6588
  {
6435
6589
  message
6436
6590
  },
6437
6591
  message.entry_id ?? `${message.timestamp ?? "user"}-${index}`
6438
- ) : message.role === "error" ? /* @__PURE__ */ jsx28(
6592
+ ) : message.role === "error" ? /* @__PURE__ */ jsx29(
6439
6593
  "div",
6440
6594
  {
6441
6595
  className: "border-l-[2px] border-l-red-500 px-3 py-2 text-[11px] text-red-200",
@@ -6443,16 +6597,16 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6443
6597
  },
6444
6598
  message.entry_id ?? `${message.timestamp ?? "error"}-${index}`
6445
6599
  ) : null
6446
- ) }) : status === "running" ? /* @__PURE__ */ jsxs23("div", { className: "px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
6447
- /* @__PURE__ */ jsx28(Loader24, { size: 12, className: "mr-1.5 inline animate-spin" }),
6600
+ ) }) : status === "running" ? /* @__PURE__ */ jsxs24("div", { className: "px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
6601
+ /* @__PURE__ */ jsx29(Loader24, { size: 12, className: "mr-1.5 inline animate-spin" }),
6448
6602
  "\u6B63\u5728\u542F\u52A8..."
6449
- ] }) : toolCall.result ? /* @__PURE__ */ jsx28("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 })
6603
+ ] }) : toolCall.result ? /* @__PURE__ */ jsx29("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 })
6450
6604
  ]
6451
6605
  }
6452
6606
  );
6453
6607
  }
6454
6608
  function ExpandedChildUserMessage({ message }) {
6455
- return /* @__PURE__ */ jsx28("div", { className: "pl-8", children: /* @__PURE__ */ jsx28(UserMessageBubble, { message }) });
6609
+ return /* @__PURE__ */ jsx29("div", { className: "pl-8", children: /* @__PURE__ */ jsx29(UserMessageBubble, { message }) });
6456
6610
  }
6457
6611
  function ExpandedChildAssistantMessage({
6458
6612
  message,
@@ -6465,12 +6619,12 @@ function ExpandedChildAssistantMessage({
6465
6619
  const firstToolCallId = toolCalls[0]?.id;
6466
6620
  const toolReasoning = !isStreaming && !text && hasToolCalls ? message.reasoning : void 0;
6467
6621
  const standaloneReasoning = !isStreaming && !text && !hasToolCalls ? message.reasoning : void 0;
6468
- return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-2", children: [
6469
- message.reasoning && isStreaming && /* @__PURE__ */ jsxs23(Reasoning, { isStreaming, children: [
6470
- /* @__PURE__ */ jsx28(ReasoningTrigger, {}),
6471
- /* @__PURE__ */ jsx28(ReasoningContent, { children: message.reasoning })
6622
+ return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-2", children: [
6623
+ message.reasoning && isStreaming && /* @__PURE__ */ jsxs24(Reasoning, { isStreaming, children: [
6624
+ /* @__PURE__ */ jsx29(ReasoningTrigger, {}),
6625
+ /* @__PURE__ */ jsx29(ReasoningContent, { children: message.reasoning })
6472
6626
  ] }),
6473
- text ? /* @__PURE__ */ jsx28(
6627
+ text ? /* @__PURE__ */ jsx29(
6474
6628
  ChildText,
6475
6629
  {
6476
6630
  text,
@@ -6479,10 +6633,10 @@ function ExpandedChildAssistantMessage({
6479
6633
  reasoning: !isStreaming ? message.reasoning : void 0
6480
6634
  }
6481
6635
  ) : null,
6482
- !text && isStreaming && /* @__PURE__ */ jsx28("span", { className: "pl-8 text-[12px] text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
6483
- standaloneReasoning ? /* @__PURE__ */ jsx28("div", { className: "pl-8", children: /* @__PURE__ */ jsx28(ThinkingBadge, { reasoning: standaloneReasoning, variant: "block" }) }) : null,
6484
- hasToolCalls && /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-2", children: toolCalls.map(
6485
- (toolCall, index) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx28(
6636
+ !text && isStreaming && /* @__PURE__ */ jsx29("span", { className: "pl-8 text-[12px] text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
6637
+ standaloneReasoning ? /* @__PURE__ */ jsx29("div", { className: "pl-8", children: /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning: standaloneReasoning, variant: "block" }) }) : null,
6638
+ hasToolCalls && /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2", children: toolCalls.map(
6639
+ (toolCall, index) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx29(
6486
6640
  AgentLoopBlock,
6487
6641
  {
6488
6642
  toolCall,
@@ -6490,7 +6644,7 @@ function ExpandedChildAssistantMessage({
6490
6644
  reasoning: toolCall.id === firstToolCallId ? toolReasoning : void 0
6491
6645
  },
6492
6646
  toolCall.id
6493
- ) : /* @__PURE__ */ jsx28(
6647
+ ) : /* @__PURE__ */ jsx29(
6494
6648
  ToolCallBlock,
6495
6649
  {
6496
6650
  toolCall,
@@ -6502,8 +6656,8 @@ function ExpandedChildAssistantMessage({
6502
6656
  toolCall.id
6503
6657
  )
6504
6658
  ) }),
6505
- message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx28("div", { className: "flex flex-col gap-2", children: message.blocks.map(
6506
- (block, index) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx28("div", { className: "ml-4", children: /* @__PURE__ */ jsx28(ResourceIframe, { ui: block.content, sessionId }) }, `${block.tool_call_id}-${index}`) : null
6659
+ message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2", children: message.blocks.map(
6660
+ (block, index) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx29("div", { className: "ml-4", children: /* @__PURE__ */ jsx29(ResourceIframe, { ui: block.content, sessionId }) }, `${block.tool_call_id}-${index}`) : null
6507
6661
  ) }) : null
6508
6662
  ] });
6509
6663
  }
@@ -6513,8 +6667,8 @@ function ChildText({
6513
6667
  sessionId,
6514
6668
  reasoning
6515
6669
  }) {
6516
- return /* @__PURE__ */ jsxs23("div", { className: "pl-8 text-[12px] leading-6 text-[hsl(var(--foreground))]", children: [
6517
- /* @__PURE__ */ jsx28(
6670
+ return /* @__PURE__ */ jsxs24("div", { className: "pl-8 text-[12px] leading-6 text-[hsl(var(--foreground))]", children: [
6671
+ /* @__PURE__ */ jsx29(
6518
6672
  MarkdownContent,
6519
6673
  {
6520
6674
  mode: "streaming",
@@ -6524,8 +6678,8 @@ function ChildText({
6524
6678
  children: text
6525
6679
  }
6526
6680
  ),
6527
- isStreaming && /* @__PURE__ */ jsx28("span", { className: "ml-0.5 inline-block h-[1em] w-[3px] animate-pulse rounded-sm bg-current opacity-60" }),
6528
- reasoning ? /* @__PURE__ */ jsx28(ThinkingBadge, { reasoning }) : null
6681
+ isStreaming && /* @__PURE__ */ jsx29("span", { className: "ml-0.5 inline-block h-[1em] w-[3px] animate-pulse rounded-sm bg-current opacity-60" }),
6682
+ reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning }) : null
6529
6683
  ] });
6530
6684
  }
6531
6685
  function getLoopCardStyles(status) {
@@ -6565,7 +6719,7 @@ function getLoopCardStyles(status) {
6565
6719
  }
6566
6720
 
6567
6721
  // src/react/components/chat/AssistantTurnBlock.tsx
6568
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
6722
+ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
6569
6723
  function defaultTurnDisplayMode({
6570
6724
  forceExpanded,
6571
6725
  hasActionableToolCall
@@ -6719,7 +6873,7 @@ function AssistantTurnBlock({
6719
6873
  ),
6720
6874
  [allToolCalls]
6721
6875
  );
6722
- const [displayMode, setDisplayMode] = useState16(
6876
+ const [displayMode, setDisplayMode] = useState17(
6723
6877
  defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall })
6724
6878
  );
6725
6879
  const wasStreamingRef = useRef10(isStreaming);
@@ -6740,7 +6894,7 @@ function AssistantTurnBlock({
6740
6894
  const hasInterruptedState = messages.some((message) => message.status === "interrupted");
6741
6895
  const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
6742
6896
  const memoryRefs = Array.isArray(messages[0]?.memory_refs) ? messages[0].memory_refs : [];
6743
- return /* @__PURE__ */ jsxs24(
6897
+ return /* @__PURE__ */ jsxs25(
6744
6898
  "div",
6745
6899
  {
6746
6900
  className: cn(
@@ -6749,17 +6903,17 @@ function AssistantTurnBlock({
6749
6903
  customization?.classNames?.assistantTurn
6750
6904
  ),
6751
6905
  children: [
6752
- memoryRefs.length > 0 && /* @__PURE__ */ jsx29(MemoryRefsHint, { refs: memoryRefs }),
6753
- hasInterruptedState && /* @__PURE__ */ jsx29("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" }),
6754
- !isStreaming && /* @__PURE__ */ jsx29("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs24(
6906
+ memoryRefs.length > 0 && /* @__PURE__ */ jsx30(MemoryRefsHint, { refs: memoryRefs }),
6907
+ hasInterruptedState && /* @__PURE__ */ jsx30("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" }),
6908
+ !isStreaming && /* @__PURE__ */ jsx30("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs25(
6755
6909
  "button",
6756
6910
  {
6757
6911
  type: "button",
6758
6912
  onClick: () => setDisplayMode(displayMode === "detail" ? "compact" : "detail"),
6759
6913
  className: "inline-flex shrink-0 items-center gap-1 text-xs text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
6760
6914
  children: [
6761
- /* @__PURE__ */ jsx29("span", { children: effectiveMode === "detail" ? "\u7CBE\u7B80" : "\u8BE6\u7EC6" }),
6762
- /* @__PURE__ */ jsx29(
6915
+ /* @__PURE__ */ jsx30("span", { children: effectiveMode === "detail" ? "\u7CBE\u7B80" : "\u8BE6\u7EC6" }),
6916
+ /* @__PURE__ */ jsx30(
6763
6917
  ChevronRight5,
6764
6918
  {
6765
6919
  size: 18,
@@ -6769,7 +6923,7 @@ function AssistantTurnBlock({
6769
6923
  ]
6770
6924
  }
6771
6925
  ) }),
6772
- effectiveMode === "detail" ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx29(
6926
+ effectiveMode === "detail" ? /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx30(
6773
6927
  AssistantMessages,
6774
6928
  {
6775
6929
  messages,
@@ -6782,15 +6936,15 @@ function AssistantTurnBlock({
6782
6936
  showToolDetails: true,
6783
6937
  customization
6784
6938
  }
6785
- ) }) : /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-4", children: [
6786
- resourceBlocks.length > 0 ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-3", children: resourceBlocks.map((block) => /* @__PURE__ */ jsx29(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null,
6787
- finalMessage ? /* @__PURE__ */ jsx29(
6939
+ ) }) : /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-4", children: [
6940
+ resourceBlocks.length > 0 ? /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-3", children: resourceBlocks.map((block) => /* @__PURE__ */ jsx30(ResourceIframe, { ui: block.ui, sessionId }, block.key)) }) : null,
6941
+ finalMessage ? /* @__PURE__ */ jsx30(
6788
6942
  "div",
6789
6943
  {
6790
6944
  className: cn(
6791
6945
  resourceBlocks.length > 0 && "border-t border-[hsl(var(--border))] pt-4"
6792
6946
  ),
6793
- children: /* @__PURE__ */ jsx29(
6947
+ children: /* @__PURE__ */ jsx30(
6794
6948
  AssistantMessageContent,
6795
6949
  {
6796
6950
  message: finalMessage,
@@ -6801,7 +6955,7 @@ function AssistantTurnBlock({
6801
6955
  }
6802
6956
  )
6803
6957
  }
6804
- ) : isStreaming ? /* @__PURE__ */ jsx29("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }) : null
6958
+ ) : isStreaming ? /* @__PURE__ */ jsx30("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }) : null
6805
6959
  ] }) })
6806
6960
  ]
6807
6961
  }
@@ -6831,16 +6985,16 @@ function AssistantMessages({
6831
6985
  const toolRenderItems = groupDetailedToolCalls(toolCalls);
6832
6986
  const toolReasoning = hasReasoning && !hasText && !hasAttachments && hasToolCalls && !isStreamingLastMessage ? reasoning : void 0;
6833
6987
  const contentReasoning = hasReasoning && !isStreamingLastMessage && (hasText || hasAttachments || !hasToolCalls) ? reasoning : void 0;
6834
- return /* @__PURE__ */ jsxs24(
6988
+ return /* @__PURE__ */ jsxs25(
6835
6989
  "div",
6836
6990
  {
6837
6991
  className: "flex flex-col gap-3",
6838
6992
  children: [
6839
- hasReasoning && isStreamingLastMessage && /* @__PURE__ */ jsxs24(Reasoning, { isStreaming: isStreamingLastMessage, children: [
6840
- /* @__PURE__ */ jsx29(ReasoningTrigger, {}),
6841
- /* @__PURE__ */ jsx29(ReasoningContent, { children: reasoning })
6993
+ hasReasoning && isStreamingLastMessage && /* @__PURE__ */ jsxs25(Reasoning, { isStreaming: isStreamingLastMessage, children: [
6994
+ /* @__PURE__ */ jsx30(ReasoningTrigger, {}),
6995
+ /* @__PURE__ */ jsx30(ReasoningContent, { children: reasoning })
6842
6996
  ] }),
6843
- /* @__PURE__ */ jsx29(
6997
+ /* @__PURE__ */ jsx30(
6844
6998
  AssistantMessageContent,
6845
6999
  {
6846
7000
  message,
@@ -6850,9 +7004,9 @@ function AssistantMessages({
6850
7004
  className: customization?.classNames?.assistantText
6851
7005
  }
6852
7006
  ),
6853
- hasToolCalls && showToolDetails && /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2", children: toolRenderItems.map((item) => {
7007
+ hasToolCalls && showToolDetails && /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-2", children: toolRenderItems.map((item) => {
6854
7008
  if (item.kind === "read_group" || item.kind === "load_skill_group") {
6855
- return /* @__PURE__ */ jsx29(
7009
+ return /* @__PURE__ */ jsx30(
6856
7010
  CompactToolGroupBlock,
6857
7011
  {
6858
7012
  toolCalls: item.toolCalls,
@@ -6870,7 +7024,7 @@ function AssistantMessages({
6870
7024
  );
6871
7025
  }
6872
7026
  const { toolCall } = item;
6873
- return formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx29(
7027
+ return formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx30(
6874
7028
  AgentLoopBlock,
6875
7029
  {
6876
7030
  toolCall,
@@ -6878,7 +7032,7 @@ function AssistantMessages({
6878
7032
  reasoning: toolCall.id === firstToolCallId ? toolReasoning : void 0
6879
7033
  },
6880
7034
  toolCall.id
6881
- ) : customization?.components?.ToolCall ? /* @__PURE__ */ jsx29(
7035
+ ) : customization?.components?.ToolCall ? /* @__PURE__ */ jsx30(
6882
7036
  customization.components.ToolCall,
6883
7037
  {
6884
7038
  toolCall,
@@ -6893,7 +7047,7 @@ function AssistantMessages({
6893
7047
  customization
6894
7048
  },
6895
7049
  toolCall.id
6896
- ) : /* @__PURE__ */ jsx29(
7050
+ ) : /* @__PURE__ */ jsx30(
6897
7051
  ToolCallBlock,
6898
7052
  {
6899
7053
  toolCall,
@@ -6910,8 +7064,8 @@ function AssistantMessages({
6910
7064
  toolCall.id
6911
7065
  );
6912
7066
  }) }),
6913
- showToolDetails && message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2", children: message.blocks.map(
6914
- (block, blockIndex) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx29("div", { className: "ml-4", children: /* @__PURE__ */ jsx29(ResourceIframe, { ui: block.content, sessionId }) }, `${block.tool_call_id}-${blockIndex}`) : null
7067
+ showToolDetails && message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-2", children: message.blocks.map(
7068
+ (block, blockIndex) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */ jsx30("div", { className: "ml-4", children: /* @__PURE__ */ jsx30(ResourceIframe, { ui: block.content, sessionId }) }, `${block.tool_call_id}-${blockIndex}`) : null
6915
7069
  ) }) : null
6916
7070
  ]
6917
7071
  },
@@ -6946,7 +7100,7 @@ function CompactToolGroupBlock({
6946
7100
  level,
6947
7101
  customization
6948
7102
  }) {
6949
- const [expanded, setExpanded] = useState16(false);
7103
+ const [expanded, setExpanded] = useState17(false);
6950
7104
  const indentClass = level === 2 ? "ml-3" : "ml-4";
6951
7105
  const hasError = toolCalls.some(
6952
7106
  (tc) => tc.status === "error" || tc.status === "cancelled"
@@ -6961,12 +7115,12 @@ function CompactToolGroupBlock({
6961
7115
  });
6962
7116
  const tags = kind === "read_group" ? fileNames : toolCalls.map(getLoadedSkillName);
6963
7117
  const title = kind === "read_group" ? `\u8BFB\u53D6 ${toolCalls.length} \u4E2A\u6587\u4EF6` : toolCalls.length > 1 ? `\u52A0\u8F7D ${toolCalls.length} \u4E2A\u6280\u80FD` : "\u52A0\u8F7D\u6280\u80FD";
6964
- return /* @__PURE__ */ jsxs24("div", { className: cn(indentClass, "text-xs"), children: [
6965
- /* @__PURE__ */ jsxs24("div", { className: cn(
7118
+ return /* @__PURE__ */ jsxs25("div", { className: cn(indentClass, "text-xs"), children: [
7119
+ /* @__PURE__ */ jsxs25("div", { className: cn(
6966
7120
  "flex items-center gap-2 border-l-[3px] px-3 py-2",
6967
7121
  hasError ? "border-l-[hsl(var(--destructive))]" : "border-l-[hsl(var(--primary))]"
6968
7122
  ), children: [
6969
- /* @__PURE__ */ jsxs24(
7123
+ /* @__PURE__ */ jsxs25(
6970
7124
  "button",
6971
7125
  {
6972
7126
  type: "button",
@@ -6974,7 +7128,7 @@ function CompactToolGroupBlock({
6974
7128
  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",
6975
7129
  "aria-expanded": expanded,
6976
7130
  children: [
6977
- /* @__PURE__ */ jsx29(
7131
+ /* @__PURE__ */ jsx30(
6978
7132
  ChevronRight5,
6979
7133
  {
6980
7134
  size: 11,
@@ -6984,18 +7138,18 @@ function CompactToolGroupBlock({
6984
7138
  )
6985
7139
  }
6986
7140
  ),
6987
- hasError ? /* @__PURE__ */ jsxs24("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--destructive))]", children: [
6988
- /* @__PURE__ */ jsx29(AlertCircle, { size: 11 }),
6989
- /* @__PURE__ */ jsx29("span", { children: "\u5931\u8D25" })
6990
- ] }) : /* @__PURE__ */ jsxs24("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--primary))]", children: [
6991
- /* @__PURE__ */ jsx29(Check4, { size: 11 }),
6992
- /* @__PURE__ */ jsx29("span", { children: "\u5B8C\u6210" })
7141
+ hasError ? /* @__PURE__ */ jsxs25("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--destructive))]", children: [
7142
+ /* @__PURE__ */ jsx30(AlertCircle, { size: 11 }),
7143
+ /* @__PURE__ */ jsx30("span", { children: "\u5931\u8D25" })
7144
+ ] }) : /* @__PURE__ */ jsxs25("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--primary))]", children: [
7145
+ /* @__PURE__ */ jsx30(Check4, { size: 11 }),
7146
+ /* @__PURE__ */ jsx30("span", { children: "\u5B8C\u6210" })
6993
7147
  ] }),
6994
- /* @__PURE__ */ jsx29("span", { className: "min-w-0 shrink-0 font-medium text-[hsl(var(--foreground))]", children: title })
7148
+ /* @__PURE__ */ jsx30("span", { className: "min-w-0 shrink-0 font-medium text-[hsl(var(--foreground))]", children: title })
6995
7149
  ]
6996
7150
  }
6997
7151
  ),
6998
- /* @__PURE__ */ jsx29("div", { className: "flex min-w-0 flex-1 flex-wrap gap-1.5", children: tags.map((tag, index) => /* @__PURE__ */ jsx29(
7152
+ /* @__PURE__ */ jsx30("div", { className: "flex min-w-0 flex-1 flex-wrap gap-1.5", children: tags.map((tag, index) => /* @__PURE__ */ jsx30(
6999
7153
  "span",
7000
7154
  {
7001
7155
  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))]",
@@ -7004,12 +7158,12 @@ function CompactToolGroupBlock({
7004
7158
  },
7005
7159
  `${tag}-${index}`
7006
7160
  )) }),
7007
- reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning, variant: "block" }) : null,
7008
- totalDurationMs > 0 ? /* @__PURE__ */ jsx29("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration2(totalDurationMs) }) : null
7161
+ reasoning ? /* @__PURE__ */ jsx30(ThinkingBadge, { reasoning, variant: "block" }) : null,
7162
+ totalDurationMs > 0 ? /* @__PURE__ */ jsx30("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration2(totalDurationMs) }) : null
7009
7163
  ] }),
7010
- expanded ? /* @__PURE__ */ jsx29("div", { className: "mt-1 flex flex-col gap-1", children: toolCalls.map((toolCall) => {
7164
+ expanded ? /* @__PURE__ */ jsx30("div", { className: "mt-1 flex flex-col gap-1", children: toolCalls.map((toolCall) => {
7011
7165
  const CustomToolCall = customization?.components?.ToolCall;
7012
- return CustomToolCall ? /* @__PURE__ */ jsx29(
7166
+ return CustomToolCall ? /* @__PURE__ */ jsx30(
7013
7167
  CustomToolCall,
7014
7168
  {
7015
7169
  toolCall,
@@ -7023,7 +7177,7 @@ function CompactToolGroupBlock({
7023
7177
  customization
7024
7178
  },
7025
7179
  toolCall.id
7026
- ) : /* @__PURE__ */ jsx29(
7180
+ ) : /* @__PURE__ */ jsx30(
7027
7181
  ToolCallBlock,
7028
7182
  {
7029
7183
  toolCall,
@@ -7054,8 +7208,8 @@ function AssistantMessageContent({
7054
7208
  if (!text && imageParts.length === 0 && fileParts.length === 0 && !isStreaming && !reasoning) {
7055
7209
  return null;
7056
7210
  }
7057
- return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-3", children: [
7058
- imageParts.length > 0 && /* @__PURE__ */ jsx29("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx29(
7211
+ return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-3", children: [
7212
+ imageParts.length > 0 && /* @__PURE__ */ jsx30("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx30(
7059
7213
  "img",
7060
7214
  {
7061
7215
  src: part.image_url.url,
@@ -7064,8 +7218,8 @@ function AssistantMessageContent({
7064
7218
  },
7065
7219
  part.image_url.url
7066
7220
  )) }),
7067
- /* @__PURE__ */ jsx29(MessageFileAttachmentList, { files: fileParts }),
7068
- text ? /* @__PURE__ */ jsx29(
7221
+ /* @__PURE__ */ jsx30(MessageFileAttachmentList, { files: fileParts }),
7222
+ text ? /* @__PURE__ */ jsx30(
7069
7223
  AssistantText,
7070
7224
  {
7071
7225
  text,
@@ -7075,8 +7229,8 @@ function AssistantMessageContent({
7075
7229
  className
7076
7230
  }
7077
7231
  ) : null,
7078
- !text && isStreaming && /* @__PURE__ */ jsx29("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
7079
- !text && reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning, variant: "block" }) : null
7232
+ !text && isStreaming && /* @__PURE__ */ jsx30("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
7233
+ !text && reasoning ? /* @__PURE__ */ jsx30(ThinkingBadge, { reasoning, variant: "block" }) : null
7080
7234
  ] });
7081
7235
  }
7082
7236
  function AssistantText({
@@ -7096,8 +7250,8 @@ function AssistantText({
7096
7250
  () => ({ sessionId, messageId, sendMessage }),
7097
7251
  [sessionId, messageId, sendMessage]
7098
7252
  );
7099
- return /* @__PURE__ */ jsxs24("div", { className: cn("text-[15px] leading-8 text-[hsl(var(--foreground))]", className), children: [
7100
- /* @__PURE__ */ jsx29(CardContext.Provider, { value: cardCtx, children: /* @__PURE__ */ jsx29(
7253
+ return /* @__PURE__ */ jsxs25("div", { className: cn("text-[15px] leading-8 text-[hsl(var(--foreground))]", className), children: [
7254
+ /* @__PURE__ */ jsx30(CardContext.Provider, { value: cardCtx, children: /* @__PURE__ */ jsx30(
7101
7255
  MarkdownContent,
7102
7256
  {
7103
7257
  mode: "streaming",
@@ -7107,30 +7261,30 @@ function AssistantText({
7107
7261
  children: text
7108
7262
  }
7109
7263
  ) }),
7110
- reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning }) : null
7264
+ reasoning ? /* @__PURE__ */ jsx30(ThinkingBadge, { reasoning }) : null
7111
7265
  ] });
7112
7266
  }
7113
7267
  function MemoryRefsHint({ refs: rawRefs }) {
7114
7268
  const refs = Array.isArray(rawRefs) ? rawRefs : [];
7115
- const [expanded, setExpanded] = useState16(false);
7269
+ const [expanded, setExpanded] = useState17(false);
7116
7270
  const hasSkill = refs.some((r3) => r3.skill_name);
7117
7271
  const label = hasSkill ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
7118
- return /* @__PURE__ */ jsxs24("div", { className: "ml-4", children: [
7119
- /* @__PURE__ */ jsxs24(
7272
+ return /* @__PURE__ */ jsxs25("div", { className: "ml-4", children: [
7273
+ /* @__PURE__ */ jsxs25(
7120
7274
  "button",
7121
7275
  {
7122
7276
  type: "button",
7123
7277
  onClick: () => setExpanded(!expanded),
7124
7278
  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)]",
7125
7279
  children: [
7126
- /* @__PURE__ */ jsx29(BookOpen, { size: 12 }),
7127
- /* @__PURE__ */ jsxs24("span", { children: [
7280
+ /* @__PURE__ */ jsx30(BookOpen, { size: 12 }),
7281
+ /* @__PURE__ */ jsxs25("span", { children: [
7128
7282
  label,
7129
7283
  "\uFF08",
7130
7284
  refs.length,
7131
7285
  "\uFF09"
7132
7286
  ] }),
7133
- /* @__PURE__ */ jsx29(
7287
+ /* @__PURE__ */ jsx30(
7134
7288
  ChevronRight5,
7135
7289
  {
7136
7290
  size: 10,
@@ -7140,13 +7294,13 @@ function MemoryRefsHint({ refs: rawRefs }) {
7140
7294
  ]
7141
7295
  }
7142
7296
  ),
7143
- expanded && /* @__PURE__ */ jsxs24("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: [
7144
- refs.map((ref) => /* @__PURE__ */ jsxs24("div", { className: "flex items-start gap-2 text-[11px] text-[hsl(var(--foreground)/0.82)]", children: [
7145
- /* @__PURE__ */ jsx29("span", { className: "mt-0.5 shrink-0 text-[hsl(var(--primary)/0.75)]", children: "\u2022" }),
7146
- /* @__PURE__ */ jsx29("span", { className: "line-clamp-1", children: ref.content_preview }),
7147
- ref.skill_name && /* @__PURE__ */ jsx29("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 })
7297
+ expanded && /* @__PURE__ */ jsxs25("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: [
7298
+ refs.map((ref) => /* @__PURE__ */ jsxs25("div", { className: "flex items-start gap-2 text-[11px] text-[hsl(var(--foreground)/0.82)]", children: [
7299
+ /* @__PURE__ */ jsx30("span", { className: "mt-0.5 shrink-0 text-[hsl(var(--primary)/0.75)]", children: "\u2022" }),
7300
+ /* @__PURE__ */ jsx30("span", { className: "line-clamp-1", children: ref.content_preview }),
7301
+ ref.skill_name && /* @__PURE__ */ jsx30("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 })
7148
7302
  ] }, ref.id)),
7149
- /* @__PURE__ */ jsx29(
7303
+ /* @__PURE__ */ jsx30(
7150
7304
  "a",
7151
7305
  {
7152
7306
  href: MEMORIES_ROUTE,
@@ -7159,9 +7313,9 @@ function MemoryRefsHint({ refs: rawRefs }) {
7159
7313
  }
7160
7314
 
7161
7315
  // src/react/components/chat/CompactionCard.tsx
7162
- import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight6, Loader2 as Loader25, Square as Square2, XCircle } from "lucide-react";
7163
- import { useState as useState17 } from "react";
7164
- import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
7316
+ import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight6, Loader2 as Loader25, Square as Square3, XCircle } from "lucide-react";
7317
+ import { useState as useState18 } from "react";
7318
+ import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
7165
7319
  var PERCENT_FORMATTER = new Intl.NumberFormat("zh-CN", {
7166
7320
  style: "percent",
7167
7321
  maximumFractionDigits: 0
@@ -7220,7 +7374,7 @@ function CompactionCard({
7220
7374
  ...compaction,
7221
7375
  status: status ?? "completed"
7222
7376
  } : activeCompaction;
7223
- const [expanded, setExpanded] = useState17(false);
7377
+ const [expanded, setExpanded] = useState18(false);
7224
7378
  if (!source || !source.compaction_id) {
7225
7379
  return null;
7226
7380
  }
@@ -7231,9 +7385,9 @@ function CompactionCard({
7231
7385
  const hasSummary = typeof source.summary_full === "string" && source.summary_full.trim().length > 0 && !isGenericArchiveSummary(source.summary_full);
7232
7386
  const hasFailureReason = source.status === "failed" && Boolean(source.failure_reason);
7233
7387
  const canExpand = source.status === "completed" && (hasSummary || archivedToolCalls.length > 0) || hasFailureReason;
7234
- return /* @__PURE__ */ jsxs25("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: [
7235
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between gap-2", children: [
7236
- /* @__PURE__ */ jsxs25(
7388
+ return /* @__PURE__ */ jsxs26("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: [
7389
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between gap-2", children: [
7390
+ /* @__PURE__ */ jsxs26(
7237
7391
  "button",
7238
7392
  {
7239
7393
  type: "button",
@@ -7244,21 +7398,21 @@ function CompactionCard({
7244
7398
  ),
7245
7399
  "aria-expanded": expanded,
7246
7400
  children: [
7247
- canExpand ? expanded ? /* @__PURE__ */ jsx30(ChevronDown2, { size: 12, className: "shrink-0" }) : /* @__PURE__ */ jsx30(ChevronRight6, { size: 12, className: "shrink-0" }) : null,
7248
- /* @__PURE__ */ jsx30("span", { children: source.status === "streaming" ? /* @__PURE__ */ jsxs25("span", { className: "inline-flex items-center gap-1", children: [
7249
- /* @__PURE__ */ jsx30(Loader25, { size: 12, className: "animate-spin" }),
7401
+ canExpand ? expanded ? /* @__PURE__ */ jsx31(ChevronDown2, { size: 12, className: "shrink-0" }) : /* @__PURE__ */ jsx31(ChevronRight6, { size: 12, className: "shrink-0" }) : null,
7402
+ /* @__PURE__ */ jsx31("span", { children: source.status === "streaming" ? /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1", children: [
7403
+ /* @__PURE__ */ jsx31(Loader25, { size: 12, className: "animate-spin" }),
7250
7404
  "\u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587"
7251
- ] }) : source.status === "failed" ? /* @__PURE__ */ jsxs25("span", { className: "inline-flex items-center gap-1 text-rose-500/80", children: [
7252
- /* @__PURE__ */ jsx30(XCircle, { size: 12 }),
7405
+ ] }) : source.status === "failed" ? /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1 text-rose-500/80", children: [
7406
+ /* @__PURE__ */ jsx31(XCircle, { size: 12 }),
7253
7407
  "\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25"
7254
- ] }) : source.status === "interrupted" ? /* @__PURE__ */ jsxs25("span", { className: "inline-flex items-center gap-1 text-amber-500/80", children: [
7255
- /* @__PURE__ */ jsx30(Square2, { size: 11 }),
7408
+ ] }) : source.status === "interrupted" ? /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1 text-amber-500/80", children: [
7409
+ /* @__PURE__ */ jsx31(Square3, { size: 11 }),
7256
7410
  "\u4E0A\u4E0B\u6587\u538B\u7F29\u5DF2\u53D6\u6D88"
7257
7411
  ] }) : "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
7258
7412
  ]
7259
7413
  }
7260
7414
  ),
7261
- canCancel ? /* @__PURE__ */ jsx30(
7415
+ canCancel ? /* @__PURE__ */ jsx31(
7262
7416
  "button",
7263
7417
  {
7264
7418
  type: "button",
@@ -7268,13 +7422,13 @@ function CompactionCard({
7268
7422
  }
7269
7423
  ) : null
7270
7424
  ] }),
7271
- expanded ? /* @__PURE__ */ jsxs25("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: [
7272
- /* @__PURE__ */ jsxs25("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-[hsl(var(--muted-foreground))]", children: [
7273
- /* @__PURE__ */ jsxs25("span", { children: [
7425
+ expanded ? /* @__PURE__ */ jsxs26("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: [
7426
+ /* @__PURE__ */ jsxs26("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-[hsl(var(--muted-foreground))]", children: [
7427
+ /* @__PURE__ */ jsxs26("span", { children: [
7274
7428
  "#",
7275
7429
  shortId(source.compaction_id)
7276
7430
  ] }),
7277
- /* @__PURE__ */ jsxs25("span", { children: [
7431
+ /* @__PURE__ */ jsxs26("span", { children: [
7278
7432
  "\u8282\u7701 ",
7279
7433
  formatSavedRatio(source.saved_ratio),
7280
7434
  "\uFF08",
@@ -7284,31 +7438,31 @@ function CompactionCard({
7284
7438
  formatTokens(source.tokens_after),
7285
7439
  " token\uFF09"
7286
7440
  ] }),
7287
- /* @__PURE__ */ jsxs25("span", { children: [
7441
+ /* @__PURE__ */ jsxs26("span", { children: [
7288
7442
  "\u5F52\u6863 ",
7289
7443
  archivedCount,
7290
7444
  " \u4E2A\u5DE5\u5177\u7ED3\u679C"
7291
7445
  ] })
7292
7446
  ] }),
7293
- archivedToolCalls.length > 0 ? /* @__PURE__ */ jsx30("div", { className: "mt-2 space-y-1.5", children: archivedToolCalls.map((item, index) => {
7447
+ archivedToolCalls.length > 0 ? /* @__PURE__ */ jsx31("div", { className: "mt-2 space-y-1.5", children: archivedToolCalls.map((item, index) => {
7294
7448
  const archivePath = getArchivePath(item, archivedFiles);
7295
- return /* @__PURE__ */ jsxs25(
7449
+ return /* @__PURE__ */ jsxs26(
7296
7450
  "div",
7297
7451
  {
7298
7452
  className: "rounded-md border border-[hsl(var(--border))]/70 bg-[hsl(var(--muted))]/35 px-2 py-1.5",
7299
7453
  children: [
7300
- /* @__PURE__ */ jsxs25("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-[hsl(var(--foreground))]", children: [
7301
- /* @__PURE__ */ jsx30("span", { className: "font-medium", children: getArchivedToolLabel(item) }),
7302
- item.tool_call_id ? /* @__PURE__ */ jsx30("span", { className: "font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.tool_call_id }) : null
7454
+ /* @__PURE__ */ jsxs26("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-[hsl(var(--foreground))]", children: [
7455
+ /* @__PURE__ */ jsx31("span", { className: "font-medium", children: getArchivedToolLabel(item) }),
7456
+ item.tool_call_id ? /* @__PURE__ */ jsx31("span", { className: "font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.tool_call_id }) : null
7303
7457
  ] }),
7304
- archivePath ? /* @__PURE__ */ jsx30("div", { className: "mt-0.5 break-all font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: archivePath }) : null
7458
+ archivePath ? /* @__PURE__ */ jsx31("div", { className: "mt-0.5 break-all font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: archivePath }) : null
7305
7459
  ]
7306
7460
  },
7307
7461
  item.tool_call_id || item.entry_id || `${item.tool_name}-${index}`
7308
7462
  );
7309
7463
  }) }) : null,
7310
- hasSummary ? /* @__PURE__ */ jsx30("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,
7311
- source.status === "failed" && source.failure_reason ? /* @__PURE__ */ jsxs25("div", { className: "mt-2 text-rose-500/90", children: [
7464
+ hasSummary ? /* @__PURE__ */ jsx31("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,
7465
+ source.status === "failed" && source.failure_reason ? /* @__PURE__ */ jsxs26("div", { className: "mt-2 text-rose-500/90", children: [
7312
7466
  "\u5931\u8D25\u539F\u56E0\uFF1A",
7313
7467
  source.failure_reason
7314
7468
  ] }) : null
@@ -7319,7 +7473,7 @@ function CompactionCard({
7319
7473
  // src/react/components/chat/RenderErrorBoundary.tsx
7320
7474
  import { AlertTriangle as AlertTriangle2 } from "lucide-react";
7321
7475
  import { Component } from "react";
7322
- import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
7476
+ import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
7323
7477
  function getFirstComponentName(componentStack) {
7324
7478
  const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
7325
7479
  return match?.[1] ?? null;
@@ -7352,18 +7506,18 @@ var RenderErrorBoundary = class extends Component {
7352
7506
  return children;
7353
7507
  }
7354
7508
  const componentName = getFirstComponentName(componentStack);
7355
- return /* @__PURE__ */ jsx31("div", { className: "rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs26("div", { className: "flex items-start gap-2", children: [
7356
- /* @__PURE__ */ jsx31(AlertTriangle2, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
7357
- /* @__PURE__ */ jsxs26("div", { className: "min-w-0 flex-1", children: [
7358
- /* @__PURE__ */ jsxs26("div", { className: "font-medium", children: [
7509
+ return /* @__PURE__ */ jsx32("div", { className: "rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs27("div", { className: "flex items-start gap-2", children: [
7510
+ /* @__PURE__ */ jsx32(AlertTriangle2, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
7511
+ /* @__PURE__ */ jsxs27("div", { className: "min-w-0 flex-1", children: [
7512
+ /* @__PURE__ */ jsxs27("div", { className: "font-medium", children: [
7359
7513
  label,
7360
7514
  "\u6E32\u67D3\u5931\u8D25"
7361
7515
  ] }),
7362
- /* @__PURE__ */ jsxs26("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
7516
+ /* @__PURE__ */ jsxs27("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
7363
7517
  componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
7364
7518
  error.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
7365
7519
  ] }),
7366
- details ? /* @__PURE__ */ jsx31("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
7520
+ details ? /* @__PURE__ */ jsx32("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
7367
7521
  ] })
7368
7522
  ] }) });
7369
7523
  }
@@ -7381,8 +7535,8 @@ import {
7381
7535
  TerminalSquare,
7382
7536
  WandSparkles
7383
7537
  } from "lucide-react";
7384
- import { useEffect as useEffect15, useMemo as useMemo16, useState as useState18 } from "react";
7385
- import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
7538
+ import { useEffect as useEffect15, useMemo as useMemo16, useState as useState19 } from "react";
7539
+ import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
7386
7540
  var EMPTY_EVENTS = [];
7387
7541
  function formatElapsedDuration(durationMs) {
7388
7542
  if (durationMs == null) return null;
@@ -7460,7 +7614,7 @@ function getTurnStartedAt(events) {
7460
7614
  return null;
7461
7615
  }
7462
7616
  function useElapsedDuration(startedAt, active) {
7463
- const [now, setNow] = useState18(() => Date.now());
7617
+ const [now, setNow] = useState19(() => Date.now());
7464
7618
  useEffect15(() => {
7465
7619
  if (!active || startedAt == null) {
7466
7620
  return;
@@ -7492,22 +7646,22 @@ function StickyStatusBar({
7492
7646
  }
7493
7647
  const elapsedLabel = formatElapsedDuration(elapsedDuration);
7494
7648
  const Icon = action.Icon;
7495
- return /* @__PURE__ */ jsxs27(
7649
+ return /* @__PURE__ */ jsxs28(
7496
7650
  "button",
7497
7651
  {
7498
7652
  type: "button",
7499
7653
  onClick: onJumpToLatest,
7500
7654
  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",
7501
7655
  children: [
7502
- /* @__PURE__ */ jsx32("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__ */ jsx32(Icon, { size: 18, className: Icon === LoaderCircle2 ? "animate-spin" : void 0 }) }),
7503
- /* @__PURE__ */ jsxs27("div", { className: "min-w-0 flex-1", children: [
7504
- /* @__PURE__ */ jsx32("div", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: action.label }),
7505
- /* @__PURE__ */ jsxs27("div", { className: "mt-1 flex flex-wrap items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
7506
- elapsedLabel ? /* @__PURE__ */ jsxs27("span", { className: "font-mono", children: [
7656
+ /* @__PURE__ */ jsx33("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__ */ jsx33(Icon, { size: 18, className: Icon === LoaderCircle2 ? "animate-spin" : void 0 }) }),
7657
+ /* @__PURE__ */ jsxs28("div", { className: "min-w-0 flex-1", children: [
7658
+ /* @__PURE__ */ jsx33("div", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: action.label }),
7659
+ /* @__PURE__ */ jsxs28("div", { className: "mt-1 flex flex-wrap items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
7660
+ elapsedLabel ? /* @__PURE__ */ jsxs28("span", { className: "font-mono", children: [
7507
7661
  "\u5DF2\u6301\u7EED ",
7508
7662
  elapsedLabel
7509
7663
  ] }) : null,
7510
- /* @__PURE__ */ jsx32("span", { children: "\u70B9\u51FB\u8DF3\u5230\u6700\u65B0\u4F4D\u7F6E" })
7664
+ /* @__PURE__ */ jsx33("span", { children: "\u70B9\u51FB\u8DF3\u5230\u6700\u65B0\u4F4D\u7F6E" })
7511
7665
  ] })
7512
7666
  ] })
7513
7667
  ]
@@ -7516,7 +7670,7 @@ function StickyStatusBar({
7516
7670
  }
7517
7671
 
7518
7672
  // src/react/components/chat/TurnNavRail.tsx
7519
- import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
7673
+ import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
7520
7674
  function TurnNavRail({
7521
7675
  items,
7522
7676
  activeTurnId,
@@ -7525,14 +7679,14 @@ function TurnNavRail({
7525
7679
  if (items.length < 2) {
7526
7680
  return null;
7527
7681
  }
7528
- return /* @__PURE__ */ jsx33(
7682
+ return /* @__PURE__ */ jsx34(
7529
7683
  "nav",
7530
7684
  {
7531
7685
  "aria-label": "\u56DE\u5408\u5BFC\u822A",
7532
7686
  className: "absolute right-2 top-4 z-10 hidden flex-col items-end gap-0.5 md:flex",
7533
7687
  children: items.map((item, index) => {
7534
7688
  const isActive = item.id === activeTurnId;
7535
- return /* @__PURE__ */ jsxs28(
7689
+ return /* @__PURE__ */ jsxs29(
7536
7690
  "button",
7537
7691
  {
7538
7692
  type: "button",
@@ -7540,8 +7694,8 @@ function TurnNavRail({
7540
7694
  "aria-current": isActive ? "true" : void 0,
7541
7695
  className: "group relative flex h-3.5 items-center",
7542
7696
  children: [
7543
- /* @__PURE__ */ jsx33("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` }),
7544
- /* @__PURE__ */ jsx33(
7697
+ /* @__PURE__ */ jsx34("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` }),
7698
+ /* @__PURE__ */ jsx34(
7545
7699
  "span",
7546
7700
  {
7547
7701
  className: cn(
@@ -7560,7 +7714,7 @@ function TurnNavRail({
7560
7714
  }
7561
7715
 
7562
7716
  // src/react/components/chat/MessageList.tsx
7563
- import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
7717
+ import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
7564
7718
  function parseModeChange(message) {
7565
7719
  if (message.kind !== "mode_change" || typeof message.content !== "string") {
7566
7720
  return null;
@@ -7758,7 +7912,7 @@ function MessageList({
7758
7912
  const containerRef = useRef11(null);
7759
7913
  const scrollContainerRef = useRef11(null);
7760
7914
  const frameRef = useRef11(null);
7761
- const [activeTurnId, setActiveTurnId] = useState19(lastTurnId);
7915
+ const [activeTurnId, setActiveTurnId] = useState20(lastTurnId);
7762
7916
  const layoutSignature = useMemo17(
7763
7917
  () => getMessagesMeasureSignature(messages),
7764
7918
  [messages]
@@ -7821,13 +7975,13 @@ function MessageList({
7821
7975
  const handleSelectTurn = useCallback12((turnId) => {
7822
7976
  document.getElementById(turnId)?.scrollIntoView({ behavior: "smooth", block: "start" });
7823
7977
  }, []);
7824
- return /* @__PURE__ */ jsxs29(
7978
+ return /* @__PURE__ */ jsxs30(
7825
7979
  "div",
7826
7980
  {
7827
7981
  ref: containerRef,
7828
7982
  className: `relative min-h-0 flex-1 ${customization?.classNames?.messageListRoot ?? ""}`,
7829
7983
  children: [
7830
- turnNavItems.length > 1 ? /* @__PURE__ */ jsx34(
7984
+ turnNavItems.length > 1 ? /* @__PURE__ */ jsx35(
7831
7985
  TurnNavRail,
7832
7986
  {
7833
7987
  items: turnNavItems,
@@ -7835,8 +7989,8 @@ function MessageList({
7835
7989
  onSelectTurn: handleSelectTurn
7836
7990
  }
7837
7991
  ) : null,
7838
- /* @__PURE__ */ jsxs29(StickToBottom, { className: "h-full overflow-y-hidden", resize: "smooth", children: [
7839
- /* @__PURE__ */ jsx34(StickToBottom.Content, { className: "px-5 py-6", children: /* @__PURE__ */ jsx34(
7992
+ /* @__PURE__ */ jsxs30(StickToBottom, { className: "h-full overflow-y-hidden", resize: "smooth", children: [
7993
+ /* @__PURE__ */ jsx35(StickToBottom.Content, { className: "px-5 py-6", children: /* @__PURE__ */ jsx35(
7840
7994
  MessageListContent,
7841
7995
  {
7842
7996
  askAnswers,
@@ -7853,7 +8007,7 @@ function MessageList({
7853
8007
  customization
7854
8008
  }
7855
8009
  ) }),
7856
- /* @__PURE__ */ jsx34(ScrollToBottomButton, {})
8010
+ /* @__PURE__ */ jsx35(ScrollToBottomButton, {})
7857
8011
  ] })
7858
8012
  ]
7859
8013
  }
@@ -7881,8 +8035,8 @@ function MessageListContent({
7881
8035
  }
7882
8036
  scrollToBottom();
7883
8037
  }, [lastTurnId, scrollToBottom]);
7884
- return /* @__PURE__ */ jsx34("div", { className: `mx-auto max-w-3xl ${customization?.classNames?.messageListContent ?? ""}`, children: /* @__PURE__ */ jsxs29("div", { className: `min-w-0 flex flex-col gap-8 ${customization?.classNames?.messageListInner ?? ""}`, children: [
7885
- stickyTurn ? /* @__PURE__ */ jsx34(
8038
+ return /* @__PURE__ */ jsx35("div", { className: `mx-auto max-w-3xl ${customization?.classNames?.messageListContent ?? ""}`, children: /* @__PURE__ */ jsxs30("div", { className: `min-w-0 flex flex-col gap-8 ${customization?.classNames?.messageListInner ?? ""}`, children: [
8039
+ stickyTurn ? /* @__PURE__ */ jsx35(
7886
8040
  StickyStatusBar,
7887
8041
  {
7888
8042
  sessionId,
@@ -7892,31 +8046,31 @@ function MessageListContent({
7892
8046
  onJumpToLatest: handleJumpToLatest
7893
8047
  }
7894
8048
  ) : null,
7895
- renderBlocks.length === 0 ? customization?.components?.EmptyState ? /* @__PURE__ */ jsx34(customization.components.EmptyState, {}) : /* @__PURE__ */ jsxs29("div", { className: `flex flex-col items-center justify-center gap-3 py-24 text-[hsl(var(--muted-foreground))] ${customization?.classNames?.emptyState ?? ""}`, children: [
7896
- /* @__PURE__ */ jsx34(MessageSquare, { size: 40, strokeWidth: 1.5 }),
7897
- /* @__PURE__ */ jsx34("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
7898
- /* @__PURE__ */ jsx34("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
8049
+ renderBlocks.length === 0 ? customization?.components?.EmptyState ? /* @__PURE__ */ jsx35(customization.components.EmptyState, {}) : /* @__PURE__ */ jsxs30("div", { className: `flex flex-col items-center justify-center gap-3 py-24 text-[hsl(var(--muted-foreground))] ${customization?.classNames?.emptyState ?? ""}`, children: [
8050
+ /* @__PURE__ */ jsx35(MessageSquare, { size: 40, strokeWidth: 1.5 }),
8051
+ /* @__PURE__ */ jsx35("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
8052
+ /* @__PURE__ */ jsx35("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
7899
8053
  ] }) : renderBlocks.map((block, blockIndex) => {
7900
8054
  if (block.type === "message") {
7901
- return /* @__PURE__ */ jsx34("div", { className: "msg-animate", children: isUserMessage(block.message) ? customization?.components?.UserMessage ? /* @__PURE__ */ jsx34(
8055
+ return /* @__PURE__ */ jsx35("div", { className: "msg-animate", children: isUserMessage(block.message) ? customization?.components?.UserMessage ? /* @__PURE__ */ jsx35(
7902
8056
  customization.components.UserMessage,
7903
8057
  {
7904
8058
  message: block.message,
7905
8059
  className: customization.classNames?.userMessage
7906
8060
  }
7907
- ) : /* @__PURE__ */ jsx34(
8061
+ ) : /* @__PURE__ */ jsx35(
7908
8062
  UserMessageBubble,
7909
8063
  {
7910
8064
  message: block.message,
7911
8065
  className: customization?.classNames?.userMessage
7912
8066
  }
7913
- ) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */ jsx34(
8067
+ ) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */ jsx35(
7914
8068
  customization.components.ErrorMessage,
7915
8069
  {
7916
8070
  message: block.message,
7917
8071
  className: customization.classNames?.errorMessage
7918
8072
  }
7919
- ) : /* @__PURE__ */ jsx34(
8073
+ ) : /* @__PURE__ */ jsx35(
7920
8074
  ErrorMessageBlock,
7921
8075
  {
7922
8076
  message: block.message,
@@ -7933,20 +8087,20 @@ function MessageListContent({
7933
8087
  );
7934
8088
  const isFollowedByPlanningExit = nextBlock?.type === "planning_divider" && nextBlock.kind === "planning_exit";
7935
8089
  const showPlanCard = (hasExitPlan || isFollowedByPlanningExit) && onConfirmPlan && sessionStatus === "waiting_for_input";
7936
- return /* @__PURE__ */ jsxs29(
8090
+ return /* @__PURE__ */ jsxs30(
7937
8091
  "div",
7938
8092
  {
7939
8093
  id: block.anchorId,
7940
8094
  "data-turn-id": block.anchorId,
7941
8095
  className: "msg-animate flex scroll-mt-6 flex-col gap-4",
7942
8096
  children: [
7943
- /* @__PURE__ */ jsx34(
8097
+ /* @__PURE__ */ jsx35(
7944
8098
  RenderErrorBoundary,
7945
8099
  {
7946
8100
  label: "\u52A9\u624B\u6D88\u606F",
7947
8101
  details: block.key,
7948
8102
  resetKey: getMessagesRenderSignature(block.messages),
7949
- children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx34(
8103
+ children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx35(
7950
8104
  customization.components.AssistantTurn,
7951
8105
  {
7952
8106
  turnKey: block.key,
@@ -7959,7 +8113,7 @@ function MessageListContent({
7959
8113
  sessionStatus,
7960
8114
  customization
7961
8115
  }
7962
- ) : /* @__PURE__ */ jsx34(
8116
+ ) : /* @__PURE__ */ jsx35(
7963
8117
  AssistantTurnBlock,
7964
8118
  {
7965
8119
  turnKey: block.key,
@@ -7975,13 +8129,13 @@ function MessageListContent({
7975
8129
  )
7976
8130
  }
7977
8131
  ),
7978
- showPlanCard ? /* @__PURE__ */ jsx34(
8132
+ showPlanCard ? /* @__PURE__ */ jsx35(
7979
8133
  RenderErrorBoundary,
7980
8134
  {
7981
8135
  label: "\u89C4\u5212\u6458\u8981",
7982
8136
  details: block.key,
7983
8137
  resetKey: `${sessionStatus ?? ""}:${layoutSignature}`,
7984
- children: /* @__PURE__ */ jsx34(
8138
+ children: /* @__PURE__ */ jsx35(
7985
8139
  PlanSummaryCard,
7986
8140
  {
7987
8141
  messages: extractLatestPlanMessages(messages),
@@ -7997,7 +8151,7 @@ function MessageListContent({
7997
8151
  );
7998
8152
  }
7999
8153
  if (block.type === "compaction") {
8000
- return /* @__PURE__ */ jsx34("div", { className: "msg-animate", children: /* @__PURE__ */ jsx34(
8154
+ return /* @__PURE__ */ jsx35("div", { className: "msg-animate", children: /* @__PURE__ */ jsx35(
8001
8155
  CompactionCard,
8002
8156
  {
8003
8157
  sessionId,
@@ -8006,41 +8160,41 @@ function MessageListContent({
8006
8160
  }
8007
8161
  ) }, block.key);
8008
8162
  }
8009
- return /* @__PURE__ */ jsx34(PlanningDivider, { kind: block.kind }, block.key);
8163
+ return /* @__PURE__ */ jsx35(PlanningDivider, { kind: block.kind }, block.key);
8010
8164
  }),
8011
- sessionStatus === "interrupted" && !hasInterruptedTurn ? /* @__PURE__ */ jsx34("div", { className: "flex", children: /* @__PURE__ */ jsx34("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
8165
+ sessionStatus === "interrupted" && !hasInterruptedTurn ? /* @__PURE__ */ jsx35("div", { className: "flex", children: /* @__PURE__ */ jsx35("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
8012
8166
  ] }) });
8013
8167
  }
8014
8168
  function ScrollToBottomButton() {
8015
8169
  const { isAtBottom, scrollToBottom } = useStickToBottomContext();
8016
8170
  if (isAtBottom) return null;
8017
- return /* @__PURE__ */ jsxs29(
8171
+ return /* @__PURE__ */ jsxs30(
8018
8172
  "button",
8019
8173
  {
8020
8174
  type: "button",
8021
8175
  onClick: () => scrollToBottom(),
8022
8176
  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))]",
8023
8177
  children: [
8024
- /* @__PURE__ */ jsx34(ChevronDown3, { size: 14 }),
8025
- /* @__PURE__ */ jsx34("span", { children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
8178
+ /* @__PURE__ */ jsx35(ChevronDown3, { size: 14 }),
8179
+ /* @__PURE__ */ jsx35("span", { children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
8026
8180
  ]
8027
8181
  }
8028
8182
  );
8029
8183
  }
8030
8184
  function PlanningDivider({ kind }) {
8031
8185
  const isEnter = kind === "planning_enter";
8032
- return /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-3 py-1", children: [
8033
- /* @__PURE__ */ jsx34("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
8034
- /* @__PURE__ */ jsxs29("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: [
8035
- /* @__PURE__ */ jsx34(Lightbulb2, { size: 12 }),
8036
- /* @__PURE__ */ jsx34("span", { children: isEnter ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
8186
+ return /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-3 py-1", children: [
8187
+ /* @__PURE__ */ jsx35("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
8188
+ /* @__PURE__ */ jsxs30("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: [
8189
+ /* @__PURE__ */ jsx35(Lightbulb2, { size: 12 }),
8190
+ /* @__PURE__ */ jsx35("span", { children: isEnter ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
8037
8191
  ] }),
8038
- /* @__PURE__ */ jsx34("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
8192
+ /* @__PURE__ */ jsx35("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
8039
8193
  ] });
8040
8194
  }
8041
8195
 
8042
8196
  // src/react/components/chat/ChatView.tsx
8043
- import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
8197
+ import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
8044
8198
  function ChatView({
8045
8199
  sessionId,
8046
8200
  renderAttachments,
@@ -8079,13 +8233,13 @@ function ChatView({
8079
8233
  );
8080
8234
  const customization = { classNames, components, renderers };
8081
8235
  const SkillStatus = components?.SkillStatusBar;
8082
- return /* @__PURE__ */ jsxs30("div", { className: `flex min-h-0 flex-1 flex-col overflow-hidden ${classNames?.root ?? ""}`, children: [
8083
- isViewer && /* @__PURE__ */ jsxs30("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: [
8084
- /* @__PURE__ */ jsx35(Eye, { size: 14 }),
8236
+ return /* @__PURE__ */ jsxs31("div", { className: `flex min-h-0 flex-1 flex-col overflow-hidden ${classNames?.root ?? ""}`, children: [
8237
+ isViewer && /* @__PURE__ */ jsxs31("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: [
8238
+ /* @__PURE__ */ jsx36(Eye, { size: 14 }),
8085
8239
  "\u4F60\u6B63\u5728\u67E5\u770B\u5206\u4EAB\u7684\u4F1A\u8BDD\uFF08\u53EA\u8BFB\uFF09"
8086
8240
  ] }),
8087
- !isViewer && /* @__PURE__ */ jsx35(ConnectionBanner, {}),
8088
- /* @__PURE__ */ jsx35(
8241
+ !isViewer && /* @__PURE__ */ jsx36(ConnectionBanner, {}),
8242
+ /* @__PURE__ */ jsx36(
8089
8243
  MessageList,
8090
8244
  {
8091
8245
  sessionId,
@@ -8097,7 +8251,7 @@ function ChatView({
8097
8251
  },
8098
8252
  sessionId
8099
8253
  ),
8100
- !isViewer && /* @__PURE__ */ jsx35(
8254
+ !isViewer && /* @__PURE__ */ jsx36(
8101
8255
  ChatInput,
8102
8256
  {
8103
8257
  onSend: (msg, _targetSessionId, model) => send(msg, mode, void 0, { model: model || void 0 }),
@@ -8172,4 +8326,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
8172
8326
  * Licensed under the MIT License. See License.txt in the project root for license information.
8173
8327
  *--------------------------------------------------------------------------------------------*)
8174
8328
  */
8175
- //# sourceMappingURL=chunk-LKOBHTL7.js.map
8329
+ //# sourceMappingURL=chunk-75BPCDBW.js.map