@blade-hq/agent-kit 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AskUserQuestionBlock-CjvG_pUY.d.ts → AskUserQuestionBlock---kOTouk.d.ts} +2 -2
- package/dist/{SkillStatusBar-B7-EU8A4.d.ts → SkillStatusBar-DpbkD4Jx.d.ts} +3 -3
- package/dist/{blade-client-BKiP6U73.d.ts → blade-client-CFvmjs5R.d.ts} +6 -2
- package/dist/{chunk-CFZDKYT3.js → chunk-4ZEOWH6U.js} +2 -2
- package/dist/{chunk-ROGNJYST.js → chunk-7JX26TWV.js} +4 -2
- package/dist/chunk-7JX26TWV.js.map +1 -0
- package/dist/{chunk-ZGM3H24C.js → chunk-EV225FLR.js} +1218 -1031
- package/dist/chunk-EV225FLR.js.map +1 -0
- package/dist/{chunk-2FTEBWEM.js → chunk-LVLGDM76.js} +45 -13
- package/dist/chunk-LVLGDM76.js.map +1 -0
- package/dist/{chunk-C7VSMOXN.js → chunk-PTMCGZFG.js} +14 -11
- package/dist/chunk-PTMCGZFG.js.map +1 -0
- package/dist/{chunk-M2ZCTKY7.js → chunk-YW2THJUX.js} +2 -2
- package/dist/client/index.d.ts +11 -7
- package/dist/client/index.js +1 -1
- package/dist/{projection-DIfyh6RK.d.ts → projection-BWYEFYNn.d.ts} +1 -1
- package/dist/react/api/vibe-coding.d.ts +3 -3
- package/dist/react/api/vibe-coding.js +2 -2
- package/dist/react/components/chat/index.d.ts +6 -6
- package/dist/react/components/chat/index.js +5 -5
- package/dist/react/components/plan/index.d.ts +3 -3
- package/dist/react/components/plan/index.js +3 -3
- package/dist/react/components/session/index.js +3 -3
- package/dist/react/components/workspace/index.js +3 -3
- package/dist/react/index.d.ts +10 -8
- package/dist/react/index.js +6 -6
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-2FTEBWEM.js.map +0 -1
- package/dist/chunk-C7VSMOXN.js.map +0 -1
- package/dist/chunk-ROGNJYST.js.map +0 -1
- package/dist/chunk-ZGM3H24C.js.map +0 -1
- /package/dist/{chunk-CFZDKYT3.js.map → chunk-4ZEOWH6U.js.map} +0 -0
- /package/dist/{chunk-M2ZCTKY7.js.map → chunk-YW2THJUX.js.map} +0 -0
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
getCodeLanguageFromFilename,
|
|
9
9
|
parseAskUserQuestion,
|
|
10
10
|
useHighlightedCodeHtml
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-LVLGDM76.js";
|
|
12
12
|
import {
|
|
13
13
|
Collapsible,
|
|
14
14
|
CollapsibleContent,
|
|
15
15
|
CollapsibleTrigger,
|
|
16
16
|
resolveSessionFilePreviewTarget
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-4ZEOWH6U.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-
|
|
60
|
+
} from "./chunk-PTMCGZFG.js";
|
|
60
61
|
import {
|
|
61
62
|
registerBridgeIframe,
|
|
62
63
|
tapBridgeEvent
|
|
@@ -65,7 +66,7 @@ import {
|
|
|
65
66
|
ModelOption,
|
|
66
67
|
ModelsConfig,
|
|
67
68
|
ModelsResource
|
|
68
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-7JX26TWV.js";
|
|
69
70
|
import {
|
|
70
71
|
cn,
|
|
71
72
|
copyToClipboard
|
|
@@ -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
|
|
184
|
+
useState as useState7
|
|
184
185
|
} from "react";
|
|
185
186
|
import { createRoot } from "react-dom/client";
|
|
186
187
|
import { toast } from "sonner";
|
|
@@ -703,6 +704,21 @@ function usePreferredModel() {
|
|
|
703
704
|
|
|
704
705
|
// src/react/components/model/ModelSelector.tsx
|
|
705
706
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
707
|
+
var inputModalityLabels = {
|
|
708
|
+
text: "\u6587\u672C",
|
|
709
|
+
image: "\u56FE\u7247",
|
|
710
|
+
file: "\u6587\u4EF6",
|
|
711
|
+
audio: "\u97F3\u9891",
|
|
712
|
+
video: "\u89C6\u9891"
|
|
713
|
+
};
|
|
714
|
+
function getInputModalities(model) {
|
|
715
|
+
const values = model.inputModalities && model.inputModalities.length > 0 ? model.inputModalities : model.supportsImage ? ["text", "image"] : ["text"];
|
|
716
|
+
const normalized = values.map((value) => value.trim().toLowerCase()).filter((value) => value.length > 0);
|
|
717
|
+
return normalized.length > 0 ? Array.from(new Set(normalized)) : ["text"];
|
|
718
|
+
}
|
|
719
|
+
function formatInputModalities(model) {
|
|
720
|
+
return getInputModalities(model).map((value) => inputModalityLabels[value] ?? value).join("\u3001");
|
|
721
|
+
}
|
|
706
722
|
function ModelSelector({
|
|
707
723
|
value,
|
|
708
724
|
onValueChange,
|
|
@@ -728,13 +744,21 @@ function ModelSelector({
|
|
|
728
744
|
const normalized = query.trim().toLowerCase();
|
|
729
745
|
if (!normalized) return models;
|
|
730
746
|
return models.filter(
|
|
731
|
-
(model) =>
|
|
747
|
+
(model) => {
|
|
748
|
+
const inputLabel = formatInputModalities(model).toLowerCase();
|
|
749
|
+
return model.id.toLowerCase().includes(normalized) || model.label.toLowerCase().includes(normalized) || inputLabel.includes(normalized);
|
|
750
|
+
}
|
|
732
751
|
);
|
|
733
752
|
}, [models, query]);
|
|
734
753
|
const canSelect = models.length > 0;
|
|
735
|
-
const
|
|
736
|
-
const
|
|
754
|
+
const selectedModel = models.find((model) => model.id === value);
|
|
755
|
+
const defaultModelOption = models.find((model) => model.id === defaultModel);
|
|
756
|
+
const selectedLabel = selectedModel?.label;
|
|
757
|
+
const defaultLabel = defaultModelOption?.label;
|
|
737
758
|
const label = isLoading ? "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B..." : models.length === 0 ? "\u65E0\u53EF\u7528\u6A21\u578B" : selectedLabel || defaultLabel || value.trim() || "\u672A\u8FDE\u63A5\u5230\u6A21\u578B";
|
|
759
|
+
const activeModel = selectedModel ?? defaultModelOption;
|
|
760
|
+
const activeInputLabel = activeModel ? formatInputModalities(activeModel) : "";
|
|
761
|
+
const selectorTitle = activeInputLabel ? `${label}\uFF0C\u652F\u6301\u8F93\u5165\uFF1A${activeInputLabel}` : label;
|
|
738
762
|
const dropdownPosition = placement === "top" ? "bottom-[calc(100%+8px)]" : "top-[calc(100%+8px)]";
|
|
739
763
|
if (!canSelect) {
|
|
740
764
|
return /* @__PURE__ */ jsxs(
|
|
@@ -757,17 +781,24 @@ function ModelSelector({
|
|
|
757
781
|
disabled,
|
|
758
782
|
onClick: () => setIsOpen((current) => !current),
|
|
759
783
|
className: "flex min-w-0 items-center gap-1 rounded-lg px-2.5 py-[5px] text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50",
|
|
760
|
-
title:
|
|
784
|
+
title: selectorTitle,
|
|
761
785
|
children: [
|
|
762
786
|
/* @__PURE__ */ jsx2(Sparkles, { size: 14, "aria-hidden": "true" }),
|
|
763
|
-
/* @__PURE__ */ jsx2(
|
|
787
|
+
/* @__PURE__ */ jsx2(
|
|
788
|
+
"span",
|
|
789
|
+
{
|
|
790
|
+
className: `min-w-0 truncate whitespace-nowrap text-xs ${compact ? "max-w-[120px]" : "max-w-[180px]"}`,
|
|
791
|
+
children: label
|
|
792
|
+
}
|
|
793
|
+
),
|
|
794
|
+
activeInputLabel ? /* @__PURE__ */ jsx2("span", { className: "shrink-0 rounded border border-[hsl(var(--border))] px-1 py-0 text-[10px] leading-4 text-[hsl(var(--muted-foreground))]", children: activeInputLabel }) : null
|
|
764
795
|
]
|
|
765
796
|
}
|
|
766
797
|
),
|
|
767
798
|
isOpen && /* @__PURE__ */ jsxs(
|
|
768
799
|
"div",
|
|
769
800
|
{
|
|
770
|
-
className: `absolute left-0 z-50 w-[
|
|
801
|
+
className: `absolute left-0 z-50 w-[320px] overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] shadow-xl ${dropdownPosition}`,
|
|
771
802
|
children: [
|
|
772
803
|
/* @__PURE__ */ jsx2("div", { className: "border-b border-[hsl(var(--border))] p-2", children: /* @__PURE__ */ jsx2(
|
|
773
804
|
"input",
|
|
@@ -778,21 +809,28 @@ function ModelSelector({
|
|
|
778
809
|
className: "h-8 w-full rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--background))] px-2.5 text-xs text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground))] focus:border-[hsl(var(--ring))]"
|
|
779
810
|
}
|
|
780
811
|
) }),
|
|
781
|
-
/* @__PURE__ */ jsx2("div", { className: "max-h-[220px] overflow-y-auto p-1", children: filteredModels.length === 0 ? /* @__PURE__ */ jsx2("div", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6CA1\u6709\u5339\u914D\u7684\u6A21\u578B" }) : filteredModels.map((model) =>
|
|
782
|
-
|
|
783
|
-
{
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
812
|
+
/* @__PURE__ */ jsx2("div", { className: "max-h-[220px] overflow-y-auto p-1", children: filteredModels.length === 0 ? /* @__PURE__ */ jsx2("div", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6CA1\u6709\u5339\u914D\u7684\u6A21\u578B" }) : filteredModels.map((model) => {
|
|
813
|
+
const inputLabel = formatInputModalities(model);
|
|
814
|
+
const title = model.id === model.label ? `${model.id}\uFF0C\u652F\u6301\u8F93\u5165\uFF1A${inputLabel}` : `${model.label} (${model.id})\uFF0C\u652F\u6301\u8F93\u5165\uFF1A${inputLabel}`;
|
|
815
|
+
return /* @__PURE__ */ jsxs(
|
|
816
|
+
"button",
|
|
817
|
+
{
|
|
818
|
+
type: "button",
|
|
819
|
+
onClick: () => {
|
|
820
|
+
onValueChange(model.id);
|
|
821
|
+
setIsOpen(false);
|
|
822
|
+
setQuery("");
|
|
823
|
+
},
|
|
824
|
+
className: `flex w-full items-center justify-between gap-3 rounded-lg px-3 py-2 text-left text-xs transition-colors ${model.id === value ? "bg-[hsl(var(--accent))] text-[hsl(var(--foreground))]" : "text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]"}`,
|
|
825
|
+
title,
|
|
826
|
+
children: [
|
|
827
|
+
/* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: model.label }),
|
|
828
|
+
/* @__PURE__ */ jsx2("span", { className: "shrink-0 text-[11px] text-[hsl(var(--muted-foreground))]", children: inputLabel })
|
|
829
|
+
]
|
|
789
830
|
},
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
},
|
|
794
|
-
model.id
|
|
795
|
-
)) })
|
|
831
|
+
model.id
|
|
832
|
+
);
|
|
833
|
+
}) })
|
|
796
834
|
]
|
|
797
835
|
}
|
|
798
836
|
)
|
|
@@ -1258,11 +1296,177 @@ var SkillCompletionMenu = forwardRef2(
|
|
|
1258
1296
|
}
|
|
1259
1297
|
);
|
|
1260
1298
|
|
|
1299
|
+
// src/react/components/chat/BackgroundTasksPill.tsx
|
|
1300
|
+
import { FileText, Square, Terminal } from "lucide-react";
|
|
1301
|
+
import { useState as useState6 } from "react";
|
|
1302
|
+
|
|
1303
|
+
// src/react/hooks/use-background-tasks.ts
|
|
1304
|
+
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
1305
|
+
var EMPTY_TASKS = [];
|
|
1306
|
+
function useBackgroundTasks(sessionId) {
|
|
1307
|
+
const setTasks = useBackgroundStore((state) => state.setTasks);
|
|
1308
|
+
const tasks = useBackgroundStore((state) => sessionId ? state.tasks[sessionId] : void 0);
|
|
1309
|
+
const query = useQuery2({
|
|
1310
|
+
queryKey: ["background-tasks", sessionId],
|
|
1311
|
+
queryFn: ({ signal }) => listBackgroundTasks(sessionId, { signal }).then((items) => {
|
|
1312
|
+
setTasks(sessionId, items);
|
|
1313
|
+
return items;
|
|
1314
|
+
}),
|
|
1315
|
+
enabled: Boolean(sessionId)
|
|
1316
|
+
});
|
|
1317
|
+
return {
|
|
1318
|
+
data: tasks ?? query.data ?? EMPTY_TASKS,
|
|
1319
|
+
loading: query.isLoading,
|
|
1320
|
+
error: query.error,
|
|
1321
|
+
refetch: query.refetch
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
// src/react/components/chat/BackgroundTasksPill.tsx
|
|
1326
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1327
|
+
function formatStartedAt(value) {
|
|
1328
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
1329
|
+
return "\u542F\u52A8\u65F6\u95F4\u672A\u77E5";
|
|
1330
|
+
}
|
|
1331
|
+
return new Intl.DateTimeFormat("zh-CN", {
|
|
1332
|
+
hour: "2-digit",
|
|
1333
|
+
minute: "2-digit"
|
|
1334
|
+
}).format(new Date(value * 1e3));
|
|
1335
|
+
}
|
|
1336
|
+
function statusLabel(status) {
|
|
1337
|
+
if (status === "running") return "\u8FD0\u884C\u4E2D";
|
|
1338
|
+
if (status === "failed") return "\u5931\u8D25";
|
|
1339
|
+
if (status === "cancelled") return "\u5DF2\u505C\u6B62";
|
|
1340
|
+
if (status === "done" || status === "succeeded") return "\u5DF2\u7ED3\u675F";
|
|
1341
|
+
return status || "\u672A\u77E5";
|
|
1342
|
+
}
|
|
1343
|
+
function statusClass(status) {
|
|
1344
|
+
if (status === "running") return "border-amber-500/35 bg-amber-500/10 text-amber-500";
|
|
1345
|
+
if (status === "failed") return "border-rose-500/35 bg-rose-500/10 text-rose-500";
|
|
1346
|
+
return "border-[hsl(var(--border))] bg-[hsl(var(--muted))]/40 text-[hsl(var(--muted-foreground))]";
|
|
1347
|
+
}
|
|
1348
|
+
function BackgroundTasksPill({ sessionId }) {
|
|
1349
|
+
const { data: tasks } = useBackgroundTasks(sessionId);
|
|
1350
|
+
const [open, setOpen] = useState6(false);
|
|
1351
|
+
const [logTask, setLogTask] = useState6(null);
|
|
1352
|
+
if (tasks.length === 0) return null;
|
|
1353
|
+
const runningCount = tasks.filter((task) => task.status === "running").length;
|
|
1354
|
+
const openTaskLog = async (task) => {
|
|
1355
|
+
const title = `${task.id} ${task.description || task.command || "\u540E\u53F0\u4EFB\u52A1"}`;
|
|
1356
|
+
setLogTask({ id: task.id, title, output: "", loading: true, error: null });
|
|
1357
|
+
try {
|
|
1358
|
+
const detail = await getBackgroundTask(sessionId, task.id, 300);
|
|
1359
|
+
setLogTask({
|
|
1360
|
+
id: task.id,
|
|
1361
|
+
title,
|
|
1362
|
+
output: detail.output || "\u6682\u65E0\u8F93\u51FA",
|
|
1363
|
+
loading: false,
|
|
1364
|
+
error: null
|
|
1365
|
+
});
|
|
1366
|
+
} catch (error) {
|
|
1367
|
+
setLogTask({
|
|
1368
|
+
id: task.id,
|
|
1369
|
+
title,
|
|
1370
|
+
output: "",
|
|
1371
|
+
loading: false,
|
|
1372
|
+
error: error instanceof Error ? error.message : "\u65E5\u5FD7\u52A0\u8F7D\u5931\u8D25"
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
const requestStopTask = (task) => {
|
|
1377
|
+
const name = `${task.id}\uFF08${task.description || task.command || "\u540E\u53F0\u4EFB\u52A1"}\uFF09`;
|
|
1378
|
+
getSocket().send(
|
|
1379
|
+
sessionId,
|
|
1380
|
+
`\u8BF7\u5148\u5411\u6211\u4E8C\u6B21\u786E\u8BA4\uFF0C\u7136\u540E\u5E2E\u6211\u505C\u6B62\u540E\u53F0\u4EFB\u52A1 ${name}\u3002`,
|
|
1381
|
+
"executing"
|
|
1382
|
+
);
|
|
1383
|
+
setOpen(false);
|
|
1384
|
+
};
|
|
1385
|
+
return /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1386
|
+
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: [
|
|
1387
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-3", children: [
|
|
1388
|
+
/* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
|
|
1389
|
+
/* @__PURE__ */ jsx5("div", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: logTask.title }),
|
|
1390
|
+
/* @__PURE__ */ jsx5("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u540E\u53F0\u4EFB\u52A1\u65E5\u5FD7" })
|
|
1391
|
+
] }),
|
|
1392
|
+
/* @__PURE__ */ jsx5(
|
|
1393
|
+
"button",
|
|
1394
|
+
{
|
|
1395
|
+
type: "button",
|
|
1396
|
+
onClick: () => setLogTask(null),
|
|
1397
|
+
className: "rounded-md border border-[hsl(var(--border))] px-2.5 py-1 text-xs text-[hsl(var(--foreground))] hover:bg-[hsl(var(--accent))]",
|
|
1398
|
+
children: "\u5173\u95ED"
|
|
1399
|
+
}
|
|
1400
|
+
)
|
|
1401
|
+
] }),
|
|
1402
|
+
/* @__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 })
|
|
1403
|
+
] }) }) : null,
|
|
1404
|
+
/* @__PURE__ */ jsxs4("div", { className: "relative mb-2 flex justify-start", children: [
|
|
1405
|
+
/* @__PURE__ */ jsxs4(
|
|
1406
|
+
"button",
|
|
1407
|
+
{
|
|
1408
|
+
type: "button",
|
|
1409
|
+
onClick: () => setOpen((value) => !value),
|
|
1410
|
+
className: cn(
|
|
1411
|
+
"inline-flex h-8 items-center gap-2 rounded-full border px-3 text-xs font-medium shadow-sm transition-colors",
|
|
1412
|
+
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))]"
|
|
1413
|
+
),
|
|
1414
|
+
children: [
|
|
1415
|
+
/* @__PURE__ */ jsx5(Terminal, { size: 13 }),
|
|
1416
|
+
"\u540E\u53F0\u4EFB\u52A1 ",
|
|
1417
|
+
tasks.length,
|
|
1418
|
+
runningCount > 0 ? /* @__PURE__ */ jsxs4("span", { children: [
|
|
1419
|
+
"\u8FD0\u884C\u4E2D ",
|
|
1420
|
+
runningCount
|
|
1421
|
+
] }) : null
|
|
1422
|
+
]
|
|
1423
|
+
}
|
|
1424
|
+
),
|
|
1425
|
+
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: [
|
|
1426
|
+
/* @__PURE__ */ jsx5("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
|
|
1427
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
|
|
1428
|
+
/* @__PURE__ */ jsx5("span", { className: "font-mono font-semibold", children: task.id }),
|
|
1429
|
+
/* @__PURE__ */ jsx5("span", { className: cn("rounded-full border px-1.5 py-0.5 text-[10px]", statusClass(task.status)), children: statusLabel(task.status) })
|
|
1430
|
+
] }),
|
|
1431
|
+
/* @__PURE__ */ jsx5("div", { className: "mt-1 break-words text-[hsl(var(--foreground))]", children: task.description || task.command }),
|
|
1432
|
+
/* @__PURE__ */ jsx5("div", { className: "mt-1 text-[11px] text-[hsl(var(--muted-foreground))]", children: formatStartedAt(task.started_at) })
|
|
1433
|
+
] }) }),
|
|
1434
|
+
/* @__PURE__ */ jsxs4("div", { className: "mt-2 flex items-center gap-1.5", children: [
|
|
1435
|
+
/* @__PURE__ */ jsxs4(
|
|
1436
|
+
"button",
|
|
1437
|
+
{
|
|
1438
|
+
type: "button",
|
|
1439
|
+
onClick: () => void openTaskLog(task),
|
|
1440
|
+
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))]",
|
|
1441
|
+
children: [
|
|
1442
|
+
/* @__PURE__ */ jsx5(FileText, { size: 11 }),
|
|
1443
|
+
"\u65E5\u5FD7"
|
|
1444
|
+
]
|
|
1445
|
+
}
|
|
1446
|
+
),
|
|
1447
|
+
task.status === "running" ? /* @__PURE__ */ jsxs4(
|
|
1448
|
+
"button",
|
|
1449
|
+
{
|
|
1450
|
+
type: "button",
|
|
1451
|
+
onClick: () => requestStopTask(task),
|
|
1452
|
+
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",
|
|
1453
|
+
children: [
|
|
1454
|
+
/* @__PURE__ */ jsx5(Square, { size: 10 }),
|
|
1455
|
+
"\u505C\u6B62"
|
|
1456
|
+
]
|
|
1457
|
+
}
|
|
1458
|
+
) : null
|
|
1459
|
+
] })
|
|
1460
|
+
] }, task.id)) }) }) : null
|
|
1461
|
+
] })
|
|
1462
|
+
] });
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1261
1465
|
// src/react/components/chat/FileSizeLimitDialog.tsx
|
|
1262
1466
|
import { X } from "lucide-react";
|
|
1263
1467
|
import { useEffect as useEffect6 } from "react";
|
|
1264
1468
|
import { createPortal } from "react-dom";
|
|
1265
|
-
import { jsx as
|
|
1469
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1266
1470
|
function FileSizeLimitDialog({
|
|
1267
1471
|
open,
|
|
1268
1472
|
onOpenChange,
|
|
@@ -1284,7 +1488,7 @@ function FileSizeLimitDialog({
|
|
|
1284
1488
|
}
|
|
1285
1489
|
const limitText = formatFileSize(limitBytes);
|
|
1286
1490
|
return createPortal(
|
|
1287
|
-
/* @__PURE__ */
|
|
1491
|
+
/* @__PURE__ */ jsx6(
|
|
1288
1492
|
"div",
|
|
1289
1493
|
{
|
|
1290
1494
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",
|
|
@@ -1297,45 +1501,45 @@ function FileSizeLimitDialog({
|
|
|
1297
1501
|
role: "dialog",
|
|
1298
1502
|
"aria-modal": "true",
|
|
1299
1503
|
"aria-labelledby": "file-size-limit-dialog-title",
|
|
1300
|
-
children: /* @__PURE__ */
|
|
1504
|
+
children: /* @__PURE__ */ jsxs5(
|
|
1301
1505
|
"div",
|
|
1302
1506
|
{
|
|
1303
1507
|
className: "w-full max-w-lg overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--background))] shadow-2xl",
|
|
1304
1508
|
onClick: (event) => event.stopPropagation(),
|
|
1305
1509
|
onKeyDown: (event) => event.stopPropagation(),
|
|
1306
1510
|
children: [
|
|
1307
|
-
/* @__PURE__ */
|
|
1308
|
-
/* @__PURE__ */
|
|
1309
|
-
/* @__PURE__ */
|
|
1310
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
|
|
1512
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
1513
|
+
/* @__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" }),
|
|
1514
|
+
/* @__PURE__ */ jsxs5("p", { className: "mt-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
1311
1515
|
"\u5355\u4E2A\u9644\u4EF6\u6700\u5927\u652F\u6301 ",
|
|
1312
1516
|
limitText,
|
|
1313
1517
|
"\u3002\u4EE5\u4E0B\u6587\u4EF6\u672A\u52A0\u5165\u9644\u4EF6\u5217\u8868\u3002"
|
|
1314
1518
|
] })
|
|
1315
1519
|
] }),
|
|
1316
|
-
/* @__PURE__ */
|
|
1520
|
+
/* @__PURE__ */ jsx6(
|
|
1317
1521
|
"button",
|
|
1318
1522
|
{
|
|
1319
1523
|
type: "button",
|
|
1320
1524
|
onClick: () => onOpenChange(false),
|
|
1321
1525
|
title: "\u5173\u95ED",
|
|
1322
1526
|
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__ */
|
|
1527
|
+
children: /* @__PURE__ */ jsx6(X, { size: 14 })
|
|
1324
1528
|
}
|
|
1325
1529
|
)
|
|
1326
1530
|
] }),
|
|
1327
|
-
/* @__PURE__ */
|
|
1531
|
+
/* @__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
1532
|
"div",
|
|
1329
1533
|
{
|
|
1330
1534
|
className: "flex items-center justify-between gap-3 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-3 py-2",
|
|
1331
1535
|
children: [
|
|
1332
|
-
/* @__PURE__ */
|
|
1333
|
-
/* @__PURE__ */
|
|
1536
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 truncate text-sm text-[hsl(var(--foreground))]", children: file.name }),
|
|
1537
|
+
/* @__PURE__ */ jsx6("span", { className: "shrink-0 text-xs text-[hsl(var(--muted-foreground))]", children: formatFileSize(file.size) })
|
|
1334
1538
|
]
|
|
1335
1539
|
},
|
|
1336
1540
|
`${file.name}:${file.size}`
|
|
1337
1541
|
)) }) }),
|
|
1338
|
-
/* @__PURE__ */
|
|
1542
|
+
/* @__PURE__ */ jsx6("div", { className: "flex justify-end border-t border-[hsl(var(--border))] px-4 py-3", children: /* @__PURE__ */ jsx6(
|
|
1339
1543
|
"button",
|
|
1340
1544
|
{
|
|
1341
1545
|
type: "button",
|
|
@@ -1358,28 +1562,6 @@ import { useQuery as useQuery5 } from "@tanstack/react-query";
|
|
|
1358
1562
|
import { RefreshCw } from "lucide-react";
|
|
1359
1563
|
import { useMemo as useMemo6 } from "react";
|
|
1360
1564
|
|
|
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
1565
|
// src/react/hooks/use-context-stats.ts
|
|
1384
1566
|
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
1385
1567
|
var EMPTY_CONTEXT_STATS = {
|
|
@@ -1455,7 +1637,7 @@ function useTokenPressure(sessionId) {
|
|
|
1455
1637
|
}
|
|
1456
1638
|
|
|
1457
1639
|
// src/react/components/chat/ProgressCircle.tsx
|
|
1458
|
-
import { jsx as
|
|
1640
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1459
1641
|
var LEVEL_STYLES = {
|
|
1460
1642
|
normal: {
|
|
1461
1643
|
strokeClass: "stroke-slate-400",
|
|
@@ -1486,15 +1668,15 @@ function ProgressCircle({
|
|
|
1486
1668
|
const circumference = 2 * Math.PI * radius;
|
|
1487
1669
|
const dashOffset = circumference * (1 - clamped / 100);
|
|
1488
1670
|
const styles = LEVEL_STYLES[level];
|
|
1489
|
-
return /* @__PURE__ */
|
|
1490
|
-
/* @__PURE__ */
|
|
1671
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn("group relative inline-flex", className), children: [
|
|
1672
|
+
/* @__PURE__ */ jsx7(
|
|
1491
1673
|
"button",
|
|
1492
1674
|
{
|
|
1493
1675
|
type: "button",
|
|
1494
1676
|
"aria-label": `\u4E0A\u4E0B\u6587\u5DF2\u4F7F\u7528 ${Math.round(clamped)}%`,
|
|
1495
1677
|
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__ */
|
|
1497
|
-
/* @__PURE__ */
|
|
1678
|
+
children: /* @__PURE__ */ jsxs6("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, "aria-hidden": "true", children: [
|
|
1679
|
+
/* @__PURE__ */ jsx7(
|
|
1498
1680
|
"circle",
|
|
1499
1681
|
{
|
|
1500
1682
|
cx: size / 2,
|
|
@@ -1505,7 +1687,7 @@ function ProgressCircle({
|
|
|
1505
1687
|
className: styles.trackClass
|
|
1506
1688
|
}
|
|
1507
1689
|
),
|
|
1508
|
-
/* @__PURE__ */
|
|
1690
|
+
/* @__PURE__ */ jsx7(
|
|
1509
1691
|
"circle",
|
|
1510
1692
|
{
|
|
1511
1693
|
cx: size / 2,
|
|
@@ -1523,12 +1705,12 @@ function ProgressCircle({
|
|
|
1523
1705
|
] })
|
|
1524
1706
|
}
|
|
1525
1707
|
),
|
|
1526
|
-
detail ? /* @__PURE__ */
|
|
1708
|
+
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
1709
|
] });
|
|
1528
1710
|
}
|
|
1529
1711
|
|
|
1530
1712
|
// src/react/components/chat/SkillStatusBar.tsx
|
|
1531
|
-
import { jsx as
|
|
1713
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1532
1714
|
var COMPACT_NUMBER_FORMATTER = new Intl.NumberFormat("zh-CN", {
|
|
1533
1715
|
notation: "compact",
|
|
1534
1716
|
maximumFractionDigits: 1
|
|
@@ -1572,8 +1754,8 @@ function HoverPanel({
|
|
|
1572
1754
|
title,
|
|
1573
1755
|
children
|
|
1574
1756
|
}) {
|
|
1575
|
-
return /* @__PURE__ */
|
|
1576
|
-
/* @__PURE__ */
|
|
1757
|
+
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: [
|
|
1758
|
+
/* @__PURE__ */ jsx8("div", { className: "mb-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-slate-400", children: title }),
|
|
1577
1759
|
children
|
|
1578
1760
|
] });
|
|
1579
1761
|
}
|
|
@@ -1592,13 +1774,10 @@ function SkillStatusBar({
|
|
|
1592
1774
|
enabled: Boolean(sessionId)
|
|
1593
1775
|
});
|
|
1594
1776
|
const { data: contextStats } = useContextStats(sessionId);
|
|
1595
|
-
const { data: tasks } = useBackgroundTasks(sessionId);
|
|
1596
1777
|
const tokenPressure = useTokenPressure(sessionId);
|
|
1597
1778
|
const connectionStatus = useConnectionStore((state) => state.status);
|
|
1598
1779
|
const reconnectAttempt = useConnectionStore((state) => state.reconnectAttempt);
|
|
1599
1780
|
const hasEverConnected = useConnectionStore((state) => state.hasEverConnected);
|
|
1600
|
-
const runningTaskItems = tasks.filter((task) => task.status === "running");
|
|
1601
|
-
const runningTasks = runningTaskItems.length;
|
|
1602
1781
|
const statsReady = !loading && !error;
|
|
1603
1782
|
const skillStoreConnected = statsReady && skillStats.remote_connected;
|
|
1604
1783
|
const connectionMeta = useMemo6(
|
|
@@ -1610,11 +1789,6 @@ function SkillStatusBar({
|
|
|
1610
1789
|
[connectionStatus, reconnectAttempt, hasEverConnected]
|
|
1611
1790
|
);
|
|
1612
1791
|
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
1792
|
{
|
|
1619
1793
|
key: "loaded",
|
|
1620
1794
|
dotClass: statsReady ? "bg-emerald-500" : "bg-[hsl(var(--muted-foreground))]",
|
|
@@ -1628,18 +1802,18 @@ function SkillStatusBar({
|
|
|
1628
1802
|
].filter((item) => item.key !== "total" || skillStats.remote_configured);
|
|
1629
1803
|
const tokenSummary = useMemo6(() => {
|
|
1630
1804
|
return {
|
|
1631
|
-
detail: /* @__PURE__ */
|
|
1632
|
-
/* @__PURE__ */
|
|
1633
|
-
/* @__PURE__ */
|
|
1634
|
-
/* @__PURE__ */
|
|
1805
|
+
detail: /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
1806
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3 border-t border-slate-800 pt-1", children: [
|
|
1807
|
+
/* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "\u5DF2\u7528" }),
|
|
1808
|
+
/* @__PURE__ */ jsx8("span", { className: "font-mono", children: formatTokenNumber(contextStats.tokens_used) })
|
|
1635
1809
|
] }),
|
|
1636
|
-
contextStats.context_window > 0 ? /* @__PURE__ */
|
|
1637
|
-
/* @__PURE__ */
|
|
1638
|
-
/* @__PURE__ */
|
|
1639
|
-
] }) : /* @__PURE__ */
|
|
1640
|
-
/* @__PURE__ */
|
|
1641
|
-
/* @__PURE__ */
|
|
1642
|
-
/* @__PURE__ */
|
|
1810
|
+
contextStats.context_window > 0 ? /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1811
|
+
/* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "\u4E0A\u4E0B\u6587\u7A97\u53E3" }),
|
|
1812
|
+
/* @__PURE__ */ jsx8("span", { className: "font-mono", children: formatCompactNumber(contextStats.context_window) })
|
|
1813
|
+
] }) : /* @__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" }),
|
|
1814
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1815
|
+
/* @__PURE__ */ jsx8("span", { className: "text-slate-400", children: "\u6574\u7406\u9608\u503C" }),
|
|
1816
|
+
/* @__PURE__ */ jsx8("span", { className: "font-mono", children: contextStats.compaction_ratio > 0 ? `${Math.round(contextStats.compaction_ratio * 100)}%` : "\u5DF2\u7981\u7528" })
|
|
1643
1817
|
] })
|
|
1644
1818
|
] }),
|
|
1645
1819
|
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 +1823,9 @@ function SkillStatusBar({
|
|
|
1649
1823
|
const containerClass = vertical ? "text-[11px] text-[hsl(var(--muted-foreground))]" : "bg-[hsl(var(--background))] px-5 pt-2";
|
|
1650
1824
|
const innerClass = vertical ? "" : "mx-auto max-w-3xl";
|
|
1651
1825
|
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__ */
|
|
1653
|
-
tokenSummary ? /* @__PURE__ */
|
|
1654
|
-
/* @__PURE__ */
|
|
1826
|
+
return /* @__PURE__ */ jsx8("div", { className: cn(containerClass, className), children: /* @__PURE__ */ jsx8("div", { className: cn(innerClass, innerClassName), children: /* @__PURE__ */ jsxs7("div", { className: listClass, children: [
|
|
1827
|
+
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: [
|
|
1828
|
+
/* @__PURE__ */ jsx8(
|
|
1655
1829
|
ProgressCircle,
|
|
1656
1830
|
{
|
|
1657
1831
|
percentage: tokenPressure.ratio * 100,
|
|
@@ -1659,10 +1833,10 @@ function SkillStatusBar({
|
|
|
1659
1833
|
detail: tokenSummary.detail
|
|
1660
1834
|
}
|
|
1661
1835
|
),
|
|
1662
|
-
/* @__PURE__ */
|
|
1663
|
-
tokenSummary.warn ? /* @__PURE__ */
|
|
1836
|
+
/* @__PURE__ */ jsx8("span", { className: "font-mono", children: tokenSummary.label }),
|
|
1837
|
+
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
1838
|
] }) : null,
|
|
1665
|
-
connectionStatus !== "connected" ? /* @__PURE__ */
|
|
1839
|
+
connectionStatus !== "connected" ? /* @__PURE__ */ jsxs7(
|
|
1666
1840
|
"div",
|
|
1667
1841
|
{
|
|
1668
1842
|
className: cn(
|
|
@@ -1670,30 +1844,21 @@ function SkillStatusBar({
|
|
|
1670
1844
|
connectionMeta.toneClass
|
|
1671
1845
|
),
|
|
1672
1846
|
children: [
|
|
1673
|
-
/* @__PURE__ */
|
|
1674
|
-
/* @__PURE__ */
|
|
1847
|
+
/* @__PURE__ */ jsx8("span", { className: cn("inline-block h-1.5 w-1.5 rounded-full", connectionMeta.dotClass) }),
|
|
1848
|
+
/* @__PURE__ */ jsx8("span", { children: connectionMeta.label })
|
|
1675
1849
|
]
|
|
1676
1850
|
}
|
|
1677
1851
|
) : null,
|
|
1678
|
-
items.map((item, index) => /* @__PURE__ */
|
|
1852
|
+
items.map((item, index) => /* @__PURE__ */ jsxs7(
|
|
1679
1853
|
"div",
|
|
1680
1854
|
{
|
|
1681
1855
|
className: "flex items-center gap-2 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2.5 py-1",
|
|
1682
1856
|
children: [
|
|
1683
|
-
index > 0 && !tokenPressure && /* @__PURE__ */
|
|
1684
|
-
/* @__PURE__ */
|
|
1685
|
-
item.key === "
|
|
1686
|
-
/* @__PURE__ */
|
|
1687
|
-
|
|
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(
|
|
1857
|
+
index > 0 && !tokenPressure && /* @__PURE__ */ jsx8("span", { className: "hidden text-[hsl(var(--border))]", children: "\xB7" }),
|
|
1858
|
+
/* @__PURE__ */ jsx8("span", { className: `inline-block h-1.5 w-1.5 rounded-full ${item.dotClass}` }),
|
|
1859
|
+
item.key === "loaded" ? /* @__PURE__ */ jsxs7("div", { className: "group relative flex items-center gap-1.5", children: [
|
|
1860
|
+
/* @__PURE__ */ jsx8("span", { className: "cursor-help font-mono", children: item.text }),
|
|
1861
|
+
onResync ? /* @__PURE__ */ jsx8(
|
|
1697
1862
|
"button",
|
|
1698
1863
|
{
|
|
1699
1864
|
type: "button",
|
|
@@ -1701,21 +1866,21 @@ function SkillStatusBar({
|
|
|
1701
1866
|
disabled: isResyncing,
|
|
1702
1867
|
"aria-label": "\u540C\u6B65\u6280\u80FD",
|
|
1703
1868
|
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__ */
|
|
1869
|
+
children: /* @__PURE__ */ jsx8(RefreshCw, { size: 11, className: isResyncing ? "animate-spin" : "" })
|
|
1705
1870
|
}
|
|
1706
1871
|
) : null,
|
|
1707
|
-
statsReady && sessionSkills.length > 0 ? /* @__PURE__ */
|
|
1872
|
+
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
1873
|
"div",
|
|
1709
1874
|
{
|
|
1710
1875
|
className: "flex items-start gap-2 py-1 leading-relaxed",
|
|
1711
1876
|
children: [
|
|
1712
|
-
/* @__PURE__ */
|
|
1713
|
-
/* @__PURE__ */
|
|
1877
|
+
/* @__PURE__ */ jsx8("span", { className: "mt-1.5 inline-block h-2 w-2 shrink-0 rounded-full border border-emerald-300 bg-transparent" }),
|
|
1878
|
+
/* @__PURE__ */ jsx8("span", { className: "break-words", children: skillDisplayName(skill) })
|
|
1714
1879
|
]
|
|
1715
1880
|
},
|
|
1716
1881
|
skill.skill_id
|
|
1717
1882
|
)) }) }) : null
|
|
1718
|
-
] }) : /* @__PURE__ */
|
|
1883
|
+
] }) : /* @__PURE__ */ jsx8("span", { className: "font-mono", children: item.text })
|
|
1719
1884
|
]
|
|
1720
1885
|
},
|
|
1721
1886
|
item.key
|
|
@@ -1850,7 +2015,7 @@ var SkillMention = Mention2.extend({
|
|
|
1850
2015
|
});
|
|
1851
2016
|
|
|
1852
2017
|
// src/react/components/chat/ChatInput.tsx
|
|
1853
|
-
import { Fragment, jsx as
|
|
2018
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1854
2019
|
function getEditorText(editor) {
|
|
1855
2020
|
return editor?.getText({ blockSeparator: "\n" }) ?? "";
|
|
1856
2021
|
}
|
|
@@ -1890,7 +2055,7 @@ function getFileCardIcon(attachment) {
|
|
|
1890
2055
|
return FileCode2;
|
|
1891
2056
|
}
|
|
1892
2057
|
if (attachment.mimeType.startsWith("text/") || /\.(txt|pdf|doc|docx|rtf|odt)$/.test(lowerName)) {
|
|
1893
|
-
return
|
|
2058
|
+
return FileText2;
|
|
1894
2059
|
}
|
|
1895
2060
|
return File2;
|
|
1896
2061
|
}
|
|
@@ -1966,21 +2131,21 @@ function ComposerFilePill({
|
|
|
1966
2131
|
const isFile = attachment.kind === "file";
|
|
1967
2132
|
const isFailed = isFile && attachment.status === "failed";
|
|
1968
2133
|
const isUploading = isFile && attachment.status === "uploading";
|
|
1969
|
-
return /* @__PURE__ */
|
|
2134
|
+
return /* @__PURE__ */ jsxs8(
|
|
1970
2135
|
"div",
|
|
1971
2136
|
{
|
|
1972
2137
|
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
2138
|
children: [
|
|
1974
|
-
isUploading ? /* @__PURE__ */
|
|
1975
|
-
/* @__PURE__ */
|
|
1976
|
-
/* @__PURE__ */
|
|
2139
|
+
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))]" }),
|
|
2140
|
+
/* @__PURE__ */ jsx9("span", { className: "max-w-32 truncate", children: attachment.name }),
|
|
2141
|
+
/* @__PURE__ */ jsx9(
|
|
1977
2142
|
"button",
|
|
1978
2143
|
{
|
|
1979
2144
|
type: "button",
|
|
1980
2145
|
onClick: () => onRemove(attachment.id),
|
|
1981
2146
|
"aria-label": `\u79FB\u9664 ${attachment.name}`,
|
|
1982
2147
|
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__ */
|
|
2148
|
+
children: /* @__PURE__ */ jsx9(X2, { size: 10 })
|
|
1984
2149
|
}
|
|
1985
2150
|
)
|
|
1986
2151
|
]
|
|
@@ -1993,13 +2158,13 @@ function AddContextDialog({
|
|
|
1993
2158
|
onAdd
|
|
1994
2159
|
}) {
|
|
1995
2160
|
const CONTEXT_INLINE_THRESHOLD = 200;
|
|
1996
|
-
const [label, setLabel] =
|
|
1997
|
-
const [content, setContent] =
|
|
1998
|
-
const [showSessionPicker, setShowSessionPicker] =
|
|
1999
|
-
const [sessions, setSessions] =
|
|
2000
|
-
const [loadingSessions, setLoadingSessions] =
|
|
2001
|
-
const [importingId, setImportingId] =
|
|
2002
|
-
const [isImportProcessing, setIsImportProcessing] =
|
|
2161
|
+
const [label, setLabel] = useState7("");
|
|
2162
|
+
const [content, setContent] = useState7("");
|
|
2163
|
+
const [showSessionPicker, setShowSessionPicker] = useState7(false);
|
|
2164
|
+
const [sessions, setSessions] = useState7([]);
|
|
2165
|
+
const [loadingSessions, setLoadingSessions] = useState7(false);
|
|
2166
|
+
const [importingId, setImportingId] = useState7(null);
|
|
2167
|
+
const [isImportProcessing, setIsImportProcessing] = useState7(false);
|
|
2003
2168
|
const sanitizeContextFolderName = (raw) => {
|
|
2004
2169
|
const normalized = raw.trim().toLowerCase();
|
|
2005
2170
|
const safe = normalized.replace(/[^\w\-.\u4e00-\u9fa5]+/g, "_").replace(/^_+|_+$/g, "");
|
|
@@ -2099,7 +2264,7 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
|
|
|
2099
2264
|
setImportingId(null);
|
|
2100
2265
|
}
|
|
2101
2266
|
};
|
|
2102
|
-
return /* @__PURE__ */
|
|
2267
|
+
return /* @__PURE__ */ jsx9(
|
|
2103
2268
|
"div",
|
|
2104
2269
|
{
|
|
2105
2270
|
className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-4",
|
|
@@ -2107,44 +2272,44 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
|
|
|
2107
2272
|
onKeyDown: (e) => {
|
|
2108
2273
|
if (e.key === "Escape") onClose();
|
|
2109
2274
|
},
|
|
2110
|
-
children: /* @__PURE__ */
|
|
2275
|
+
children: /* @__PURE__ */ jsxs8(
|
|
2111
2276
|
"div",
|
|
2112
2277
|
{
|
|
2113
2278
|
className: "w-full max-w-lg flex flex-col rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-2xl",
|
|
2114
2279
|
onClick: (e) => e.stopPropagation(),
|
|
2115
2280
|
onKeyDown: (e) => e.stopPropagation(),
|
|
2116
2281
|
children: [
|
|
2117
|
-
/* @__PURE__ */
|
|
2118
|
-
/* @__PURE__ */
|
|
2119
|
-
/* @__PURE__ */
|
|
2282
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-5 py-3", children: [
|
|
2283
|
+
/* @__PURE__ */ jsx9("h4", { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u6DFB\u52A0\u4E0A\u4E0B\u6587" }),
|
|
2284
|
+
/* @__PURE__ */ jsx9(
|
|
2120
2285
|
"button",
|
|
2121
2286
|
{
|
|
2122
2287
|
type: "button",
|
|
2123
2288
|
onClick: onClose,
|
|
2124
2289
|
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__ */
|
|
2290
|
+
children: /* @__PURE__ */ jsx9(X2, { size: 14 })
|
|
2126
2291
|
}
|
|
2127
2292
|
)
|
|
2128
2293
|
] }),
|
|
2129
|
-
/* @__PURE__ */
|
|
2130
|
-
/* @__PURE__ */
|
|
2131
|
-
/* @__PURE__ */
|
|
2294
|
+
/* @__PURE__ */ jsxs8("div", { className: "px-5 py-4 space-y-3", children: [
|
|
2295
|
+
/* @__PURE__ */ jsxs8("div", { className: "relative", children: [
|
|
2296
|
+
/* @__PURE__ */ jsxs8(
|
|
2132
2297
|
"button",
|
|
2133
2298
|
{
|
|
2134
2299
|
type: "button",
|
|
2135
2300
|
onClick: handleLoadSessions,
|
|
2136
2301
|
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
2302
|
children: [
|
|
2138
|
-
/* @__PURE__ */
|
|
2303
|
+
/* @__PURE__ */ jsx9(Import, { size: 12 }),
|
|
2139
2304
|
"\u4ECE\u5176\u4ED6\u4F1A\u8BDD\u5BFC\u5165",
|
|
2140
|
-
/* @__PURE__ */
|
|
2305
|
+
/* @__PURE__ */ jsx9(ChevronDown, { size: 10, className: `transition-transform ${showSessionPicker ? "rotate-180" : ""}` })
|
|
2141
2306
|
]
|
|
2142
2307
|
}
|
|
2143
2308
|
),
|
|
2144
|
-
showSessionPicker && /* @__PURE__ */
|
|
2145
|
-
/* @__PURE__ */
|
|
2309
|
+
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: [
|
|
2310
|
+
/* @__PURE__ */ jsx9(Loader22, { size: 12, className: "animate-spin" }),
|
|
2146
2311
|
"\u52A0\u8F7D\u4F1A\u8BDD\u5217\u8868\u2026"
|
|
2147
|
-
] }) : sessions.length === 0 ? /* @__PURE__ */
|
|
2312
|
+
] }) : 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
2313
|
"button",
|
|
2149
2314
|
{
|
|
2150
2315
|
type: "button",
|
|
@@ -2152,16 +2317,16 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
|
|
|
2152
2317
|
onClick: () => handleImportSession(s.id),
|
|
2153
2318
|
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
2319
|
children: [
|
|
2155
|
-
importingId === s.id && /* @__PURE__ */
|
|
2156
|
-
/* @__PURE__ */
|
|
2320
|
+
importingId === s.id && /* @__PURE__ */ jsx9(Loader22, { size: 10, className: "shrink-0 animate-spin" }),
|
|
2321
|
+
/* @__PURE__ */ jsx9("span", { className: "truncate", children: s.intent })
|
|
2157
2322
|
]
|
|
2158
2323
|
},
|
|
2159
2324
|
s.id
|
|
2160
2325
|
)) })
|
|
2161
2326
|
] }),
|
|
2162
|
-
/* @__PURE__ */
|
|
2163
|
-
/* @__PURE__ */
|
|
2164
|
-
/* @__PURE__ */
|
|
2327
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
2328
|
+
/* @__PURE__ */ jsx9("label", { htmlFor: "ctx-label", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u6807\u7B7E" }),
|
|
2329
|
+
/* @__PURE__ */ jsx9(
|
|
2165
2330
|
"input",
|
|
2166
2331
|
{
|
|
2167
2332
|
id: "ctx-label",
|
|
@@ -2172,13 +2337,13 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
|
|
|
2172
2337
|
}
|
|
2173
2338
|
)
|
|
2174
2339
|
] }),
|
|
2175
|
-
/* @__PURE__ */
|
|
2176
|
-
/* @__PURE__ */
|
|
2177
|
-
isImportProcessing && /* @__PURE__ */
|
|
2178
|
-
/* @__PURE__ */
|
|
2340
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
2341
|
+
/* @__PURE__ */ jsx9("label", { htmlFor: "ctx-content", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u5185\u5BB9" }),
|
|
2342
|
+
isImportProcessing && /* @__PURE__ */ jsxs8("div", { className: "mb-1.5 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
2343
|
+
/* @__PURE__ */ jsx9(Loader22, { size: 11, className: "animate-spin" }),
|
|
2179
2344
|
"\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
2345
|
] }),
|
|
2181
|
-
/* @__PURE__ */
|
|
2346
|
+
/* @__PURE__ */ jsx9(
|
|
2182
2347
|
"textarea",
|
|
2183
2348
|
{
|
|
2184
2349
|
id: "ctx-content",
|
|
@@ -2191,8 +2356,8 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
|
|
|
2191
2356
|
)
|
|
2192
2357
|
] })
|
|
2193
2358
|
] }),
|
|
2194
|
-
/* @__PURE__ */
|
|
2195
|
-
/* @__PURE__ */
|
|
2359
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex justify-end gap-2 border-t border-[hsl(var(--border))] px-5 py-3", children: [
|
|
2360
|
+
/* @__PURE__ */ jsx9(
|
|
2196
2361
|
"button",
|
|
2197
2362
|
{
|
|
2198
2363
|
type: "button",
|
|
@@ -2201,7 +2366,7 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
|
|
|
2201
2366
|
children: "\u53D6\u6D88"
|
|
2202
2367
|
}
|
|
2203
2368
|
),
|
|
2204
|
-
/* @__PURE__ */
|
|
2369
|
+
/* @__PURE__ */ jsx9(
|
|
2205
2370
|
"button",
|
|
2206
2371
|
{
|
|
2207
2372
|
type: "button",
|
|
@@ -2229,11 +2394,11 @@ function ComposerContextPill({
|
|
|
2229
2394
|
content,
|
|
2230
2395
|
onRemove
|
|
2231
2396
|
}) {
|
|
2232
|
-
const [showDetail, setShowDetail] =
|
|
2397
|
+
const [showDetail, setShowDetail] = useState7(false);
|
|
2233
2398
|
const tokenK = formatTokenK(content);
|
|
2234
|
-
return /* @__PURE__ */
|
|
2235
|
-
/* @__PURE__ */
|
|
2236
|
-
/* @__PURE__ */
|
|
2399
|
+
return /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
2400
|
+
/* @__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: [
|
|
2401
|
+
/* @__PURE__ */ jsx9(
|
|
2237
2402
|
"button",
|
|
2238
2403
|
{
|
|
2239
2404
|
type: "button",
|
|
@@ -2243,7 +2408,7 @@ function ComposerContextPill({
|
|
|
2243
2408
|
children: label
|
|
2244
2409
|
}
|
|
2245
2410
|
),
|
|
2246
|
-
/* @__PURE__ */
|
|
2411
|
+
/* @__PURE__ */ jsx9(
|
|
2247
2412
|
"span",
|
|
2248
2413
|
{
|
|
2249
2414
|
className: "shrink-0 rounded bg-[hsl(var(--background))] px-1.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]",
|
|
@@ -2251,18 +2416,18 @@ function ComposerContextPill({
|
|
|
2251
2416
|
children: tokenK
|
|
2252
2417
|
}
|
|
2253
2418
|
),
|
|
2254
|
-
/* @__PURE__ */
|
|
2419
|
+
/* @__PURE__ */ jsx9(
|
|
2255
2420
|
"button",
|
|
2256
2421
|
{
|
|
2257
2422
|
type: "button",
|
|
2258
2423
|
onClick: () => onRemove(id),
|
|
2259
2424
|
"aria-label": `\u79FB\u9664\u4E0A\u4E0B\u6587 ${label}`,
|
|
2260
2425
|
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__ */
|
|
2426
|
+
children: /* @__PURE__ */ jsx9(X2, { size: 10 })
|
|
2262
2427
|
}
|
|
2263
2428
|
)
|
|
2264
2429
|
] }),
|
|
2265
|
-
showDetail && /* @__PURE__ */
|
|
2430
|
+
showDetail && /* @__PURE__ */ jsx9(
|
|
2266
2431
|
"div",
|
|
2267
2432
|
{
|
|
2268
2433
|
className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-6",
|
|
@@ -2270,26 +2435,26 @@ function ComposerContextPill({
|
|
|
2270
2435
|
onKeyDown: (e) => {
|
|
2271
2436
|
if (e.key === "Escape") setShowDetail(false);
|
|
2272
2437
|
},
|
|
2273
|
-
children: /* @__PURE__ */
|
|
2438
|
+
children: /* @__PURE__ */ jsxs8(
|
|
2274
2439
|
"div",
|
|
2275
2440
|
{
|
|
2276
2441
|
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
2442
|
onClick: (e) => e.stopPropagation(),
|
|
2278
2443
|
onKeyDown: (e) => e.stopPropagation(),
|
|
2279
2444
|
children: [
|
|
2280
|
-
/* @__PURE__ */
|
|
2281
|
-
/* @__PURE__ */
|
|
2282
|
-
/* @__PURE__ */
|
|
2445
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [
|
|
2446
|
+
/* @__PURE__ */ jsx9("h4", { className: "text-xs font-semibold text-[hsl(var(--foreground))]", children: label }),
|
|
2447
|
+
/* @__PURE__ */ jsx9(
|
|
2283
2448
|
"button",
|
|
2284
2449
|
{
|
|
2285
2450
|
type: "button",
|
|
2286
2451
|
onClick: () => setShowDetail(false),
|
|
2287
2452
|
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__ */
|
|
2453
|
+
children: /* @__PURE__ */ jsx9(X2, { size: 14 })
|
|
2289
2454
|
}
|
|
2290
2455
|
)
|
|
2291
2456
|
] }),
|
|
2292
|
-
/* @__PURE__ */
|
|
2457
|
+
/* @__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
2458
|
]
|
|
2294
2459
|
}
|
|
2295
2460
|
)
|
|
@@ -2443,7 +2608,7 @@ function ChatInput({
|
|
|
2443
2608
|
onResyncSkills,
|
|
2444
2609
|
isResyncingSkills = false
|
|
2445
2610
|
}) {
|
|
2446
|
-
const [input, setInputInternal] =
|
|
2611
|
+
const [input, setInputInternal] = useState7(externalDraft?.value ?? "");
|
|
2447
2612
|
const setInput = useEffectEvent2((value) => {
|
|
2448
2613
|
setInputInternal(value);
|
|
2449
2614
|
externalDraft?.setValue(value);
|
|
@@ -2459,7 +2624,7 @@ function ChatInput({
|
|
|
2459
2624
|
}
|
|
2460
2625
|
setInputInternal(externalDraftValue);
|
|
2461
2626
|
}, [externalDraftValue]);
|
|
2462
|
-
const [composerAttachments, setComposerAttachmentsInternal] =
|
|
2627
|
+
const [composerAttachments, setComposerAttachmentsInternal] = useState7(
|
|
2463
2628
|
externalAttachments?.value ?? []
|
|
2464
2629
|
);
|
|
2465
2630
|
const setComposerAttachments = useEffectEvent2(
|
|
@@ -2479,10 +2644,10 @@ function ChatInput({
|
|
|
2479
2644
|
if (composerAttachmentsRef.current === externalAttachmentsValue) return;
|
|
2480
2645
|
setComposerAttachmentsInternal(externalAttachmentsValue);
|
|
2481
2646
|
}, [externalAttachmentsValue]);
|
|
2482
|
-
const [dragging, setDragging] =
|
|
2483
|
-
const [isEditorFocused, setIsEditorFocused] =
|
|
2484
|
-
const [oversizedFiles, setOversizedFiles] =
|
|
2485
|
-
const [selectedModel, setSelectedModel] =
|
|
2647
|
+
const [dragging, setDragging] = useState7(false);
|
|
2648
|
+
const [isEditorFocused, setIsEditorFocused] = useState7(false);
|
|
2649
|
+
const [oversizedFiles, setOversizedFiles] = useState7([]);
|
|
2650
|
+
const [selectedModel, setSelectedModel] = useState7("");
|
|
2486
2651
|
const { setPreferredModel } = usePreferredModel();
|
|
2487
2652
|
const queryClient = useQueryClient2();
|
|
2488
2653
|
const actionMenuRef = useRef4(null);
|
|
@@ -2522,7 +2687,7 @@ function ChatInput({
|
|
|
2522
2687
|
const inputHistory = useInputHistory(activeSessionId);
|
|
2523
2688
|
const getSessionId = useEffectEvent2(() => activeSessionId);
|
|
2524
2689
|
const handleSlashCommand = useEffectEvent2((commandId) => onCommand?.(commandId));
|
|
2525
|
-
const [localImageUrls, setLocalImageUrls] =
|
|
2690
|
+
const [localImageUrls, setLocalImageUrls] = useState7({});
|
|
2526
2691
|
useEffect7(() => {
|
|
2527
2692
|
const closeActionMenu = (event) => {
|
|
2528
2693
|
const menu = actionMenuRef.current;
|
|
@@ -2650,7 +2815,7 @@ function ChatInput({
|
|
|
2650
2815
|
if (!container || !root) return;
|
|
2651
2816
|
updateSuggestionPosition(container, props.clientRect);
|
|
2652
2817
|
root.render(
|
|
2653
|
-
/* @__PURE__ */
|
|
2818
|
+
/* @__PURE__ */ jsx9(
|
|
2654
2819
|
FileCompletionMenu,
|
|
2655
2820
|
{
|
|
2656
2821
|
ref: (instance) => {
|
|
@@ -2727,7 +2892,7 @@ function ChatInput({
|
|
|
2727
2892
|
if (!container || !root) return;
|
|
2728
2893
|
updateSuggestionPosition(container, props.clientRect);
|
|
2729
2894
|
root.render(
|
|
2730
|
-
/* @__PURE__ */
|
|
2895
|
+
/* @__PURE__ */ jsx9(
|
|
2731
2896
|
SkillCompletionMenu,
|
|
2732
2897
|
{
|
|
2733
2898
|
ref: (instance) => {
|
|
@@ -3055,7 +3220,7 @@ function ChatInput({
|
|
|
3055
3220
|
const removeAttachment = (id) => {
|
|
3056
3221
|
setComposerAttachments((prev) => prev.filter((attachment) => attachment.id !== id));
|
|
3057
3222
|
};
|
|
3058
|
-
const [showAddContext, setShowAddContext] =
|
|
3223
|
+
const [showAddContext, setShowAddContext] = useState7(false);
|
|
3059
3224
|
const isPlanning = mode === "planning";
|
|
3060
3225
|
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
3226
|
const attachments = renderAttachments?.() ?? null;
|
|
@@ -3074,385 +3239,388 @@ function ChatInput({
|
|
|
3074
3239
|
);
|
|
3075
3240
|
const hasValidAttachments = composerAttachments.some((attachment) => attachment.status !== "failed");
|
|
3076
3241
|
const isSendDisabled = connectionStatus !== "connected" || hasUploadingFiles || !input.trim() && !hasValidAttachments && !hasRenderedAttachments && !hasPendingContexts;
|
|
3077
|
-
return /* @__PURE__ */
|
|
3078
|
-
/* @__PURE__ */
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
editor2.
|
|
3099
|
-
editor2
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3242
|
+
return /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
3243
|
+
/* @__PURE__ */ jsx9("div", { className: `bg-[hsl(var(--background))] px-5 py-3 ${className ?? ""}`, children: /* @__PURE__ */ jsxs8("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: [
|
|
3244
|
+
activeSessionId ? /* @__PURE__ */ jsx9(BackgroundTasksPill, { sessionId: activeSessionId }) : null,
|
|
3245
|
+
/* @__PURE__ */ jsx9(
|
|
3246
|
+
"div",
|
|
3247
|
+
{
|
|
3248
|
+
className: "relative",
|
|
3249
|
+
onDragOver: (event) => {
|
|
3250
|
+
event.preventDefault();
|
|
3251
|
+
setDragging(true);
|
|
3252
|
+
},
|
|
3253
|
+
onDragLeave: () => setDragging(false),
|
|
3254
|
+
onDrop: (event) => {
|
|
3255
|
+
event.preventDefault();
|
|
3256
|
+
setDragging(false);
|
|
3257
|
+
const fileRef = event.dataTransfer.getData("application/blade-file-ref");
|
|
3258
|
+
if (fileRef) {
|
|
3259
|
+
try {
|
|
3260
|
+
const { path, name } = JSON.parse(fileRef);
|
|
3261
|
+
const normalizedPath = path.replace(/^\.?\//, "");
|
|
3262
|
+
const sandboxPath = path.startsWith("/") ? path : activeSessionId ? `/root/\u667A\u80FD\u52A9\u624B\u5DE5\u4F5C\u7A7A\u95F4/${activeSessionId}/${normalizedPath}` : normalizedPath;
|
|
3263
|
+
const editor2 = editorRef.current;
|
|
3264
|
+
if (editor2) {
|
|
3265
|
+
editor2.commands.focus("end");
|
|
3266
|
+
editor2.commands.insertContent([
|
|
3267
|
+
{ type: "fileMention", attrs: { path: sandboxPath, name } },
|
|
3268
|
+
{ type: "text", text: " " }
|
|
3269
|
+
]);
|
|
3270
|
+
}
|
|
3271
|
+
} catch {
|
|
3103
3272
|
}
|
|
3104
|
-
|
|
3273
|
+
return;
|
|
3105
3274
|
}
|
|
3106
|
-
|
|
3107
|
-
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3275
|
+
void stableAppendFiles(event.dataTransfer.files);
|
|
3276
|
+
},
|
|
3277
|
+
children: /* @__PURE__ */ jsxs8(
|
|
3278
|
+
"div",
|
|
3279
|
+
{
|
|
3280
|
+
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))]"}`,
|
|
3281
|
+
children: [
|
|
3282
|
+
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" }) }),
|
|
3283
|
+
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: [
|
|
3284
|
+
imageAttachments.length > 0 && /* @__PURE__ */ jsx9("div", { className: "grid grid-cols-3 gap-2", children: imageAttachments.map((attachment) => /* @__PURE__ */ jsxs8(
|
|
3285
|
+
"div",
|
|
3286
|
+
{
|
|
3287
|
+
className: "relative overflow-hidden rounded-xl border border-[hsl(var(--border))]",
|
|
3288
|
+
children: [
|
|
3289
|
+
/* @__PURE__ */ jsx9(
|
|
3290
|
+
"img",
|
|
3291
|
+
{
|
|
3292
|
+
src: getImagePreviewUrl(attachment, activeSessionId, localImageUrls),
|
|
3293
|
+
alt: attachment.name || "\u56FE\u7247\u9884\u89C8",
|
|
3294
|
+
className: "h-24 w-full object-cover"
|
|
3295
|
+
}
|
|
3296
|
+
),
|
|
3297
|
+
/* @__PURE__ */ jsx9(
|
|
3298
|
+
"button",
|
|
3299
|
+
{
|
|
3300
|
+
type: "button",
|
|
3301
|
+
onClick: () => removeAttachment(attachment.id),
|
|
3302
|
+
"aria-label": `\u79FB\u9664 ${attachment.name || "\u56FE\u7247"}`,
|
|
3303
|
+
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))]",
|
|
3304
|
+
children: /* @__PURE__ */ jsx9(X2, { size: 12 })
|
|
3305
|
+
}
|
|
3306
|
+
)
|
|
3307
|
+
]
|
|
3308
|
+
},
|
|
3309
|
+
attachment.id
|
|
3310
|
+
)) }),
|
|
3311
|
+
fileAttachments.length > 0 && /* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => /* @__PURE__ */ jsx9(
|
|
3312
|
+
ComposerFilePill,
|
|
3313
|
+
{
|
|
3314
|
+
attachment,
|
|
3315
|
+
onRemove: removeAttachment
|
|
3316
|
+
},
|
|
3317
|
+
attachment.id
|
|
3318
|
+
)) })
|
|
3319
|
+
] }),
|
|
3320
|
+
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: [
|
|
3321
|
+
pendingContexts?.map((context) => /* @__PURE__ */ jsx9(
|
|
3322
|
+
ComposerContextPill,
|
|
3323
|
+
{
|
|
3324
|
+
id: context.id,
|
|
3325
|
+
label: context.label,
|
|
3326
|
+
content: context.content,
|
|
3327
|
+
onRemove: (contextId) => {
|
|
3328
|
+
if (!activeSessionId) {
|
|
3329
|
+
return;
|
|
3138
3330
|
}
|
|
3139
|
-
|
|
3140
|
-
]
|
|
3141
|
-
},
|
|
3142
|
-
attachment.id
|
|
3143
|
-
)) }),
|
|
3144
|
-
fileAttachments.length > 0 && /* @__PURE__ */ jsx8("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => /* @__PURE__ */ jsx8(
|
|
3145
|
-
ComposerFilePill,
|
|
3146
|
-
{
|
|
3147
|
-
attachment,
|
|
3148
|
-
onRemove: removeAttachment
|
|
3149
|
-
},
|
|
3150
|
-
attachment.id
|
|
3151
|
-
)) })
|
|
3152
|
-
] }),
|
|
3153
|
-
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: [
|
|
3154
|
-
pendingContexts?.map((context) => /* @__PURE__ */ jsx8(
|
|
3155
|
-
ComposerContextPill,
|
|
3156
|
-
{
|
|
3157
|
-
id: context.id,
|
|
3158
|
-
label: context.label,
|
|
3159
|
-
content: context.content,
|
|
3160
|
-
onRemove: (contextId) => {
|
|
3161
|
-
if (!activeSessionId) {
|
|
3162
|
-
return;
|
|
3331
|
+
removePendingContext(activeSessionId, contextId);
|
|
3163
3332
|
}
|
|
3164
|
-
|
|
3333
|
+
},
|
|
3334
|
+
context.id
|
|
3335
|
+
)),
|
|
3336
|
+
isSkillEditor && /* @__PURE__ */ jsx9(
|
|
3337
|
+
"button",
|
|
3338
|
+
{
|
|
3339
|
+
type: "button",
|
|
3340
|
+
onClick: () => setShowAddContext(true),
|
|
3341
|
+
title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
3342
|
+
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))]",
|
|
3343
|
+
children: /* @__PURE__ */ jsx9(Plus, { size: 12 })
|
|
3165
3344
|
}
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
"button",
|
|
3345
|
+
)
|
|
3346
|
+
] }) : null,
|
|
3347
|
+
showAddContext && activeSessionId && /* @__PURE__ */ jsx9(
|
|
3348
|
+
AddContextDialog,
|
|
3171
3349
|
{
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
)
|
|
3179
|
-
] }) : null,
|
|
3180
|
-
showAddContext && activeSessionId && /* @__PURE__ */ jsx8(
|
|
3181
|
-
AddContextDialog,
|
|
3182
|
-
{
|
|
3183
|
-
sessionId: activeSessionId,
|
|
3184
|
-
onClose: () => setShowAddContext(false),
|
|
3185
|
-
onAdd: (label, content) => {
|
|
3186
|
-
if (activeSessionId) {
|
|
3187
|
-
useUiBridgeStore.getState().addPendingContext(activeSessionId, { label, content });
|
|
3350
|
+
sessionId: activeSessionId,
|
|
3351
|
+
onClose: () => setShowAddContext(false),
|
|
3352
|
+
onAdd: (label, content) => {
|
|
3353
|
+
if (activeSessionId) {
|
|
3354
|
+
useUiBridgeStore.getState().addPendingContext(activeSessionId, { label, content });
|
|
3355
|
+
}
|
|
3188
3356
|
}
|
|
3189
3357
|
}
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
"input",
|
|
3202
|
-
{
|
|
3203
|
-
ref: fileInputRef,
|
|
3204
|
-
type: "file",
|
|
3205
|
-
accept: "*/*",
|
|
3206
|
-
multiple: true,
|
|
3207
|
-
onChange: (event) => {
|
|
3208
|
-
if (event.target.files) {
|
|
3209
|
-
void appendFiles(event.target.files);
|
|
3210
|
-
event.target.value = "";
|
|
3211
|
-
}
|
|
3212
|
-
},
|
|
3213
|
-
className: "hidden"
|
|
3214
|
-
}
|
|
3215
|
-
),
|
|
3216
|
-
/* @__PURE__ */ jsx8(
|
|
3217
|
-
"input",
|
|
3218
|
-
{
|
|
3219
|
-
ref: folderInputRef,
|
|
3220
|
-
type: "file",
|
|
3221
|
-
multiple: true,
|
|
3222
|
-
onChange: (event) => {
|
|
3223
|
-
if (event.target.files) {
|
|
3224
|
-
void appendFiles(event.target.files);
|
|
3225
|
-
event.target.value = "";
|
|
3226
|
-
}
|
|
3227
|
-
},
|
|
3228
|
-
className: "hidden",
|
|
3229
|
-
...{ webkitdirectory: "" }
|
|
3230
|
-
}
|
|
3231
|
-
),
|
|
3232
|
-
/* @__PURE__ */ jsxs7("details", { ref: actionMenuRef, className: "group relative", children: [
|
|
3233
|
-
/* @__PURE__ */ jsx8(
|
|
3234
|
-
"summary",
|
|
3358
|
+
),
|
|
3359
|
+
attachments ? /* @__PURE__ */ jsx9("div", { className: "border-b border-[hsl(var(--border))] px-3 py-3", children: attachments }) : null,
|
|
3360
|
+
slotAboveTextarea ? /* @__PURE__ */ jsx9("div", { className: "border-b border-[hsl(var(--border))] px-3 py-2", children: slotAboveTextarea }) : null,
|
|
3361
|
+
/* @__PURE__ */ jsxs8("div", { className: "relative", children: [
|
|
3362
|
+
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 }),
|
|
3363
|
+
/* @__PURE__ */ jsx9(EditorContent, { editor })
|
|
3364
|
+
] }),
|
|
3365
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between border-t border-[hsl(var(--border))] px-3 py-1.5", children: [
|
|
3366
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
3367
|
+
/* @__PURE__ */ jsx9(
|
|
3368
|
+
"input",
|
|
3235
3369
|
{
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3370
|
+
ref: fileInputRef,
|
|
3371
|
+
type: "file",
|
|
3372
|
+
accept: "*/*",
|
|
3373
|
+
multiple: true,
|
|
3374
|
+
onChange: (event) => {
|
|
3375
|
+
if (event.target.files) {
|
|
3376
|
+
void appendFiles(event.target.files);
|
|
3377
|
+
event.target.value = "";
|
|
3378
|
+
}
|
|
3379
|
+
},
|
|
3380
|
+
className: "hidden"
|
|
3240
3381
|
}
|
|
3241
3382
|
),
|
|
3242
|
-
/* @__PURE__ */
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3383
|
+
/* @__PURE__ */ jsx9(
|
|
3384
|
+
"input",
|
|
3385
|
+
{
|
|
3386
|
+
ref: folderInputRef,
|
|
3387
|
+
type: "file",
|
|
3388
|
+
multiple: true,
|
|
3389
|
+
onChange: (event) => {
|
|
3390
|
+
if (event.target.files) {
|
|
3391
|
+
void appendFiles(event.target.files);
|
|
3392
|
+
event.target.value = "";
|
|
3393
|
+
}
|
|
3394
|
+
},
|
|
3395
|
+
className: "hidden",
|
|
3396
|
+
...{ webkitdirectory: "" }
|
|
3397
|
+
}
|
|
3398
|
+
),
|
|
3399
|
+
/* @__PURE__ */ jsxs8("details", { ref: actionMenuRef, className: "group relative", children: [
|
|
3400
|
+
/* @__PURE__ */ jsx9(
|
|
3401
|
+
"summary",
|
|
3260
3402
|
{
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
},
|
|
3266
|
-
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3267
|
-
children: [
|
|
3268
|
-
/* @__PURE__ */ jsx8(FolderUp, { size: 13 }),
|
|
3269
|
-
"\u4E0A\u4F20\u6587\u4EF6\u5939"
|
|
3270
|
-
]
|
|
3403
|
+
"aria-label": "\u6DFB\u52A0\u5185\u5BB9",
|
|
3404
|
+
title: "\u6DFB\u52A0\u5185\u5BB9",
|
|
3405
|
+
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",
|
|
3406
|
+
children: /* @__PURE__ */ jsx9(Plus, { size: 14 })
|
|
3271
3407
|
}
|
|
3272
3408
|
),
|
|
3273
|
-
|
|
3274
|
-
/* @__PURE__ */
|
|
3409
|
+
/* @__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: [
|
|
3410
|
+
/* @__PURE__ */ jsxs8(
|
|
3275
3411
|
"button",
|
|
3276
3412
|
{
|
|
3277
3413
|
type: "button",
|
|
3278
3414
|
onClick: () => {
|
|
3279
3415
|
actionMenuRef.current?.removeAttribute("open");
|
|
3280
|
-
|
|
3281
|
-
},
|
|
3282
|
-
disabled: isStreaming,
|
|
3283
|
-
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",
|
|
3284
|
-
children: [
|
|
3285
|
-
isStreaming ? /* @__PURE__ */ jsx8(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx8(Scissors, { size: 13 }),
|
|
3286
|
-
"\u6574\u7406\u5BF9\u8BDD"
|
|
3287
|
-
]
|
|
3288
|
-
}
|
|
3289
|
-
),
|
|
3290
|
-
/* @__PURE__ */ jsxs7(
|
|
3291
|
-
"button",
|
|
3292
|
-
{
|
|
3293
|
-
type: "button",
|
|
3294
|
-
onClick: () => {
|
|
3295
|
-
actionMenuRef.current?.removeAttribute("open");
|
|
3296
|
-
void onCommand("download_session");
|
|
3416
|
+
fileInputRef.current?.click();
|
|
3297
3417
|
},
|
|
3298
3418
|
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3299
3419
|
children: [
|
|
3300
|
-
/* @__PURE__ */
|
|
3301
|
-
"\
|
|
3420
|
+
/* @__PURE__ */ jsx9(Paperclip, { size: 13 }),
|
|
3421
|
+
"\u4E0A\u4F20\u6587\u4EF6"
|
|
3302
3422
|
]
|
|
3303
3423
|
}
|
|
3304
3424
|
),
|
|
3305
|
-
|
|
3306
|
-
"button",
|
|
3307
|
-
{
|
|
3308
|
-
type: "button",
|
|
3309
|
-
onClick: () => {
|
|
3310
|
-
actionMenuRef.current?.removeAttribute("open");
|
|
3311
|
-
void onCommand("share_session");
|
|
3312
|
-
},
|
|
3313
|
-
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3314
|
-
children: [
|
|
3315
|
-
/* @__PURE__ */ jsx8(Share2, { size: 13 }),
|
|
3316
|
-
"\u5206\u4EAB\u4F1A\u8BDD"
|
|
3317
|
-
]
|
|
3318
|
-
}
|
|
3319
|
-
) : null,
|
|
3320
|
-
/* @__PURE__ */ jsxs7(
|
|
3425
|
+
/* @__PURE__ */ jsxs8(
|
|
3321
3426
|
"button",
|
|
3322
3427
|
{
|
|
3323
3428
|
type: "button",
|
|
3324
3429
|
onClick: () => {
|
|
3325
3430
|
actionMenuRef.current?.removeAttribute("open");
|
|
3326
|
-
|
|
3431
|
+
folderInputRef.current?.click();
|
|
3327
3432
|
},
|
|
3328
3433
|
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3329
3434
|
children: [
|
|
3330
|
-
/* @__PURE__ */
|
|
3331
|
-
"\
|
|
3435
|
+
/* @__PURE__ */ jsx9(FolderUp, { size: 13 }),
|
|
3436
|
+
"\u4E0A\u4F20\u6587\u4EF6\u5939"
|
|
3332
3437
|
]
|
|
3333
3438
|
}
|
|
3334
3439
|
),
|
|
3335
|
-
/* @__PURE__ */
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3440
|
+
onCommand ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
3441
|
+
/* @__PURE__ */ jsxs8(
|
|
3442
|
+
"button",
|
|
3443
|
+
{
|
|
3444
|
+
type: "button",
|
|
3445
|
+
onClick: () => {
|
|
3446
|
+
actionMenuRef.current?.removeAttribute("open");
|
|
3447
|
+
void onCommand("compact");
|
|
3448
|
+
},
|
|
3449
|
+
disabled: isStreaming,
|
|
3450
|
+
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",
|
|
3451
|
+
children: [
|
|
3452
|
+
isStreaming ? /* @__PURE__ */ jsx9(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx9(Scissors, { size: 13 }),
|
|
3453
|
+
"\u6574\u7406\u5BF9\u8BDD"
|
|
3454
|
+
]
|
|
3455
|
+
}
|
|
3456
|
+
),
|
|
3457
|
+
/* @__PURE__ */ jsxs8(
|
|
3458
|
+
"button",
|
|
3459
|
+
{
|
|
3460
|
+
type: "button",
|
|
3461
|
+
onClick: () => {
|
|
3462
|
+
actionMenuRef.current?.removeAttribute("open");
|
|
3463
|
+
void onCommand("download_session");
|
|
3464
|
+
},
|
|
3465
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3466
|
+
children: [
|
|
3467
|
+
/* @__PURE__ */ jsx9(Download, { size: 13 }),
|
|
3468
|
+
"\u5BFC\u51FA\u4F1A\u8BDD"
|
|
3469
|
+
]
|
|
3470
|
+
}
|
|
3471
|
+
),
|
|
3472
|
+
canShareSession ? /* @__PURE__ */ jsxs8(
|
|
3473
|
+
"button",
|
|
3474
|
+
{
|
|
3475
|
+
type: "button",
|
|
3476
|
+
onClick: () => {
|
|
3477
|
+
actionMenuRef.current?.removeAttribute("open");
|
|
3478
|
+
void onCommand("share_session");
|
|
3479
|
+
},
|
|
3480
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3481
|
+
children: [
|
|
3482
|
+
/* @__PURE__ */ jsx9(Share2, { size: 13 }),
|
|
3483
|
+
"\u5206\u4EAB\u4F1A\u8BDD"
|
|
3484
|
+
]
|
|
3485
|
+
}
|
|
3486
|
+
) : null,
|
|
3487
|
+
/* @__PURE__ */ jsxs8(
|
|
3488
|
+
"button",
|
|
3489
|
+
{
|
|
3490
|
+
type: "button",
|
|
3491
|
+
onClick: () => {
|
|
3492
|
+
actionMenuRef.current?.removeAttribute("open");
|
|
3493
|
+
void onCommand("extract_skill");
|
|
3494
|
+
},
|
|
3495
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3496
|
+
children: [
|
|
3497
|
+
/* @__PURE__ */ jsx9(FlaskConical, { size: 13 }),
|
|
3498
|
+
"\u63D0\u53D6\u6280\u80FD"
|
|
3499
|
+
]
|
|
3500
|
+
}
|
|
3501
|
+
),
|
|
3502
|
+
/* @__PURE__ */ jsxs8(
|
|
3503
|
+
"button",
|
|
3504
|
+
{
|
|
3505
|
+
type: "button",
|
|
3506
|
+
onClick: () => {
|
|
3507
|
+
actionMenuRef.current?.removeAttribute("open");
|
|
3508
|
+
void onCommand("generate_app");
|
|
3509
|
+
},
|
|
3510
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3511
|
+
children: [
|
|
3512
|
+
/* @__PURE__ */ jsx9(Rocket, { size: 13 }),
|
|
3513
|
+
"\u751F\u6210\u5E94\u7528"
|
|
3514
|
+
]
|
|
3515
|
+
}
|
|
3516
|
+
)
|
|
3517
|
+
] }) : null,
|
|
3518
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 px-3 py-2", children: [
|
|
3519
|
+
/* @__PURE__ */ jsx9(Sparkles2, { size: 13 }),
|
|
3520
|
+
/* @__PURE__ */ jsx9("span", { className: "shrink-0", children: "\u6A21\u578B" }),
|
|
3521
|
+
/* @__PURE__ */ jsx9(
|
|
3522
|
+
ModelSelector,
|
|
3523
|
+
{
|
|
3524
|
+
value: selectedModel,
|
|
3525
|
+
onValueChange: (model) => {
|
|
3526
|
+
setSelectedModel(model);
|
|
3527
|
+
if (activeSessionId) {
|
|
3528
|
+
patchSession(activeSessionId, { model });
|
|
3529
|
+
}
|
|
3530
|
+
setPreferredModel(model);
|
|
3531
|
+
},
|
|
3532
|
+
compact: true,
|
|
3533
|
+
placement: "top"
|
|
3534
|
+
}
|
|
3535
|
+
)
|
|
3536
|
+
] })
|
|
3369
3537
|
] })
|
|
3370
|
-
] })
|
|
3371
|
-
|
|
3372
|
-
/* @__PURE__ */ jsx8(
|
|
3373
|
-
"button",
|
|
3374
|
-
{
|
|
3375
|
-
type: "button",
|
|
3376
|
-
onClick: onToggleMode,
|
|
3377
|
-
disabled: isStreaming || !onToggleMode,
|
|
3378
|
-
"aria-pressed": isPlanning,
|
|
3379
|
-
"aria-label": isPlanning ? "\u5173\u95ED\u89C4\u5212\u6A21\u5F0F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
|
|
3380
|
-
title: isPlanning ? "\u89C4\u5212\u6A21\u5F0F\u5DF2\u5F00\u542F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
|
|
3381
|
-
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`,
|
|
3382
|
-
children: /* @__PURE__ */ jsx8(Lightbulb, { size: 13 })
|
|
3383
|
-
}
|
|
3384
|
-
)
|
|
3385
|
-
] }),
|
|
3386
|
-
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5", children: [
|
|
3387
|
-
/* @__PURE__ */ jsxs7("div", { className: "group/help relative", children: [
|
|
3388
|
-
/* @__PURE__ */ jsx8(
|
|
3538
|
+
] }),
|
|
3539
|
+
/* @__PURE__ */ jsx9(
|
|
3389
3540
|
"button",
|
|
3390
3541
|
{
|
|
3391
3542
|
type: "button",
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3543
|
+
onClick: onToggleMode,
|
|
3544
|
+
disabled: isStreaming || !onToggleMode,
|
|
3545
|
+
"aria-pressed": isPlanning,
|
|
3546
|
+
"aria-label": isPlanning ? "\u5173\u95ED\u89C4\u5212\u6A21\u5F0F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
|
|
3547
|
+
title: isPlanning ? "\u89C4\u5212\u6A21\u5F0F\u5DF2\u5F00\u542F" : "\u5F00\u542F\u89C4\u5212\u6A21\u5F0F",
|
|
3548
|
+
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`,
|
|
3549
|
+
children: /* @__PURE__ */ jsx9(Lightbulb, { size: 13 })
|
|
3395
3550
|
}
|
|
3396
|
-
)
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3551
|
+
)
|
|
3552
|
+
] }),
|
|
3553
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1.5", children: [
|
|
3554
|
+
/* @__PURE__ */ jsxs8("div", { className: "group/help relative", children: [
|
|
3555
|
+
/* @__PURE__ */ jsx9(
|
|
3556
|
+
"button",
|
|
3400
3557
|
{
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
className: skillStatusBarClassName,
|
|
3406
|
-
innerClassName: skillStatusBarInnerClassName
|
|
3558
|
+
type: "button",
|
|
3559
|
+
"aria-label": "\u67E5\u770B\u8F93\u5165\u63D0\u793A",
|
|
3560
|
+
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))]",
|
|
3561
|
+
children: /* @__PURE__ */ jsx9(CircleHelp, { size: 13 })
|
|
3407
3562
|
}
|
|
3408
|
-
)
|
|
3409
|
-
/* @__PURE__ */
|
|
3410
|
-
/* @__PURE__ */
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3563
|
+
),
|
|
3564
|
+
/* @__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: [
|
|
3565
|
+
activeSessionId ? /* @__PURE__ */ jsx9("div", { className: "mb-2 border-b border-[hsl(var(--border))] pb-2", children: /* @__PURE__ */ jsx9(
|
|
3566
|
+
SkillStatusBarComponent,
|
|
3567
|
+
{
|
|
3568
|
+
sessionId: activeSessionId,
|
|
3569
|
+
onResync: onResyncSkills,
|
|
3570
|
+
isResyncing: isResyncingSkills,
|
|
3571
|
+
vertical: true,
|
|
3572
|
+
className: skillStatusBarClassName,
|
|
3573
|
+
innerClassName: skillStatusBarInnerClassName
|
|
3574
|
+
}
|
|
3575
|
+
) }) : null,
|
|
3576
|
+
/* @__PURE__ */ jsxs8("div", { className: "space-y-0.5", children: [
|
|
3577
|
+
/* @__PURE__ */ jsx9("div", { children: "Shift+Enter \u6362\u884C" }),
|
|
3578
|
+
/* @__PURE__ */ jsx9("div", { children: "/ \u8C03\u7528\u6280\u80FD" }),
|
|
3579
|
+
/* @__PURE__ */ jsx9("div", { children: "@ \u5F15\u7528\u6587\u4EF6" })
|
|
3580
|
+
] })
|
|
3581
|
+
] }) })
|
|
3582
|
+
] }),
|
|
3583
|
+
/* @__PURE__ */ jsx9(
|
|
3584
|
+
"button",
|
|
3585
|
+
{
|
|
3586
|
+
type: "button",
|
|
3587
|
+
onClick: asrEnabled ? voice.toggle : handleMicDisabledClick,
|
|
3588
|
+
disabled: isStreaming,
|
|
3589
|
+
"aria-label": !asrEnabled ? "\u8BED\u97F3\u8F93\u5165\u672A\u5F00\u542F" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u5F00\u59CB\u8BED\u97F3\u8F93\u5165",
|
|
3590
|
+
title: !asrEnabled ? "\u8BED\u97F3\u8F93\u5165\u672A\u5F00\u542F" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u8BED\u97F3\u8F93\u5165",
|
|
3591
|
+
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))]"}`,
|
|
3592
|
+
children: !asrEnabled ? /* @__PURE__ */ jsx9(MicOff, { size: 13 }) : isRecording ? /* @__PURE__ */ jsx9(VoiceWaveform, { level: voiceLevel, size: 18 }) : /* @__PURE__ */ jsx9(Mic, { size: 13 })
|
|
3593
|
+
}
|
|
3594
|
+
),
|
|
3595
|
+
isStreaming ? /* @__PURE__ */ jsx9(
|
|
3596
|
+
"button",
|
|
3597
|
+
{
|
|
3598
|
+
type: "button",
|
|
3599
|
+
onClick: onStop,
|
|
3600
|
+
"aria-label": "\u505C\u6B62\u751F\u6210",
|
|
3601
|
+
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",
|
|
3602
|
+
children: /* @__PURE__ */ jsx9(Square2, { size: 13 })
|
|
3603
|
+
}
|
|
3604
|
+
) : /* @__PURE__ */ jsx9(
|
|
3605
|
+
"button",
|
|
3606
|
+
{
|
|
3607
|
+
type: "button",
|
|
3608
|
+
onClick: handleSubmit,
|
|
3609
|
+
disabled: isSendDisabled || isRecording,
|
|
3610
|
+
"aria-label": "\u53D1\u9001\u6D88\u606F",
|
|
3611
|
+
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",
|
|
3612
|
+
children: /* @__PURE__ */ jsx9(Send, { size: 13 })
|
|
3613
|
+
}
|
|
3614
|
+
)
|
|
3615
|
+
] })
|
|
3448
3616
|
] })
|
|
3449
|
-
]
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
/* @__PURE__ */
|
|
3617
|
+
]
|
|
3618
|
+
}
|
|
3619
|
+
)
|
|
3620
|
+
}
|
|
3621
|
+
)
|
|
3622
|
+
] }) }),
|
|
3623
|
+
/* @__PURE__ */ jsx9(
|
|
3456
3624
|
FileSizeLimitDialog,
|
|
3457
3625
|
{
|
|
3458
3626
|
open: oversizedFiles.length > 0,
|
|
@@ -3470,18 +3638,18 @@ function ChatInput({
|
|
|
3470
3638
|
|
|
3471
3639
|
// src/react/components/chat/ConnectionBanner.tsx
|
|
3472
3640
|
import { AlertTriangle, LoaderCircle } from "lucide-react";
|
|
3473
|
-
import { jsx as
|
|
3641
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3474
3642
|
function getBannerCopy(status, reconnectAttempt, hasEverConnected) {
|
|
3475
3643
|
if (status === "connecting") {
|
|
3476
3644
|
return {
|
|
3477
|
-
icon: /* @__PURE__ */
|
|
3645
|
+
icon: /* @__PURE__ */ jsx10(LoaderCircle, { size: 14, className: "animate-spin" }),
|
|
3478
3646
|
toneClass: "border-amber-500/25 bg-amber-500/10 text-amber-100",
|
|
3479
3647
|
title: "\u8FDE\u63A5\u5DF2\u65AD\u5F00\uFF0C\u6B63\u5728\u91CD\u8FDE\u2026",
|
|
3480
3648
|
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"
|
|
3481
3649
|
};
|
|
3482
3650
|
}
|
|
3483
3651
|
return {
|
|
3484
|
-
icon: /* @__PURE__ */
|
|
3652
|
+
icon: /* @__PURE__ */ jsx10(AlertTriangle, { size: 14 }),
|
|
3485
3653
|
toneClass: "border-rose-500/25 bg-rose-500/10 text-rose-100",
|
|
3486
3654
|
title: hasEverConnected ? "\u8FDE\u63A5\u5DF2\u65AD\u5F00\uFF0C\u6B63\u5728\u7B49\u5F85\u91CD\u8FDE\u2026" : "\u6682\u65F6\u65E0\u6CD5\u5EFA\u7ACB\u8FDE\u63A5",
|
|
3487
3655
|
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"
|
|
@@ -3496,7 +3664,7 @@ function ConnectionBanner() {
|
|
|
3496
3664
|
return null;
|
|
3497
3665
|
}
|
|
3498
3666
|
const copy = getBannerCopy(status, reconnectAttempt, hasEverConnected);
|
|
3499
|
-
return /* @__PURE__ */
|
|
3667
|
+
return /* @__PURE__ */ jsx10("div", { className: "bg-[hsl(var(--background))] px-5 pt-3", children: /* @__PURE__ */ jsxs9(
|
|
3500
3668
|
"div",
|
|
3501
3669
|
{
|
|
3502
3670
|
className: cn(
|
|
@@ -3504,10 +3672,10 @@ function ConnectionBanner() {
|
|
|
3504
3672
|
copy.toneClass
|
|
3505
3673
|
),
|
|
3506
3674
|
children: [
|
|
3507
|
-
/* @__PURE__ */
|
|
3508
|
-
/* @__PURE__ */
|
|
3509
|
-
/* @__PURE__ */
|
|
3510
|
-
/* @__PURE__ */
|
|
3675
|
+
/* @__PURE__ */ jsx10("span", { className: "mt-0.5 shrink-0", children: copy.icon }),
|
|
3676
|
+
/* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
|
|
3677
|
+
/* @__PURE__ */ jsx10("div", { className: "text-sm font-medium", children: copy.title }),
|
|
3678
|
+
/* @__PURE__ */ jsx10("div", { className: "text-xs opacity-80", children: copy.detail })
|
|
3511
3679
|
] })
|
|
3512
3680
|
]
|
|
3513
3681
|
}
|
|
@@ -3522,11 +3690,11 @@ import {
|
|
|
3522
3690
|
useEffectEvent as useEffectEvent4,
|
|
3523
3691
|
useMemo as useMemo17,
|
|
3524
3692
|
useRef as useRef11,
|
|
3525
|
-
useState as
|
|
3693
|
+
useState as useState20
|
|
3526
3694
|
} from "react";
|
|
3527
3695
|
|
|
3528
3696
|
// ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
|
|
3529
|
-
import { useCallback as useCallback7, useMemo as useMemo8, useRef as useRef5, useState as
|
|
3697
|
+
import { useCallback as useCallback7, useMemo as useMemo8, useRef as useRef5, useState as useState8 } from "react";
|
|
3530
3698
|
var DEFAULT_SPRING_ANIMATION = {
|
|
3531
3699
|
/**
|
|
3532
3700
|
* A value from 0 to 1, on how much to damp the animation.
|
|
@@ -3563,9 +3731,9 @@ globalThis.document?.addEventListener("click", () => {
|
|
|
3563
3731
|
mouseDown = false;
|
|
3564
3732
|
});
|
|
3565
3733
|
var useStickToBottom = (options = {}) => {
|
|
3566
|
-
const [escapedFromLock, updateEscapedFromLock] =
|
|
3567
|
-
const [isAtBottom, updateIsAtBottom] =
|
|
3568
|
-
const [isNearBottom, setIsNearBottom] =
|
|
3734
|
+
const [escapedFromLock, updateEscapedFromLock] = useState8(false);
|
|
3735
|
+
const [isAtBottom, updateIsAtBottom] = useState8(options.initial !== false);
|
|
3736
|
+
const [isNearBottom, setIsNearBottom] = useState8(false);
|
|
3569
3737
|
const optionsRef = useRef5(null);
|
|
3570
3738
|
optionsRef.current = options;
|
|
3571
3739
|
const isSelecting = useCallback7(() => {
|
|
@@ -3951,7 +4119,7 @@ function useStickToBottomContext() {
|
|
|
3951
4119
|
|
|
3952
4120
|
// src/react/components/chat/AssistantTurnBlock.tsx
|
|
3953
4121
|
import { AlertCircle, BookOpen, Check as Check4, ChevronRight as ChevronRight5 } from "lucide-react";
|
|
3954
|
-
import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo15, useRef as useRef10, useState as
|
|
4122
|
+
import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo15, useRef as useRef10, useState as useState17 } from "react";
|
|
3955
4123
|
|
|
3956
4124
|
// src/react/routes.ts
|
|
3957
4125
|
var MEMORIES_ROUTE = "/memories";
|
|
@@ -3970,7 +4138,7 @@ import {
|
|
|
3970
4138
|
useEffect as useEffect9,
|
|
3971
4139
|
useMemo as useMemo11,
|
|
3972
4140
|
useRef as useRef7,
|
|
3973
|
-
useState as
|
|
4141
|
+
useState as useState9
|
|
3974
4142
|
} from "react";
|
|
3975
4143
|
import { createPortal as createPortal2 } from "react-dom";
|
|
3976
4144
|
import { Streamdown } from "streamdown";
|
|
@@ -3978,7 +4146,7 @@ import { Streamdown } from "streamdown";
|
|
|
3978
4146
|
// src/react/components/ai-elements/shimmer.tsx
|
|
3979
4147
|
import { motion } from "motion/react";
|
|
3980
4148
|
import { memo, useMemo as useMemo10 } from "react";
|
|
3981
|
-
import { jsx as
|
|
4149
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
3982
4150
|
var motionComponentCache = /* @__PURE__ */ new Map();
|
|
3983
4151
|
var getMotionComponent = (element) => {
|
|
3984
4152
|
let component = motionComponentCache.get(element);
|
|
@@ -4002,7 +4170,7 @@ var ShimmerComponent = ({
|
|
|
4002
4170
|
() => (children?.length ?? 0) * spread,
|
|
4003
4171
|
[children, spread]
|
|
4004
4172
|
);
|
|
4005
|
-
return /* @__PURE__ */
|
|
4173
|
+
return /* @__PURE__ */ jsx11(
|
|
4006
4174
|
MotionComponent,
|
|
4007
4175
|
{
|
|
4008
4176
|
animate: { backgroundPosition: "0% center" },
|
|
@@ -4028,7 +4196,7 @@ var ShimmerComponent = ({
|
|
|
4028
4196
|
var Shimmer = memo(ShimmerComponent);
|
|
4029
4197
|
|
|
4030
4198
|
// src/react/components/ai-elements/reasoning.tsx
|
|
4031
|
-
import { Fragment as
|
|
4199
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4032
4200
|
var ReasoningContext = createContext2(null);
|
|
4033
4201
|
var useReasoning = () => {
|
|
4034
4202
|
const context = useContext2(ReasoningContext);
|
|
@@ -4062,7 +4230,7 @@ var Reasoning = memo2(
|
|
|
4062
4230
|
prop: durationProp
|
|
4063
4231
|
});
|
|
4064
4232
|
const hasEverStreamedRef = useRef7(isStreaming);
|
|
4065
|
-
const [hasAutoClosed, setHasAutoClosed] =
|
|
4233
|
+
const [hasAutoClosed, setHasAutoClosed] = useState9(false);
|
|
4066
4234
|
const startTimeRef = useRef7(null);
|
|
4067
4235
|
useEffect9(() => {
|
|
4068
4236
|
if (isStreaming) {
|
|
@@ -4099,7 +4267,7 @@ var Reasoning = memo2(
|
|
|
4099
4267
|
() => ({ duration, isOpen, isStreaming, setIsOpen }),
|
|
4100
4268
|
[duration, isOpen, isStreaming, setIsOpen]
|
|
4101
4269
|
);
|
|
4102
|
-
return /* @__PURE__ */
|
|
4270
|
+
return /* @__PURE__ */ jsx12(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx12(
|
|
4103
4271
|
Collapsible,
|
|
4104
4272
|
{
|
|
4105
4273
|
className: cn("not-prose mb-4", className),
|
|
@@ -4113,12 +4281,12 @@ var Reasoning = memo2(
|
|
|
4113
4281
|
);
|
|
4114
4282
|
var defaultGetThinkingMessage = (isStreaming, duration) => {
|
|
4115
4283
|
if (isStreaming || duration === 0) {
|
|
4116
|
-
return /* @__PURE__ */
|
|
4284
|
+
return /* @__PURE__ */ jsx12(Shimmer, { duration: 1, children: "\u6DF1\u5EA6\u601D\u8003\u4E2D..." });
|
|
4117
4285
|
}
|
|
4118
4286
|
if (duration === void 0) {
|
|
4119
|
-
return /* @__PURE__ */
|
|
4287
|
+
return /* @__PURE__ */ jsx12("p", { children: "\u5DF2\u6DF1\u5EA6\u601D\u8003" });
|
|
4120
4288
|
}
|
|
4121
|
-
return /* @__PURE__ */
|
|
4289
|
+
return /* @__PURE__ */ jsxs10("p", { children: [
|
|
4122
4290
|
"\u5DF2\u6DF1\u5EA6\u601D\u8003 ",
|
|
4123
4291
|
duration,
|
|
4124
4292
|
" \u79D2"
|
|
@@ -4132,7 +4300,7 @@ var ReasoningTrigger = memo2(
|
|
|
4132
4300
|
...props
|
|
4133
4301
|
}) => {
|
|
4134
4302
|
const { isStreaming, isOpen, duration } = useReasoning();
|
|
4135
|
-
return /* @__PURE__ */
|
|
4303
|
+
return /* @__PURE__ */ jsx12(
|
|
4136
4304
|
CollapsibleTrigger,
|
|
4137
4305
|
{
|
|
4138
4306
|
className: cn(
|
|
@@ -4140,10 +4308,10 @@ var ReasoningTrigger = memo2(
|
|
|
4140
4308
|
className
|
|
4141
4309
|
),
|
|
4142
4310
|
...props,
|
|
4143
|
-
children: children ?? /* @__PURE__ */
|
|
4144
|
-
/* @__PURE__ */
|
|
4311
|
+
children: children ?? /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
4312
|
+
/* @__PURE__ */ jsx12(BrainIcon, { className: "size-4" }),
|
|
4145
4313
|
getThinkingMessage(isStreaming, duration),
|
|
4146
|
-
/* @__PURE__ */
|
|
4314
|
+
/* @__PURE__ */ jsx12(
|
|
4147
4315
|
ChevronDownIcon,
|
|
4148
4316
|
{
|
|
4149
4317
|
className: cn(
|
|
@@ -4160,7 +4328,7 @@ var ReasoningTrigger = memo2(
|
|
|
4160
4328
|
var streamdownPlugins = { cjk, math, mermaid };
|
|
4161
4329
|
var streamdownComponents = { code: CardCodeBlock };
|
|
4162
4330
|
var ReasoningContent = memo2(
|
|
4163
|
-
({ className, children, ...props }) => /* @__PURE__ */
|
|
4331
|
+
({ className, children, ...props }) => /* @__PURE__ */ jsx12(
|
|
4164
4332
|
CollapsibleContent,
|
|
4165
4333
|
{
|
|
4166
4334
|
className: cn(
|
|
@@ -4169,7 +4337,7 @@ var ReasoningContent = memo2(
|
|
|
4169
4337
|
className
|
|
4170
4338
|
),
|
|
4171
4339
|
...props,
|
|
4172
|
-
children: /* @__PURE__ */
|
|
4340
|
+
children: /* @__PURE__ */ jsx12(Streamdown, { components: streamdownComponents, plugins: streamdownPlugins, children })
|
|
4173
4341
|
}
|
|
4174
4342
|
)
|
|
4175
4343
|
);
|
|
@@ -4178,8 +4346,8 @@ function compactReasoningText(text) {
|
|
|
4178
4346
|
}
|
|
4179
4347
|
function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
|
|
4180
4348
|
const compactReasoning = compactReasoningText(reasoning);
|
|
4181
|
-
const [open, setOpen] =
|
|
4182
|
-
return /* @__PURE__ */
|
|
4349
|
+
const [open, setOpen] = useState9(false);
|
|
4350
|
+
return /* @__PURE__ */ jsxs10(
|
|
4183
4351
|
"span",
|
|
4184
4352
|
{
|
|
4185
4353
|
className: cn(
|
|
@@ -4187,7 +4355,7 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
|
|
|
4187
4355
|
variant === "inline" ? "ml-1" : "ml-1 shrink-0"
|
|
4188
4356
|
),
|
|
4189
4357
|
children: [
|
|
4190
|
-
/* @__PURE__ */
|
|
4358
|
+
/* @__PURE__ */ jsx12(
|
|
4191
4359
|
"button",
|
|
4192
4360
|
{
|
|
4193
4361
|
type: "button",
|
|
@@ -4202,7 +4370,7 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
|
|
|
4202
4370
|
}
|
|
4203
4371
|
),
|
|
4204
4372
|
open ? createPortal2(
|
|
4205
|
-
/* @__PURE__ */
|
|
4373
|
+
/* @__PURE__ */ jsx12(
|
|
4206
4374
|
"div",
|
|
4207
4375
|
{
|
|
4208
4376
|
className: "fixed inset-0 z-[70] flex items-center justify-center bg-black/10 p-6",
|
|
@@ -4218,26 +4386,26 @@ function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
|
|
|
4218
4386
|
setOpen(false);
|
|
4219
4387
|
}
|
|
4220
4388
|
},
|
|
4221
|
-
children: /* @__PURE__ */
|
|
4389
|
+
children: /* @__PURE__ */ jsxs10(
|
|
4222
4390
|
"div",
|
|
4223
4391
|
{
|
|
4224
4392
|
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",
|
|
4225
4393
|
"aria-label": "\u601D\u8003\u8BE6\u60C5",
|
|
4226
4394
|
children: [
|
|
4227
|
-
/* @__PURE__ */
|
|
4228
|
-
/* @__PURE__ */
|
|
4229
|
-
/* @__PURE__ */
|
|
4395
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-2", children: [
|
|
4396
|
+
/* @__PURE__ */ jsx12("span", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u601D\u8003\u8BE6\u60C5" }),
|
|
4397
|
+
/* @__PURE__ */ jsx12(
|
|
4230
4398
|
"button",
|
|
4231
4399
|
{
|
|
4232
4400
|
type: "button",
|
|
4233
4401
|
onClick: () => setOpen(false),
|
|
4234
4402
|
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",
|
|
4235
4403
|
"aria-label": "\u5173\u95ED\u601D\u8003\u8BE6\u60C5",
|
|
4236
|
-
children: /* @__PURE__ */
|
|
4404
|
+
children: /* @__PURE__ */ jsx12(XIcon, { size: 14, "aria-hidden": "true" })
|
|
4237
4405
|
}
|
|
4238
4406
|
)
|
|
4239
4407
|
] }),
|
|
4240
|
-
/* @__PURE__ */
|
|
4408
|
+
/* @__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 }) })
|
|
4241
4409
|
]
|
|
4242
4410
|
}
|
|
4243
4411
|
)
|
|
@@ -4254,12 +4422,12 @@ ReasoningTrigger.displayName = "ReasoningTrigger";
|
|
|
4254
4422
|
ReasoningContent.displayName = "ReasoningContent";
|
|
4255
4423
|
|
|
4256
4424
|
// src/react/components/chat/AgentLoopBlock.tsx
|
|
4257
|
-
import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as
|
|
4258
|
-
import { useEffect as useEffect13, useMemo as useMemo14, useState as
|
|
4425
|
+
import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText6, Loader2 as Loader24, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
|
|
4426
|
+
import { useEffect as useEffect13, useMemo as useMemo14, useState as useState16 } from "react";
|
|
4259
4427
|
|
|
4260
4428
|
// src/react/components/chat/ResourceIframe.tsx
|
|
4261
|
-
import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef8, useState as
|
|
4262
|
-
import { jsx as
|
|
4429
|
+
import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef8, useState as useState10 } from "react";
|
|
4430
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
4263
4431
|
function isResourceBridgeMessage(value) {
|
|
4264
4432
|
return typeof value === "object" && value !== null && value.__resourceBridge === true && typeof value.action === "string";
|
|
4265
4433
|
}
|
|
@@ -4276,7 +4444,7 @@ function ResourceIframe({ ui, sessionId }) {
|
|
|
4276
4444
|
const theme = useUiStore((state) => state.theme);
|
|
4277
4445
|
const resourceUri = ui.resourceUri ?? ui.resourceURI;
|
|
4278
4446
|
const iframeLabel = ui.title ?? resourceUri ?? "\u5DE5\u5177\u754C\u9762";
|
|
4279
|
-
const [autoHeight, setAutoHeight] =
|
|
4447
|
+
const [autoHeight, setAutoHeight] = useState10(null);
|
|
4280
4448
|
useEffect10(() => {
|
|
4281
4449
|
setAutoHeight(null);
|
|
4282
4450
|
}, [ui.resourceHTML, resourceUri]);
|
|
@@ -4365,7 +4533,7 @@ function ResourceIframe({ ui, sessionId }) {
|
|
|
4365
4533
|
}
|
|
4366
4534
|
const inlineHeight = autoHeight ?? ui.height;
|
|
4367
4535
|
const sandbox = resourceUri ? "allow-scripts allow-same-origin" : "allow-scripts";
|
|
4368
|
-
return /* @__PURE__ */
|
|
4536
|
+
return /* @__PURE__ */ jsx13(
|
|
4369
4537
|
"iframe",
|
|
4370
4538
|
{
|
|
4371
4539
|
ref: iframeRef,
|
|
@@ -4387,10 +4555,10 @@ function ResourceIframe({ ui, sessionId }) {
|
|
|
4387
4555
|
|
|
4388
4556
|
// src/react/components/chat/ToolCallBlock.tsx
|
|
4389
4557
|
import { Check, ChevronRight as ChevronRight3, Loader2 as Loader23, MessageSquareMore, PanelRightOpen, X as X4 } from "lucide-react";
|
|
4390
|
-
import { useMemo as useMemo12, useState as
|
|
4558
|
+
import { useMemo as useMemo12, useState as useState13 } from "react";
|
|
4391
4559
|
|
|
4392
4560
|
// src/react/components/chat/tool-renderers/shared.tsx
|
|
4393
|
-
import { jsx as
|
|
4561
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
4394
4562
|
function getResultText(result) {
|
|
4395
4563
|
if (typeof result === "string") return result;
|
|
4396
4564
|
if (Array.isArray(result)) {
|
|
@@ -4457,7 +4625,7 @@ function CodePreview({
|
|
|
4457
4625
|
}) {
|
|
4458
4626
|
const { highlightedHtml } = useHighlightedCodeHtml(content, getCodeLanguage(filePath));
|
|
4459
4627
|
if (!content.trim()) {
|
|
4460
|
-
return /* @__PURE__ */
|
|
4628
|
+
return /* @__PURE__ */ jsx14(
|
|
4461
4629
|
"pre",
|
|
4462
4630
|
{
|
|
4463
4631
|
className: cn(
|
|
@@ -4465,11 +4633,11 @@ function CodePreview({
|
|
|
4465
4633
|
"bg-[hsl(var(--muted))]/35 p-3 font-mono text-[11px] text-[hsl(var(--muted-foreground))]",
|
|
4466
4634
|
className
|
|
4467
4635
|
),
|
|
4468
|
-
children: /* @__PURE__ */
|
|
4636
|
+
children: /* @__PURE__ */ jsx14("code", { children: emptyLabel })
|
|
4469
4637
|
}
|
|
4470
4638
|
);
|
|
4471
4639
|
}
|
|
4472
|
-
return /* @__PURE__ */
|
|
4640
|
+
return /* @__PURE__ */ jsx14(
|
|
4473
4641
|
"pre",
|
|
4474
4642
|
{
|
|
4475
4643
|
className: cn(
|
|
@@ -4477,19 +4645,19 @@ function CodePreview({
|
|
|
4477
4645
|
"bg-[hsl(var(--muted))]/35 p-3 text-[11px]",
|
|
4478
4646
|
className
|
|
4479
4647
|
),
|
|
4480
|
-
children: highlightedHtml ? /* @__PURE__ */
|
|
4648
|
+
children: highlightedHtml ? /* @__PURE__ */ jsx14(
|
|
4481
4649
|
"code",
|
|
4482
4650
|
{
|
|
4483
4651
|
className: "font-mono",
|
|
4484
4652
|
dangerouslySetInnerHTML: { __html: highlightedHtml }
|
|
4485
4653
|
}
|
|
4486
|
-
) : /* @__PURE__ */
|
|
4654
|
+
) : /* @__PURE__ */ jsx14("code", { className: "whitespace-pre-wrap break-words font-mono text-[hsl(var(--foreground))]", children: content })
|
|
4487
4655
|
}
|
|
4488
4656
|
);
|
|
4489
4657
|
}
|
|
4490
4658
|
|
|
4491
4659
|
// src/react/components/chat/tool-renderers/BashRenderer.tsx
|
|
4492
|
-
import { jsx as
|
|
4660
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4493
4661
|
function pickOutputField(data) {
|
|
4494
4662
|
if (!data) return null;
|
|
4495
4663
|
for (const key of ["output", "stdout", "stderr"]) {
|
|
@@ -4499,7 +4667,7 @@ function pickOutputField(data) {
|
|
|
4499
4667
|
return null;
|
|
4500
4668
|
}
|
|
4501
4669
|
function MetaPill({ label }) {
|
|
4502
|
-
return /* @__PURE__ */
|
|
4670
|
+
return /* @__PURE__ */ jsx15("span", { className: "rounded-full border border-border bg-muted px-2 py-0.5 text-[10px] text-secondary-foreground", children: label });
|
|
4503
4671
|
}
|
|
4504
4672
|
function BashRenderer({ toolCall }) {
|
|
4505
4673
|
const argsValue = parseJsonValue(toolCall.arguments);
|
|
@@ -4522,16 +4690,16 @@ function BashRenderer({ toolCall }) {
|
|
|
4522
4690
|
const rawFallbackOutput = result === null && typeof resultStr === "string" && resultStr.trim().length > 0 ? resultStr : null;
|
|
4523
4691
|
const output = structuredOutput !== null ? structuredOutput : errorMessage ?? rawFallbackOutput ?? (normalizedName === "BgBash" ? "" : null);
|
|
4524
4692
|
const hasFailure = toolCall.status === "error" || timedOut || exitCode !== null && exitCode !== 0;
|
|
4525
|
-
return /* @__PURE__ */
|
|
4526
|
-
(description || cwd) && /* @__PURE__ */
|
|
4527
|
-
description ? /* @__PURE__ */
|
|
4528
|
-
cwd ? /* @__PURE__ */
|
|
4693
|
+
return /* @__PURE__ */ jsxs11("div", { className: "space-y-3", children: [
|
|
4694
|
+
(description || cwd) && /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
4695
|
+
description ? /* @__PURE__ */ jsx15("span", { children: description }) : null,
|
|
4696
|
+
cwd ? /* @__PURE__ */ jsx15("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: cwd }) : null
|
|
4529
4697
|
] }),
|
|
4530
|
-
/* @__PURE__ */
|
|
4531
|
-
/* @__PURE__ */
|
|
4532
|
-
/* @__PURE__ */
|
|
4698
|
+
/* @__PURE__ */ jsxs11("div", { className: "overflow-hidden rounded-lg border border-border bg-card", children: [
|
|
4699
|
+
/* @__PURE__ */ jsx15("div", { className: "border-b border-border px-3 py-2 text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u547D\u4EE4" }),
|
|
4700
|
+
/* @__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"}` }) })
|
|
4533
4701
|
] }),
|
|
4534
|
-
/* @__PURE__ */
|
|
4702
|
+
/* @__PURE__ */ jsxs11(
|
|
4535
4703
|
"div",
|
|
4536
4704
|
{
|
|
4537
4705
|
className: cn(
|
|
@@ -4539,26 +4707,26 @@ function BashRenderer({ toolCall }) {
|
|
|
4539
4707
|
hasFailure ? "border-red-500/50" : "border-border"
|
|
4540
4708
|
),
|
|
4541
4709
|
children: [
|
|
4542
|
-
/* @__PURE__ */
|
|
4543
|
-
/* @__PURE__ */
|
|
4544
|
-
/* @__PURE__ */
|
|
4545
|
-
taskId ? /* @__PURE__ */
|
|
4546
|
-
exitCode !== null ? /* @__PURE__ */
|
|
4547
|
-
timedOut ? /* @__PURE__ */
|
|
4548
|
-
truncated ? /* @__PURE__ */
|
|
4549
|
-
normalizedName === "BgBash" && !taskId ? /* @__PURE__ */
|
|
4710
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center justify-between gap-2 border-b border-border px-3 py-2", children: [
|
|
4711
|
+
/* @__PURE__ */ jsx15("div", { className: "text-[10px] uppercase tracking-[0.16em] text-muted-foreground", children: "\u8F93\u51FA" }),
|
|
4712
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
4713
|
+
taskId ? /* @__PURE__ */ jsx15(MetaPill, { label: `\u4EFB\u52A1 ${taskId}` }) : null,
|
|
4714
|
+
exitCode !== null ? /* @__PURE__ */ jsx15(MetaPill, { label: `\u9000\u51FA\u7801 ${exitCode}` }) : null,
|
|
4715
|
+
timedOut ? /* @__PURE__ */ jsx15(MetaPill, { label: "\u5DF2\u8D85\u65F6" }) : null,
|
|
4716
|
+
truncated ? /* @__PURE__ */ jsx15(MetaPill, { label: "\u8F93\u51FA\u5DF2\u622A\u65AD" }) : null,
|
|
4717
|
+
normalizedName === "BgBash" && !taskId ? /* @__PURE__ */ jsx15(MetaPill, { label: "\u540E\u53F0\u4EFB\u52A1" }) : null
|
|
4550
4718
|
] })
|
|
4551
4719
|
] }),
|
|
4552
|
-
/* @__PURE__ */
|
|
4720
|
+
/* @__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" }) })
|
|
4553
4721
|
]
|
|
4554
4722
|
}
|
|
4555
4723
|
),
|
|
4556
|
-
cwdResetNote ? /* @__PURE__ */
|
|
4724
|
+
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
|
|
4557
4725
|
] });
|
|
4558
4726
|
}
|
|
4559
4727
|
|
|
4560
4728
|
// src/react/components/chat/tool-renderers/FileEditRenderer.tsx
|
|
4561
|
-
import { jsx as
|
|
4729
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4562
4730
|
var MAX_DIFF_LINES = 200;
|
|
4563
4731
|
function computeDiff(oldText, newText) {
|
|
4564
4732
|
const oldLines = oldText.split("\n");
|
|
@@ -4635,6 +4803,26 @@ function buildWritePreview(content) {
|
|
|
4635
4803
|
newLine: index + 1
|
|
4636
4804
|
}));
|
|
4637
4805
|
}
|
|
4806
|
+
function buildEditPreview(args) {
|
|
4807
|
+
const edits = Array.isArray(args?.edits) ? args.edits : null;
|
|
4808
|
+
if (edits) {
|
|
4809
|
+
return edits.flatMap((rawEdit, index) => {
|
|
4810
|
+
if (!isPlainObject(rawEdit)) {
|
|
4811
|
+
return [];
|
|
4812
|
+
}
|
|
4813
|
+
const oldText = getStringValue(rawEdit, "old_text") ?? "";
|
|
4814
|
+
const newText = getStringValue(rawEdit, "new_text") ?? "";
|
|
4815
|
+
const lines = computeDiff(oldText, newText);
|
|
4816
|
+
return index === 0 ? lines : [
|
|
4817
|
+
{ type: "unchanged", value: "", oldLine: null, newLine: null },
|
|
4818
|
+
...lines
|
|
4819
|
+
];
|
|
4820
|
+
});
|
|
4821
|
+
}
|
|
4822
|
+
const oldString = getStringValue(args, "old_string") ?? "";
|
|
4823
|
+
const newString = getStringValue(args, "new_string") ?? "";
|
|
4824
|
+
return computeDiff(oldString, newString);
|
|
4825
|
+
}
|
|
4638
4826
|
function extractChecksum(result) {
|
|
4639
4827
|
const text = typeof result === "string" ? result : null;
|
|
4640
4828
|
const match = text?.match(/\[checksum:\s*([^\]]+)\]/);
|
|
@@ -4648,26 +4836,26 @@ function FileEditRenderer({ toolCall }) {
|
|
|
4648
4836
|
const fileName = getFileName(filePath);
|
|
4649
4837
|
const errorMessage = extractErrorMessage(toolCall.result);
|
|
4650
4838
|
const checksum = extractChecksum(toolCall.result);
|
|
4839
|
+
const description = getStringValue(args, "description");
|
|
4651
4840
|
const writeContent = getStringValue(args, "content") ?? "";
|
|
4652
|
-
const
|
|
4653
|
-
const newString = getStringValue(args, "new_string") ?? "";
|
|
4654
|
-
const diffLines = normalizedName === "Write" ? buildWritePreview(writeContent) : computeDiff(oldString, newString);
|
|
4841
|
+
const diffLines = normalizedName === "Write" ? buildWritePreview(writeContent) : buildEditPreview(args);
|
|
4655
4842
|
const resultStr = typeof toolCall.result === "string" ? toolCall.result : null;
|
|
4656
4843
|
const summaryText = resultStr?.trim() && !errorMessage ? resultStr.trim() : null;
|
|
4657
|
-
return /* @__PURE__ */
|
|
4658
|
-
/* @__PURE__ */
|
|
4659
|
-
/* @__PURE__ */
|
|
4660
|
-
/* @__PURE__ */
|
|
4661
|
-
/* @__PURE__ */
|
|
4844
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-3", children: [
|
|
4845
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-start justify-between gap-3", children: [
|
|
4846
|
+
/* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
|
|
4847
|
+
/* @__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" }),
|
|
4848
|
+
/* @__PURE__ */ jsx16("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: filePath ?? fileName })
|
|
4662
4849
|
] }),
|
|
4663
|
-
checksum ? /* @__PURE__ */
|
|
4850
|
+
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
|
|
4664
4851
|
] }),
|
|
4665
|
-
|
|
4666
|
-
/* @__PURE__ */
|
|
4667
|
-
|
|
4668
|
-
/* @__PURE__ */
|
|
4852
|
+
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,
|
|
4853
|
+
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,
|
|
4854
|
+
/* @__PURE__ */ jsxs12("div", { className: "overflow-hidden rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20", children: [
|
|
4855
|
+
/* @__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" }),
|
|
4856
|
+
/* @__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) => {
|
|
4669
4857
|
const prefix = line.type === "added" ? "+ " : line.type === "removed" ? "- " : " ";
|
|
4670
|
-
return /* @__PURE__ */
|
|
4858
|
+
return /* @__PURE__ */ jsxs12(
|
|
4671
4859
|
"div",
|
|
4672
4860
|
{
|
|
4673
4861
|
className: cn(
|
|
@@ -4677,9 +4865,9 @@ function FileEditRenderer({ toolCall }) {
|
|
|
4677
4865
|
line.type === "unchanged" && "text-[hsl(var(--foreground))]"
|
|
4678
4866
|
),
|
|
4679
4867
|
children: [
|
|
4680
|
-
/* @__PURE__ */
|
|
4681
|
-
/* @__PURE__ */
|
|
4682
|
-
/* @__PURE__ */
|
|
4868
|
+
/* @__PURE__ */ jsx16("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.oldLine ?? "" }),
|
|
4869
|
+
/* @__PURE__ */ jsx16("span", { className: "select-none py-0.5 text-right text-[10px] text-[hsl(var(--muted-foreground))]", children: line.newLine ?? "" }),
|
|
4870
|
+
/* @__PURE__ */ jsxs12("span", { className: "min-w-0 whitespace-pre-wrap break-words py-0.5", children: [
|
|
4683
4871
|
prefix,
|
|
4684
4872
|
line.value
|
|
4685
4873
|
] })
|
|
@@ -4687,24 +4875,24 @@ function FileEditRenderer({ toolCall }) {
|
|
|
4687
4875
|
},
|
|
4688
4876
|
`${line.type}-${line.oldLine}-${line.newLine}-${index}`
|
|
4689
4877
|
);
|
|
4690
|
-
}) : /* @__PURE__ */
|
|
4878
|
+
}) : /* @__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" }) })
|
|
4691
4879
|
] }),
|
|
4692
|
-
summaryText ? /* @__PURE__ */
|
|
4880
|
+
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
|
|
4693
4881
|
] });
|
|
4694
4882
|
}
|
|
4695
4883
|
|
|
4696
4884
|
// src/react/components/chat/tool-renderers/FileReadRenderer.tsx
|
|
4697
|
-
import { useState as
|
|
4885
|
+
import { useState as useState12 } from "react";
|
|
4698
4886
|
|
|
4699
4887
|
// src/react/components/chat/ImageLightbox.tsx
|
|
4700
4888
|
import { ChevronLeft, ChevronRight as ChevronRight2, Download as Download2, ExternalLink, Minus, Plus as Plus2, RotateCcw, X as X3 } from "lucide-react";
|
|
4701
|
-
import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef9, useState as
|
|
4889
|
+
import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
|
|
4702
4890
|
import { createPortal as createPortal3 } from "react-dom";
|
|
4703
|
-
import { Fragment as
|
|
4891
|
+
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4704
4892
|
function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
4705
|
-
const [currentIndex, setCurrentIndex] =
|
|
4706
|
-
const [scale, setScale] =
|
|
4707
|
-
const [translate, setTranslate] =
|
|
4893
|
+
const [currentIndex, setCurrentIndex] = useState11(initialIndex);
|
|
4894
|
+
const [scale, setScale] = useState11(1);
|
|
4895
|
+
const [translate, setTranslate] = useState11({ x: 0, y: 0 });
|
|
4708
4896
|
const dragging = useRef9(false);
|
|
4709
4897
|
const dragStart = useRef9({ x: 0, y: 0 });
|
|
4710
4898
|
const translateStart = useRef9({ x: 0, y: 0 });
|
|
@@ -4810,22 +4998,22 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
|
4810
4998
|
if (images.length === 0) {
|
|
4811
4999
|
return createPortal3(
|
|
4812
5000
|
// biome-ignore lint/a11y/useKeyWithClickEvents: ESC handler is registered via useEffect
|
|
4813
|
-
/* @__PURE__ */
|
|
5001
|
+
/* @__PURE__ */ jsxs13(
|
|
4814
5002
|
"div",
|
|
4815
5003
|
{
|
|
4816
5004
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80",
|
|
4817
5005
|
onClick: close,
|
|
4818
5006
|
children: [
|
|
4819
|
-
/* @__PURE__ */
|
|
5007
|
+
/* @__PURE__ */ jsx17(
|
|
4820
5008
|
"button",
|
|
4821
5009
|
{
|
|
4822
5010
|
type: "button",
|
|
4823
5011
|
onClick: close,
|
|
4824
5012
|
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",
|
|
4825
|
-
children: /* @__PURE__ */
|
|
5013
|
+
children: /* @__PURE__ */ jsx17(X3, { size: 20 })
|
|
4826
5014
|
}
|
|
4827
5015
|
),
|
|
4828
|
-
/* @__PURE__ */
|
|
5016
|
+
/* @__PURE__ */ jsx17("span", { className: "text-sm text-white/60", children: "\u52A0\u8F7D\u4E2D..." })
|
|
4829
5017
|
]
|
|
4830
5018
|
}
|
|
4831
5019
|
),
|
|
@@ -4836,46 +5024,46 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
|
4836
5024
|
const showNav = images.length > 1;
|
|
4837
5025
|
return createPortal3(
|
|
4838
5026
|
// biome-ignore lint/a11y/useKeyWithClickEvents: ESC handler is registered via useEffect
|
|
4839
|
-
/* @__PURE__ */
|
|
4840
|
-
/* @__PURE__ */
|
|
5027
|
+
/* @__PURE__ */ jsxs13("div", { className: "fixed inset-0 z-50 bg-black/80", onClick: handleAreaClick, children: [
|
|
5028
|
+
/* @__PURE__ */ jsxs13(
|
|
4841
5029
|
"div",
|
|
4842
5030
|
{
|
|
4843
5031
|
className: "absolute right-4 top-4 z-10 flex items-center gap-1.5",
|
|
4844
5032
|
onClick: (e) => e.stopPropagation(),
|
|
4845
5033
|
children: [
|
|
4846
|
-
/* @__PURE__ */
|
|
5034
|
+
/* @__PURE__ */ jsx17(
|
|
4847
5035
|
"button",
|
|
4848
5036
|
{
|
|
4849
5037
|
type: "button",
|
|
4850
5038
|
onClick: handleDownload,
|
|
4851
5039
|
title: "\u4E0B\u8F7D\u56FE\u7247",
|
|
4852
5040
|
className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
|
|
4853
|
-
children: /* @__PURE__ */
|
|
5041
|
+
children: /* @__PURE__ */ jsx17(Download2, { size: 18 })
|
|
4854
5042
|
}
|
|
4855
5043
|
),
|
|
4856
|
-
/* @__PURE__ */
|
|
5044
|
+
/* @__PURE__ */ jsx17(
|
|
4857
5045
|
"button",
|
|
4858
5046
|
{
|
|
4859
5047
|
type: "button",
|
|
4860
5048
|
onClick: handleOpenInNewTab,
|
|
4861
5049
|
title: "\u65B0\u6807\u7B7E\u9875\u6253\u5F00",
|
|
4862
5050
|
className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
|
|
4863
|
-
children: /* @__PURE__ */
|
|
5051
|
+
children: /* @__PURE__ */ jsx17(ExternalLink, { size: 18 })
|
|
4864
5052
|
}
|
|
4865
5053
|
),
|
|
4866
|
-
/* @__PURE__ */
|
|
5054
|
+
/* @__PURE__ */ jsx17(
|
|
4867
5055
|
"button",
|
|
4868
5056
|
{
|
|
4869
5057
|
type: "button",
|
|
4870
5058
|
onClick: close,
|
|
4871
5059
|
className: "rounded-full bg-black/50 p-2 text-white/80 transition-colors hover:bg-black/70 hover:text-white",
|
|
4872
|
-
children: /* @__PURE__ */
|
|
5060
|
+
children: /* @__PURE__ */ jsx17(X3, { size: 20 })
|
|
4873
5061
|
}
|
|
4874
5062
|
)
|
|
4875
5063
|
]
|
|
4876
5064
|
}
|
|
4877
5065
|
),
|
|
4878
|
-
showNav && currentIndex > 0 && /* @__PURE__ */
|
|
5066
|
+
showNav && currentIndex > 0 && /* @__PURE__ */ jsx17(
|
|
4879
5067
|
"button",
|
|
4880
5068
|
{
|
|
4881
5069
|
type: "button",
|
|
@@ -4884,10 +5072,10 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
|
4884
5072
|
goPrev();
|
|
4885
5073
|
},
|
|
4886
5074
|
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",
|
|
4887
|
-
children: /* @__PURE__ */
|
|
5075
|
+
children: /* @__PURE__ */ jsx17(ChevronLeft, { size: 24 })
|
|
4888
5076
|
}
|
|
4889
5077
|
),
|
|
4890
|
-
showNav && currentIndex < images.length - 1 && /* @__PURE__ */
|
|
5078
|
+
showNav && currentIndex < images.length - 1 && /* @__PURE__ */ jsx17(
|
|
4891
5079
|
"button",
|
|
4892
5080
|
{
|
|
4893
5081
|
type: "button",
|
|
@@ -4896,51 +5084,51 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
|
4896
5084
|
goNext();
|
|
4897
5085
|
},
|
|
4898
5086
|
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",
|
|
4899
|
-
children: /* @__PURE__ */
|
|
5087
|
+
children: /* @__PURE__ */ jsx17(ChevronRight2, { size: 24 })
|
|
4900
5088
|
}
|
|
4901
5089
|
),
|
|
4902
|
-
/* @__PURE__ */
|
|
4903
|
-
/* @__PURE__ */
|
|
5090
|
+
/* @__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: [
|
|
5091
|
+
/* @__PURE__ */ jsx17(
|
|
4904
5092
|
"button",
|
|
4905
5093
|
{
|
|
4906
5094
|
type: "button",
|
|
4907
5095
|
onClick: zoomOut,
|
|
4908
5096
|
className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
|
|
4909
|
-
children: /* @__PURE__ */
|
|
5097
|
+
children: /* @__PURE__ */ jsx17(Minus, { size: 16 })
|
|
4910
5098
|
}
|
|
4911
5099
|
),
|
|
4912
|
-
/* @__PURE__ */
|
|
5100
|
+
/* @__PURE__ */ jsxs13("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
|
|
4913
5101
|
Math.round(scale * 100),
|
|
4914
5102
|
"%"
|
|
4915
5103
|
] }),
|
|
4916
|
-
/* @__PURE__ */
|
|
5104
|
+
/* @__PURE__ */ jsx17(
|
|
4917
5105
|
"button",
|
|
4918
5106
|
{
|
|
4919
5107
|
type: "button",
|
|
4920
5108
|
onClick: zoomIn,
|
|
4921
5109
|
className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
|
|
4922
|
-
children: /* @__PURE__ */
|
|
5110
|
+
children: /* @__PURE__ */ jsx17(Plus2, { size: 16 })
|
|
4923
5111
|
}
|
|
4924
5112
|
),
|
|
4925
|
-
/* @__PURE__ */
|
|
5113
|
+
/* @__PURE__ */ jsx17(
|
|
4926
5114
|
"button",
|
|
4927
5115
|
{
|
|
4928
5116
|
type: "button",
|
|
4929
5117
|
onClick: reset,
|
|
4930
5118
|
className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
|
|
4931
|
-
children: /* @__PURE__ */
|
|
5119
|
+
children: /* @__PURE__ */ jsx17(RotateCcw, { size: 16 })
|
|
4932
5120
|
}
|
|
4933
5121
|
),
|
|
4934
|
-
showNav && /* @__PURE__ */
|
|
4935
|
-
/* @__PURE__ */
|
|
4936
|
-
/* @__PURE__ */
|
|
5122
|
+
showNav && /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
5123
|
+
/* @__PURE__ */ jsx17("div", { className: "mx-1 h-4 w-px bg-white/20" }),
|
|
5124
|
+
/* @__PURE__ */ jsxs13("span", { className: "min-w-[3rem] text-center text-xs text-white/80", children: [
|
|
4937
5125
|
currentIndex + 1,
|
|
4938
5126
|
" / ",
|
|
4939
5127
|
images.length
|
|
4940
5128
|
] })
|
|
4941
5129
|
] })
|
|
4942
5130
|
] }),
|
|
4943
|
-
/* @__PURE__ */
|
|
5131
|
+
/* @__PURE__ */ jsx17(
|
|
4944
5132
|
"div",
|
|
4945
5133
|
{
|
|
4946
5134
|
className: "flex h-full w-full items-center justify-center overflow-hidden p-12",
|
|
@@ -4951,7 +5139,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
|
4951
5139
|
onMouseUp: handleMouseUp,
|
|
4952
5140
|
onMouseLeave: handleMouseUp,
|
|
4953
5141
|
onDoubleClick: handleDoubleClick,
|
|
4954
|
-
children: /* @__PURE__ */
|
|
5142
|
+
children: /* @__PURE__ */ jsx17(
|
|
4955
5143
|
"img",
|
|
4956
5144
|
{
|
|
4957
5145
|
ref: imgRef,
|
|
@@ -4973,7 +5161,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
|
4973
5161
|
}
|
|
4974
5162
|
|
|
4975
5163
|
// src/react/components/chat/tool-renderers/FileReadRenderer.tsx
|
|
4976
|
-
import { jsx as
|
|
5164
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4977
5165
|
var NUMBERED_LINE_RE = /^(\s*\d+)\t([\s\S]*)$/;
|
|
4978
5166
|
function parseReadResult(result) {
|
|
4979
5167
|
if (!result) {
|
|
@@ -5017,11 +5205,12 @@ function formatLineRange(startLine, endLine) {
|
|
|
5017
5205
|
return startLine === endLine ? `\u7B2C ${startLine} \u884C` : `\u7B2C ${startLine}-${endLine} \u884C`;
|
|
5018
5206
|
}
|
|
5019
5207
|
function FileReadRenderer({ toolCall }) {
|
|
5020
|
-
const [lightboxIndex, setLightboxIndex] =
|
|
5208
|
+
const [lightboxIndex, setLightboxIndex] = useState12(null);
|
|
5021
5209
|
const argsValue = parseJsonValue(toolCall.arguments);
|
|
5022
5210
|
const args = isPlainObject(argsValue) ? argsValue : null;
|
|
5023
5211
|
const filePath = extractToolFilePath(toolCall);
|
|
5024
5212
|
const fileName = getFileName(filePath);
|
|
5213
|
+
const description = getStringValue(args, "description");
|
|
5025
5214
|
const resultText = getResultText(toolCall.result);
|
|
5026
5215
|
const imageUrls = getResultImageUrls(toolCall.result);
|
|
5027
5216
|
const isImageResult = imageUrls.length > 0;
|
|
@@ -5032,27 +5221,28 @@ function FileReadRenderer({ toolCall }) {
|
|
|
5032
5221
|
const resolvedStartLine = startLine ?? (lineCount > 0 ? fallbackStart : null);
|
|
5033
5222
|
const resolvedEndLine = endLine ?? (resolvedStartLine !== null && lineCount > 0 ? resolvedStartLine + lineCount - 1 : null);
|
|
5034
5223
|
const lineRange = formatLineRange(resolvedStartLine, resolvedEndLine);
|
|
5035
|
-
return /* @__PURE__ */
|
|
5036
|
-
/* @__PURE__ */
|
|
5037
|
-
/* @__PURE__ */
|
|
5038
|
-
/* @__PURE__ */
|
|
5039
|
-
filePath ? /* @__PURE__ */
|
|
5224
|
+
return /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
|
|
5225
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-start justify-between gap-3", children: [
|
|
5226
|
+
/* @__PURE__ */ jsxs14("div", { className: "min-w-0", children: [
|
|
5227
|
+
/* @__PURE__ */ jsx18("div", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: fileName }),
|
|
5228
|
+
filePath ? /* @__PURE__ */ jsx18("div", { className: "truncate text-[10px] text-[hsl(var(--muted-foreground))]", children: filePath }) : null
|
|
5040
5229
|
] }),
|
|
5041
|
-
/* @__PURE__ */
|
|
5042
|
-
lineRange ? /* @__PURE__ */
|
|
5043
|
-
checksum ? /* @__PURE__ */
|
|
5230
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex flex-wrap items-center justify-end gap-1.5", children: [
|
|
5231
|
+
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,
|
|
5232
|
+
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
|
|
5044
5233
|
] })
|
|
5045
5234
|
] }),
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5235
|
+
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,
|
|
5236
|
+
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,
|
|
5237
|
+
isImageResult ? /* @__PURE__ */ jsxs14("div", { className: "grid gap-2", children: [
|
|
5238
|
+
imageUrls.map((url, idx) => /* @__PURE__ */ jsx18(
|
|
5049
5239
|
"button",
|
|
5050
5240
|
{
|
|
5051
5241
|
type: "button",
|
|
5052
5242
|
onClick: () => setLightboxIndex(idx),
|
|
5053
5243
|
className: "cursor-zoom-in",
|
|
5054
5244
|
title: "\u67E5\u770B\u5927\u56FE",
|
|
5055
|
-
children: /* @__PURE__ */
|
|
5245
|
+
children: /* @__PURE__ */ jsx18(
|
|
5056
5246
|
"img",
|
|
5057
5247
|
{
|
|
5058
5248
|
src: url,
|
|
@@ -5063,7 +5253,7 @@ function FileReadRenderer({ toolCall }) {
|
|
|
5063
5253
|
},
|
|
5064
5254
|
url.slice(0, 64)
|
|
5065
5255
|
)),
|
|
5066
|
-
/* @__PURE__ */
|
|
5256
|
+
/* @__PURE__ */ jsx18(
|
|
5067
5257
|
ImageLightbox,
|
|
5068
5258
|
{
|
|
5069
5259
|
open: lightboxIndex != null,
|
|
@@ -5074,15 +5264,15 @@ function FileReadRenderer({ toolCall }) {
|
|
|
5074
5264
|
initialIndex: lightboxIndex ?? 0
|
|
5075
5265
|
}
|
|
5076
5266
|
),
|
|
5077
|
-
content ? /* @__PURE__ */
|
|
5078
|
-
] }) : !errorMessage ? /* @__PURE__ */
|
|
5079
|
-
note ? /* @__PURE__ */
|
|
5267
|
+
content ? /* @__PURE__ */ jsx18("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: content }) : null
|
|
5268
|
+
] }) : !errorMessage ? /* @__PURE__ */ jsx18(CodePreview, { content, filePath, className: "max-h-[360px]" }) : null,
|
|
5269
|
+
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
|
|
5080
5270
|
] });
|
|
5081
5271
|
}
|
|
5082
5272
|
|
|
5083
5273
|
// src/react/components/chat/tool-renderers/SearchRenderer.tsx
|
|
5084
|
-
import { ExternalLink as ExternalLink2, FileText as
|
|
5085
|
-
import { jsx as
|
|
5274
|
+
import { ExternalLink as ExternalLink2, FileText as FileText3, Folder as Folder2, Globe2 } from "lucide-react";
|
|
5275
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
5086
5276
|
function toRecordArray(value) {
|
|
5087
5277
|
return Array.isArray(value) ? value.filter(isPlainObject) : [];
|
|
5088
5278
|
}
|
|
@@ -5144,7 +5334,7 @@ function parseWebFetchResult(result) {
|
|
|
5144
5334
|
};
|
|
5145
5335
|
}
|
|
5146
5336
|
function renderEmptyState(label) {
|
|
5147
|
-
return /* @__PURE__ */
|
|
5337
|
+
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 });
|
|
5148
5338
|
}
|
|
5149
5339
|
function SearchRenderer({ toolCall }) {
|
|
5150
5340
|
const normalizedName = formatToolName(toolCall.name);
|
|
@@ -5153,26 +5343,26 @@ function SearchRenderer({ toolCall }) {
|
|
|
5153
5343
|
const resultStr = getResultText(toolCall.result);
|
|
5154
5344
|
const errorMessage = extractErrorMessage(resultStr);
|
|
5155
5345
|
if (errorMessage) {
|
|
5156
|
-
return /* @__PURE__ */
|
|
5346
|
+
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 });
|
|
5157
5347
|
}
|
|
5158
5348
|
if (normalizedName === "Ls" || normalizedName === "Glob") {
|
|
5159
5349
|
const items = parseDirectoryItems(resultStr);
|
|
5160
5350
|
const path = getStringValue(args, "path");
|
|
5161
|
-
return /* @__PURE__ */
|
|
5162
|
-
path ? /* @__PURE__ */
|
|
5351
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-3", children: [
|
|
5352
|
+
path ? /* @__PURE__ */ jsxs15("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
5163
5353
|
"\u76EE\u5F55\uFF1A",
|
|
5164
5354
|
path
|
|
5165
5355
|
] }) : null,
|
|
5166
|
-
items.length > 0 ? /* @__PURE__ */
|
|
5356
|
+
items.length > 0 ? /* @__PURE__ */ jsx19("div", { className: "grid gap-2", children: items.map((item) => /* @__PURE__ */ jsxs15(
|
|
5167
5357
|
"div",
|
|
5168
5358
|
{
|
|
5169
5359
|
className: "flex items-center justify-between gap-3 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-2",
|
|
5170
5360
|
children: [
|
|
5171
|
-
/* @__PURE__ */
|
|
5172
|
-
item.isDir ? /* @__PURE__ */
|
|
5173
|
-
/* @__PURE__ */
|
|
5361
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
5362
|
+
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))]" }),
|
|
5363
|
+
/* @__PURE__ */ jsx19("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: item.name })
|
|
5174
5364
|
] }),
|
|
5175
|
-
/* @__PURE__ */
|
|
5365
|
+
/* @__PURE__ */ jsx19("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: item.isDir ? "\u76EE\u5F55" : formatBytes(item.size) ?? "\u6587\u4EF6" })
|
|
5176
5366
|
]
|
|
5177
5367
|
},
|
|
5178
5368
|
`${item.name}-${item.size}-${item.isDir}`
|
|
@@ -5182,28 +5372,28 @@ function SearchRenderer({ toolCall }) {
|
|
|
5182
5372
|
if (normalizedName === "Grep") {
|
|
5183
5373
|
const { matches, searchPath } = parseGrepResult(resultStr);
|
|
5184
5374
|
const pattern = getStringValue(args, "pattern");
|
|
5185
|
-
return /* @__PURE__ */
|
|
5186
|
-
/* @__PURE__ */
|
|
5187
|
-
pattern ? /* @__PURE__ */
|
|
5188
|
-
searchPath ? /* @__PURE__ */
|
|
5375
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-3", children: [
|
|
5376
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
5377
|
+
pattern ? /* @__PURE__ */ jsx19("span", { className: "rounded-full bg-[hsl(var(--muted))] px-2 py-0.5 font-mono", children: pattern }) : null,
|
|
5378
|
+
searchPath ? /* @__PURE__ */ jsxs15("span", { children: [
|
|
5189
5379
|
"\u8303\u56F4\uFF1A",
|
|
5190
5380
|
searchPath
|
|
5191
5381
|
] }) : null
|
|
5192
5382
|
] }),
|
|
5193
|
-
matches.length > 0 ? /* @__PURE__ */
|
|
5383
|
+
matches.length > 0 ? /* @__PURE__ */ jsx19("div", { className: "grid gap-2", children: matches.map((match) => /* @__PURE__ */ jsxs15(
|
|
5194
5384
|
"div",
|
|
5195
5385
|
{
|
|
5196
5386
|
className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-2",
|
|
5197
5387
|
children: [
|
|
5198
|
-
/* @__PURE__ */
|
|
5199
|
-
/* @__PURE__ */
|
|
5200
|
-
match.lineNumber !== null ? /* @__PURE__ */
|
|
5388
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between gap-3", children: [
|
|
5389
|
+
/* @__PURE__ */ jsx19("span", { className: "truncate font-mono text-[11px] text-[hsl(var(--foreground))]", children: match.path }),
|
|
5390
|
+
match.lineNumber !== null ? /* @__PURE__ */ jsxs15("span", { className: "shrink-0 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
|
|
5201
5391
|
"\u7B2C ",
|
|
5202
5392
|
match.lineNumber,
|
|
5203
5393
|
" \u884C"
|
|
5204
5394
|
] }) : null
|
|
5205
5395
|
] }),
|
|
5206
|
-
/* @__PURE__ */
|
|
5396
|
+
/* @__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 }) })
|
|
5207
5397
|
]
|
|
5208
5398
|
},
|
|
5209
5399
|
`${match.path}-${match.lineNumber}-${match.line}`
|
|
@@ -5212,16 +5402,16 @@ function SearchRenderer({ toolCall }) {
|
|
|
5212
5402
|
}
|
|
5213
5403
|
const { results, summary } = normalizedName === "WebFetch" ? parseWebFetchResult(resultStr) : { results: parseWebResults(resultStr), summary: null };
|
|
5214
5404
|
const query = getStringValue(args, "query");
|
|
5215
|
-
return /* @__PURE__ */
|
|
5216
|
-
query ? /* @__PURE__ */
|
|
5405
|
+
return /* @__PURE__ */ jsxs15("div", { className: "space-y-3", children: [
|
|
5406
|
+
query ? /* @__PURE__ */ jsxs15("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
5217
5407
|
"\u67E5\u8BE2\uFF1A",
|
|
5218
5408
|
query
|
|
5219
5409
|
] }) : null,
|
|
5220
|
-
summary ? /* @__PURE__ */
|
|
5221
|
-
/* @__PURE__ */
|
|
5222
|
-
/* @__PURE__ */
|
|
5410
|
+
summary ? /* @__PURE__ */ jsxs15("div", { className: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-3", children: [
|
|
5411
|
+
/* @__PURE__ */ jsx19("div", { className: "mb-2 text-[10px] uppercase tracking-[0.16em] text-[hsl(var(--muted-foreground))]", children: "\u6458\u8981" }),
|
|
5412
|
+
/* @__PURE__ */ jsx19("p", { className: "whitespace-pre-wrap text-[11px] leading-5 text-[hsl(var(--foreground))]", children: summary })
|
|
5223
5413
|
] }) : null,
|
|
5224
|
-
results.length > 0 ? /* @__PURE__ */
|
|
5414
|
+
results.length > 0 ? /* @__PURE__ */ jsx19("div", { className: "grid gap-2", children: results.map((item, index) => /* @__PURE__ */ jsx19(
|
|
5225
5415
|
"a",
|
|
5226
5416
|
{
|
|
5227
5417
|
href: item.url ?? void 0,
|
|
@@ -5231,12 +5421,12 @@ function SearchRenderer({ toolCall }) {
|
|
|
5231
5421
|
"rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-3 transition-colors",
|
|
5232
5422
|
item.url && "hover:border-[hsl(var(--ring))] hover:bg-[hsl(var(--muted))]/35"
|
|
5233
5423
|
),
|
|
5234
|
-
children: /* @__PURE__ */
|
|
5235
|
-
/* @__PURE__ */
|
|
5236
|
-
/* @__PURE__ */
|
|
5237
|
-
/* @__PURE__ */
|
|
5238
|
-
/* @__PURE__ */
|
|
5239
|
-
item.url ? /* @__PURE__ */
|
|
5424
|
+
children: /* @__PURE__ */ jsxs15("div", { className: "flex items-start gap-3", children: [
|
|
5425
|
+
/* @__PURE__ */ jsx19(Globe2, { size: 15, className: "mt-0.5 shrink-0 text-blue-300" }),
|
|
5426
|
+
/* @__PURE__ */ jsxs15("div", { className: "min-w-0 flex-1", children: [
|
|
5427
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-start justify-between gap-3", children: [
|
|
5428
|
+
/* @__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" }),
|
|
5429
|
+
item.url ? /* @__PURE__ */ jsx19(
|
|
5240
5430
|
ExternalLink2,
|
|
5241
5431
|
{
|
|
5242
5432
|
size: 12,
|
|
@@ -5244,8 +5434,8 @@ function SearchRenderer({ toolCall }) {
|
|
|
5244
5434
|
}
|
|
5245
5435
|
) : null
|
|
5246
5436
|
] }),
|
|
5247
|
-
item.url ? /* @__PURE__ */
|
|
5248
|
-
item.description ? /* @__PURE__ */
|
|
5437
|
+
item.url ? /* @__PURE__ */ jsx19("div", { className: "mt-1 truncate font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.url }) : null,
|
|
5438
|
+
item.description ? /* @__PURE__ */ jsx19("p", { className: "mt-2 line-clamp-3 text-[11px] leading-5 text-[hsl(var(--muted-foreground))]", children: item.description }) : null
|
|
5249
5439
|
] })
|
|
5250
5440
|
] })
|
|
5251
5441
|
},
|
|
@@ -5272,7 +5462,7 @@ function getRenderer(toolName) {
|
|
|
5272
5462
|
}
|
|
5273
5463
|
|
|
5274
5464
|
// src/react/components/chat/ToolCallBlock.tsx
|
|
5275
|
-
import { Fragment as
|
|
5465
|
+
import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5276
5466
|
function FilePathLink({ filePath, sessionId }) {
|
|
5277
5467
|
const activeSessionId = useSessionStore((s) => s.activeSessionId);
|
|
5278
5468
|
const pushArtifact = useUiStore((s) => s.pushArtifact);
|
|
@@ -5290,14 +5480,14 @@ function FilePathLink({ filePath, sessionId }) {
|
|
|
5290
5480
|
} catch {
|
|
5291
5481
|
}
|
|
5292
5482
|
};
|
|
5293
|
-
return /* @__PURE__ */
|
|
5483
|
+
return /* @__PURE__ */ jsx20(
|
|
5294
5484
|
"button",
|
|
5295
5485
|
{
|
|
5296
5486
|
type: "button",
|
|
5297
5487
|
onClick: handleClick,
|
|
5298
5488
|
className: "flex min-w-0 items-center gap-1 text-blue-400 hover:text-blue-300 hover:underline cursor-pointer font-mono",
|
|
5299
5489
|
title: `\u9884\u89C8 ${filePath}`,
|
|
5300
|
-
children: /* @__PURE__ */
|
|
5490
|
+
children: /* @__PURE__ */ jsx20("span", { className: "truncate", children: fileName })
|
|
5301
5491
|
}
|
|
5302
5492
|
);
|
|
5303
5493
|
}
|
|
@@ -5313,7 +5503,7 @@ function ToolCallBlock({
|
|
|
5313
5503
|
reasoning,
|
|
5314
5504
|
customization
|
|
5315
5505
|
}) {
|
|
5316
|
-
const [expanded, setExpanded] =
|
|
5506
|
+
const [expanded, setExpanded] = useState13(false);
|
|
5317
5507
|
const activeSessionId = useSessionStore((s) => s.activeSessionId);
|
|
5318
5508
|
const sessions = useSessionStore((s) => s.sessions);
|
|
5319
5509
|
const pushArtifact = useUiStore((s) => s.pushArtifact);
|
|
@@ -5340,7 +5530,7 @@ function ToolCallBlock({
|
|
|
5340
5530
|
const canAnswer = toolCall.status === "awaiting_answer" && Boolean(resolvedOnAnswer) && Boolean(resolvedSessionStatus);
|
|
5341
5531
|
const shouldRenderQuestion = Boolean(askData) && (canAnswer || resolvedAnswered || toolCall.status === "done");
|
|
5342
5532
|
if (askData && shouldRenderQuestion) {
|
|
5343
|
-
const questionBlock = /* @__PURE__ */
|
|
5533
|
+
const questionBlock = /* @__PURE__ */ jsx20(
|
|
5344
5534
|
AskUserQuestionBlock,
|
|
5345
5535
|
{
|
|
5346
5536
|
data: askData,
|
|
@@ -5354,9 +5544,9 @@ function ToolCallBlock({
|
|
|
5354
5544
|
if (!reasoning) {
|
|
5355
5545
|
return questionBlock;
|
|
5356
5546
|
}
|
|
5357
|
-
return /* @__PURE__ */
|
|
5547
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
|
|
5358
5548
|
questionBlock,
|
|
5359
|
-
/* @__PURE__ */
|
|
5549
|
+
/* @__PURE__ */ jsx20("div", { className: "ml-4", children: /* @__PURE__ */ jsx20(ThinkingBadge, { reasoning, variant: "block" }) })
|
|
5360
5550
|
] });
|
|
5361
5551
|
}
|
|
5362
5552
|
}
|
|
@@ -5368,11 +5558,11 @@ function ToolCallBlock({
|
|
|
5368
5558
|
const borderWidthClass = level === 2 ? "border-l-[2px]" : "border-l-[3px]";
|
|
5369
5559
|
const indentClass = level === 2 ? "ml-3" : "ml-4";
|
|
5370
5560
|
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))]";
|
|
5371
|
-
const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */
|
|
5561
|
+
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 });
|
|
5372
5562
|
const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
|
|
5373
|
-
return /* @__PURE__ */
|
|
5374
|
-
/* @__PURE__ */
|
|
5375
|
-
/* @__PURE__ */
|
|
5563
|
+
return /* @__PURE__ */ jsxs16("div", { className: cn(indentClass, "text-xs", customization?.classNames?.toolCall), children: [
|
|
5564
|
+
/* @__PURE__ */ jsxs16("div", { className: cn(borderWidthClass, toneClass, "flex items-center gap-2 px-3 py-2"), children: [
|
|
5565
|
+
/* @__PURE__ */ jsxs16(
|
|
5376
5566
|
"button",
|
|
5377
5567
|
{
|
|
5378
5568
|
type: "button",
|
|
@@ -5380,7 +5570,7 @@ function ToolCallBlock({
|
|
|
5380
5570
|
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",
|
|
5381
5571
|
"aria-expanded": expanded,
|
|
5382
5572
|
children: [
|
|
5383
|
-
/* @__PURE__ */
|
|
5573
|
+
/* @__PURE__ */ jsx20(
|
|
5384
5574
|
ChevronRight3,
|
|
5385
5575
|
{
|
|
5386
5576
|
size: 11,
|
|
@@ -5390,19 +5580,19 @@ function ToolCallBlock({
|
|
|
5390
5580
|
)
|
|
5391
5581
|
}
|
|
5392
5582
|
),
|
|
5393
|
-
/* @__PURE__ */
|
|
5583
|
+
/* @__PURE__ */ jsxs16("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
|
|
5394
5584
|
statusIcon,
|
|
5395
|
-
/* @__PURE__ */
|
|
5585
|
+
/* @__PURE__ */ jsx20("span", { children: getToolStatusLabel(toolCall.status) })
|
|
5396
5586
|
] }),
|
|
5397
|
-
/* @__PURE__ */
|
|
5587
|
+
/* @__PURE__ */ jsxs16("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: [
|
|
5398
5588
|
displayName,
|
|
5399
5589
|
toolCall.status === "error" ? "\uFF08\u5F85\u91CD\u8BD5\uFF09" : ""
|
|
5400
5590
|
] })
|
|
5401
5591
|
]
|
|
5402
5592
|
}
|
|
5403
5593
|
),
|
|
5404
|
-
filePath && /* @__PURE__ */
|
|
5405
|
-
loadedSkillName ? /* @__PURE__ */
|
|
5594
|
+
filePath && /* @__PURE__ */ jsx20("span", { className: "flex min-w-0 max-w-[50%] text-[hsl(var(--muted-foreground))]", children: /* @__PURE__ */ jsx20(FilePathLink, { filePath, sessionId: resolvedSessionId }) }),
|
|
5595
|
+
loadedSkillName ? /* @__PURE__ */ jsx20(
|
|
5406
5596
|
"span",
|
|
5407
5597
|
{
|
|
5408
5598
|
className: "min-w-0 max-w-[50%] shrink truncate text-[hsl(var(--foreground))]",
|
|
@@ -5410,9 +5600,9 @@ function ToolCallBlock({
|
|
|
5410
5600
|
children: loadedSkillName
|
|
5411
5601
|
}
|
|
5412
5602
|
) : null,
|
|
5413
|
-
reasoning ? /* @__PURE__ */
|
|
5414
|
-
typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */
|
|
5415
|
-
uiMeta?.target === "preview" && resolvedSessionId && !isInternalStatusPreview(uiMeta) ? /* @__PURE__ */
|
|
5603
|
+
reasoning ? /* @__PURE__ */ jsx20(ThinkingBadge, { reasoning, variant: "block" }) : null,
|
|
5604
|
+
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) }),
|
|
5605
|
+
uiMeta?.target === "preview" && resolvedSessionId && !isInternalStatusPreview(uiMeta) ? /* @__PURE__ */ jsxs16(
|
|
5416
5606
|
"button",
|
|
5417
5607
|
{
|
|
5418
5608
|
type: "button",
|
|
@@ -5430,18 +5620,18 @@ function ToolCallBlock({
|
|
|
5430
5620
|
className: "inline-flex shrink-0 items-center gap-1 text-blue-400 hover:text-blue-300 hover:underline cursor-pointer",
|
|
5431
5621
|
title: `\u6253\u5F00 ${uiMeta.title ?? displayName}`,
|
|
5432
5622
|
children: [
|
|
5433
|
-
/* @__PURE__ */
|
|
5434
|
-
/* @__PURE__ */
|
|
5623
|
+
/* @__PURE__ */ jsx20(PanelRightOpen, { size: 11 }),
|
|
5624
|
+
/* @__PURE__ */ jsx20("span", { children: uiMeta.title ?? displayName })
|
|
5435
5625
|
]
|
|
5436
5626
|
}
|
|
5437
5627
|
) : null
|
|
5438
5628
|
] }),
|
|
5439
|
-
expanded && /* @__PURE__ */
|
|
5440
|
-
/* @__PURE__ */
|
|
5441
|
-
/* @__PURE__ */
|
|
5442
|
-
toolCall.result != null && /* @__PURE__ */
|
|
5443
|
-
/* @__PURE__ */
|
|
5444
|
-
/* @__PURE__ */
|
|
5629
|
+
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: [
|
|
5630
|
+
/* @__PURE__ */ jsx20("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
|
|
5631
|
+
/* @__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) }),
|
|
5632
|
+
toolCall.result != null && /* @__PURE__ */ jsxs16(Fragment5, { children: [
|
|
5633
|
+
/* @__PURE__ */ jsx20("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
|
|
5634
|
+
/* @__PURE__ */ jsx20(
|
|
5445
5635
|
"pre",
|
|
5446
5636
|
{
|
|
5447
5637
|
className: cn(
|
|
@@ -5517,7 +5707,7 @@ function buildAskUserPayload(argumentsJson) {
|
|
|
5517
5707
|
}
|
|
5518
5708
|
|
|
5519
5709
|
// src/react/components/chat/UserMessageBubble.tsx
|
|
5520
|
-
import { useState as
|
|
5710
|
+
import { useState as useState15 } from "react";
|
|
5521
5711
|
|
|
5522
5712
|
// src/react/lib/preview-dispatch.ts
|
|
5523
5713
|
var IMAGE_EXTS = [
|
|
@@ -5662,7 +5852,7 @@ import { Download as Download3, X as X5 } from "lucide-react";
|
|
|
5662
5852
|
import { useEffect as useEffect12 } from "react";
|
|
5663
5853
|
import { createPortal as createPortal4 } from "react-dom";
|
|
5664
5854
|
import { useQuery as useQuery6 } from "@tanstack/react-query";
|
|
5665
|
-
import { jsx as
|
|
5855
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5666
5856
|
function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
|
|
5667
5857
|
useEffect12(() => {
|
|
5668
5858
|
if (!open) return;
|
|
@@ -5690,7 +5880,7 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
|
|
|
5690
5880
|
staleTime: 6e4
|
|
5691
5881
|
});
|
|
5692
5882
|
if (!open) return null;
|
|
5693
|
-
const body = /* @__PURE__ */
|
|
5883
|
+
const body = /* @__PURE__ */ jsx21(
|
|
5694
5884
|
"div",
|
|
5695
5885
|
{
|
|
5696
5886
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4",
|
|
@@ -5701,17 +5891,17 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
|
|
|
5701
5891
|
role: "dialog",
|
|
5702
5892
|
"aria-modal": "true",
|
|
5703
5893
|
"aria-labelledby": "attachment-preview-title",
|
|
5704
|
-
children: /* @__PURE__ */
|
|
5894
|
+
children: /* @__PURE__ */ jsxs17(
|
|
5705
5895
|
"div",
|
|
5706
5896
|
{
|
|
5707
5897
|
className: "max-h-[90vh] w-full max-w-3xl overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--background))] shadow-2xl",
|
|
5708
5898
|
onClick: (e) => e.stopPropagation(),
|
|
5709
5899
|
onKeyDown: (e) => e.stopPropagation(),
|
|
5710
5900
|
children: [
|
|
5711
|
-
/* @__PURE__ */
|
|
5712
|
-
/* @__PURE__ */
|
|
5713
|
-
/* @__PURE__ */
|
|
5714
|
-
url && /* @__PURE__ */
|
|
5901
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
|
|
5902
|
+
/* @__PURE__ */ jsx21("h3", { id: "attachment-preview-title", className: "truncate text-sm font-semibold text-[hsl(var(--foreground))]", children: filename }),
|
|
5903
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1", children: [
|
|
5904
|
+
url && /* @__PURE__ */ jsx21(
|
|
5715
5905
|
"a",
|
|
5716
5906
|
{
|
|
5717
5907
|
href: url,
|
|
@@ -5720,22 +5910,22 @@ function AttachmentPreviewDialog({ open, onOpenChange, filename, url, mode }) {
|
|
|
5720
5910
|
rel: "noopener noreferrer",
|
|
5721
5911
|
title: "\u4E0B\u8F7D",
|
|
5722
5912
|
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))]",
|
|
5723
|
-
children: /* @__PURE__ */
|
|
5913
|
+
children: /* @__PURE__ */ jsx21(Download3, { size: 14 })
|
|
5724
5914
|
}
|
|
5725
5915
|
),
|
|
5726
|
-
/* @__PURE__ */
|
|
5916
|
+
/* @__PURE__ */ jsx21(
|
|
5727
5917
|
"button",
|
|
5728
5918
|
{
|
|
5729
5919
|
type: "button",
|
|
5730
5920
|
onClick: () => onOpenChange(false),
|
|
5731
5921
|
title: "\u5173\u95ED",
|
|
5732
5922
|
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))]",
|
|
5733
|
-
children: /* @__PURE__ */
|
|
5923
|
+
children: /* @__PURE__ */ jsx21(X5, { size: 14 })
|
|
5734
5924
|
}
|
|
5735
5925
|
)
|
|
5736
5926
|
] })
|
|
5737
5927
|
] }),
|
|
5738
|
-
/* @__PURE__ */
|
|
5928
|
+
/* @__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 }) })
|
|
5739
5929
|
]
|
|
5740
5930
|
}
|
|
5741
5931
|
)
|
|
@@ -5750,43 +5940,43 @@ function renderContent({
|
|
|
5750
5940
|
error
|
|
5751
5941
|
}) {
|
|
5752
5942
|
if (!url) {
|
|
5753
|
-
return /* @__PURE__ */
|
|
5943
|
+
return /* @__PURE__ */ jsx21("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u6B64\u9644\u4EF6\u6682\u65E0\u53EF\u7528\u9884\u89C8\u5730\u5740\u3002" });
|
|
5754
5944
|
}
|
|
5755
5945
|
if (mode === "default") {
|
|
5756
|
-
return /* @__PURE__ */
|
|
5946
|
+
return /* @__PURE__ */ jsxs17("p", { className: "text-[hsl(var(--muted-foreground))]", children: [
|
|
5757
5947
|
"\u6B64\u7C7B\u578B\u6682\u4E0D\u652F\u6301\u5185\u5D4C\u9884\u89C8\u3002\u8BF7\u70B9\u51FB\u53F3\u4E0A\u89D2",
|
|
5758
|
-
/* @__PURE__ */
|
|
5948
|
+
/* @__PURE__ */ jsx21("span", { className: "mx-1 font-medium text-[hsl(var(--foreground))]", children: "\u4E0B\u8F7D" }),
|
|
5759
5949
|
"\u6309\u94AE\u67E5\u770B\u3002"
|
|
5760
5950
|
] });
|
|
5761
5951
|
}
|
|
5762
5952
|
if (error) {
|
|
5763
|
-
return /* @__PURE__ */
|
|
5953
|
+
return /* @__PURE__ */ jsxs17("p", { className: "text-[hsl(var(--destructive))]", children: [
|
|
5764
5954
|
"\u52A0\u8F7D\u5931\u8D25\uFF1A",
|
|
5765
5955
|
String(error?.message ?? error)
|
|
5766
5956
|
] });
|
|
5767
5957
|
}
|
|
5768
5958
|
if (content == null) {
|
|
5769
|
-
return /* @__PURE__ */
|
|
5959
|
+
return /* @__PURE__ */ jsx21("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u52A0\u8F7D\u4E2D\u2026" });
|
|
5770
5960
|
}
|
|
5771
5961
|
if (mode === "markdown") {
|
|
5772
|
-
return /* @__PURE__ */
|
|
5962
|
+
return /* @__PURE__ */ jsx21(MarkdownContent, { className: "prose prose-sm prose-invert max-w-none", children: content });
|
|
5773
5963
|
}
|
|
5774
|
-
return /* @__PURE__ */
|
|
5964
|
+
return /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap font-mono text-xs leading-relaxed", children: content });
|
|
5775
5965
|
}
|
|
5776
5966
|
|
|
5777
5967
|
// src/react/components/chat/MessageContextPills.tsx
|
|
5778
5968
|
import { Bookmark } from "lucide-react";
|
|
5779
|
-
import { jsx as
|
|
5969
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5780
5970
|
function MessageContextPills({ contexts }) {
|
|
5781
5971
|
if (contexts.length === 0) return null;
|
|
5782
|
-
return /* @__PURE__ */
|
|
5972
|
+
return /* @__PURE__ */ jsx22("div", { className: "flex flex-wrap gap-1.5", children: contexts.map((ctx, index) => /* @__PURE__ */ jsxs18(
|
|
5783
5973
|
"div",
|
|
5784
5974
|
{
|
|
5785
5975
|
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)]",
|
|
5786
5976
|
title: ctx.content,
|
|
5787
5977
|
children: [
|
|
5788
|
-
/* @__PURE__ */
|
|
5789
|
-
/* @__PURE__ */
|
|
5978
|
+
/* @__PURE__ */ jsx22(Bookmark, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.65)]" }),
|
|
5979
|
+
/* @__PURE__ */ jsx22("span", { className: "max-w-56 truncate", children: ctx.label })
|
|
5790
5980
|
]
|
|
5791
5981
|
},
|
|
5792
5982
|
`${ctx.label}:${index}`
|
|
@@ -5794,8 +5984,8 @@ function MessageContextPills({ contexts }) {
|
|
|
5794
5984
|
}
|
|
5795
5985
|
|
|
5796
5986
|
// src/react/components/chat/MessageFileAttachmentList.tsx
|
|
5797
|
-
import { Archive as Archive2, File as File3, FileCode2 as FileCode22, FileText as
|
|
5798
|
-
import { Fragment as
|
|
5987
|
+
import { Archive as Archive2, File as File3, FileCode2 as FileCode22, FileText as FileText4, Film as Film2, Music as Music2 } from "lucide-react";
|
|
5988
|
+
import { Fragment as Fragment6, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5799
5989
|
function getFileIcon(fileName) {
|
|
5800
5990
|
const lowerName = fileName.toLowerCase();
|
|
5801
5991
|
if (/\.(zip|rar|7z|tar|gz|bz2|xz)$/.test(lowerName)) {
|
|
@@ -5811,7 +6001,7 @@ function getFileIcon(fileName) {
|
|
|
5811
6001
|
return Film2;
|
|
5812
6002
|
}
|
|
5813
6003
|
if (/\.(txt|pdf|doc|docx|rtf|odt)$/.test(lowerName)) {
|
|
5814
|
-
return
|
|
6004
|
+
return FileText4;
|
|
5815
6005
|
}
|
|
5816
6006
|
return File3;
|
|
5817
6007
|
}
|
|
@@ -5824,15 +6014,15 @@ function MessageFileAttachmentList({
|
|
|
5824
6014
|
return null;
|
|
5825
6015
|
}
|
|
5826
6016
|
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))]";
|
|
5827
|
-
return /* @__PURE__ */
|
|
6017
|
+
return /* @__PURE__ */ jsx23("div", { className: cn("flex flex-wrap gap-1.5", className), children: files.map((file) => {
|
|
5828
6018
|
const Icon = getFileIcon(file.name);
|
|
5829
6019
|
const key = `${file.name}-${file.data.slice(0, 32)}`;
|
|
5830
|
-
const content = /* @__PURE__ */
|
|
5831
|
-
/* @__PURE__ */
|
|
5832
|
-
/* @__PURE__ */
|
|
6020
|
+
const content = /* @__PURE__ */ jsxs19(Fragment6, { children: [
|
|
6021
|
+
/* @__PURE__ */ jsx23(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
|
|
6022
|
+
/* @__PURE__ */ jsx23("span", { className: "max-w-32 truncate", children: file.name })
|
|
5833
6023
|
] });
|
|
5834
6024
|
if (onPreview) {
|
|
5835
|
-
return /* @__PURE__ */
|
|
6025
|
+
return /* @__PURE__ */ jsx23(
|
|
5836
6026
|
"button",
|
|
5837
6027
|
{
|
|
5838
6028
|
type: "button",
|
|
@@ -5844,16 +6034,16 @@ function MessageFileAttachmentList({
|
|
|
5844
6034
|
key
|
|
5845
6035
|
);
|
|
5846
6036
|
}
|
|
5847
|
-
return /* @__PURE__ */
|
|
6037
|
+
return /* @__PURE__ */ jsx23("div", { className: pillClass, title: file.name, children: content }, key);
|
|
5848
6038
|
}) });
|
|
5849
6039
|
}
|
|
5850
6040
|
|
|
5851
6041
|
// src/react/components/chat/MessageActions.tsx
|
|
5852
6042
|
import { Check as Check2, Copy } from "lucide-react";
|
|
5853
|
-
import { useState as
|
|
5854
|
-
import { jsx as
|
|
6043
|
+
import { useState as useState14 } from "react";
|
|
6044
|
+
import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
5855
6045
|
function MessageActions({ content, className }) {
|
|
5856
|
-
const [copied, setCopied] =
|
|
6046
|
+
const [copied, setCopied] = useState14(false);
|
|
5857
6047
|
const handleCopy = async () => {
|
|
5858
6048
|
const ok = await copyToClipboard(content);
|
|
5859
6049
|
if (ok) {
|
|
@@ -5861,7 +6051,7 @@ function MessageActions({ content, className }) {
|
|
|
5861
6051
|
setTimeout(() => setCopied(false), 2e3);
|
|
5862
6052
|
}
|
|
5863
6053
|
};
|
|
5864
|
-
return /* @__PURE__ */
|
|
6054
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("flex items-center gap-1 mt-1.5", className), children: /* @__PURE__ */ jsxs20(
|
|
5865
6055
|
"button",
|
|
5866
6056
|
{
|
|
5867
6057
|
type: "button",
|
|
@@ -5871,16 +6061,16 @@ function MessageActions({ content, className }) {
|
|
|
5871
6061
|
copied ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--accent))]"
|
|
5872
6062
|
),
|
|
5873
6063
|
children: [
|
|
5874
|
-
copied ? /* @__PURE__ */
|
|
5875
|
-
/* @__PURE__ */
|
|
6064
|
+
copied ? /* @__PURE__ */ jsx24(Check2, { size: 12 }) : /* @__PURE__ */ jsx24(Copy, { size: 12 }),
|
|
6065
|
+
/* @__PURE__ */ jsx24("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
|
|
5876
6066
|
]
|
|
5877
6067
|
}
|
|
5878
6068
|
) });
|
|
5879
6069
|
}
|
|
5880
6070
|
|
|
5881
6071
|
// src/react/components/chat/TextAttachmentPills.tsx
|
|
5882
|
-
import { Archive as Archive3, File as File4, FileCode2 as FileCode23, FileText as
|
|
5883
|
-
import { Fragment as
|
|
6072
|
+
import { Archive as Archive3, File as File4, FileCode2 as FileCode23, FileText as FileText5, Film as Film3, Music as Music3, FileSpreadsheet, Image } from "lucide-react";
|
|
6073
|
+
import { Fragment as Fragment7, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5884
6074
|
function getFileIcon2(fileName) {
|
|
5885
6075
|
const lower2 = fileName.toLowerCase();
|
|
5886
6076
|
if (/\.(zip|rar|7z|tar|gz)$/.test(lower2)) return Archive3;
|
|
@@ -5889,21 +6079,21 @@ function getFileIcon2(fileName) {
|
|
|
5889
6079
|
if (/\.(mp4|mov|mkv|avi|webm)$/.test(lower2)) return Film3;
|
|
5890
6080
|
if (/\.(png|jpg|jpeg|gif|svg|webp|bmp)$/.test(lower2)) return Image;
|
|
5891
6081
|
if (/\.(xlsx?|csv)$/.test(lower2)) return FileSpreadsheet;
|
|
5892
|
-
if (/\.(txt|pdf|docx?|rtf|md)$/.test(lower2)) return
|
|
6082
|
+
if (/\.(txt|pdf|docx?|rtf|md)$/.test(lower2)) return FileText5;
|
|
5893
6083
|
return File4;
|
|
5894
6084
|
}
|
|
5895
6085
|
function TextAttachmentPills({ attachments, onPreview }) {
|
|
5896
6086
|
if (attachments.length === 0) return null;
|
|
5897
6087
|
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)]";
|
|
5898
|
-
return /* @__PURE__ */
|
|
6088
|
+
return /* @__PURE__ */ jsx25("div", { className: "flex flex-wrap gap-1.5", children: attachments.map((att, index) => {
|
|
5899
6089
|
const Icon = getFileIcon2(att.name);
|
|
5900
6090
|
const key = `${att.uploadedPath ?? att.name}:${att.name}:${index}`;
|
|
5901
|
-
const content = /* @__PURE__ */
|
|
5902
|
-
/* @__PURE__ */
|
|
5903
|
-
/* @__PURE__ */
|
|
6091
|
+
const content = /* @__PURE__ */ jsxs21(Fragment7, { children: [
|
|
6092
|
+
/* @__PURE__ */ jsx25(Icon, { size: 12, className: "shrink-0 text-[hsl(var(--primary)/0.6)]" }),
|
|
6093
|
+
/* @__PURE__ */ jsx25("span", { className: "max-w-40 truncate", children: att.name })
|
|
5904
6094
|
] });
|
|
5905
6095
|
if (onPreview) {
|
|
5906
|
-
return /* @__PURE__ */
|
|
6096
|
+
return /* @__PURE__ */ jsx25(
|
|
5907
6097
|
"button",
|
|
5908
6098
|
{
|
|
5909
6099
|
type: "button",
|
|
@@ -5915,7 +6105,7 @@ function TextAttachmentPills({ attachments, onPreview }) {
|
|
|
5915
6105
|
key
|
|
5916
6106
|
);
|
|
5917
6107
|
}
|
|
5918
|
-
return /* @__PURE__ */
|
|
6108
|
+
return /* @__PURE__ */ jsx25("div", { className: pillClass, title: att.name, children: content }, key);
|
|
5919
6109
|
}) });
|
|
5920
6110
|
}
|
|
5921
6111
|
|
|
@@ -5924,34 +6114,34 @@ import { RefreshCcw } from "lucide-react";
|
|
|
5924
6114
|
|
|
5925
6115
|
// src/react/components/chat/whatif-quote-context.tsx
|
|
5926
6116
|
import { createContext as createContext3, useContext as useContext3, useMemo as useMemo13 } from "react";
|
|
5927
|
-
import { jsx as
|
|
6117
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
5928
6118
|
var WhatIfQuoteContext = createContext3({});
|
|
5929
6119
|
function WhatIfQuoteProvider({
|
|
5930
6120
|
onJumpToStep,
|
|
5931
6121
|
children
|
|
5932
6122
|
}) {
|
|
5933
6123
|
const value = useMemo13(() => ({ onJumpToStep }), [onJumpToStep]);
|
|
5934
|
-
return /* @__PURE__ */
|
|
6124
|
+
return /* @__PURE__ */ jsx26(WhatIfQuoteContext.Provider, { value, children });
|
|
5935
6125
|
}
|
|
5936
6126
|
function useWhatIfQuoteContext() {
|
|
5937
6127
|
return useContext3(WhatIfQuoteContext);
|
|
5938
6128
|
}
|
|
5939
6129
|
|
|
5940
6130
|
// src/react/components/chat/WhatIfUserBubble.tsx
|
|
5941
|
-
import { jsx as
|
|
6131
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5942
6132
|
function WhatIfUserBubble({ parsed, onQuoteClick }) {
|
|
5943
6133
|
const { onJumpToStep } = useWhatIfQuoteContext();
|
|
5944
6134
|
const handleQuoteClick = onQuoteClick ?? onJumpToStep;
|
|
5945
6135
|
const { fromStep, quotes, userText } = parsed;
|
|
5946
|
-
return /* @__PURE__ */
|
|
5947
|
-
/* @__PURE__ */
|
|
5948
|
-
/* @__PURE__ */
|
|
5949
|
-
/* @__PURE__ */
|
|
6136
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col items-end gap-2", children: [
|
|
6137
|
+
/* @__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: [
|
|
6138
|
+
/* @__PURE__ */ jsx27(RefreshCcw, { size: 10 }),
|
|
6139
|
+
/* @__PURE__ */ jsx27("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
|
|
5950
6140
|
] }),
|
|
5951
|
-
quotes.length > 0 && /* @__PURE__ */
|
|
6141
|
+
quotes.length > 0 && /* @__PURE__ */ jsx27("div", { className: "flex flex-wrap justify-end gap-1.5", children: quotes.map((q, i) => {
|
|
5952
6142
|
const clickable = q.stepNumber != null && !!handleQuoteClick;
|
|
5953
6143
|
const label = q.stepNumber != null ? `\u6B65\u9AA4${q.stepNumber} \xB7 ${q.label}` : q.label;
|
|
5954
|
-
return /* @__PURE__ */
|
|
6144
|
+
return /* @__PURE__ */ jsxs22(
|
|
5955
6145
|
"button",
|
|
5956
6146
|
{
|
|
5957
6147
|
type: "button",
|
|
@@ -5960,14 +6150,14 @@ function WhatIfUserBubble({ parsed, onQuoteClick }) {
|
|
|
5960
6150
|
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))]",
|
|
5961
6151
|
title: clickable ? "\u8DF3\u8F6C\u5230\u5BF9\u5E94\u6B65\u9AA4\u5361\u7247" : void 0,
|
|
5962
6152
|
children: [
|
|
5963
|
-
/* @__PURE__ */
|
|
5964
|
-
/* @__PURE__ */
|
|
6153
|
+
/* @__PURE__ */ jsx27("span", { children: "\u21B3" }),
|
|
6154
|
+
/* @__PURE__ */ jsx27("span", { className: "max-w-[14rem] truncate", children: label })
|
|
5965
6155
|
]
|
|
5966
6156
|
},
|
|
5967
6157
|
`${q.stepNumber ?? "x"}-${i}`
|
|
5968
6158
|
);
|
|
5969
6159
|
}) }),
|
|
5970
|
-
userText && /* @__PURE__ */
|
|
6160
|
+
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(
|
|
5971
6161
|
MarkdownContent,
|
|
5972
6162
|
{
|
|
5973
6163
|
className: "prose prose-sm prose-invert max-w-none [&_li>p]:inline [&_p]:mb-3 [&_p:last-child]:mb-0",
|
|
@@ -5979,7 +6169,7 @@ function WhatIfUserBubble({ parsed, onQuoteClick }) {
|
|
|
5979
6169
|
}
|
|
5980
6170
|
|
|
5981
6171
|
// src/react/components/chat/UserMessageBubble.tsx
|
|
5982
|
-
import { jsx as
|
|
6172
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
5983
6173
|
function isUserMessage(message) {
|
|
5984
6174
|
return message.role === "user";
|
|
5985
6175
|
}
|
|
@@ -6007,9 +6197,9 @@ function UserMessageBubble({ message, className }) {
|
|
|
6007
6197
|
const trimmedClean = cleanText.trim();
|
|
6008
6198
|
const whatifParsed = trimmedClean && imageParts.length === 0 && fileParts.length === 0 && textAttachments.length === 0 ? parseWhatIfPrompt(cleanText) : null;
|
|
6009
6199
|
if (whatifParsed) {
|
|
6010
|
-
return /* @__PURE__ */
|
|
6011
|
-
/* @__PURE__ */
|
|
6012
|
-
whatifParsed.userText && /* @__PURE__ */
|
|
6200
|
+
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: [
|
|
6201
|
+
/* @__PURE__ */ jsx28(WhatIfUserBubble, { parsed: whatifParsed }),
|
|
6202
|
+
whatifParsed.userText && /* @__PURE__ */ jsx28(
|
|
6013
6203
|
MessageActions,
|
|
6014
6204
|
{
|
|
6015
6205
|
content: whatifParsed.userText,
|
|
@@ -6043,8 +6233,8 @@ function UserMessageBubble({ message, className }) {
|
|
|
6043
6233
|
alt: attachment.name || "\u7528\u6237\u4E0A\u4F20\u7684\u56FE\u7247"
|
|
6044
6234
|
}))
|
|
6045
6235
|
];
|
|
6046
|
-
const [lightboxIndex, setLightboxIndex] =
|
|
6047
|
-
const [preview, setPreview] =
|
|
6236
|
+
const [lightboxIndex, setLightboxIndex] = useState15(null);
|
|
6237
|
+
const [preview, setPreview] = useState15(null);
|
|
6048
6238
|
const handleTextAttachmentPreview = (attachment) => {
|
|
6049
6239
|
if (!activeSessionId) return;
|
|
6050
6240
|
const pathForUrl = attachment.uploadedPath ?? attachment.name;
|
|
@@ -6063,16 +6253,16 @@ function UserMessageBubble({ message, className }) {
|
|
|
6063
6253
|
const mode = kind === "text" ? lower2.endsWith(".md") ? "markdown" : "text" : "default";
|
|
6064
6254
|
setPreview({ filename: attachment.name, url, mode });
|
|
6065
6255
|
};
|
|
6066
|
-
return /* @__PURE__ */
|
|
6067
|
-
(imageParts.length > 0 || imageTextAttachments.length > 0) && /* @__PURE__ */
|
|
6068
|
-
imageParts.map((part, idx) => /* @__PURE__ */
|
|
6256
|
+
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: [
|
|
6257
|
+
(imageParts.length > 0 || imageTextAttachments.length > 0) && /* @__PURE__ */ jsxs23("div", { className: "grid gap-2", children: [
|
|
6258
|
+
imageParts.map((part, idx) => /* @__PURE__ */ jsx28(
|
|
6069
6259
|
"button",
|
|
6070
6260
|
{
|
|
6071
6261
|
type: "button",
|
|
6072
6262
|
onClick: () => setLightboxIndex(idx),
|
|
6073
6263
|
className: "cursor-zoom-in",
|
|
6074
6264
|
title: "\u67E5\u770B\u5927\u56FE",
|
|
6075
|
-
children: /* @__PURE__ */
|
|
6265
|
+
children: /* @__PURE__ */ jsx28(
|
|
6076
6266
|
"img",
|
|
6077
6267
|
{
|
|
6078
6268
|
src: part.image_url.url,
|
|
@@ -6083,14 +6273,14 @@ function UserMessageBubble({ message, className }) {
|
|
|
6083
6273
|
},
|
|
6084
6274
|
part.image_url.url
|
|
6085
6275
|
)),
|
|
6086
|
-
imageTextAttachments.map((attachment, idx) => /* @__PURE__ */
|
|
6276
|
+
imageTextAttachments.map((attachment, idx) => /* @__PURE__ */ jsx28(
|
|
6087
6277
|
"button",
|
|
6088
6278
|
{
|
|
6089
6279
|
type: "button",
|
|
6090
6280
|
onClick: () => setLightboxIndex(imageParts.length + idx),
|
|
6091
6281
|
className: "cursor-zoom-in",
|
|
6092
6282
|
title: "\u67E5\u770B\u5927\u56FE",
|
|
6093
|
-
children: /* @__PURE__ */
|
|
6283
|
+
children: /* @__PURE__ */ jsx28(
|
|
6094
6284
|
"img",
|
|
6095
6285
|
{
|
|
6096
6286
|
src: attachment.url,
|
|
@@ -6102,7 +6292,7 @@ function UserMessageBubble({ message, className }) {
|
|
|
6102
6292
|
`${attachment.uploadedPath}:${attachment.name}`
|
|
6103
6293
|
))
|
|
6104
6294
|
] }),
|
|
6105
|
-
lightboxImages.length > 0 && /* @__PURE__ */
|
|
6295
|
+
lightboxImages.length > 0 && /* @__PURE__ */ jsx28(
|
|
6106
6296
|
ImageLightbox,
|
|
6107
6297
|
{
|
|
6108
6298
|
open: lightboxIndex != null,
|
|
@@ -6113,15 +6303,15 @@ function UserMessageBubble({ message, className }) {
|
|
|
6113
6303
|
initialIndex: lightboxIndex ?? 0
|
|
6114
6304
|
}
|
|
6115
6305
|
),
|
|
6116
|
-
/* @__PURE__ */
|
|
6117
|
-
/* @__PURE__ */
|
|
6306
|
+
/* @__PURE__ */ jsx28(MessageFileAttachmentList, { files: fileParts }),
|
|
6307
|
+
/* @__PURE__ */ jsx28(
|
|
6118
6308
|
TextAttachmentPills,
|
|
6119
6309
|
{
|
|
6120
6310
|
attachments: nonImageTextAttachments,
|
|
6121
6311
|
onPreview: handleTextAttachmentPreview
|
|
6122
6312
|
}
|
|
6123
6313
|
),
|
|
6124
|
-
preview && /* @__PURE__ */
|
|
6314
|
+
preview && /* @__PURE__ */ jsx28(
|
|
6125
6315
|
AttachmentPreviewDialog,
|
|
6126
6316
|
{
|
|
6127
6317
|
open: preview != null,
|
|
@@ -6133,8 +6323,8 @@ function UserMessageBubble({ message, className }) {
|
|
|
6133
6323
|
mode: preview.mode
|
|
6134
6324
|
}
|
|
6135
6325
|
),
|
|
6136
|
-
/* @__PURE__ */
|
|
6137
|
-
trimmedClean && /* @__PURE__ */
|
|
6326
|
+
/* @__PURE__ */ jsx28(MessageContextPills, { contexts: textContexts }),
|
|
6327
|
+
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(
|
|
6138
6328
|
MarkdownContent,
|
|
6139
6329
|
{
|
|
6140
6330
|
className: "prose prose-sm prose-invert max-w-none [&_li>p]:inline [&_p]:mb-3 [&_p:last-child]:mb-0",
|
|
@@ -6142,7 +6332,7 @@ function UserMessageBubble({ message, className }) {
|
|
|
6142
6332
|
children: cleanText
|
|
6143
6333
|
}
|
|
6144
6334
|
) }),
|
|
6145
|
-
trimmedClean && /* @__PURE__ */
|
|
6335
|
+
trimmedClean && /* @__PURE__ */ jsx28(
|
|
6146
6336
|
MessageActions,
|
|
6147
6337
|
{
|
|
6148
6338
|
content: trimmedClean,
|
|
@@ -6157,14 +6347,14 @@ function ErrorMessageBlock({
|
|
|
6157
6347
|
}) {
|
|
6158
6348
|
const text = getTextContent(message.content);
|
|
6159
6349
|
const looksLikeModelUnavailable = /no source matches this model|404/i.test(text);
|
|
6160
|
-
return /* @__PURE__ */
|
|
6350
|
+
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: [
|
|
6161
6351
|
text,
|
|
6162
|
-
looksLikeModelUnavailable ? /* @__PURE__ */
|
|
6352
|
+
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
|
|
6163
6353
|
] }) });
|
|
6164
6354
|
}
|
|
6165
6355
|
|
|
6166
6356
|
// src/react/components/chat/AgentLoopBlock.tsx
|
|
6167
|
-
import { Fragment as
|
|
6357
|
+
import { Fragment as Fragment8, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
6168
6358
|
var EMPTY_MESSAGES2 = [];
|
|
6169
6359
|
var EMPTY_AGENT_LOOPS = {};
|
|
6170
6360
|
var COLLAPSED_SUMMARY_HIDDEN_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -6211,7 +6401,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6211
6401
|
() => visibleLoopToolCalls.some((childToolCall) => childToolCall.status === "awaiting_answer"),
|
|
6212
6402
|
[visibleLoopToolCalls]
|
|
6213
6403
|
);
|
|
6214
|
-
const [expanded, setExpanded] =
|
|
6404
|
+
const [expanded, setExpanded] = useState16(hasAwaitingAnswer);
|
|
6215
6405
|
const completedToolLabels = useMemo14(
|
|
6216
6406
|
() => visibleLoopToolCalls.flatMap((childToolCall) => {
|
|
6217
6407
|
const isCompleted = childToolCall.status === "done" || childToolCall.status !== "pending" && childToolCall.status !== "awaiting_answer" && childToolCall.status !== "error" && childToolCall.status !== "cancelled";
|
|
@@ -6257,7 +6447,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6257
6447
|
const description = safeParseDescription(toolCall.arguments);
|
|
6258
6448
|
const status = hasAwaitingAnswer || toolCall.status === "awaiting_answer" ? "awaiting_answer" : toolCall.status === "pending" || loopEntry?.info.status === "running" ? "running" : "done";
|
|
6259
6449
|
const cardStyles = getLoopCardStyles(status);
|
|
6260
|
-
return /* @__PURE__ */
|
|
6450
|
+
return /* @__PURE__ */ jsxs24(
|
|
6261
6451
|
"div",
|
|
6262
6452
|
{
|
|
6263
6453
|
className: cn(
|
|
@@ -6265,8 +6455,8 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6265
6455
|
cardStyles.borderClass
|
|
6266
6456
|
),
|
|
6267
6457
|
children: [
|
|
6268
|
-
status === "running" || status === "awaiting_answer" ? /* @__PURE__ */
|
|
6269
|
-
/* @__PURE__ */
|
|
6458
|
+
status === "running" || status === "awaiting_answer" ? /* @__PURE__ */ jsxs24(Fragment8, { children: [
|
|
6459
|
+
/* @__PURE__ */ jsxs24(
|
|
6270
6460
|
"div",
|
|
6271
6461
|
{
|
|
6272
6462
|
className: cn(
|
|
@@ -6274,24 +6464,24 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6274
6464
|
cardStyles.headerClass
|
|
6275
6465
|
),
|
|
6276
6466
|
children: [
|
|
6277
|
-
/* @__PURE__ */
|
|
6467
|
+
/* @__PURE__ */ jsx29(
|
|
6278
6468
|
"button",
|
|
6279
6469
|
{
|
|
6280
6470
|
type: "button",
|
|
6281
6471
|
onClick: toggleExpanded,
|
|
6282
6472
|
"aria-expanded": expanded,
|
|
6283
6473
|
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",
|
|
6284
|
-
children: /* @__PURE__ */
|
|
6285
|
-
status === "awaiting_answer" ? /* @__PURE__ */
|
|
6286
|
-
/* @__PURE__ */
|
|
6474
|
+
children: /* @__PURE__ */ jsxs24("span", { className: "min-w-0 flex items-center gap-2", children: [
|
|
6475
|
+
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" }),
|
|
6476
|
+
/* @__PURE__ */ jsxs24("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: [
|
|
6287
6477
|
description,
|
|
6288
6478
|
status === "awaiting_answer" ? " \u2014 \u7B49\u5F85\u56DE\u7B54" : ""
|
|
6289
6479
|
] })
|
|
6290
6480
|
] })
|
|
6291
6481
|
}
|
|
6292
6482
|
),
|
|
6293
|
-
reasoning ? /* @__PURE__ */
|
|
6294
|
-
/* @__PURE__ */
|
|
6483
|
+
reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning, variant: "block" }) : null,
|
|
6484
|
+
/* @__PURE__ */ jsx29(
|
|
6295
6485
|
Bot,
|
|
6296
6486
|
{
|
|
6297
6487
|
size: 13,
|
|
@@ -6299,14 +6489,14 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6299
6489
|
"aria-label": "\u5B50\u667A\u80FD\u4F53"
|
|
6300
6490
|
}
|
|
6301
6491
|
),
|
|
6302
|
-
/* @__PURE__ */
|
|
6492
|
+
/* @__PURE__ */ jsx29(
|
|
6303
6493
|
"button",
|
|
6304
6494
|
{
|
|
6305
6495
|
type: "button",
|
|
6306
6496
|
onClick: toggleExpanded,
|
|
6307
6497
|
"aria-expanded": expanded,
|
|
6308
6498
|
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",
|
|
6309
|
-
children: /* @__PURE__ */
|
|
6499
|
+
children: /* @__PURE__ */ jsx29(
|
|
6310
6500
|
ChevronRight4,
|
|
6311
6501
|
{
|
|
6312
6502
|
size: 14,
|
|
@@ -6321,7 +6511,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6321
6511
|
]
|
|
6322
6512
|
}
|
|
6323
6513
|
),
|
|
6324
|
-
!expanded ? /* @__PURE__ */
|
|
6514
|
+
!expanded ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-1 py-2", children: visibleLoopToolCalls.length > 0 ? visibleLoopToolCalls.map((childToolCall) => /* @__PURE__ */ jsx29(
|
|
6325
6515
|
ToolCallBlock,
|
|
6326
6516
|
{
|
|
6327
6517
|
toolCall: childToolCall,
|
|
@@ -6329,12 +6519,12 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6329
6519
|
level: 2
|
|
6330
6520
|
},
|
|
6331
6521
|
childToolCall.id
|
|
6332
|
-
)) : /* @__PURE__ */
|
|
6333
|
-
/* @__PURE__ */
|
|
6334
|
-
/* @__PURE__ */
|
|
6335
|
-
] }) }) : status === "awaiting_answer" ? /* @__PURE__ */
|
|
6336
|
-
] }) : /* @__PURE__ */
|
|
6337
|
-
/* @__PURE__ */
|
|
6522
|
+
)) : /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
6523
|
+
/* @__PURE__ */ jsx29(Loader24, { size: 12, className: "shrink-0 animate-spin text-blue-500" }),
|
|
6524
|
+
/* @__PURE__ */ jsx29("span", { children: "\u6B63\u5728\u542F\u52A8..." })
|
|
6525
|
+
] }) }) : 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
|
|
6526
|
+
] }) : /* @__PURE__ */ jsxs24(Fragment8, { children: [
|
|
6527
|
+
/* @__PURE__ */ jsxs24(
|
|
6338
6528
|
"div",
|
|
6339
6529
|
{
|
|
6340
6530
|
className: cn(
|
|
@@ -6342,21 +6532,21 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6342
6532
|
cardStyles.headerClass
|
|
6343
6533
|
),
|
|
6344
6534
|
children: [
|
|
6345
|
-
/* @__PURE__ */
|
|
6535
|
+
/* @__PURE__ */ jsx29(
|
|
6346
6536
|
"button",
|
|
6347
6537
|
{
|
|
6348
6538
|
type: "button",
|
|
6349
6539
|
onClick: toggleExpanded,
|
|
6350
6540
|
"aria-expanded": expanded,
|
|
6351
6541
|
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",
|
|
6352
|
-
children: /* @__PURE__ */
|
|
6353
|
-
/* @__PURE__ */
|
|
6354
|
-
/* @__PURE__ */
|
|
6542
|
+
children: /* @__PURE__ */ jsxs24("span", { className: "min-w-0 flex items-center gap-2", children: [
|
|
6543
|
+
/* @__PURE__ */ jsx29(Check3, { size: 14, className: "shrink-0 text-emerald-500" }),
|
|
6544
|
+
/* @__PURE__ */ jsx29("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: description })
|
|
6355
6545
|
] })
|
|
6356
6546
|
}
|
|
6357
6547
|
),
|
|
6358
|
-
reasoning ? /* @__PURE__ */
|
|
6359
|
-
/* @__PURE__ */
|
|
6548
|
+
reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning, variant: "block" }) : null,
|
|
6549
|
+
/* @__PURE__ */ jsx29(
|
|
6360
6550
|
Bot,
|
|
6361
6551
|
{
|
|
6362
6552
|
size: 13,
|
|
@@ -6364,14 +6554,14 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6364
6554
|
"aria-label": "\u5B50\u667A\u80FD\u4F53"
|
|
6365
6555
|
}
|
|
6366
6556
|
),
|
|
6367
|
-
/* @__PURE__ */
|
|
6557
|
+
/* @__PURE__ */ jsx29(
|
|
6368
6558
|
"button",
|
|
6369
6559
|
{
|
|
6370
6560
|
type: "button",
|
|
6371
6561
|
onClick: toggleExpanded,
|
|
6372
6562
|
"aria-expanded": expanded,
|
|
6373
6563
|
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",
|
|
6374
|
-
children: /* @__PURE__ */
|
|
6564
|
+
children: /* @__PURE__ */ jsx29(
|
|
6375
6565
|
ChevronRight4,
|
|
6376
6566
|
{
|
|
6377
6567
|
size: 14,
|
|
@@ -6386,9 +6576,9 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6386
6576
|
]
|
|
6387
6577
|
}
|
|
6388
6578
|
),
|
|
6389
|
-
!expanded ? /* @__PURE__ */
|
|
6390
|
-
/* @__PURE__ */
|
|
6391
|
-
(item) => item.kind === "file" ? /* @__PURE__ */
|
|
6579
|
+
!expanded ? /* @__PURE__ */ jsxs24(Fragment8, { children: [
|
|
6580
|
+
/* @__PURE__ */ jsx29("div", { className: "flex flex-wrap gap-1.5 px-4 py-2", children: completedToolLabels.length > 0 ? completedToolLabels.map(
|
|
6581
|
+
(item) => item.kind === "file" ? /* @__PURE__ */ jsxs24(
|
|
6392
6582
|
"span",
|
|
6393
6583
|
{
|
|
6394
6584
|
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",
|
|
@@ -6399,12 +6589,12 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6399
6589
|
},
|
|
6400
6590
|
title: item.label,
|
|
6401
6591
|
children: [
|
|
6402
|
-
/* @__PURE__ */
|
|
6403
|
-
/* @__PURE__ */
|
|
6592
|
+
/* @__PURE__ */ jsx29(FileText6, { size: 12, className: "shrink-0", "aria-hidden": "true" }),
|
|
6593
|
+
/* @__PURE__ */ jsx29("span", { className: "truncate", children: item.label })
|
|
6404
6594
|
]
|
|
6405
6595
|
},
|
|
6406
6596
|
item.key
|
|
6407
|
-
) : /* @__PURE__ */
|
|
6597
|
+
) : /* @__PURE__ */ jsx29(
|
|
6408
6598
|
"span",
|
|
6409
6599
|
{
|
|
6410
6600
|
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",
|
|
@@ -6417,12 +6607,12 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6417
6607
|
},
|
|
6418
6608
|
item.key
|
|
6419
6609
|
)
|
|
6420
|
-
) : /* @__PURE__ */
|
|
6421
|
-
inlineToolUiBlocks.length > 0 ? /* @__PURE__ */
|
|
6610
|
+
) : /* @__PURE__ */ jsx29("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5DE5\u5177\u8C03\u7528" }) }),
|
|
6611
|
+
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
|
|
6422
6612
|
] }) : null
|
|
6423
6613
|
] }),
|
|
6424
|
-
expanded && /* @__PURE__ */
|
|
6425
|
-
(message, index) => message.role === "assistant" ? /* @__PURE__ */
|
|
6614
|
+
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(
|
|
6615
|
+
(message, index) => message.role === "assistant" ? /* @__PURE__ */ jsx29(
|
|
6426
6616
|
ExpandedChildAssistantMessage,
|
|
6427
6617
|
{
|
|
6428
6618
|
message,
|
|
@@ -6430,13 +6620,13 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6430
6620
|
isStreaming: message.status === "streaming"
|
|
6431
6621
|
},
|
|
6432
6622
|
message.entry_id ?? `${message.timestamp ?? "child"}-${index}`
|
|
6433
|
-
) : message.role === "user" ? /* @__PURE__ */
|
|
6623
|
+
) : message.role === "user" ? /* @__PURE__ */ jsx29(
|
|
6434
6624
|
ExpandedChildUserMessage,
|
|
6435
6625
|
{
|
|
6436
6626
|
message
|
|
6437
6627
|
},
|
|
6438
6628
|
message.entry_id ?? `${message.timestamp ?? "user"}-${index}`
|
|
6439
|
-
) : message.role === "error" ? /* @__PURE__ */
|
|
6629
|
+
) : message.role === "error" ? /* @__PURE__ */ jsx29(
|
|
6440
6630
|
"div",
|
|
6441
6631
|
{
|
|
6442
6632
|
className: "border-l-[2px] border-l-red-500 px-3 py-2 text-[11px] text-red-200",
|
|
@@ -6444,16 +6634,16 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6444
6634
|
},
|
|
6445
6635
|
message.entry_id ?? `${message.timestamp ?? "error"}-${index}`
|
|
6446
6636
|
) : null
|
|
6447
|
-
) }) : status === "running" ? /* @__PURE__ */
|
|
6448
|
-
/* @__PURE__ */
|
|
6637
|
+
) }) : status === "running" ? /* @__PURE__ */ jsxs24("div", { className: "px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
6638
|
+
/* @__PURE__ */ jsx29(Loader24, { size: 12, className: "mr-1.5 inline animate-spin" }),
|
|
6449
6639
|
"\u6B63\u5728\u542F\u52A8..."
|
|
6450
|
-
] }) : toolCall.result ? /* @__PURE__ */
|
|
6640
|
+
] }) : 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 })
|
|
6451
6641
|
]
|
|
6452
6642
|
}
|
|
6453
6643
|
);
|
|
6454
6644
|
}
|
|
6455
6645
|
function ExpandedChildUserMessage({ message }) {
|
|
6456
|
-
return /* @__PURE__ */
|
|
6646
|
+
return /* @__PURE__ */ jsx29("div", { className: "pl-8", children: /* @__PURE__ */ jsx29(UserMessageBubble, { message }) });
|
|
6457
6647
|
}
|
|
6458
6648
|
function ExpandedChildAssistantMessage({
|
|
6459
6649
|
message,
|
|
@@ -6466,12 +6656,12 @@ function ExpandedChildAssistantMessage({
|
|
|
6466
6656
|
const firstToolCallId = toolCalls[0]?.id;
|
|
6467
6657
|
const toolReasoning = !isStreaming && !text && hasToolCalls ? message.reasoning : void 0;
|
|
6468
6658
|
const standaloneReasoning = !isStreaming && !text && !hasToolCalls ? message.reasoning : void 0;
|
|
6469
|
-
return /* @__PURE__ */
|
|
6470
|
-
message.reasoning && isStreaming && /* @__PURE__ */
|
|
6471
|
-
/* @__PURE__ */
|
|
6472
|
-
/* @__PURE__ */
|
|
6659
|
+
return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-2", children: [
|
|
6660
|
+
message.reasoning && isStreaming && /* @__PURE__ */ jsxs24(Reasoning, { isStreaming, children: [
|
|
6661
|
+
/* @__PURE__ */ jsx29(ReasoningTrigger, {}),
|
|
6662
|
+
/* @__PURE__ */ jsx29(ReasoningContent, { children: message.reasoning })
|
|
6473
6663
|
] }),
|
|
6474
|
-
text ? /* @__PURE__ */
|
|
6664
|
+
text ? /* @__PURE__ */ jsx29(
|
|
6475
6665
|
ChildText,
|
|
6476
6666
|
{
|
|
6477
6667
|
text,
|
|
@@ -6480,10 +6670,10 @@ function ExpandedChildAssistantMessage({
|
|
|
6480
6670
|
reasoning: !isStreaming ? message.reasoning : void 0
|
|
6481
6671
|
}
|
|
6482
6672
|
) : null,
|
|
6483
|
-
!text && isStreaming && /* @__PURE__ */
|
|
6484
|
-
standaloneReasoning ? /* @__PURE__ */
|
|
6485
|
-
hasToolCalls && /* @__PURE__ */
|
|
6486
|
-
(toolCall, index) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */
|
|
6673
|
+
!text && isStreaming && /* @__PURE__ */ jsx29("span", { className: "pl-8 text-[12px] text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
|
|
6674
|
+
standaloneReasoning ? /* @__PURE__ */ jsx29("div", { className: "pl-8", children: /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning: standaloneReasoning, variant: "block" }) }) : null,
|
|
6675
|
+
hasToolCalls && /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2", children: toolCalls.map(
|
|
6676
|
+
(toolCall, index) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx29(
|
|
6487
6677
|
AgentLoopBlock,
|
|
6488
6678
|
{
|
|
6489
6679
|
toolCall,
|
|
@@ -6491,7 +6681,7 @@ function ExpandedChildAssistantMessage({
|
|
|
6491
6681
|
reasoning: toolCall.id === firstToolCallId ? toolReasoning : void 0
|
|
6492
6682
|
},
|
|
6493
6683
|
toolCall.id
|
|
6494
|
-
) : /* @__PURE__ */
|
|
6684
|
+
) : /* @__PURE__ */ jsx29(
|
|
6495
6685
|
ToolCallBlock,
|
|
6496
6686
|
{
|
|
6497
6687
|
toolCall,
|
|
@@ -6503,8 +6693,8 @@ function ExpandedChildAssistantMessage({
|
|
|
6503
6693
|
toolCall.id
|
|
6504
6694
|
)
|
|
6505
6695
|
) }),
|
|
6506
|
-
message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */
|
|
6507
|
-
(block, index) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */
|
|
6696
|
+
message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2", children: message.blocks.map(
|
|
6697
|
+
(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
|
|
6508
6698
|
) }) : null
|
|
6509
6699
|
] });
|
|
6510
6700
|
}
|
|
@@ -6514,8 +6704,8 @@ function ChildText({
|
|
|
6514
6704
|
sessionId,
|
|
6515
6705
|
reasoning
|
|
6516
6706
|
}) {
|
|
6517
|
-
return /* @__PURE__ */
|
|
6518
|
-
/* @__PURE__ */
|
|
6707
|
+
return /* @__PURE__ */ jsxs24("div", { className: "pl-8 text-[12px] leading-6 text-[hsl(var(--foreground))]", children: [
|
|
6708
|
+
/* @__PURE__ */ jsx29(
|
|
6519
6709
|
MarkdownContent,
|
|
6520
6710
|
{
|
|
6521
6711
|
mode: "streaming",
|
|
@@ -6525,8 +6715,8 @@ function ChildText({
|
|
|
6525
6715
|
children: text
|
|
6526
6716
|
}
|
|
6527
6717
|
),
|
|
6528
|
-
isStreaming && /* @__PURE__ */
|
|
6529
|
-
reasoning ? /* @__PURE__ */
|
|
6718
|
+
isStreaming && /* @__PURE__ */ jsx29("span", { className: "ml-0.5 inline-block h-[1em] w-[3px] animate-pulse rounded-sm bg-current opacity-60" }),
|
|
6719
|
+
reasoning ? /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning }) : null
|
|
6530
6720
|
] });
|
|
6531
6721
|
}
|
|
6532
6722
|
function getLoopCardStyles(status) {
|
|
@@ -6566,7 +6756,7 @@ function getLoopCardStyles(status) {
|
|
|
6566
6756
|
}
|
|
6567
6757
|
|
|
6568
6758
|
// src/react/components/chat/AssistantTurnBlock.tsx
|
|
6569
|
-
import { jsx as
|
|
6759
|
+
import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
6570
6760
|
function defaultTurnDisplayMode({
|
|
6571
6761
|
forceExpanded,
|
|
6572
6762
|
hasActionableToolCall
|
|
@@ -6720,7 +6910,7 @@ function AssistantTurnBlock({
|
|
|
6720
6910
|
),
|
|
6721
6911
|
[allToolCalls]
|
|
6722
6912
|
);
|
|
6723
|
-
const [displayMode, setDisplayMode] =
|
|
6913
|
+
const [displayMode, setDisplayMode] = useState17(
|
|
6724
6914
|
defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall })
|
|
6725
6915
|
);
|
|
6726
6916
|
const wasStreamingRef = useRef10(isStreaming);
|
|
@@ -6741,7 +6931,7 @@ function AssistantTurnBlock({
|
|
|
6741
6931
|
const hasInterruptedState = messages.some((message) => message.status === "interrupted");
|
|
6742
6932
|
const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
|
|
6743
6933
|
const memoryRefs = Array.isArray(messages[0]?.memory_refs) ? messages[0].memory_refs : [];
|
|
6744
|
-
return /* @__PURE__ */
|
|
6934
|
+
return /* @__PURE__ */ jsxs25(
|
|
6745
6935
|
"div",
|
|
6746
6936
|
{
|
|
6747
6937
|
className: cn(
|
|
@@ -6750,17 +6940,17 @@ function AssistantTurnBlock({
|
|
|
6750
6940
|
customization?.classNames?.assistantTurn
|
|
6751
6941
|
),
|
|
6752
6942
|
children: [
|
|
6753
|
-
memoryRefs.length > 0 && /* @__PURE__ */
|
|
6754
|
-
hasInterruptedState && /* @__PURE__ */
|
|
6755
|
-
!isStreaming && /* @__PURE__ */
|
|
6943
|
+
memoryRefs.length > 0 && /* @__PURE__ */ jsx30(MemoryRefsHint, { refs: memoryRefs }),
|
|
6944
|
+
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" }),
|
|
6945
|
+
!isStreaming && /* @__PURE__ */ jsx30("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs25(
|
|
6756
6946
|
"button",
|
|
6757
6947
|
{
|
|
6758
6948
|
type: "button",
|
|
6759
6949
|
onClick: () => setDisplayMode(displayMode === "detail" ? "compact" : "detail"),
|
|
6760
6950
|
className: "inline-flex shrink-0 items-center gap-1 text-xs text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
|
|
6761
6951
|
children: [
|
|
6762
|
-
/* @__PURE__ */
|
|
6763
|
-
/* @__PURE__ */
|
|
6952
|
+
/* @__PURE__ */ jsx30("span", { children: effectiveMode === "detail" ? "\u7CBE\u7B80" : "\u8BE6\u7EC6" }),
|
|
6953
|
+
/* @__PURE__ */ jsx30(
|
|
6764
6954
|
ChevronRight5,
|
|
6765
6955
|
{
|
|
6766
6956
|
size: 18,
|
|
@@ -6770,7 +6960,7 @@ function AssistantTurnBlock({
|
|
|
6770
6960
|
]
|
|
6771
6961
|
}
|
|
6772
6962
|
) }),
|
|
6773
|
-
effectiveMode === "detail" ? /* @__PURE__ */
|
|
6963
|
+
effectiveMode === "detail" ? /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-3", children: /* @__PURE__ */ jsx30(
|
|
6774
6964
|
AssistantMessages,
|
|
6775
6965
|
{
|
|
6776
6966
|
messages,
|
|
@@ -6783,15 +6973,15 @@ function AssistantTurnBlock({
|
|
|
6783
6973
|
showToolDetails: true,
|
|
6784
6974
|
customization
|
|
6785
6975
|
}
|
|
6786
|
-
) }) : /* @__PURE__ */
|
|
6787
|
-
resourceBlocks.length > 0 ? /* @__PURE__ */
|
|
6788
|
-
finalMessage ? /* @__PURE__ */
|
|
6976
|
+
) }) : /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-4", children: [
|
|
6977
|
+
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,
|
|
6978
|
+
finalMessage ? /* @__PURE__ */ jsx30(
|
|
6789
6979
|
"div",
|
|
6790
6980
|
{
|
|
6791
6981
|
className: cn(
|
|
6792
6982
|
resourceBlocks.length > 0 && "border-t border-[hsl(var(--border))] pt-4"
|
|
6793
6983
|
),
|
|
6794
|
-
children: /* @__PURE__ */
|
|
6984
|
+
children: /* @__PURE__ */ jsx30(
|
|
6795
6985
|
AssistantMessageContent,
|
|
6796
6986
|
{
|
|
6797
6987
|
message: finalMessage,
|
|
@@ -6802,7 +6992,7 @@ function AssistantTurnBlock({
|
|
|
6802
6992
|
}
|
|
6803
6993
|
)
|
|
6804
6994
|
}
|
|
6805
|
-
) : isStreaming ? /* @__PURE__ */
|
|
6995
|
+
) : isStreaming ? /* @__PURE__ */ jsx30("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }) : null
|
|
6806
6996
|
] }) })
|
|
6807
6997
|
]
|
|
6808
6998
|
}
|
|
@@ -6832,16 +7022,16 @@ function AssistantMessages({
|
|
|
6832
7022
|
const toolRenderItems = groupDetailedToolCalls(toolCalls);
|
|
6833
7023
|
const toolReasoning = hasReasoning && !hasText && !hasAttachments && hasToolCalls && !isStreamingLastMessage ? reasoning : void 0;
|
|
6834
7024
|
const contentReasoning = hasReasoning && !isStreamingLastMessage && (hasText || hasAttachments || !hasToolCalls) ? reasoning : void 0;
|
|
6835
|
-
return /* @__PURE__ */
|
|
7025
|
+
return /* @__PURE__ */ jsxs25(
|
|
6836
7026
|
"div",
|
|
6837
7027
|
{
|
|
6838
7028
|
className: "flex flex-col gap-3",
|
|
6839
7029
|
children: [
|
|
6840
|
-
hasReasoning && isStreamingLastMessage && /* @__PURE__ */
|
|
6841
|
-
/* @__PURE__ */
|
|
6842
|
-
/* @__PURE__ */
|
|
7030
|
+
hasReasoning && isStreamingLastMessage && /* @__PURE__ */ jsxs25(Reasoning, { isStreaming: isStreamingLastMessage, children: [
|
|
7031
|
+
/* @__PURE__ */ jsx30(ReasoningTrigger, {}),
|
|
7032
|
+
/* @__PURE__ */ jsx30(ReasoningContent, { children: reasoning })
|
|
6843
7033
|
] }),
|
|
6844
|
-
/* @__PURE__ */
|
|
7034
|
+
/* @__PURE__ */ jsx30(
|
|
6845
7035
|
AssistantMessageContent,
|
|
6846
7036
|
{
|
|
6847
7037
|
message,
|
|
@@ -6851,9 +7041,9 @@ function AssistantMessages({
|
|
|
6851
7041
|
className: customization?.classNames?.assistantText
|
|
6852
7042
|
}
|
|
6853
7043
|
),
|
|
6854
|
-
hasToolCalls && showToolDetails && /* @__PURE__ */
|
|
7044
|
+
hasToolCalls && showToolDetails && /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-2", children: toolRenderItems.map((item) => {
|
|
6855
7045
|
if (item.kind === "read_group" || item.kind === "load_skill_group") {
|
|
6856
|
-
return /* @__PURE__ */
|
|
7046
|
+
return /* @__PURE__ */ jsx30(
|
|
6857
7047
|
CompactToolGroupBlock,
|
|
6858
7048
|
{
|
|
6859
7049
|
toolCalls: item.toolCalls,
|
|
@@ -6871,7 +7061,7 @@ function AssistantMessages({
|
|
|
6871
7061
|
);
|
|
6872
7062
|
}
|
|
6873
7063
|
const { toolCall } = item;
|
|
6874
|
-
return formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */
|
|
7064
|
+
return formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx30(
|
|
6875
7065
|
AgentLoopBlock,
|
|
6876
7066
|
{
|
|
6877
7067
|
toolCall,
|
|
@@ -6879,7 +7069,7 @@ function AssistantMessages({
|
|
|
6879
7069
|
reasoning: toolCall.id === firstToolCallId ? toolReasoning : void 0
|
|
6880
7070
|
},
|
|
6881
7071
|
toolCall.id
|
|
6882
|
-
) : customization?.components?.ToolCall ? /* @__PURE__ */
|
|
7072
|
+
) : customization?.components?.ToolCall ? /* @__PURE__ */ jsx30(
|
|
6883
7073
|
customization.components.ToolCall,
|
|
6884
7074
|
{
|
|
6885
7075
|
toolCall,
|
|
@@ -6894,7 +7084,7 @@ function AssistantMessages({
|
|
|
6894
7084
|
customization
|
|
6895
7085
|
},
|
|
6896
7086
|
toolCall.id
|
|
6897
|
-
) : /* @__PURE__ */
|
|
7087
|
+
) : /* @__PURE__ */ jsx30(
|
|
6898
7088
|
ToolCallBlock,
|
|
6899
7089
|
{
|
|
6900
7090
|
toolCall,
|
|
@@ -6911,8 +7101,8 @@ function AssistantMessages({
|
|
|
6911
7101
|
toolCall.id
|
|
6912
7102
|
);
|
|
6913
7103
|
}) }),
|
|
6914
|
-
showToolDetails && message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */
|
|
6915
|
-
(block, blockIndex) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? /* @__PURE__ */
|
|
7104
|
+
showToolDetails && message.blocks?.some((block) => block.type === "tool_ui") ? /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-2", children: message.blocks.map(
|
|
7105
|
+
(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
|
|
6916
7106
|
) }) : null
|
|
6917
7107
|
]
|
|
6918
7108
|
},
|
|
@@ -6947,7 +7137,7 @@ function CompactToolGroupBlock({
|
|
|
6947
7137
|
level,
|
|
6948
7138
|
customization
|
|
6949
7139
|
}) {
|
|
6950
|
-
const [expanded, setExpanded] =
|
|
7140
|
+
const [expanded, setExpanded] = useState17(false);
|
|
6951
7141
|
const indentClass = level === 2 ? "ml-3" : "ml-4";
|
|
6952
7142
|
const hasError = toolCalls.some(
|
|
6953
7143
|
(tc) => tc.status === "error" || tc.status === "cancelled"
|
|
@@ -6962,12 +7152,12 @@ function CompactToolGroupBlock({
|
|
|
6962
7152
|
});
|
|
6963
7153
|
const tags = kind === "read_group" ? fileNames : toolCalls.map(getLoadedSkillName);
|
|
6964
7154
|
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";
|
|
6965
|
-
return /* @__PURE__ */
|
|
6966
|
-
/* @__PURE__ */
|
|
7155
|
+
return /* @__PURE__ */ jsxs25("div", { className: cn(indentClass, "text-xs"), children: [
|
|
7156
|
+
/* @__PURE__ */ jsxs25("div", { className: cn(
|
|
6967
7157
|
"flex items-center gap-2 border-l-[3px] px-3 py-2",
|
|
6968
7158
|
hasError ? "border-l-[hsl(var(--destructive))]" : "border-l-[hsl(var(--primary))]"
|
|
6969
7159
|
), children: [
|
|
6970
|
-
/* @__PURE__ */
|
|
7160
|
+
/* @__PURE__ */ jsxs25(
|
|
6971
7161
|
"button",
|
|
6972
7162
|
{
|
|
6973
7163
|
type: "button",
|
|
@@ -6975,7 +7165,7 @@ function CompactToolGroupBlock({
|
|
|
6975
7165
|
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",
|
|
6976
7166
|
"aria-expanded": expanded,
|
|
6977
7167
|
children: [
|
|
6978
|
-
/* @__PURE__ */
|
|
7168
|
+
/* @__PURE__ */ jsx30(
|
|
6979
7169
|
ChevronRight5,
|
|
6980
7170
|
{
|
|
6981
7171
|
size: 11,
|
|
@@ -6985,18 +7175,18 @@ function CompactToolGroupBlock({
|
|
|
6985
7175
|
)
|
|
6986
7176
|
}
|
|
6987
7177
|
),
|
|
6988
|
-
hasError ? /* @__PURE__ */
|
|
6989
|
-
/* @__PURE__ */
|
|
6990
|
-
/* @__PURE__ */
|
|
6991
|
-
] }) : /* @__PURE__ */
|
|
6992
|
-
/* @__PURE__ */
|
|
6993
|
-
/* @__PURE__ */
|
|
7178
|
+
hasError ? /* @__PURE__ */ jsxs25("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--destructive))]", children: [
|
|
7179
|
+
/* @__PURE__ */ jsx30(AlertCircle, { size: 11 }),
|
|
7180
|
+
/* @__PURE__ */ jsx30("span", { children: "\u5931\u8D25" })
|
|
7181
|
+
] }) : /* @__PURE__ */ jsxs25("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--primary))]", children: [
|
|
7182
|
+
/* @__PURE__ */ jsx30(Check4, { size: 11 }),
|
|
7183
|
+
/* @__PURE__ */ jsx30("span", { children: "\u5B8C\u6210" })
|
|
6994
7184
|
] }),
|
|
6995
|
-
/* @__PURE__ */
|
|
7185
|
+
/* @__PURE__ */ jsx30("span", { className: "min-w-0 shrink-0 font-medium text-[hsl(var(--foreground))]", children: title })
|
|
6996
7186
|
]
|
|
6997
7187
|
}
|
|
6998
7188
|
),
|
|
6999
|
-
/* @__PURE__ */
|
|
7189
|
+
/* @__PURE__ */ jsx30("div", { className: "flex min-w-0 flex-1 flex-wrap gap-1.5", children: tags.map((tag, index) => /* @__PURE__ */ jsx30(
|
|
7000
7190
|
"span",
|
|
7001
7191
|
{
|
|
7002
7192
|
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))]",
|
|
@@ -7005,12 +7195,12 @@ function CompactToolGroupBlock({
|
|
|
7005
7195
|
},
|
|
7006
7196
|
`${tag}-${index}`
|
|
7007
7197
|
)) }),
|
|
7008
|
-
reasoning ? /* @__PURE__ */
|
|
7009
|
-
totalDurationMs > 0 ? /* @__PURE__ */
|
|
7198
|
+
reasoning ? /* @__PURE__ */ jsx30(ThinkingBadge, { reasoning, variant: "block" }) : null,
|
|
7199
|
+
totalDurationMs > 0 ? /* @__PURE__ */ jsx30("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration2(totalDurationMs) }) : null
|
|
7010
7200
|
] }),
|
|
7011
|
-
expanded ? /* @__PURE__ */
|
|
7201
|
+
expanded ? /* @__PURE__ */ jsx30("div", { className: "mt-1 flex flex-col gap-1", children: toolCalls.map((toolCall) => {
|
|
7012
7202
|
const CustomToolCall = customization?.components?.ToolCall;
|
|
7013
|
-
return CustomToolCall ? /* @__PURE__ */
|
|
7203
|
+
return CustomToolCall ? /* @__PURE__ */ jsx30(
|
|
7014
7204
|
CustomToolCall,
|
|
7015
7205
|
{
|
|
7016
7206
|
toolCall,
|
|
@@ -7024,7 +7214,7 @@ function CompactToolGroupBlock({
|
|
|
7024
7214
|
customization
|
|
7025
7215
|
},
|
|
7026
7216
|
toolCall.id
|
|
7027
|
-
) : /* @__PURE__ */
|
|
7217
|
+
) : /* @__PURE__ */ jsx30(
|
|
7028
7218
|
ToolCallBlock,
|
|
7029
7219
|
{
|
|
7030
7220
|
toolCall,
|
|
@@ -7055,8 +7245,8 @@ function AssistantMessageContent({
|
|
|
7055
7245
|
if (!text && imageParts.length === 0 && fileParts.length === 0 && !isStreaming && !reasoning) {
|
|
7056
7246
|
return null;
|
|
7057
7247
|
}
|
|
7058
|
-
return /* @__PURE__ */
|
|
7059
|
-
imageParts.length > 0 && /* @__PURE__ */
|
|
7248
|
+
return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-3", children: [
|
|
7249
|
+
imageParts.length > 0 && /* @__PURE__ */ jsx30("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx30(
|
|
7060
7250
|
"img",
|
|
7061
7251
|
{
|
|
7062
7252
|
src: part.image_url.url,
|
|
@@ -7065,8 +7255,8 @@ function AssistantMessageContent({
|
|
|
7065
7255
|
},
|
|
7066
7256
|
part.image_url.url
|
|
7067
7257
|
)) }),
|
|
7068
|
-
/* @__PURE__ */
|
|
7069
|
-
text ? /* @__PURE__ */
|
|
7258
|
+
/* @__PURE__ */ jsx30(MessageFileAttachmentList, { files: fileParts }),
|
|
7259
|
+
text ? /* @__PURE__ */ jsx30(
|
|
7070
7260
|
AssistantText,
|
|
7071
7261
|
{
|
|
7072
7262
|
text,
|
|
@@ -7076,8 +7266,8 @@ function AssistantMessageContent({
|
|
|
7076
7266
|
className
|
|
7077
7267
|
}
|
|
7078
7268
|
) : null,
|
|
7079
|
-
!text && isStreaming && /* @__PURE__ */
|
|
7080
|
-
!text && reasoning ? /* @__PURE__ */
|
|
7269
|
+
!text && isStreaming && /* @__PURE__ */ jsx30("span", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
|
|
7270
|
+
!text && reasoning ? /* @__PURE__ */ jsx30(ThinkingBadge, { reasoning, variant: "block" }) : null
|
|
7081
7271
|
] });
|
|
7082
7272
|
}
|
|
7083
7273
|
function AssistantText({
|
|
@@ -7097,8 +7287,8 @@ function AssistantText({
|
|
|
7097
7287
|
() => ({ sessionId, messageId, sendMessage }),
|
|
7098
7288
|
[sessionId, messageId, sendMessage]
|
|
7099
7289
|
);
|
|
7100
|
-
return /* @__PURE__ */
|
|
7101
|
-
/* @__PURE__ */
|
|
7290
|
+
return /* @__PURE__ */ jsxs25("div", { className: cn("text-[15px] leading-8 text-[hsl(var(--foreground))]", className), children: [
|
|
7291
|
+
/* @__PURE__ */ jsx30(CardContext.Provider, { value: cardCtx, children: /* @__PURE__ */ jsx30(
|
|
7102
7292
|
MarkdownContent,
|
|
7103
7293
|
{
|
|
7104
7294
|
mode: "streaming",
|
|
@@ -7108,30 +7298,30 @@ function AssistantText({
|
|
|
7108
7298
|
children: text
|
|
7109
7299
|
}
|
|
7110
7300
|
) }),
|
|
7111
|
-
reasoning ? /* @__PURE__ */
|
|
7301
|
+
reasoning ? /* @__PURE__ */ jsx30(ThinkingBadge, { reasoning }) : null
|
|
7112
7302
|
] });
|
|
7113
7303
|
}
|
|
7114
7304
|
function MemoryRefsHint({ refs: rawRefs }) {
|
|
7115
7305
|
const refs = Array.isArray(rawRefs) ? rawRefs : [];
|
|
7116
|
-
const [expanded, setExpanded] =
|
|
7306
|
+
const [expanded, setExpanded] = useState17(false);
|
|
7117
7307
|
const hasSkill = refs.some((r3) => r3.skill_name);
|
|
7118
7308
|
const label = hasSkill ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
|
|
7119
|
-
return /* @__PURE__ */
|
|
7120
|
-
/* @__PURE__ */
|
|
7309
|
+
return /* @__PURE__ */ jsxs25("div", { className: "ml-4", children: [
|
|
7310
|
+
/* @__PURE__ */ jsxs25(
|
|
7121
7311
|
"button",
|
|
7122
7312
|
{
|
|
7123
7313
|
type: "button",
|
|
7124
7314
|
onClick: () => setExpanded(!expanded),
|
|
7125
7315
|
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)]",
|
|
7126
7316
|
children: [
|
|
7127
|
-
/* @__PURE__ */
|
|
7128
|
-
/* @__PURE__ */
|
|
7317
|
+
/* @__PURE__ */ jsx30(BookOpen, { size: 12 }),
|
|
7318
|
+
/* @__PURE__ */ jsxs25("span", { children: [
|
|
7129
7319
|
label,
|
|
7130
7320
|
"\uFF08",
|
|
7131
7321
|
refs.length,
|
|
7132
7322
|
"\uFF09"
|
|
7133
7323
|
] }),
|
|
7134
|
-
/* @__PURE__ */
|
|
7324
|
+
/* @__PURE__ */ jsx30(
|
|
7135
7325
|
ChevronRight5,
|
|
7136
7326
|
{
|
|
7137
7327
|
size: 10,
|
|
@@ -7141,13 +7331,13 @@ function MemoryRefsHint({ refs: rawRefs }) {
|
|
|
7141
7331
|
]
|
|
7142
7332
|
}
|
|
7143
7333
|
),
|
|
7144
|
-
expanded && /* @__PURE__ */
|
|
7145
|
-
refs.map((ref) => /* @__PURE__ */
|
|
7146
|
-
/* @__PURE__ */
|
|
7147
|
-
/* @__PURE__ */
|
|
7148
|
-
ref.skill_name && /* @__PURE__ */
|
|
7334
|
+
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: [
|
|
7335
|
+
refs.map((ref) => /* @__PURE__ */ jsxs25("div", { className: "flex items-start gap-2 text-[11px] text-[hsl(var(--foreground)/0.82)]", children: [
|
|
7336
|
+
/* @__PURE__ */ jsx30("span", { className: "mt-0.5 shrink-0 text-[hsl(var(--primary)/0.75)]", children: "\u2022" }),
|
|
7337
|
+
/* @__PURE__ */ jsx30("span", { className: "line-clamp-1", children: ref.content_preview }),
|
|
7338
|
+
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 })
|
|
7149
7339
|
] }, ref.id)),
|
|
7150
|
-
/* @__PURE__ */
|
|
7340
|
+
/* @__PURE__ */ jsx30(
|
|
7151
7341
|
"a",
|
|
7152
7342
|
{
|
|
7153
7343
|
href: MEMORIES_ROUTE,
|
|
@@ -7160,9 +7350,9 @@ function MemoryRefsHint({ refs: rawRefs }) {
|
|
|
7160
7350
|
}
|
|
7161
7351
|
|
|
7162
7352
|
// src/react/components/chat/CompactionCard.tsx
|
|
7163
|
-
import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight6, Loader2 as Loader25, Square as
|
|
7164
|
-
import { useState as
|
|
7165
|
-
import { jsx as
|
|
7353
|
+
import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight6, Loader2 as Loader25, Square as Square3, XCircle } from "lucide-react";
|
|
7354
|
+
import { useState as useState18 } from "react";
|
|
7355
|
+
import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
7166
7356
|
var PERCENT_FORMATTER = new Intl.NumberFormat("zh-CN", {
|
|
7167
7357
|
style: "percent",
|
|
7168
7358
|
maximumFractionDigits: 0
|
|
@@ -7221,7 +7411,7 @@ function CompactionCard({
|
|
|
7221
7411
|
...compaction,
|
|
7222
7412
|
status: status ?? "completed"
|
|
7223
7413
|
} : activeCompaction;
|
|
7224
|
-
const [expanded, setExpanded] =
|
|
7414
|
+
const [expanded, setExpanded] = useState18(false);
|
|
7225
7415
|
if (!source || !source.compaction_id) {
|
|
7226
7416
|
return null;
|
|
7227
7417
|
}
|
|
@@ -7232,9 +7422,9 @@ function CompactionCard({
|
|
|
7232
7422
|
const hasSummary = typeof source.summary_full === "string" && source.summary_full.trim().length > 0 && !isGenericArchiveSummary(source.summary_full);
|
|
7233
7423
|
const hasFailureReason = source.status === "failed" && Boolean(source.failure_reason);
|
|
7234
7424
|
const canExpand = source.status === "completed" && (hasSummary || archivedToolCalls.length > 0) || hasFailureReason;
|
|
7235
|
-
return /* @__PURE__ */
|
|
7236
|
-
/* @__PURE__ */
|
|
7237
|
-
/* @__PURE__ */
|
|
7425
|
+
return /* @__PURE__ */ jsxs26("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
7426
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between gap-2", children: [
|
|
7427
|
+
/* @__PURE__ */ jsxs26(
|
|
7238
7428
|
"button",
|
|
7239
7429
|
{
|
|
7240
7430
|
type: "button",
|
|
@@ -7245,21 +7435,21 @@ function CompactionCard({
|
|
|
7245
7435
|
),
|
|
7246
7436
|
"aria-expanded": expanded,
|
|
7247
7437
|
children: [
|
|
7248
|
-
canExpand ? expanded ? /* @__PURE__ */
|
|
7249
|
-
/* @__PURE__ */
|
|
7250
|
-
/* @__PURE__ */
|
|
7438
|
+
canExpand ? expanded ? /* @__PURE__ */ jsx31(ChevronDown2, { size: 12, className: "shrink-0" }) : /* @__PURE__ */ jsx31(ChevronRight6, { size: 12, className: "shrink-0" }) : null,
|
|
7439
|
+
/* @__PURE__ */ jsx31("span", { children: source.status === "streaming" ? /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1", children: [
|
|
7440
|
+
/* @__PURE__ */ jsx31(Loader25, { size: 12, className: "animate-spin" }),
|
|
7251
7441
|
"\u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587"
|
|
7252
|
-
] }) : source.status === "failed" ? /* @__PURE__ */
|
|
7253
|
-
/* @__PURE__ */
|
|
7442
|
+
] }) : source.status === "failed" ? /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1 text-rose-500/80", children: [
|
|
7443
|
+
/* @__PURE__ */ jsx31(XCircle, { size: 12 }),
|
|
7254
7444
|
"\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25"
|
|
7255
|
-
] }) : source.status === "interrupted" ? /* @__PURE__ */
|
|
7256
|
-
/* @__PURE__ */
|
|
7445
|
+
] }) : source.status === "interrupted" ? /* @__PURE__ */ jsxs26("span", { className: "inline-flex items-center gap-1 text-amber-500/80", children: [
|
|
7446
|
+
/* @__PURE__ */ jsx31(Square3, { size: 11 }),
|
|
7257
7447
|
"\u4E0A\u4E0B\u6587\u538B\u7F29\u5DF2\u53D6\u6D88"
|
|
7258
7448
|
] }) : "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
|
|
7259
7449
|
]
|
|
7260
7450
|
}
|
|
7261
7451
|
),
|
|
7262
|
-
canCancel ? /* @__PURE__ */
|
|
7452
|
+
canCancel ? /* @__PURE__ */ jsx31(
|
|
7263
7453
|
"button",
|
|
7264
7454
|
{
|
|
7265
7455
|
type: "button",
|
|
@@ -7269,13 +7459,13 @@ function CompactionCard({
|
|
|
7269
7459
|
}
|
|
7270
7460
|
) : null
|
|
7271
7461
|
] }),
|
|
7272
|
-
expanded ? /* @__PURE__ */
|
|
7273
|
-
/* @__PURE__ */
|
|
7274
|
-
/* @__PURE__ */
|
|
7462
|
+
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: [
|
|
7463
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 text-[hsl(var(--muted-foreground))]", children: [
|
|
7464
|
+
/* @__PURE__ */ jsxs26("span", { children: [
|
|
7275
7465
|
"#",
|
|
7276
7466
|
shortId(source.compaction_id)
|
|
7277
7467
|
] }),
|
|
7278
|
-
/* @__PURE__ */
|
|
7468
|
+
/* @__PURE__ */ jsxs26("span", { children: [
|
|
7279
7469
|
"\u8282\u7701 ",
|
|
7280
7470
|
formatSavedRatio(source.saved_ratio),
|
|
7281
7471
|
"\uFF08",
|
|
@@ -7285,31 +7475,31 @@ function CompactionCard({
|
|
|
7285
7475
|
formatTokens(source.tokens_after),
|
|
7286
7476
|
" token\uFF09"
|
|
7287
7477
|
] }),
|
|
7288
|
-
/* @__PURE__ */
|
|
7478
|
+
/* @__PURE__ */ jsxs26("span", { children: [
|
|
7289
7479
|
"\u5F52\u6863 ",
|
|
7290
7480
|
archivedCount,
|
|
7291
7481
|
" \u4E2A\u5DE5\u5177\u7ED3\u679C"
|
|
7292
7482
|
] })
|
|
7293
7483
|
] }),
|
|
7294
|
-
archivedToolCalls.length > 0 ? /* @__PURE__ */
|
|
7484
|
+
archivedToolCalls.length > 0 ? /* @__PURE__ */ jsx31("div", { className: "mt-2 space-y-1.5", children: archivedToolCalls.map((item, index) => {
|
|
7295
7485
|
const archivePath = getArchivePath(item, archivedFiles);
|
|
7296
|
-
return /* @__PURE__ */
|
|
7486
|
+
return /* @__PURE__ */ jsxs26(
|
|
7297
7487
|
"div",
|
|
7298
7488
|
{
|
|
7299
7489
|
className: "rounded-md border border-[hsl(var(--border))]/70 bg-[hsl(var(--muted))]/35 px-2 py-1.5",
|
|
7300
7490
|
children: [
|
|
7301
|
-
/* @__PURE__ */
|
|
7302
|
-
/* @__PURE__ */
|
|
7303
|
-
item.tool_call_id ? /* @__PURE__ */
|
|
7491
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-[hsl(var(--foreground))]", children: [
|
|
7492
|
+
/* @__PURE__ */ jsx31("span", { className: "font-medium", children: getArchivedToolLabel(item) }),
|
|
7493
|
+
item.tool_call_id ? /* @__PURE__ */ jsx31("span", { className: "font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: item.tool_call_id }) : null
|
|
7304
7494
|
] }),
|
|
7305
|
-
archivePath ? /* @__PURE__ */
|
|
7495
|
+
archivePath ? /* @__PURE__ */ jsx31("div", { className: "mt-0.5 break-all font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: archivePath }) : null
|
|
7306
7496
|
]
|
|
7307
7497
|
},
|
|
7308
7498
|
item.tool_call_id || item.entry_id || `${item.tool_name}-${index}`
|
|
7309
7499
|
);
|
|
7310
7500
|
}) }) : null,
|
|
7311
|
-
hasSummary ? /* @__PURE__ */
|
|
7312
|
-
source.status === "failed" && source.failure_reason ? /* @__PURE__ */
|
|
7501
|
+
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,
|
|
7502
|
+
source.status === "failed" && source.failure_reason ? /* @__PURE__ */ jsxs26("div", { className: "mt-2 text-rose-500/90", children: [
|
|
7313
7503
|
"\u5931\u8D25\u539F\u56E0\uFF1A",
|
|
7314
7504
|
source.failure_reason
|
|
7315
7505
|
] }) : null
|
|
@@ -7320,7 +7510,7 @@ function CompactionCard({
|
|
|
7320
7510
|
// src/react/components/chat/RenderErrorBoundary.tsx
|
|
7321
7511
|
import { AlertTriangle as AlertTriangle2 } from "lucide-react";
|
|
7322
7512
|
import { Component } from "react";
|
|
7323
|
-
import { jsx as
|
|
7513
|
+
import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
7324
7514
|
function getFirstComponentName(componentStack) {
|
|
7325
7515
|
const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
|
|
7326
7516
|
return match?.[1] ?? null;
|
|
@@ -7353,18 +7543,18 @@ var RenderErrorBoundary = class extends Component {
|
|
|
7353
7543
|
return children;
|
|
7354
7544
|
}
|
|
7355
7545
|
const componentName = getFirstComponentName(componentStack);
|
|
7356
|
-
return /* @__PURE__ */
|
|
7357
|
-
/* @__PURE__ */
|
|
7358
|
-
/* @__PURE__ */
|
|
7359
|
-
/* @__PURE__ */
|
|
7546
|
+
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: [
|
|
7547
|
+
/* @__PURE__ */ jsx32(AlertTriangle2, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
|
|
7548
|
+
/* @__PURE__ */ jsxs27("div", { className: "min-w-0 flex-1", children: [
|
|
7549
|
+
/* @__PURE__ */ jsxs27("div", { className: "font-medium", children: [
|
|
7360
7550
|
label,
|
|
7361
7551
|
"\u6E32\u67D3\u5931\u8D25"
|
|
7362
7552
|
] }),
|
|
7363
|
-
/* @__PURE__ */
|
|
7553
|
+
/* @__PURE__ */ jsxs27("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
|
|
7364
7554
|
componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
|
|
7365
7555
|
error.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
|
|
7366
7556
|
] }),
|
|
7367
|
-
details ? /* @__PURE__ */
|
|
7557
|
+
details ? /* @__PURE__ */ jsx32("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
|
|
7368
7558
|
] })
|
|
7369
7559
|
] }) });
|
|
7370
7560
|
}
|
|
@@ -7382,8 +7572,8 @@ import {
|
|
|
7382
7572
|
TerminalSquare,
|
|
7383
7573
|
WandSparkles
|
|
7384
7574
|
} from "lucide-react";
|
|
7385
|
-
import { useEffect as useEffect15, useMemo as useMemo16, useState as
|
|
7386
|
-
import { jsx as
|
|
7575
|
+
import { useEffect as useEffect15, useMemo as useMemo16, useState as useState19 } from "react";
|
|
7576
|
+
import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
7387
7577
|
var EMPTY_EVENTS = [];
|
|
7388
7578
|
function formatElapsedDuration(durationMs) {
|
|
7389
7579
|
if (durationMs == null) return null;
|
|
@@ -7461,7 +7651,7 @@ function getTurnStartedAt(events) {
|
|
|
7461
7651
|
return null;
|
|
7462
7652
|
}
|
|
7463
7653
|
function useElapsedDuration(startedAt, active) {
|
|
7464
|
-
const [now, setNow] =
|
|
7654
|
+
const [now, setNow] = useState19(() => Date.now());
|
|
7465
7655
|
useEffect15(() => {
|
|
7466
7656
|
if (!active || startedAt == null) {
|
|
7467
7657
|
return;
|
|
@@ -7493,22 +7683,22 @@ function StickyStatusBar({
|
|
|
7493
7683
|
}
|
|
7494
7684
|
const elapsedLabel = formatElapsedDuration(elapsedDuration);
|
|
7495
7685
|
const Icon = action.Icon;
|
|
7496
|
-
return /* @__PURE__ */
|
|
7686
|
+
return /* @__PURE__ */ jsxs28(
|
|
7497
7687
|
"button",
|
|
7498
7688
|
{
|
|
7499
7689
|
type: "button",
|
|
7500
7690
|
onClick: onJumpToLatest,
|
|
7501
7691
|
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",
|
|
7502
7692
|
children: [
|
|
7503
|
-
/* @__PURE__ */
|
|
7504
|
-
/* @__PURE__ */
|
|
7505
|
-
/* @__PURE__ */
|
|
7506
|
-
/* @__PURE__ */
|
|
7507
|
-
elapsedLabel ? /* @__PURE__ */
|
|
7693
|
+
/* @__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 }) }),
|
|
7694
|
+
/* @__PURE__ */ jsxs28("div", { className: "min-w-0 flex-1", children: [
|
|
7695
|
+
/* @__PURE__ */ jsx33("div", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: action.label }),
|
|
7696
|
+
/* @__PURE__ */ jsxs28("div", { className: "mt-1 flex flex-wrap items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
7697
|
+
elapsedLabel ? /* @__PURE__ */ jsxs28("span", { className: "font-mono", children: [
|
|
7508
7698
|
"\u5DF2\u6301\u7EED ",
|
|
7509
7699
|
elapsedLabel
|
|
7510
7700
|
] }) : null,
|
|
7511
|
-
/* @__PURE__ */
|
|
7701
|
+
/* @__PURE__ */ jsx33("span", { children: "\u70B9\u51FB\u8DF3\u5230\u6700\u65B0\u4F4D\u7F6E" })
|
|
7512
7702
|
] })
|
|
7513
7703
|
] })
|
|
7514
7704
|
]
|
|
@@ -7517,7 +7707,7 @@ function StickyStatusBar({
|
|
|
7517
7707
|
}
|
|
7518
7708
|
|
|
7519
7709
|
// src/react/components/chat/TurnNavRail.tsx
|
|
7520
|
-
import { jsx as
|
|
7710
|
+
import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
7521
7711
|
function TurnNavRail({
|
|
7522
7712
|
items,
|
|
7523
7713
|
activeTurnId,
|
|
@@ -7526,14 +7716,14 @@ function TurnNavRail({
|
|
|
7526
7716
|
if (items.length < 2) {
|
|
7527
7717
|
return null;
|
|
7528
7718
|
}
|
|
7529
|
-
return /* @__PURE__ */
|
|
7719
|
+
return /* @__PURE__ */ jsx34(
|
|
7530
7720
|
"nav",
|
|
7531
7721
|
{
|
|
7532
7722
|
"aria-label": "\u56DE\u5408\u5BFC\u822A",
|
|
7533
7723
|
className: "absolute right-2 top-4 z-10 hidden flex-col items-end gap-0.5 md:flex",
|
|
7534
7724
|
children: items.map((item, index) => {
|
|
7535
7725
|
const isActive = item.id === activeTurnId;
|
|
7536
|
-
return /* @__PURE__ */
|
|
7726
|
+
return /* @__PURE__ */ jsxs29(
|
|
7537
7727
|
"button",
|
|
7538
7728
|
{
|
|
7539
7729
|
type: "button",
|
|
@@ -7541,8 +7731,8 @@ function TurnNavRail({
|
|
|
7541
7731
|
"aria-current": isActive ? "true" : void 0,
|
|
7542
7732
|
className: "group relative flex h-3.5 items-center",
|
|
7543
7733
|
children: [
|
|
7544
|
-
/* @__PURE__ */
|
|
7545
|
-
/* @__PURE__ */
|
|
7734
|
+
/* @__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` }),
|
|
7735
|
+
/* @__PURE__ */ jsx34(
|
|
7546
7736
|
"span",
|
|
7547
7737
|
{
|
|
7548
7738
|
className: cn(
|
|
@@ -7561,7 +7751,7 @@ function TurnNavRail({
|
|
|
7561
7751
|
}
|
|
7562
7752
|
|
|
7563
7753
|
// src/react/components/chat/MessageList.tsx
|
|
7564
|
-
import { jsx as
|
|
7754
|
+
import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
7565
7755
|
function parseModeChange(message) {
|
|
7566
7756
|
if (message.kind !== "mode_change" || typeof message.content !== "string") {
|
|
7567
7757
|
return null;
|
|
@@ -7576,15 +7766,12 @@ function parseModeChange(message) {
|
|
|
7576
7766
|
return null;
|
|
7577
7767
|
}
|
|
7578
7768
|
function getPlanningDividerKind(message) {
|
|
7579
|
-
if (message.kind === "planning_enter" || message.kind === "planning_exit") {
|
|
7580
|
-
return message.kind;
|
|
7581
|
-
}
|
|
7582
7769
|
const modeChange = parseModeChange(message);
|
|
7583
7770
|
if (modeChange?.to === "planning") {
|
|
7584
|
-
return "
|
|
7771
|
+
return "enter";
|
|
7585
7772
|
}
|
|
7586
7773
|
if (modeChange?.from === "planning") {
|
|
7587
|
-
return "
|
|
7774
|
+
return "exit";
|
|
7588
7775
|
}
|
|
7589
7776
|
return null;
|
|
7590
7777
|
}
|
|
@@ -7759,7 +7946,7 @@ function MessageList({
|
|
|
7759
7946
|
const containerRef = useRef11(null);
|
|
7760
7947
|
const scrollContainerRef = useRef11(null);
|
|
7761
7948
|
const frameRef = useRef11(null);
|
|
7762
|
-
const [activeTurnId, setActiveTurnId] =
|
|
7949
|
+
const [activeTurnId, setActiveTurnId] = useState20(lastTurnId);
|
|
7763
7950
|
const layoutSignature = useMemo17(
|
|
7764
7951
|
() => getMessagesMeasureSignature(messages),
|
|
7765
7952
|
[messages]
|
|
@@ -7822,13 +8009,13 @@ function MessageList({
|
|
|
7822
8009
|
const handleSelectTurn = useCallback12((turnId) => {
|
|
7823
8010
|
document.getElementById(turnId)?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
7824
8011
|
}, []);
|
|
7825
|
-
return /* @__PURE__ */
|
|
8012
|
+
return /* @__PURE__ */ jsxs30(
|
|
7826
8013
|
"div",
|
|
7827
8014
|
{
|
|
7828
8015
|
ref: containerRef,
|
|
7829
8016
|
className: `relative min-h-0 flex-1 ${customization?.classNames?.messageListRoot ?? ""}`,
|
|
7830
8017
|
children: [
|
|
7831
|
-
turnNavItems.length > 1 ? /* @__PURE__ */
|
|
8018
|
+
turnNavItems.length > 1 ? /* @__PURE__ */ jsx35(
|
|
7832
8019
|
TurnNavRail,
|
|
7833
8020
|
{
|
|
7834
8021
|
items: turnNavItems,
|
|
@@ -7836,8 +8023,8 @@ function MessageList({
|
|
|
7836
8023
|
onSelectTurn: handleSelectTurn
|
|
7837
8024
|
}
|
|
7838
8025
|
) : null,
|
|
7839
|
-
/* @__PURE__ */
|
|
7840
|
-
/* @__PURE__ */
|
|
8026
|
+
/* @__PURE__ */ jsxs30(StickToBottom, { className: "h-full overflow-y-hidden", resize: "smooth", children: [
|
|
8027
|
+
/* @__PURE__ */ jsx35(StickToBottom.Content, { className: "px-5 py-6", children: /* @__PURE__ */ jsx35(
|
|
7841
8028
|
MessageListContent,
|
|
7842
8029
|
{
|
|
7843
8030
|
askAnswers,
|
|
@@ -7854,7 +8041,7 @@ function MessageList({
|
|
|
7854
8041
|
customization
|
|
7855
8042
|
}
|
|
7856
8043
|
) }),
|
|
7857
|
-
/* @__PURE__ */
|
|
8044
|
+
/* @__PURE__ */ jsx35(ScrollToBottomButton, {})
|
|
7858
8045
|
] })
|
|
7859
8046
|
]
|
|
7860
8047
|
}
|
|
@@ -7882,8 +8069,8 @@ function MessageListContent({
|
|
|
7882
8069
|
}
|
|
7883
8070
|
scrollToBottom();
|
|
7884
8071
|
}, [lastTurnId, scrollToBottom]);
|
|
7885
|
-
return /* @__PURE__ */
|
|
7886
|
-
stickyTurn ? /* @__PURE__ */
|
|
8072
|
+
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: [
|
|
8073
|
+
stickyTurn ? /* @__PURE__ */ jsx35(
|
|
7887
8074
|
StickyStatusBar,
|
|
7888
8075
|
{
|
|
7889
8076
|
sessionId,
|
|
@@ -7893,31 +8080,31 @@ function MessageListContent({
|
|
|
7893
8080
|
onJumpToLatest: handleJumpToLatest
|
|
7894
8081
|
}
|
|
7895
8082
|
) : null,
|
|
7896
|
-
renderBlocks.length === 0 ? customization?.components?.EmptyState ? /* @__PURE__ */
|
|
7897
|
-
/* @__PURE__ */
|
|
7898
|
-
/* @__PURE__ */
|
|
7899
|
-
/* @__PURE__ */
|
|
8083
|
+
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: [
|
|
8084
|
+
/* @__PURE__ */ jsx35(MessageSquare, { size: 40, strokeWidth: 1.5 }),
|
|
8085
|
+
/* @__PURE__ */ jsx35("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
|
|
8086
|
+
/* @__PURE__ */ jsx35("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
|
|
7900
8087
|
] }) : renderBlocks.map((block, blockIndex) => {
|
|
7901
8088
|
if (block.type === "message") {
|
|
7902
|
-
return /* @__PURE__ */
|
|
8089
|
+
return /* @__PURE__ */ jsx35("div", { className: "msg-animate", children: isUserMessage(block.message) ? customization?.components?.UserMessage ? /* @__PURE__ */ jsx35(
|
|
7903
8090
|
customization.components.UserMessage,
|
|
7904
8091
|
{
|
|
7905
8092
|
message: block.message,
|
|
7906
8093
|
className: customization.classNames?.userMessage
|
|
7907
8094
|
}
|
|
7908
|
-
) : /* @__PURE__ */
|
|
8095
|
+
) : /* @__PURE__ */ jsx35(
|
|
7909
8096
|
UserMessageBubble,
|
|
7910
8097
|
{
|
|
7911
8098
|
message: block.message,
|
|
7912
8099
|
className: customization?.classNames?.userMessage
|
|
7913
8100
|
}
|
|
7914
|
-
) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */
|
|
8101
|
+
) : isErrorMessage(block.message) ? customization?.components?.ErrorMessage ? /* @__PURE__ */ jsx35(
|
|
7915
8102
|
customization.components.ErrorMessage,
|
|
7916
8103
|
{
|
|
7917
8104
|
message: block.message,
|
|
7918
8105
|
className: customization.classNames?.errorMessage
|
|
7919
8106
|
}
|
|
7920
|
-
) : /* @__PURE__ */
|
|
8107
|
+
) : /* @__PURE__ */ jsx35(
|
|
7921
8108
|
ErrorMessageBlock,
|
|
7922
8109
|
{
|
|
7923
8110
|
message: block.message,
|
|
@@ -7932,22 +8119,22 @@ function MessageListContent({
|
|
|
7932
8119
|
(toolCall) => formatToolName(toolCall.name) === "ExitPlanMode" && toolCall.status !== "error" && toolCall.status !== "cancelled"
|
|
7933
8120
|
)
|
|
7934
8121
|
);
|
|
7935
|
-
const isFollowedByPlanningExit = nextBlock?.type === "planning_divider" && nextBlock.kind === "
|
|
8122
|
+
const isFollowedByPlanningExit = nextBlock?.type === "planning_divider" && nextBlock.kind === "exit";
|
|
7936
8123
|
const showPlanCard = (hasExitPlan || isFollowedByPlanningExit) && onConfirmPlan && sessionStatus === "waiting_for_input";
|
|
7937
|
-
return /* @__PURE__ */
|
|
8124
|
+
return /* @__PURE__ */ jsxs30(
|
|
7938
8125
|
"div",
|
|
7939
8126
|
{
|
|
7940
8127
|
id: block.anchorId,
|
|
7941
8128
|
"data-turn-id": block.anchorId,
|
|
7942
8129
|
className: "msg-animate flex scroll-mt-6 flex-col gap-4",
|
|
7943
8130
|
children: [
|
|
7944
|
-
/* @__PURE__ */
|
|
8131
|
+
/* @__PURE__ */ jsx35(
|
|
7945
8132
|
RenderErrorBoundary,
|
|
7946
8133
|
{
|
|
7947
8134
|
label: "\u52A9\u624B\u6D88\u606F",
|
|
7948
8135
|
details: block.key,
|
|
7949
8136
|
resetKey: getMessagesRenderSignature(block.messages),
|
|
7950
|
-
children: customization?.components?.AssistantTurn ? /* @__PURE__ */
|
|
8137
|
+
children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx35(
|
|
7951
8138
|
customization.components.AssistantTurn,
|
|
7952
8139
|
{
|
|
7953
8140
|
turnKey: block.key,
|
|
@@ -7960,7 +8147,7 @@ function MessageListContent({
|
|
|
7960
8147
|
sessionStatus,
|
|
7961
8148
|
customization
|
|
7962
8149
|
}
|
|
7963
|
-
) : /* @__PURE__ */
|
|
8150
|
+
) : /* @__PURE__ */ jsx35(
|
|
7964
8151
|
AssistantTurnBlock,
|
|
7965
8152
|
{
|
|
7966
8153
|
turnKey: block.key,
|
|
@@ -7976,13 +8163,13 @@ function MessageListContent({
|
|
|
7976
8163
|
)
|
|
7977
8164
|
}
|
|
7978
8165
|
),
|
|
7979
|
-
showPlanCard ? /* @__PURE__ */
|
|
8166
|
+
showPlanCard ? /* @__PURE__ */ jsx35(
|
|
7980
8167
|
RenderErrorBoundary,
|
|
7981
8168
|
{
|
|
7982
8169
|
label: "\u89C4\u5212\u6458\u8981",
|
|
7983
8170
|
details: block.key,
|
|
7984
8171
|
resetKey: `${sessionStatus ?? ""}:${layoutSignature}`,
|
|
7985
|
-
children: /* @__PURE__ */
|
|
8172
|
+
children: /* @__PURE__ */ jsx35(
|
|
7986
8173
|
PlanSummaryCard,
|
|
7987
8174
|
{
|
|
7988
8175
|
messages: extractLatestPlanMessages(messages),
|
|
@@ -7998,7 +8185,7 @@ function MessageListContent({
|
|
|
7998
8185
|
);
|
|
7999
8186
|
}
|
|
8000
8187
|
if (block.type === "compaction") {
|
|
8001
|
-
return /* @__PURE__ */
|
|
8188
|
+
return /* @__PURE__ */ jsx35("div", { className: "msg-animate", children: /* @__PURE__ */ jsx35(
|
|
8002
8189
|
CompactionCard,
|
|
8003
8190
|
{
|
|
8004
8191
|
sessionId,
|
|
@@ -8007,41 +8194,41 @@ function MessageListContent({
|
|
|
8007
8194
|
}
|
|
8008
8195
|
) }, block.key);
|
|
8009
8196
|
}
|
|
8010
|
-
return /* @__PURE__ */
|
|
8197
|
+
return /* @__PURE__ */ jsx35(PlanningDivider, { kind: block.kind }, block.key);
|
|
8011
8198
|
}),
|
|
8012
|
-
sessionStatus === "interrupted" && !hasInterruptedTurn ? /* @__PURE__ */
|
|
8199
|
+
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
|
|
8013
8200
|
] }) });
|
|
8014
8201
|
}
|
|
8015
8202
|
function ScrollToBottomButton() {
|
|
8016
8203
|
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
|
8017
8204
|
if (isAtBottom) return null;
|
|
8018
|
-
return /* @__PURE__ */
|
|
8205
|
+
return /* @__PURE__ */ jsxs30(
|
|
8019
8206
|
"button",
|
|
8020
8207
|
{
|
|
8021
8208
|
type: "button",
|
|
8022
8209
|
onClick: () => scrollToBottom(),
|
|
8023
8210
|
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))]",
|
|
8024
8211
|
children: [
|
|
8025
|
-
/* @__PURE__ */
|
|
8026
|
-
/* @__PURE__ */
|
|
8212
|
+
/* @__PURE__ */ jsx35(ChevronDown3, { size: 14 }),
|
|
8213
|
+
/* @__PURE__ */ jsx35("span", { children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
|
|
8027
8214
|
]
|
|
8028
8215
|
}
|
|
8029
8216
|
);
|
|
8030
8217
|
}
|
|
8031
8218
|
function PlanningDivider({ kind }) {
|
|
8032
|
-
const isEnter = kind === "
|
|
8033
|
-
return /* @__PURE__ */
|
|
8034
|
-
/* @__PURE__ */
|
|
8035
|
-
/* @__PURE__ */
|
|
8036
|
-
/* @__PURE__ */
|
|
8037
|
-
/* @__PURE__ */
|
|
8219
|
+
const isEnter = kind === "enter";
|
|
8220
|
+
return /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-3 py-1", children: [
|
|
8221
|
+
/* @__PURE__ */ jsx35("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
|
|
8222
|
+
/* @__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: [
|
|
8223
|
+
/* @__PURE__ */ jsx35(Lightbulb2, { size: 12 }),
|
|
8224
|
+
/* @__PURE__ */ jsx35("span", { children: isEnter ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
|
|
8038
8225
|
] }),
|
|
8039
|
-
/* @__PURE__ */
|
|
8226
|
+
/* @__PURE__ */ jsx35("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
|
|
8040
8227
|
] });
|
|
8041
8228
|
}
|
|
8042
8229
|
|
|
8043
8230
|
// src/react/components/chat/ChatView.tsx
|
|
8044
|
-
import { jsx as
|
|
8231
|
+
import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
8045
8232
|
function ChatView({
|
|
8046
8233
|
sessionId,
|
|
8047
8234
|
renderAttachments,
|
|
@@ -8080,13 +8267,13 @@ function ChatView({
|
|
|
8080
8267
|
);
|
|
8081
8268
|
const customization = { classNames, components, renderers };
|
|
8082
8269
|
const SkillStatus = components?.SkillStatusBar;
|
|
8083
|
-
return /* @__PURE__ */
|
|
8084
|
-
isViewer && /* @__PURE__ */
|
|
8085
|
-
/* @__PURE__ */
|
|
8270
|
+
return /* @__PURE__ */ jsxs31("div", { className: `flex min-h-0 flex-1 flex-col overflow-hidden ${classNames?.root ?? ""}`, children: [
|
|
8271
|
+
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: [
|
|
8272
|
+
/* @__PURE__ */ jsx36(Eye, { size: 14 }),
|
|
8086
8273
|
"\u4F60\u6B63\u5728\u67E5\u770B\u5206\u4EAB\u7684\u4F1A\u8BDD\uFF08\u53EA\u8BFB\uFF09"
|
|
8087
8274
|
] }),
|
|
8088
|
-
!isViewer && /* @__PURE__ */
|
|
8089
|
-
/* @__PURE__ */
|
|
8275
|
+
!isViewer && /* @__PURE__ */ jsx36(ConnectionBanner, {}),
|
|
8276
|
+
/* @__PURE__ */ jsx36(
|
|
8090
8277
|
MessageList,
|
|
8091
8278
|
{
|
|
8092
8279
|
sessionId,
|
|
@@ -8098,7 +8285,7 @@ function ChatView({
|
|
|
8098
8285
|
},
|
|
8099
8286
|
sessionId
|
|
8100
8287
|
),
|
|
8101
|
-
!isViewer && /* @__PURE__ */
|
|
8288
|
+
!isViewer && /* @__PURE__ */ jsx36(
|
|
8102
8289
|
ChatInput,
|
|
8103
8290
|
{
|
|
8104
8291
|
onSend: (msg, _targetSessionId, model) => send(msg, mode, void 0, { model: model || void 0 }),
|
|
@@ -8173,4 +8360,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
|
|
|
8173
8360
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
8174
8361
|
*--------------------------------------------------------------------------------------------*)
|
|
8175
8362
|
*/
|
|
8176
|
-
//# sourceMappingURL=chunk-
|
|
8363
|
+
//# sourceMappingURL=chunk-EV225FLR.js.map
|