@blade-hq/agent-kit 0.5.31 → 0.5.33
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/{SkillStatusBar-CvgcEiSi.d.ts → SkillStatusBar-Dp93pqlP.d.ts} +14 -3
- package/dist/{blade-client-DoodJJDz.d.ts → blade-client-DS7lV19a.d.ts} +4 -1
- package/dist/{chunk-ZWO6YBLA.js → chunk-DQXXSHCR.js} +5 -3
- package/dist/chunk-DQXXSHCR.js.map +1 -0
- package/dist/{chunk-OPMRX65X.js → chunk-EBTZAB6X.js} +13 -5
- package/dist/chunk-EBTZAB6X.js.map +1 -0
- package/dist/{chunk-BUQRNLEE.js → chunk-MGXPILAM.js} +3 -3
- package/dist/{chunk-KMQQDKGU.js → chunk-PMG4N3JO.js} +19 -3
- package/dist/chunk-PMG4N3JO.js.map +1 -0
- package/dist/{chunk-HFVB57MR.js → chunk-SGOR4YXZ.js} +63 -18
- package/dist/chunk-SGOR4YXZ.js.map +1 -0
- package/dist/{chunk-4XBNTPVS.js → chunk-UR6C4AJB.js} +2 -2
- package/dist/client/index.d.ts +145 -1
- package/dist/client/index.js +1 -1
- package/dist/react/api/vibe-coding.d.ts +2 -2
- package/dist/react/api/vibe-coding.js +2 -2
- package/dist/react/components/chat/index.d.ts +3 -3
- package/dist/react/components/chat/index.js +5 -5
- package/dist/react/components/plan/index.js +4 -4
- package/dist/react/components/session/index.js +3 -3
- package/dist/react/components/workspace/index.d.ts +2 -2
- package/dist/react/components/workspace/index.js +3 -3
- package/dist/react/index.d.ts +10 -6
- package/dist/react/index.js +8 -6
- package/dist/react/index.js.map +1 -1
- package/dist/{sessions-DFGsAOPa.d.ts → sessions-DaddUdO6.d.ts} +4 -1
- package/package.json +1 -1
- package/dist/chunk-HFVB57MR.js.map +0 -1
- package/dist/chunk-KMQQDKGU.js.map +0 -1
- package/dist/chunk-OPMRX65X.js.map +0 -1
- package/dist/chunk-ZWO6YBLA.js.map +0 -1
- /package/dist/{chunk-BUQRNLEE.js.map → chunk-MGXPILAM.js.map} +0 -0
- /package/dist/{chunk-4XBNTPVS.js.map → chunk-UR6C4AJB.js.map} +0 -0
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
getSessionFilePath,
|
|
7
7
|
resolveSessionFilePreviewTarget
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-PMG4N3JO.js";
|
|
9
9
|
import {
|
|
10
10
|
formatToolName,
|
|
11
11
|
getAuthedUrl,
|
|
12
12
|
useUiStore
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-EBTZAB6X.js";
|
|
14
14
|
import {
|
|
15
15
|
cn,
|
|
16
16
|
copyToClipboard
|
|
@@ -1933,4 +1933,4 @@ export {
|
|
|
1933
1933
|
PlanSummaryCard,
|
|
1934
1934
|
extractLatestPlanMessages
|
|
1935
1935
|
};
|
|
1936
|
-
//# sourceMappingURL=chunk-
|
|
1936
|
+
//# sourceMappingURL=chunk-MGXPILAM.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
apiFetchResponse,
|
|
3
3
|
getAuthedUrl
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EBTZAB6X.js";
|
|
5
5
|
|
|
6
6
|
// src/react/lib/session-file-preview.ts
|
|
7
7
|
var IMAGE_EXTS = /* @__PURE__ */ new Set(["png", "jpg", "jpeg", "gif", "svg", "webp", "ico", "bmp"]);
|
|
@@ -11,6 +11,7 @@ var PPT_EXTS = /* @__PURE__ */ new Set(["pptx", "ppt"]);
|
|
|
11
11
|
var CSV_EXTS = /* @__PURE__ */ new Set(["csv"]);
|
|
12
12
|
var MARKDOWN_EXTS = /* @__PURE__ */ new Set(["md", "markdown"]);
|
|
13
13
|
var HTML_EXTS = /* @__PURE__ */ new Set(["html", "htm"]);
|
|
14
|
+
var OFFICE_PDF_EXTS = /* @__PURE__ */ new Set(["vsdx", "vsd", "odt", "ods", "odp", "odg", "rtf", "wps", "wpd"]);
|
|
14
15
|
function getExt(fileName) {
|
|
15
16
|
return fileName.split(".").pop()?.toLowerCase() ?? "";
|
|
16
17
|
}
|
|
@@ -20,6 +21,9 @@ function getDisplayFileName(filePath, fileName) {
|
|
|
20
21
|
function getSessionFilePath(sessionId, filePath) {
|
|
21
22
|
return `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}`;
|
|
22
23
|
}
|
|
24
|
+
function getSessionPreviewPdfPath(sessionId, filePath) {
|
|
25
|
+
return `/api/sessions/${sessionId}/preview-pdf/${encodeURIComponent(filePath)}`;
|
|
26
|
+
}
|
|
23
27
|
function getSessionFileDownloadUrl(sessionId, filePath) {
|
|
24
28
|
return getAuthedUrl(getSessionFilePath(sessionId, filePath));
|
|
25
29
|
}
|
|
@@ -55,7 +59,18 @@ function buildBinaryPreviewTarget(fileUrl, downloadUrl, filePath, fileName) {
|
|
|
55
59
|
function buildSessionBinaryPreviewTarget(sessionId, filePath, fileName) {
|
|
56
60
|
const fileUrl = getSessionFilePath(sessionId, filePath);
|
|
57
61
|
const downloadUrl = getSessionFileDownloadUrl(sessionId, filePath);
|
|
58
|
-
|
|
62
|
+
const common = buildBinaryPreviewTarget(fileUrl, downloadUrl, filePath, fileName);
|
|
63
|
+
if (common) return common;
|
|
64
|
+
const resolvedFileName = getDisplayFileName(filePath, fileName);
|
|
65
|
+
const ext = getExt(resolvedFileName);
|
|
66
|
+
if (OFFICE_PDF_EXTS.has(ext)) {
|
|
67
|
+
const pdfUrl = getAuthedUrl(getSessionPreviewPdfPath(sessionId, filePath));
|
|
68
|
+
return { type: "pdf", content: pdfUrl, title: resolvedFileName, key: filePath };
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
function isOfficePdfPreviewable(fileName) {
|
|
73
|
+
return OFFICE_PDF_EXTS.has(getExt(fileName));
|
|
59
74
|
}
|
|
60
75
|
function resolveTextPreviewType(fileName) {
|
|
61
76
|
const ext = getExt(fileName);
|
|
@@ -98,7 +113,8 @@ export {
|
|
|
98
113
|
getSessionFilePath,
|
|
99
114
|
buildBinaryPreviewTarget,
|
|
100
115
|
buildSessionBinaryPreviewTarget,
|
|
116
|
+
isOfficePdfPreviewable,
|
|
101
117
|
resolveTextPreviewType,
|
|
102
118
|
resolveSessionFilePreviewTarget
|
|
103
119
|
};
|
|
104
|
-
//# sourceMappingURL=chunk-
|
|
120
|
+
//# sourceMappingURL=chunk-PMG4N3JO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/lib/session-file-preview.ts"],"sourcesContent":["import { apiFetchResponse, getAuthedUrl } from \"../api/client\"\nimport type { PreviewTarget } from \"../stores/ui-store\"\n\nconst IMAGE_EXTS = new Set([\"png\", \"jpg\", \"jpeg\", \"gif\", \"svg\", \"webp\", \"ico\", \"bmp\"])\nconst DOCX_EXTS = new Set([\"docx\", \"doc\"])\nconst EXCEL_EXTS = new Set([\"xlsx\", \"xls\", \"xlsm\", \"xlsb\"])\nconst PPT_EXTS = new Set([\"pptx\", \"ppt\"])\nconst CSV_EXTS = new Set([\"csv\"])\nconst MARKDOWN_EXTS = new Set([\"md\", \"markdown\"])\nconst HTML_EXTS = new Set([\"html\", \"htm\"])\n\n/** 需要后端 soffice 转 PDF 才能预览的 Office 格式 */\nconst OFFICE_PDF_EXTS = new Set([\"vsdx\", \"vsd\", \"odt\", \"ods\", \"odp\", \"odg\", \"rtf\", \"wps\", \"wpd\"])\n\nfunction getExt(fileName: string): string {\n return fileName.split(\".\").pop()?.toLowerCase() ?? \"\"\n}\n\nfunction getDisplayFileName(filePath: string, fileName?: string): string {\n return fileName?.trim() || filePath.split(\"/\").pop() || filePath\n}\n\nexport function getSessionFilePath(sessionId: string, filePath: string): string {\n return `/api/sessions/${sessionId}/files/${encodeURIComponent(filePath)}`\n}\n\nfunction getSessionPreviewPdfPath(sessionId: string, filePath: string): string {\n return `/api/sessions/${sessionId}/preview-pdf/${encodeURIComponent(filePath)}`\n}\n\nfunction getSessionFileDownloadUrl(sessionId: string, filePath: string): string {\n return getAuthedUrl(getSessionFilePath(sessionId, filePath))\n}\n\n/**\n * 后端把可解码为 UTF-8 的文件返回为 text/plain,二进制文件返回各自的 MIME。\n * 只有文本类内容才能安全地整体读进内存渲染——其余一律不能读 body。\n */\nfunction isTextualContentType(contentType: string): boolean {\n return (\n contentType.startsWith(\"text/\") ||\n contentType.includes(\"json\") ||\n contentType.includes(\"xml\") ||\n contentType.includes(\"yaml\") ||\n contentType.includes(\"javascript\")\n )\n}\n\nexport function buildBinaryPreviewTarget(\n fileUrl: string,\n downloadUrl: string,\n filePath: string,\n fileName?: string,\n): PreviewTarget | null {\n const resolvedFileName = getDisplayFileName(filePath, fileName)\n const ext = getExt(resolvedFileName)\n\n if (IMAGE_EXTS.has(ext)) {\n return { type: \"image\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (ext === \"pdf\") {\n return { type: \"pdf\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (DOCX_EXTS.has(ext)) {\n return { type: \"docx\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (EXCEL_EXTS.has(ext)) {\n return { type: \"excel\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (PPT_EXTS.has(ext)) {\n return {\n type: \"ppt\",\n content: fileUrl,\n sourceUrl: downloadUrl,\n title: resolvedFileName,\n key: filePath,\n }\n }\n\n return null\n}\n\nexport function buildSessionBinaryPreviewTarget(\n sessionId: string,\n filePath: string,\n fileName?: string,\n): PreviewTarget | null {\n const fileUrl = getSessionFilePath(sessionId, filePath)\n const downloadUrl = getSessionFileDownloadUrl(sessionId, filePath)\n const common = buildBinaryPreviewTarget(fileUrl, downloadUrl, filePath, fileName)\n if (common) return common\n\n // 需要后端 soffice 转 PDF 的 Office 格式(Visio 等)\n const resolvedFileName = getDisplayFileName(filePath, fileName)\n const ext = getExt(resolvedFileName)\n if (OFFICE_PDF_EXTS.has(ext)) {\n const pdfUrl = getAuthedUrl(getSessionPreviewPdfPath(sessionId, filePath))\n return { type: \"pdf\", content: pdfUrl, title: resolvedFileName, key: filePath }\n }\n\n return null\n}\n\n/** 判断文件是否需要后端 soffice 转 PDF 才能预览 */\nexport function isOfficePdfPreviewable(fileName: string): boolean {\n return OFFICE_PDF_EXTS.has(getExt(fileName))\n}\n\nexport function resolveTextPreviewType(fileName: string): PreviewTarget[\"type\"] {\n const ext = getExt(fileName)\n if (MARKDOWN_EXTS.has(ext)) return \"markdown\"\n if (CSV_EXTS.has(ext)) return \"csv\"\n if (HTML_EXTS.has(ext)) return \"html\"\n return \"file\"\n}\n\nexport async function resolveSessionFilePreviewTarget(\n sessionId: string,\n filePath: string,\n fileName?: string,\n): Promise<PreviewTarget> {\n const resolvedFileName = getDisplayFileName(filePath, fileName)\n const binaryTarget = buildSessionBinaryPreviewTarget(sessionId, filePath, resolvedFileName)\n if (binaryTarget) {\n return binaryTarget\n }\n\n const downloadUrl = getSessionFileDownloadUrl(sessionId, filePath)\n\n // 其余文件按后端返回的 Content-Type 分派,而不是猜扩展名:\n // 视频/音频/压缩包等二进制文件绝不能读 body(整体读进内存会卡死页面),\n // 改为把下载 URL 交给原生 <video>/<audio> 流式播放,或回退为下载。\n const res = await apiFetchResponse(getSessionFilePath(sessionId, filePath))\n const contentType = (res.headers.get(\"content-type\") ?? \"\").toLowerCase()\n\n if (contentType.startsWith(\"video/\")) {\n void res.body?.cancel()\n return { type: \"video\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (contentType.startsWith(\"audio/\")) {\n void res.body?.cancel()\n return { type: \"audio\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n if (!isTextualContentType(contentType)) {\n void res.body?.cancel()\n return { type: \"download\", content: downloadUrl, title: resolvedFileName, key: filePath }\n }\n\n const content = await res.text()\n\n return {\n type: resolveTextPreviewType(resolvedFileName),\n content,\n title: resolvedFileName,\n key: filePath,\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
getCodeLanguageFromFilename,
|
|
9
9
|
parseAskUserQuestion,
|
|
10
10
|
useHighlightedCodeHtml
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MGXPILAM.js";
|
|
12
12
|
import {
|
|
13
13
|
Collapsible,
|
|
14
14
|
CollapsibleContent,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "./chunk-H62LH2AG.js";
|
|
17
17
|
import {
|
|
18
18
|
resolveSessionFilePreviewTarget
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-PMG4N3JO.js";
|
|
20
20
|
import {
|
|
21
21
|
apiFetchResponse,
|
|
22
22
|
buildMessageContent,
|
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
useUiBridgeStore,
|
|
61
61
|
useUiStore,
|
|
62
62
|
writeFile
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-EBTZAB6X.js";
|
|
64
64
|
import {
|
|
65
65
|
registerBridgeIframe,
|
|
66
66
|
tapBridgeEvent
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
ModelOption,
|
|
70
70
|
ModelsConfig,
|
|
71
71
|
ModelsResource
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-DQXXSHCR.js";
|
|
73
73
|
import {
|
|
74
74
|
cn,
|
|
75
75
|
copyToClipboard
|
|
@@ -198,6 +198,7 @@ import {
|
|
|
198
198
|
Paperclip,
|
|
199
199
|
Plus,
|
|
200
200
|
Rocket,
|
|
201
|
+
RotateCcw,
|
|
201
202
|
Scissors,
|
|
202
203
|
Send,
|
|
203
204
|
Sparkles as Sparkles2,
|
|
@@ -2046,6 +2047,7 @@ var SkillMention = Mention2.extend({
|
|
|
2046
2047
|
|
|
2047
2048
|
// src/react/components/chat/ChatInput.tsx
|
|
2048
2049
|
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2050
|
+
var DOUBLE_ESCAPE_MS = 450;
|
|
2049
2051
|
function getEditorText(editor) {
|
|
2050
2052
|
return editor?.getText({ blockSeparator: "\n" }) ?? "";
|
|
2051
2053
|
}
|
|
@@ -2685,7 +2687,9 @@ function ChatInput({
|
|
|
2685
2687
|
skillStatusBarInnerClassName,
|
|
2686
2688
|
onResyncSkills,
|
|
2687
2689
|
isResyncingSkills = false,
|
|
2688
|
-
inputLabel = "\u8F93\u5165\u6D88\u606F"
|
|
2690
|
+
inputLabel = "\u8F93\u5165\u6D88\u606F",
|
|
2691
|
+
onDoubleEscape,
|
|
2692
|
+
composerHint
|
|
2689
2693
|
}) {
|
|
2690
2694
|
const resolvedInputLabel = inputLabel?.trim() || "\u8F93\u5165\u6D88\u606F";
|
|
2691
2695
|
const [input, setInputInternal] = useState8(externalDraft?.value ?? "");
|
|
@@ -2734,6 +2738,7 @@ function ChatInput({
|
|
|
2734
2738
|
const fileInputRef = useRef5(null);
|
|
2735
2739
|
const folderInputRef = useRef5(null);
|
|
2736
2740
|
const editorRef = useRef5(null);
|
|
2741
|
+
const lastEscapeAtRef = useRef5(0);
|
|
2737
2742
|
const localImageUrlsRef = useRef5(/* @__PURE__ */ new Map());
|
|
2738
2743
|
const activeSessionId = useSessionStore((state) => state.activeSessionId);
|
|
2739
2744
|
const sessions = useSessionStore((state) => state.sessions);
|
|
@@ -2836,7 +2841,8 @@ function ChatInput({
|
|
|
2836
2841
|
navigateUp: inputHistory.navigateUp,
|
|
2837
2842
|
navigateDown: inputHistory.navigateDown,
|
|
2838
2843
|
isNavigatingHistory: inputHistory.isNavigating,
|
|
2839
|
-
handleSubmit: stableHandleSubmit
|
|
2844
|
+
handleSubmit: stableHandleSubmit,
|
|
2845
|
+
onDoubleEscape
|
|
2840
2846
|
}));
|
|
2841
2847
|
const syncEditorState = (editorInstance) => {
|
|
2842
2848
|
const value = getEditorText(editorInstance);
|
|
@@ -3066,6 +3072,18 @@ function ChatInput({
|
|
|
3066
3072
|
replaceEditorText(editorRef.current, nextEntry);
|
|
3067
3073
|
return true;
|
|
3068
3074
|
}
|
|
3075
|
+
if (state.onDoubleEscape && event.key === "Escape" && !event.isComposing && !event.repeat) {
|
|
3076
|
+
const now = Date.now();
|
|
3077
|
+
if (now - lastEscapeAtRef.current <= DOUBLE_ESCAPE_MS) {
|
|
3078
|
+
lastEscapeAtRef.current = 0;
|
|
3079
|
+
event.preventDefault();
|
|
3080
|
+
const rect = editorRef.current?.view.dom.getBoundingClientRect() ?? null;
|
|
3081
|
+
state.onDoubleEscape(rect);
|
|
3082
|
+
return true;
|
|
3083
|
+
}
|
|
3084
|
+
lastEscapeAtRef.current = now;
|
|
3085
|
+
return false;
|
|
3086
|
+
}
|
|
3069
3087
|
if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
|
|
3070
3088
|
event.preventDefault();
|
|
3071
3089
|
if (state.connectionStatus !== "connected") {
|
|
@@ -3560,6 +3578,23 @@ function ChatInput({
|
|
|
3560
3578
|
]
|
|
3561
3579
|
}
|
|
3562
3580
|
),
|
|
3581
|
+
onDoubleEscape ? /* @__PURE__ */ jsxs8(
|
|
3582
|
+
"button",
|
|
3583
|
+
{
|
|
3584
|
+
type: "button",
|
|
3585
|
+
onClick: () => {
|
|
3586
|
+
actionMenuRef.current?.removeAttribute("open");
|
|
3587
|
+
onDoubleEscape(
|
|
3588
|
+
editorRef.current?.view.dom.getBoundingClientRect() ?? null
|
|
3589
|
+
);
|
|
3590
|
+
},
|
|
3591
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
|
|
3592
|
+
children: [
|
|
3593
|
+
/* @__PURE__ */ jsx9(RotateCcw, { size: 13 }),
|
|
3594
|
+
"\u56DE\u5230\u4E4B\u524D\u7684\u67D0\u4E00\u6B65"
|
|
3595
|
+
]
|
|
3596
|
+
}
|
|
3597
|
+
) : null,
|
|
3563
3598
|
onCommand ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
3564
3599
|
/* @__PURE__ */ jsxs8(
|
|
3565
3600
|
"button",
|
|
@@ -3699,7 +3734,8 @@ function ChatInput({
|
|
|
3699
3734
|
/* @__PURE__ */ jsxs8("div", { className: "space-y-0.5", children: [
|
|
3700
3735
|
/* @__PURE__ */ jsx9("div", { children: "Shift+Enter \u6362\u884C" }),
|
|
3701
3736
|
/* @__PURE__ */ jsx9("div", { children: "/ \u8C03\u7528\u6280\u80FD" }),
|
|
3702
|
-
/* @__PURE__ */ jsx9("div", { children: "@ \u5F15\u7528\u6587\u4EF6" })
|
|
3737
|
+
/* @__PURE__ */ jsx9("div", { children: "@ \u5F15\u7528\u6587\u4EF6" }),
|
|
3738
|
+
composerHint && /* @__PURE__ */ jsx9("div", { children: composerHint })
|
|
3703
3739
|
] })
|
|
3704
3740
|
] }) })
|
|
3705
3741
|
] }),
|
|
@@ -4525,7 +4561,7 @@ ReasoningTrigger.displayName = "ReasoningTrigger";
|
|
|
4525
4561
|
ReasoningContent.displayName = "ReasoningContent";
|
|
4526
4562
|
|
|
4527
4563
|
// src/react/components/chat/AgentLoopBlock.tsx
|
|
4528
|
-
import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText6, Loader2 as
|
|
4564
|
+
import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText6, Loader2 as Loader25, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
|
|
4529
4565
|
import { useEffect as useEffect14, useMemo as useMemo14, useState as useState17 } from "react";
|
|
4530
4566
|
|
|
4531
4567
|
// src/react/components/chat/ResourceIframe.tsx
|
|
@@ -4988,7 +5024,7 @@ function FileEditRenderer({ toolCall }) {
|
|
|
4988
5024
|
import { useState as useState13 } from "react";
|
|
4989
5025
|
|
|
4990
5026
|
// src/react/components/chat/ImageLightbox.tsx
|
|
4991
|
-
import { ChevronLeft, ChevronRight as ChevronRight2, Download as Download2, ExternalLink, Minus, Plus as Plus2, RotateCcw, X as X3 } from "lucide-react";
|
|
5027
|
+
import { ChevronLeft, ChevronRight as ChevronRight2, Download as Download2, ExternalLink, Minus, Plus as Plus2, RotateCcw as RotateCcw2, X as X3 } from "lucide-react";
|
|
4992
5028
|
import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef10, useState as useState12 } from "react";
|
|
4993
5029
|
import { createPortal as createPortal3 } from "react-dom";
|
|
4994
5030
|
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
@@ -5219,7 +5255,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
|
5219
5255
|
type: "button",
|
|
5220
5256
|
onClick: reset,
|
|
5221
5257
|
className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
|
|
5222
|
-
children: /* @__PURE__ */ jsx17(
|
|
5258
|
+
children: /* @__PURE__ */ jsx17(RotateCcw2, { size: 16 })
|
|
5223
5259
|
}
|
|
5224
5260
|
),
|
|
5225
5261
|
showNav && /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
@@ -5820,6 +5856,7 @@ function buildAskUserPayload(argumentsJson) {
|
|
|
5820
5856
|
|
|
5821
5857
|
// src/react/components/chat/UserMessageBubble.tsx
|
|
5822
5858
|
import { useQueries } from "@tanstack/react-query";
|
|
5859
|
+
import { Loader2 as Loader24 } from "lucide-react";
|
|
5823
5860
|
import { useEffect as useEffect13, useRef as useRef11, useState as useState16 } from "react";
|
|
5824
5861
|
|
|
5825
5862
|
// src/react/lib/preview-dispatch.ts
|
|
@@ -6298,6 +6335,7 @@ function buildSessionFileUrl(sessionId, filePath) {
|
|
|
6298
6335
|
`/api/sessions/${encodeURIComponent(sessionId)}/files/${encodeURIComponent(filePath)}`
|
|
6299
6336
|
);
|
|
6300
6337
|
}
|
|
6338
|
+
var isSending = (message) => message.status === "streaming";
|
|
6301
6339
|
function UserMessageBubble({ message, className }) {
|
|
6302
6340
|
const activeSessionId = useSessionStore((state) => state.activeSessionId);
|
|
6303
6341
|
const _textContent = getTextContent(message.content);
|
|
@@ -6474,13 +6512,16 @@ function UserMessageBubble({ message, className }) {
|
|
|
6474
6512
|
children: cleanText
|
|
6475
6513
|
}
|
|
6476
6514
|
) }),
|
|
6477
|
-
trimmedClean && /* @__PURE__ */
|
|
6515
|
+
trimmedClean && (isSending(message) ? /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-1.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
6516
|
+
/* @__PURE__ */ jsx29(Loader24, { size: 12, className: "animate-spin" }),
|
|
6517
|
+
/* @__PURE__ */ jsx29("span", { children: "\u53D1\u9001\u4E2D" })
|
|
6518
|
+
] }) : /* @__PURE__ */ jsx29(
|
|
6478
6519
|
MessageActions,
|
|
6479
6520
|
{
|
|
6480
6521
|
content: cleanText,
|
|
6481
6522
|
className: "opacity-0 transition-opacity group-hover:opacity-100"
|
|
6482
6523
|
}
|
|
6483
|
-
)
|
|
6524
|
+
))
|
|
6484
6525
|
] }) });
|
|
6485
6526
|
}
|
|
6486
6527
|
function ErrorMessageBlock({
|
|
@@ -6669,7 +6710,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6669
6710
|
},
|
|
6670
6711
|
childToolCall.id
|
|
6671
6712
|
)) : /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2 px-4 py-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
6672
|
-
/* @__PURE__ */ jsx30(
|
|
6713
|
+
/* @__PURE__ */ jsx30(Loader25, { size: 12, className: "shrink-0 animate-spin text-blue-500" }),
|
|
6673
6714
|
/* @__PURE__ */ jsx30("span", { children: "\u6B63\u5728\u542F\u52A8..." })
|
|
6674
6715
|
] }) }) : status === "awaiting_answer" ? /* @__PURE__ */ jsx30("div", { className: "flex flex-col gap-1 py-2", children: /* @__PURE__ */ jsx30("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
|
|
6675
6716
|
] }) : /* @__PURE__ */ jsxs25(Fragment8, { children: [
|
|
@@ -6792,7 +6833,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6792
6833
|
message.entry_id ?? `${message.timestamp ?? "error"}-${index}`
|
|
6793
6834
|
) : null
|
|
6794
6835
|
) }) : status === "running" ? /* @__PURE__ */ jsxs25("div", { className: "px-3 py-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
6795
|
-
/* @__PURE__ */ jsx30(
|
|
6836
|
+
/* @__PURE__ */ jsx30(Loader25, { size: 12, className: "mr-1.5 inline animate-spin" }),
|
|
6796
6837
|
"\u6B63\u5728\u542F\u52A8..."
|
|
6797
6838
|
] }) : toolCall.result ? /* @__PURE__ */ jsx30("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
|
|
6798
6839
|
] })
|
|
@@ -7493,7 +7534,7 @@ function MemoryRefsHint({ refs: rawRefs }) {
|
|
|
7493
7534
|
}
|
|
7494
7535
|
|
|
7495
7536
|
// src/react/components/chat/CompactionCard.tsx
|
|
7496
|
-
import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight6, Loader2 as
|
|
7537
|
+
import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight6, Loader2 as Loader26, Square as Square3, XCircle } from "lucide-react";
|
|
7497
7538
|
import { useState as useState19 } from "react";
|
|
7498
7539
|
import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
7499
7540
|
var PERCENT_FORMATTER = new Intl.NumberFormat("zh-CN", {
|
|
@@ -7570,7 +7611,7 @@ function CompactionCard({
|
|
|
7570
7611
|
children: [
|
|
7571
7612
|
canExpand ? expanded ? /* @__PURE__ */ jsx32(ChevronDown2, { size: 12, className: "shrink-0" }) : /* @__PURE__ */ jsx32(ChevronRight6, { size: 12, className: "shrink-0" }) : null,
|
|
7572
7613
|
/* @__PURE__ */ jsx32("span", { children: source.status === "streaming" ? /* @__PURE__ */ jsxs27("span", { className: "inline-flex items-center gap-1", children: [
|
|
7573
|
-
/* @__PURE__ */ jsx32(
|
|
7614
|
+
/* @__PURE__ */ jsx32(Loader26, { size: 12, className: "animate-spin" }),
|
|
7574
7615
|
"\u6B63\u5728\u538B\u7F29\u4E0A\u4E0B\u6587"
|
|
7575
7616
|
] }) : source.status === "failed" ? /* @__PURE__ */ jsxs27("span", { className: "inline-flex items-center gap-1 text-rose-500/80", children: [
|
|
7576
7617
|
/* @__PURE__ */ jsx32(XCircle, { size: 12 }),
|
|
@@ -8398,6 +8439,8 @@ function ChatView({
|
|
|
8398
8439
|
onResyncSkills,
|
|
8399
8440
|
isResyncingSkills = false,
|
|
8400
8441
|
inputLabel,
|
|
8442
|
+
onDoubleEscape,
|
|
8443
|
+
composerHint,
|
|
8401
8444
|
classNames,
|
|
8402
8445
|
components,
|
|
8403
8446
|
renderers
|
|
@@ -8477,7 +8520,9 @@ function ChatView({
|
|
|
8477
8520
|
skillStatusBarInnerClassName: classNames?.skillStatusBarInner,
|
|
8478
8521
|
onResyncSkills,
|
|
8479
8522
|
isResyncingSkills,
|
|
8480
|
-
inputLabel
|
|
8523
|
+
inputLabel,
|
|
8524
|
+
onDoubleEscape,
|
|
8525
|
+
composerHint
|
|
8481
8526
|
}
|
|
8482
8527
|
)
|
|
8483
8528
|
] });
|
|
@@ -8534,4 +8579,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
|
|
|
8534
8579
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
8535
8580
|
*--------------------------------------------------------------------------------------------*)
|
|
8536
8581
|
*/
|
|
8537
|
-
//# sourceMappingURL=chunk-
|
|
8582
|
+
//# sourceMappingURL=chunk-SGOR4YXZ.js.map
|